cdemo/tests/test_errors.cpp

133 lines
3.8 KiB
C++
Raw Permalink Normal View History

2026-04-14 02:49:57 +00:00
#include "gtest/gtest.h"
#include "src/errors.cpp"
#include <iostream>
#include <signal.h>
#include <setjmp.h>
// 用于捕获信号的跳转缓冲区
static jmp_buf env;
// 信号处理函数
void signal_handler(int sig) {
(void)sig;
longjmp(env, 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(env) == 0) {
// 尝试调用会触发段错误的函数
test_null_pointer();
// 如果执行到这里,说明没有触发段错误,测试失败
FAIL() << "Expected segmentation fault from null pointer dereference";
} else {
// 成功捕获到段错误,测试通过
SUCCEED();
}
// 恢复旧的信号处理器
sigaction(SIGSEGV, &old_sa, NULL);
}
// 测试数组越界访问
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(env) == 0) {
// 尝试调用会触发段错误的函数
test_array_out_of_bounds();
// 如果执行到这里,说明没有触发段错误,测试失败
FAIL() << "Expected segmentation fault from array out of bounds access";
} else {
// 成功捕获到段错误,测试通过
SUCCEED();
}
// 恢复旧的信号处理器
sigaction(SIGSEGV, &old_sa, NULL);
}
// 测试未初始化变量使用
TEST(ErrorsTest, TestUninitializedVar) {
// 未初始化变量的行为是未定义的,可能不会立即崩溃
// 我们只能验证函数可以执行而不崩溃(尽管行为未定义)
EXPECT_NO_FATAL_FAILURE(test_uninitialized_var());
// 注意:由于未初始化变量的值是未定义的,我们无法预测具体的输出
// 这个测试只是确保函数不会导致程序崩溃
// 在实际测试中,可能需要多次运行来观察不同的行为
}
// 边界条件测试:测试数组边界值
TEST(ErrorsTest, TestArrayBoundaryConditions) {
// 演示正确的数组访问
int arr[3] = {1, 2, 3};
// 测试合法边界
EXPECT_EQ(arr[0], 1);
EXPECT_EQ(arr[2], 3);
// 注意arr[3] 是越界的,即使编译器可能允许
// 但这是未定义行为
}
// 特殊场景测试:测试指针初始化为非空值
TEST(ErrorsTest, TestValidPointerDereference) {
int value = 42;
int* p = &value;
// 合法的指针解引用
EXPECT_EQ(*p, 42);
// 修改值
*p = 100;
EXPECT_EQ(value, 100);
}
// 测试未初始化变量的不同场景
TEST(ErrorsTest, TestUninitializedVarScenarios) {
// 场景1局部未初始化变量
{
int val;
// 行为未定义,但我们可以测试它是否可以被读取(尽管值不确定)
volatile int read_val = val; // 使用volatile防止优化
(void)read_val; // 避免未使用变量警告
}
// 场景2静态未初始化变量会被初始化为0
static int static_val;
EXPECT_EQ(static_val, 0); // 静态变量会被初始化为0
// 场景3正确初始化的变量作为对比
int initialized_val = 50;
EXPECT_EQ(initialized_val, 50);
}
// 主函数
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}