96 lines
3.8 KiB
C++
96 lines
3.8 KiB
C++
#include "gtest/gtest.h"
|
||
#include "src/memory.cpp"
|
||
#include <cstdio>
|
||
#include <cstdlib>
|
||
#include <fstream>
|
||
#include <filesystem>
|
||
|
||
namespace fs = std::filesystem;
|
||
|
||
// 测试 test_memory_leak 函数
|
||
// 注意:内存泄漏测试通常需要借助外部工具(如 Valgrind、AddressSanitizer)或自定义分配器来检测。
|
||
// 这里的测试主要验证函数能正常执行而不崩溃,并检查其副作用(如文件创建)。
|
||
// 对于内存泄漏,我们依赖外部工具或运行时检测。
|
||
TEST(MemoryTest, MemoryLeakFunctionRuns) {
|
||
// 测试函数是否能正常执行而不抛出异常或崩溃
|
||
EXPECT_NO_THROW(test_memory_leak());
|
||
// 该函数没有返回值或外部可观测的副作用,因此主要测试其可执行性
|
||
}
|
||
|
||
// 测试 test_double_free 函数
|
||
// 重复释放是未定义行为,可能导致程序崩溃。
|
||
// 我们期望测试能捕获到崩溃或异常,但具体行为取决于编译器和运行时环境。
|
||
// 在某些环境下(如使用 AddressSanitizer),可能会抛出异常或终止程序。
|
||
// 这里我们使用 EXPECT_DEATH 来测试是否会导致程序终止(在支持的情况下)。
|
||
TEST(MemoryTest, DoubleFreeCausesTermination) {
|
||
// 注意:EXPECT_DEATH 只在支持死亡测试的配置下工作(如使用 AddressSanitizer 或特定平台)。
|
||
// 如果死亡测试不可用,这个测试可能会被跳过或失败。
|
||
// 我们使用一个简单的死亡断言来检查程序是否因重复释放而终止。
|
||
// 正则表达式 ".*" 匹配任何死亡输出。
|
||
EXPECT_DEATH(test_double_free(), ".*");
|
||
}
|
||
|
||
// 测试 test_file_leak 函数
|
||
// 文件句柄泄漏测试:验证函数执行后文件是否被创建,但句柄未关闭。
|
||
// 我们无法直接测试句柄泄漏,但可以验证文件被创建。
|
||
// 注意:在函数执行后,文件 "test.txt" 应该存在于当前目录中。
|
||
TEST(MemoryTest, FileLeakCreatesFile) {
|
||
// 首先,如果文件已存在,删除它以确保测试的纯净性
|
||
std::string filename = "test.txt";
|
||
if (fs::exists(filename)) {
|
||
fs::remove(filename);
|
||
}
|
||
|
||
// 执行函数,应该创建文件
|
||
EXPECT_NO_THROW(test_file_leak());
|
||
|
||
// 验证文件是否被创建
|
||
EXPECT_TRUE(fs::exists(filename)) << "File should be created by test_file_leak";
|
||
|
||
// 可选:检查文件内容(虽然函数没有写入,但文件被打开为写入模式)
|
||
// 这里我们只检查存在性。
|
||
|
||
// 清理:删除测试文件,避免影响其他测试
|
||
if (fs::exists(filename)) {
|
||
fs::remove(filename);
|
||
}
|
||
}
|
||
|
||
// 边界和异常测试:由于这些函数没有参数,我们主要测试其行为。
|
||
// 对于 test_memory_leak 和 test_file_leak,我们测试多次调用是否累积泄漏。
|
||
// 注意:这通常需要外部工具检测。
|
||
TEST(MemoryTest, MultipleMemoryLeakCalls) {
|
||
// 多次调用,验证不会崩溃
|
||
for (int i = 0; i < 5; ++i) {
|
||
EXPECT_NO_THROW(test_memory_leak());
|
||
}
|
||
}
|
||
|
||
TEST(MemoryTest, MultipleFileLeakCalls) {
|
||
std::string filename = "test.txt";
|
||
// 清理可能存在的旧文件
|
||
if (fs::exists(filename)) {
|
||
fs::remove(filename);
|
||
}
|
||
|
||
// 多次调用,每次都会重新打开文件(可能泄漏句柄)
|
||
for (int i = 0; i < 3; ++i) {
|
||
EXPECT_NO_THROW(test_file_leak());
|
||
EXPECT_TRUE(fs::exists(filename)) << "File should exist after call " << i;
|
||
}
|
||
|
||
// 清理
|
||
if (fs::exists(filename)) {
|
||
fs::remove(filename);
|
||
}
|
||
}
|
||
|
||
// 特殊场景:测试在内存不足时 test_memory_leak 的行为(如果可能)
|
||
// 这通常难以模拟,但我们可以使用自定义分配器或模拟器。
|
||
// 由于时间限制,这里不实现。
|
||
|
||
int main(int argc, char **argv) {
|
||
::testing::InitGoogleTest(&argc, argv);
|
||
return RUN_ALL_TESTS();
|
||
}
|