cdemo/tests/test_errors.cpp

133 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();
}