cdemo/tests/test_errors.cpp

121 lines
3.8 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 (*original_sigsegv_handler)(int);
void (*original_sigabrt_handler)(int);
void SetUp() override {
// 安装自定义信号处理器
original_sigsegv_handler = signal(SIGSEGV, signal_handler);
original_sigabrt_handler = signal(SIGABRT, signal_handler);
}
void TearDown() override {
// 恢复原始信号处理器
signal(SIGSEGV, original_sigsegv_handler);
signal(SIGABRT, original_sigabrt_handler);
}
};
// 测试 test_null_pointer 函数
TEST_F(ErrorsTest, TestNullPointerTriggersSignal) {
// 设置跳转点,如果发生信号则跳转回此处
if (setjmp(jump_buffer) == 0) {
// 尝试执行会触发信号的代码
test_null_pointer();
// 如果执行到这里,说明没有触发信号,测试失败
FAIL() << "Expected test_null_pointer to trigger a signal but it didn't";
} else {
// 成功捕获到信号
SUCCEED();
}
}
// 测试 test_array_out_of_bounds 函数
TEST_F(ErrorsTest, TestArrayOutOfBoundsTriggersSignal) {
if (setjmp(jump_buffer) == 0) {
test_array_out_of_bounds();
FAIL() << "Expected test_array_out_of_bounds to trigger a signal but it didn't";
} else {
SUCCEED();
}
}
// 测试 test_uninitialized_var 函数
// 注意:使用未初始化变量不一定会触发信号,行为是未定义的
// 我们只能验证函数可以执行而不崩溃(在某些平台上)
TEST_F(ErrorsTest, TestUninitializedVarDoesNotCrash) {
// 这个测试可能通过,也可能失败,取决于编译器和运行时环境
// 我们主要验证函数可以调用而不导致程序终止
EXPECT_NO_FATAL_FAILURE(test_uninitialized_var());
}
// 边界条件测试:验证正常数组访问不会触发信号
TEST_F(ErrorsTest, TestNormalArrayAccess) {
// 创建一个简单的测试来验证正常数组访问
int arr[3] = {1, 2, 3};
if (setjmp(jump_buffer) == 0) {
// 正常访问数组元素
std::cout << "Normal array access: " << arr[0] << std::endl;
std::cout << "Normal array access: " << arr[1] << std::endl;
std::cout << "Normal array access: " << arr[2] << std::endl;
SUCCEED();
} else {
FAIL() << "Normal array access triggered a signal unexpectedly";
}
}
// 特殊场景:验证空指针检查
TEST_F(ErrorsTest, TestNullPointerCheck) {
int* p = nullptr;
if (setjmp(jump_buffer) == 0) {
// 尝试解引用空指针
*p = 10;
FAIL() << "Expected null pointer dereference to trigger a signal but it didn't";
} else {
SUCCEED();
}
}
// 特殊场景:验证数组边界检查
TEST_F(ErrorsTest, TestArrayBoundaryCheck) {
int arr[3] = {1, 2, 3};
if (setjmp(jump_buffer) == 0) {
// 尝试访问刚好越界的元素(在某些系统上可能不会立即崩溃)
volatile int value = arr[3]; // 刚好越界
// 如果执行到这里,测试可能通过,也可能失败
// 这取决于编译器和运行时环境
std::cout << "Array access at index 3 returned: " << value << std::endl;
// 我们不标记为失败,因为行为是未定义的
SUCCEED();
} else {
// 成功捕获到信号
SUCCEED();
}
}
// 主函数
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}