95 lines
3.6 KiB
C++
95 lines
3.6 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 函数
|
|||
|
|
// 注意:内存泄漏本身无法通过常规断言直接验证,但可以通过工具检测。
|
|||
|
|
// 此测试主要验证函数能正常执行而不崩溃。
|
|||
|
|
TEST(MemoryTest, MemoryLeakFunctionRuns) {
|
|||
|
|
// 调用函数,验证其能正常执行完毕(不崩溃)。
|
|||
|
|
// 内存泄漏的检测通常依赖外部工具(如Valgrind, AddressSanitizer)。
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_memory_leak());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试 test_double_free 函数
|
|||
|
|
// 重复释放会导致未定义行为,通常是程序崩溃。
|
|||
|
|
// 在启用特定工具(如AddressSanitizer)时,可以捕获此错误。
|
|||
|
|
// 此测试在常规环境下可能不稳定,标记为可能崩溃。
|
|||
|
|
TEST(MemoryTest, DoubleFreeFunctionBehavior) {
|
|||
|
|
// 由于重复释放是未定义行为,我们主要测试函数是否能被调用。
|
|||
|
|
// 实际测试中,应结合 AddressSanitizer 等工具运行。
|
|||
|
|
// 这里仅作为演示,调用函数。
|
|||
|
|
// 注意:此测试在没有保护措施的环境下可能崩溃。
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_double_free());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试 test_file_leak 函数
|
|||
|
|
// 验证文件被创建,并且函数执行后文件句柄泄漏(无法直接断言)。
|
|||
|
|
// 可以通过检查文件是否存在来间接验证部分行为。
|
|||
|
|
TEST(MemoryTest, FileLeakFunctionCreatesFile) {
|
|||
|
|
const std::string filename = "test.txt";
|
|||
|
|
// 确保测试前文件不存在,避免干扰。
|
|||
|
|
if (fs::exists(filename)) {
|
|||
|
|
fs::remove(filename);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 调用函数,应该创建文件。
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_file_leak());
|
|||
|
|
|
|||
|
|
// 验证文件确实被创建了。
|
|||
|
|
EXPECT_TRUE(fs::exists(filename)) << "File should be created by test_file_leak.";
|
|||
|
|
|
|||
|
|
// 清理:删除测试文件,避免累积。
|
|||
|
|
// 注意:由于函数没有关闭文件,在某些系统上直接删除可能失败或有问题。
|
|||
|
|
// 这里尝试删除,但主要目的是验证文件创建。
|
|||
|
|
try {
|
|||
|
|
fs::remove(filename);
|
|||
|
|
} catch (...) {
|
|||
|
|
// 忽略删除错误
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 边界/异常测试:这些函数没有参数,因此边界测试不直接适用。
|
|||
|
|
// 但可以测试在多次调用下的行为(虽然不推荐,因为会累积泄漏)。
|
|||
|
|
TEST(MemoryTest, MultipleCallsDoNotCrash) {
|
|||
|
|
// 多次调用,验证不会因为累积的未定义行为立即崩溃。
|
|||
|
|
// 这是一个压力测试,但结果不可预测。
|
|||
|
|
for (int i = 0; i < 5; ++i) {
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_memory_leak());
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_double_free());
|
|||
|
|
EXPECT_NO_FATAL_FAILURE(test_file_leak());
|
|||
|
|
// 清理文件,避免重复创建失败。
|
|||
|
|
try { fs::remove("test.txt"); } catch (...) {}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 特殊场景:与内存/文件泄漏检测工具结合使用的说明性测试。
|
|||
|
|
// 此测试实际上不运行有问题的函数,而是说明正确的模式。
|
|||
|
|
TEST(MemoryTest, CorrectPatternForComparison) {
|
|||
|
|
// 正确分配和释放内存
|
|||
|
|
{
|
|||
|
|
int* data = new int[100];
|
|||
|
|
delete[] data; // 正确释放
|
|||
|
|
data = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 正确打开和关闭文件
|
|||
|
|
{
|
|||
|
|
FILE* fp = fopen("correct_test.txt", "w");
|
|||
|
|
ASSERT_NE(fp, nullptr) << "Failed to open file correctly.";
|
|||
|
|
fclose(fp); // 正确关闭
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清理正确测试创建的文件
|
|||
|
|
fs::remove("correct_test.txt");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int main(int argc, char **argv) {
|
|||
|
|
::testing::InitGoogleTest(&argc, argv);
|
|||
|
|
return RUN_ALL_TESTS();
|
|||
|
|
}
|