78 lines
2.6 KiB
C++
78 lines
2.6 KiB
C++
|
|
#include "gtest/gtest.h"
|
|||
|
|
#include "src/errors.cpp"
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <csignal>
|
|||
|
|
#include <csetjmp>
|
|||
|
|
|
|||
|
|
// 信号处理工具,用于捕获程序崩溃
|
|||
|
|
static jmp_buf jump_buffer;
|
|||
|
|
|
|||
|
|
void signal_handler(int sig) {
|
|||
|
|
(void)sig;
|
|||
|
|
longjmp(jump_buffer, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试夹具类
|
|||
|
|
class ErrorsTest : public ::testing::Test {
|
|||
|
|
protected:
|
|||
|
|
void SetUp() override {
|
|||
|
|
// 保存旧的信号处理器
|
|||
|
|
old_sigsegv_handler = std::signal(SIGSEGV, signal_handler);
|
|||
|
|
old_sigabrt_handler = std::signal(SIGABRT, signal_handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void TearDown() override {
|
|||
|
|
// 恢复旧的信号处理器
|
|||
|
|
std::signal(SIGSEGV, old_sigsegv_handler);
|
|||
|
|
std::signal(SIGABRT, old_sigabrt_handler);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 执行一个预期会崩溃的函数,并验证它确实崩溃了
|
|||
|
|
void ExpectFunctionCrashes(void (*func)()) {
|
|||
|
|
if (setjmp(jump_buffer) == 0) {
|
|||
|
|
// 第一次进入,执行预期会崩溃的函数
|
|||
|
|
func();
|
|||
|
|
// 如果函数没有崩溃,测试失败
|
|||
|
|
FAIL() << "Expected function to crash, but it did not.";
|
|||
|
|
} else {
|
|||
|
|
// 函数崩溃,被信号处理器跳转回来,测试通过
|
|||
|
|
SUCCEED();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
using SignalHandler = void (*)(int);
|
|||
|
|
SignalHandler old_sigsegv_handler;
|
|||
|
|
SignalHandler old_sigabrt_handler;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 测试 test_null_pointer 函数
|
|||
|
|
TEST_F(ErrorsTest, test_null_pointer_CrashesOnDereference) {
|
|||
|
|
// 这个函数应该因为解引用空指针而崩溃
|
|||
|
|
ExpectFunctionCrashes(test_null_pointer);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试 test_array_out_of_bounds 函数
|
|||
|
|
TEST_F(ErrorsTest, test_array_out_of_bounds_CrashesOnOutOfBoundsAccess) {
|
|||
|
|
// 这个函数应该因为数组越界访问而崩溃
|
|||
|
|
ExpectFunctionCrashes(test_array_out_of_bounds);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试 test_uninitialized_var 函数
|
|||
|
|
// 注意:使用未初始化变量的行为是未定义的,它可能崩溃,也可能不崩溃。
|
|||
|
|
// 因此,这个测试只是执行函数,不强制断言其行为。
|
|||
|
|
// 在实际测试中,我们可能使用工具(如 Valgrind, MSAN)来检测此类错误。
|
|||
|
|
TEST_F(ErrorsTest, test_uninitialized_var_UndefinedBehavior) {
|
|||
|
|
// 由于行为未定义,我们只执行函数,不进行断言。
|
|||
|
|
// 在启用了未初始化变量检测的构建中,这可能会触发错误。
|
|||
|
|
test_uninitialized_var();
|
|||
|
|
// 没有断言,因为行为未定义。
|
|||
|
|
// 这个测试的存在是为了记录和覆盖这个函数。
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 主函数(如果单独编译测试文件需要)
|
|||
|
|
int main(int argc, char **argv) {
|
|||
|
|
::testing::InitGoogleTest(&argc, argv);
|
|||
|
|
return RUN_ALL_TESTS();
|
|||
|
|
}
|