cdemo/tests/test_memory.cpp

96 lines
3.8 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/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();
}