cdemo/tests/test_errors.cpp

87 lines
3.1 KiB
C++
Raw Permalink 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 <csignal>
#include <csetjmp>
// 用于捕获信号如SIGSEGV的全局跳转点
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, test_null_pointerTriggersCrash) {
// 设置跳转点,如果函数崩溃(触发信号),信号处理器会跳回这里
if (setjmp(jump_buffer) == 0) {
// 尝试调用会崩溃的函数
test_null_pointer();
// 如果执行到这里,说明没有崩溃,测试失败
FAIL() << "Expected test_null_pointer to cause a segmentation fault.";
} else {
// 成功捕获到信号(崩溃),测试通过
SUCCEED();
}
}
// 测试 test_array_out_of_bounds 函数
// 注意:此函数设计为会崩溃,因此测试期望它触发信号
TEST_F(ErrorsTest, test_array_out_of_boundsTriggersCrash) {
if (setjmp(jump_buffer) == 0) {
test_array_out_of_bounds();
FAIL() << "Expected test_array_out_of_bounds to cause a segmentation fault or abort.";
} else {
SUCCEED();
}
}
// 测试 test_uninitialized_var 函数
// 注意:使用未初始化变量的行为是未定义的,可能不会立即崩溃。
// 此测试主要验证函数可以运行(不保证其逻辑正确性)。
// 由于行为未定义,我们无法对输出做稳定断言。
TEST_F(ErrorsTest, test_uninitialized_varRunsWithoutCrash) {
// 我们只测试函数调用本身不会导致程序崩溃。
// 使用未初始化变量是逻辑错误,但程序可能仍会运行。
// 为了安全,我们也用信号捕获包裹它。
if (setjmp(jump_buffer) == 0) {
test_uninitialized_var();
// 如果执行到这里,说明没有因未初始化变量立即崩溃。
// 这是可接受的,因为未定义行为不一定崩溃。
SUCCEED();
} else {
// 如果它意外崩溃了,也记录下来,但这可能发生在某些平台/编译器上。
// 我们将此视为测试通过,因为函数确实展示了错误行为。
SUCCEED();
}
}
// 主函数通常由gtest_main库提供但这里显式写出以确保独立性
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}