diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp new file mode 100644 index 0000000..e7dbc4f --- /dev/null +++ b/tests/test_errors.cpp @@ -0,0 +1,136 @@ +#include "gtest/gtest.h" +#include "src/errors.cpp" +#include +#include +#include + +// 信号处理跳转点,用于捕获程序崩溃 +static jmp_buf jump_buffer; + +// 信号处理函数,用于捕获段错误等信号 +void signal_handler(int signum) { + longjmp(jump_buffer, 1); +} + +// 测试空指针解引用 +TEST(ErrorsTest, TestNullPointer) { + // 设置信号处理器以捕获段错误 + struct sigaction sa; + struct sigaction old_sa; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + // 保存旧的信号处理器 + sigaction(SIGSEGV, &sa, &old_sa); + + // 使用setjmp/longjmp来捕获信号 + if (setjmp(jump_buffer) == 0) { + // 尝试调用会触发空指针解引用的函数 + test_null_pointer(); + // 如果程序没有崩溃,测试失败 + FAIL() << "Expected null pointer dereference to cause a crash"; + } else { + // 成功捕获到信号,测试通过 + SUCCEED(); + } + + // 恢复旧的信号处理器 + sigaction(SIGSEGV, &old_sa, nullptr); +} + +// 测试数组越界访问 +TEST(ErrorsTest, TestArrayOutOfBounds) { + // 设置信号处理器以捕获段错误 + struct sigaction sa; + struct sigaction old_sa; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + // 保存旧的信号处理器 + sigaction(SIGSEGV, &sa, &old_sa); + + // 使用setjmp/longjmp来捕获信号 + if (setjmp(jump_buffer) == 0) { + // 尝试调用会触发数组越界的函数 + test_array_out_of_bounds(); + // 如果程序没有崩溃,测试失败 + FAIL() << "Expected array out of bounds access to cause a crash"; + } else { + // 成功捕获到信号,测试通过 + SUCCEED(); + } + + // 恢复旧的信号处理器 + sigaction(SIGSEGV, &old_sa, nullptr); +} + +// 测试未初始化变量使用 +TEST(ErrorsTest, TestUninitializedVar) { + // 未初始化变量的行为是未定义的,可能不会立即崩溃 + // 我们主要验证函数可以执行而不抛出异常 + // 注意:由于行为未定义,我们无法预测具体输出 + + // 重定向std::cout以捕获输出 + testing::internal::CaptureStdout(); + + // 调用函数 - 由于未定义行为,可能输出任何内容或不输出 + test_uninitialized_var(); + + // 获取输出 + std::string output = testing::internal::GetCapturedStdout(); + + // 由于未初始化变量的值是未定义的,我们无法做出具体断言 + // 但我们可以验证函数执行没有导致程序崩溃 + SUCCEED(); +} + +// 测试边界情况:多次调用错误函数 +TEST(ErrorsTest, TestMultipleErrorCalls) { + // 验证连续调用多个错误函数的行为 + // 注意:这些函数都会导致未定义行为,测试主要是验证它们不会相互干扰 + + // 设置信号处理器 + struct sigaction sa; + struct sigaction old_sa; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sigaction(SIGSEGV, &sa, &old_sa); + + // 测试顺序调用 + bool null_pointer_crashed = false; + bool array_bounds_crashed = false; + + // 测试空指针解引用 + if (setjmp(jump_buffer) == 0) { + test_null_pointer(); + } else { + null_pointer_crashed = true; + } + + // 重置跳转缓冲区 + if (setjmp(jump_buffer) == 0) { + test_array_out_of_bounds(); + } else { + array_bounds_crashed = true; + } + + // 验证两个函数都如预期般导致崩溃 + EXPECT_TRUE(null_pointer_crashed) << "Null pointer dereference should cause crash"; + EXPECT_TRUE(array_bounds_crashed) << "Array out of bounds should cause crash"; + + // 恢复信号处理器 + sigaction(SIGSEGV, &old_sa, nullptr); +} + +// 主函数 +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file