cdemo/tests/test_memory.cpp

76 lines
3.6 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/memory.cpp"
#include <cstdio>
#include <cstdlib>
#include <fstream>
// 注意:由于原函数设计为演示错误,直接调用会导致内存泄漏、重复释放或文件泄漏。
// 因此,测试用例将重点验证这些错误行为是否被正确触发,或者通过特殊手段进行检测。
// 在实际项目中应使用内存检测工具如Valgrind, AddressSanitizer或文件句柄监控来验证泄漏。
// 以下测试用例主要展示如何构建测试框架和断言,但部分测试可能无法直接通过断言验证错误本身。
// 测试 test_memory_leak
// 该函数本身就会泄漏内存,无法通过返回值或直接副作用断言。
// 通常需要外部工具检测。这里我们仅确保函数可以无异常执行。
TEST(MemoryTest, MemoryLeakFunctionRuns) {
// 期望函数可以正常执行完毕,不崩溃。
EXPECT_NO_FATAL_FAILURE(test_memory_leak());
// 注意:此测试通过并不意味着没有内存泄漏,只是函数被调用了。
}
// 测试 test_double_free
// 该函数会重复释放内存通常会导致程序崩溃如abort
// 在Google Test中我们可以预期它会因重复释放而触发致命错误如SIGABRT
// 使用 EXPECT_DEATH 来断言进程会因重复释放而终止。
TEST(MemoryTest, DoubleFreeCausesDeath) {
// 期望调用 test_double_free 会导致进程终止例如因重复释放而abort
// 注意EXPECT_DEATH 会 fork 一个子进程来运行测试语句。
// 正则表达式 ".*" 匹配任何死亡输出。
EXPECT_DEATH(test_double_free(), ".*");
}
// 测试 test_file_leak
// 该函数会打开文件但未关闭,导致文件句柄泄漏。
// 与内存泄漏类似,直接断言泄漏很困难,通常需要外部监控。
// 我们可以验证文件是否被成功创建(作为函数执行的副作用)。
// 并在测试后清理文件,同时确保函数调用本身不崩溃。
TEST(MemoryTest, FileLeakFunctionCreatesFile) {
// 首先,确保测试文件不存在(清理之前的残留)。
std::remove("test.txt");
// 调用函数,期望它无异常执行并创建文件。
EXPECT_NO_FATAL_FAILURE(test_file_leak());
// 验证文件是否被创建(这是函数的主要可观察副作用)。
std::ifstream file("test.txt");
EXPECT_TRUE(file.good()); // 文件应成功打开(即存在)。
file.close();
// 测试结束后,清理文件。注意:原函数未关闭句柄,但进程退出后系统会回收。
// 为了测试环境干净,我们删除它。
std::remove("test.txt");
}
// 边界/异常测试:这些函数无参数,因此没有直接的边界输入。
// 但我们可以考虑在调用前后检查系统状态(需要更复杂的工具集成)。
// 以下是一个示例,展示如果函数被修改为接受参数,可能的测试思路(当前不适用)。
/*
// 假设函数签名变为void test_memory_leak_with_size(size_t size);
TEST(MemoryTest, MemoryLeakWithZeroSize) {
// 测试分配大小为0的情况行为可能是实现定义的
EXPECT_NO_FATAL_FAILURE(test_memory_leak_with_size(0));
}
TEST(MemoryTest, MemoryLeakWithLargeSize) {
// 测试分配极大内存(可能失败,但函数应处理或崩溃)。
// 使用 EXPECT_DEATH 或 EXPECT_THROW 取决于函数实现。
// 例如,如果 new 抛出 std::bad_alloc
// EXPECT_THROW(test_memory_leak_with_size(SIZE_MAX), std::bad_alloc);
}
*/
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}