Compare commits
No commits in common. "test_20260415_174820" and "main" have entirely different histories.
test_20260
...
main
|
|
@ -1,99 +0,0 @@
|
||||||
#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:
|
|
||||||
// 保存原始的标准输出流
|
|
||||||
std::streambuf* original_cout;
|
|
||||||
// 用于捕获输出的字符串流
|
|
||||||
std::stringstream captured_cout;
|
|
||||||
|
|
||||||
void SetUp() override {
|
|
||||||
// 重定向 std::cout 到字符串流以捕获输出
|
|
||||||
original_cout = std::cout.rdbuf();
|
|
||||||
std::cout.rdbuf(captured_cout.rdbuf());
|
|
||||||
// 设置信号处理程序
|
|
||||||
std::signal(SIGSEGV, signal_handler);
|
|
||||||
std::signal(SIGABRT, signal_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TearDown() override {
|
|
||||||
// 恢复原始的标准输出流
|
|
||||||
std::cout.rdbuf(original_cout);
|
|
||||||
// 恢复默认信号处理
|
|
||||||
std::signal(SIGSEGV, SIG_DFL);
|
|
||||||
std::signal(SIGABRT, SIG_DFL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 辅助函数:安全执行可能崩溃的函数
|
|
||||||
bool executeWithCrashProtection(void (*func)()) {
|
|
||||||
if (setjmp(jump_buffer) == 0) {
|
|
||||||
func();
|
|
||||||
return false; // 没有崩溃
|
|
||||||
} else {
|
|
||||||
return true; // 发生了崩溃(信号被捕获)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 测试 test_null_pointer 函数
|
|
||||||
TEST_F(ErrorsTest, test_null_pointer_CausesCrash) {
|
|
||||||
// 期望函数执行会触发段错误(SIGSEGV)
|
|
||||||
bool didCrash = executeWithCrashProtection(test_null_pointer);
|
|
||||||
EXPECT_TRUE(didCrash) << "Expected test_null_pointer to cause a segmentation fault (crash).";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 测试 test_array_out_of_bounds 函数
|
|
||||||
TEST_F(ErrorsTest, test_array_out_of_bounds_CausesCrash) {
|
|
||||||
// 期望函数执行会触发段错误(SIGSEGV)或中止(SIGABRT)
|
|
||||||
bool didCrash = executeWithCrashProtection(test_array_out_of_bounds);
|
|
||||||
EXPECT_TRUE(didCrash) << "Expected test_array_out_of_bounds to cause a crash due to out-of-bounds access.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 测试 test_uninitialized_var 函数
|
|
||||||
// 注意:使用未初始化变量的行为是未定义的,可能不会立即崩溃。
|
|
||||||
// 测试主要验证函数可以执行(不保证结果),并检查是否有输出。
|
|
||||||
TEST_F(ErrorsTest, test_uninitialized_var_UndefinedBehavior) {
|
|
||||||
// 清除之前的捕获内容
|
|
||||||
captured_cout.str("");
|
|
||||||
captured_cout.clear();
|
|
||||||
|
|
||||||
// 执行函数。由于行为未定义,我们不假设它会崩溃。
|
|
||||||
// 在某些环境/编译器下,它可能运行并产生输出或什么都不做。
|
|
||||||
test_uninitialized_var();
|
|
||||||
|
|
||||||
// 获取捕获的输出
|
|
||||||
std::string output = captured_cout.str();
|
|
||||||
|
|
||||||
// 断言是不确定的,因为 val 未初始化。
|
|
||||||
// 我们只能断言它要么输出了 "val > 10",要么没有输出。
|
|
||||||
// 这是一个演示,实际中很难对未定义行为进行有意义的断言。
|
|
||||||
// 我们可以检查函数是否至少执行完毕而没有抛出异常(尽管崩溃也是可能的)。
|
|
||||||
// 更合适的做法可能是记录一个警告,或者使用工具(如 Valgrind, MSAN)来检测此类错误。
|
|
||||||
// 这里我们简单地不添加强断言,仅作为演示。
|
|
||||||
// 可以检查输出是否为空或者是特定字符串,但这依赖于未定义的值。
|
|
||||||
// 例如,如果 val 恰好 > 10,输出会是 "val > 10\n"。
|
|
||||||
// 我们只记录输出,不做确定性断言。
|
|
||||||
std::cout << "Note: test_uninitialized_var executed. Output (if any): '" << output << "'" << std::endl;
|
|
||||||
// 没有 EXPECT 断言,因为行为未定义。
|
|
||||||
// 一个替代方案是使用死亡测试,但未初始化读取不保证崩溃。
|
|
||||||
}
|
|
||||||
|
|
||||||
// 主函数(通常由 gtest_main 提供,这里显式写出用于独立编译)
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue