#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); } // 测试夹具类 class ErrorsTest : public ::testing::Test { protected: // 保存原始信号处理器 void (*original_signal_handler)(int); void SetUp() override { // 设置自定义信号处理器来捕获段错误 original_signal_handler = signal(SIGSEGV, signal_handler); } void TearDown() override { // 恢复原始信号处理器 signal(SIGSEGV, original_signal_handler); } }; // 测试 test_null_pointer 函数 TEST_F(ErrorsTest, test_null_pointer_should_crash) { // 使用 setjmp/longjmp 来捕获预期的崩溃 if (setjmp(jump_buffer) == 0) { // 这应该触发段错误 test_null_pointer(); // 如果执行到这里,说明没有崩溃,测试失败 FAIL() << "Expected test_null_pointer to crash due to null pointer dereference"; } else { // 成功捕获到信号,测试通过 SUCCEED(); } } // 测试 test_array_out_of_bounds 函数 TEST_F(ErrorsTest, test_array_out_of_bounds_should_crash) { // 使用 setjmp/longjmp 来捕获预期的崩溃 if (setjmp(jump_buffer) == 0) { // 这应该触发段错误或未定义行为 test_array_out_of_bounds(); // 如果执行到这里,说明没有崩溃,测试失败 FAIL() << "Expected test_array_out_of_bounds to crash due to array out of bounds"; } else { // 成功捕获到信号,测试通过 SUCCEED(); } } // 测试 test_uninitialized_var 函数 TEST_F(ErrorsTest, test_uninitialized_var_has_undefined_behavior) { // 未初始化变量的行为是未定义的,可能不会崩溃 // 我们只能验证函数可以执行而不崩溃(或者可能崩溃) // 由于行为未定义,我们主要测试函数能够被调用 // 注意:未初始化变量的行为是未定义的,可能不会立即导致崩溃 // 但可能导致不可预测的结果 // 我们可以多次调用该函数,观察是否有时会崩溃 bool crashed_at_least_once = false; for (int i = 0; i < 10; i++) { if (setjmp(jump_buffer) == 0) { test_uninitialized_var(); // 没有崩溃,继续下一次迭代 } else { // 发生了崩溃 crashed_at_least_once = true; // 重置跳转缓冲区以进行下一次迭代 signal(SIGSEGV, signal_handler); } } // 由于未初始化变量的行为是未定义的,我们无法做出确定的断言 // 但我们可以记录观察到的行为 if (crashed_at_least_once) { std::cout << "Note: test_uninitialized_var caused a crash in at least one iteration" << std::endl; } else { std::cout << "Note: test_uninitialized_var did not cause a crash in any iteration" << std::endl; } // 对于未定义行为,我们无法做出确定的断言 // 但测试至少验证了函数可以被调用 SUCCEED(); } // 边界条件测试:验证这些错误函数确实会导致问题 TEST_F(ErrorsTest, verify_error_functions_are_dangerous) { // 这个测试验证所有三个函数都存在潜在的危险行为 // 通过尝试执行它们并观察是否发生崩溃 int dangerous_functions = 3; int detected_danger = 0; // 测试 test_null_pointer if (setjmp(jump_buffer) == 0) { test_null_pointer(); } else { detected_danger++; signal(SIGSEGV, signal_handler); } // 测试 test_array_out_of_bounds if (setjmp(jump_buffer) == 0) { test_array_out_of_bounds(); } else { detected_danger++; signal(SIGSEGV, signal_handler); } // 测试 test_uninitialized_var (可能不会崩溃,但行为未定义) // 我们调用它但不检查崩溃,因为未初始化变量的行为是未定义的 test_uninitialized_var(); // 至少前两个函数应该被检测为危险的 EXPECT_GE(detected_danger, 2) << "At least two of the error functions should be detected as dangerous"; } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }