Source code
Revision control
Copy as Markdown
Other Tools
// Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: BSD-3-Clause
#include "hwy/abort.h"
#include <stdio.h>
#include <string>
#include "hwy/base.h"
#include "hwy/tests/hwy_gtest.h"
#include "hwy/tests/test_util-inl.h" // HWY_ASSERT_EQ
namespace hwy {
namespace {
TEST(AbortTest, WarnOverrideChain) {
WarnFunc FirstHandler = [](const char* file, int line,
const char* formatted_err) -> void {
fprintf(stderr, "%s from %d of %s", formatted_err, line, file);
};
WarnFunc SecondHandler = [](const char* file, int line,
const char* formatted_err) -> void {
fprintf(stderr, "%s from %d of %s", formatted_err, line, file);
};
// Do not check that the first SetWarnFunc returns nullptr, because it is
// not guaranteed to be the first call - other TEST may come first.
(void)SetWarnFunc(FirstHandler);
HWY_ASSERT(GetWarnFunc() == FirstHandler);
HWY_ASSERT(SetWarnFunc(SecondHandler) == FirstHandler);
HWY_ASSERT(GetWarnFunc() == SecondHandler);
HWY_ASSERT(SetWarnFunc(nullptr) == SecondHandler);
HWY_ASSERT(GetWarnFunc() == nullptr);
}
#ifdef GTEST_HAS_DEATH_TEST
std::string GetBaseName(std::string const& file_name) {
auto last_slash = file_name.find_last_of("/\\");
return file_name.substr(last_slash + 1);
}
TEST(AbortDeathTest, AbortDefault) {
std::string expected = std::string("Abort at ") + GetBaseName(__FILE__) +
":" + std::to_string(__LINE__ + 1) + ": Test Abort";
ASSERT_DEATH(HWY_ABORT("Test %s", "Abort"), expected);
}
TEST(AbortDeathTest, AbortOverride) {
const AbortFunc CustomAbortHandler = [](const char* file, int line,
const char* formatted_err) -> void {
fprintf(stderr, "%s from %02d of %s", formatted_err, line,
GetBaseName(file).data());
};
SetAbortFunc(CustomAbortHandler);
// googletest regex does not support `+` for digits on Windows?!
// Hence we insert the expected line number manually.
char buf[100];
const std::string file = GetBaseName(__FILE__);
const int line = __LINE__ + 2; // from which HWY_ABORT is called
snprintf(buf, sizeof(buf), "Test Abort from %02d of %s", line, file.c_str());
ASSERT_DEATH({ HWY_ABORT("Test %s", "Abort"); }, buf);
}
#endif // GTEST_HAS_DEATH_TEST
TEST(AbortTest, AbortOverrideChain) {
AbortFunc FirstHandler = [](const char* file, int line,
const char* formatted_err) -> void {
fprintf(stderr, "%s from %d of %s", formatted_err, line, file);
};
AbortFunc SecondHandler = [](const char* file, int line,
const char* formatted_err) -> void {
fprintf(stderr, "%s from %d of %s", formatted_err, line, file);
};
// Do not check that the first SetAbortFunc returns nullptr, because it is
// not guaranteed to be the first call - other TEST may come first.
(void)SetAbortFunc(FirstHandler);
HWY_ASSERT(GetAbortFunc() == FirstHandler);
HWY_ASSERT(SetAbortFunc(SecondHandler) == FirstHandler);
HWY_ASSERT(GetAbortFunc() == SecondHandler);
HWY_ASSERT(SetAbortFunc(nullptr) == SecondHandler);
HWY_ASSERT(GetAbortFunc() == nullptr);
}
} // namespace
} // namespace hwy
HWY_TEST_MAIN();