153 lines
5.0 KiB
C++
153 lines
5.0 KiB
C++
#include <gtest/gtest.h>
|
|
#include "test_errors.h"
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <cstdio>
|
|
|
|
// 模拟函数声明,用于测试 main 函数调用顺序
|
|
namespace {
|
|
int call_order[7] = {0};
|
|
int call_index = 0;
|
|
|
|
void mock_test_null_pointer() { call_order[call_index++] = 1; }
|
|
void mock_test_array_out_of_bounds() { call_order[call_index++] = 2; }
|
|
void mock_test_uninitialized_var() { call_order[call_index++] = 3; }
|
|
void mock_test_memory_leak() { call_order[call_index++] = 4; }
|
|
void mock_test_double_free() { call_order[call_index++] = 5; }
|
|
void mock_test_file_leak() { call_order[call_index++] = 6; }
|
|
void mock_test_unused_code() { call_order[call_index++] = 7; }
|
|
}
|
|
|
|
// 测试 main 函数的基本功能
|
|
TEST(MainTest, MainFunctionCallsAllTestFunctions) {
|
|
// 保存原始函数指针
|
|
auto original_null_pointer = test_null_pointer;
|
|
auto original_array_out_of_bounds = test_array_out_of_bounds;
|
|
auto original_uninitialized_var = test_uninitialized_var;
|
|
auto original_memory_leak = test_memory_leak;
|
|
auto original_double_free = test_double_free;
|
|
auto original_file_leak = test_file_leak;
|
|
auto original_unused_code = test_unused_code;
|
|
|
|
// 替换为模拟函数
|
|
test_null_pointer = mock_test_null_pointer;
|
|
test_array_out_of_bounds = mock_test_array_out_of_bounds;
|
|
test_uninitialized_var = mock_test_uninitialized_var;
|
|
test_memory_leak = mock_test_memory_leak;
|
|
test_double_free = mock_test_double_free;
|
|
test_file_leak = mock_test_file_leak;
|
|
test_unused_code = mock_test_unused_code;
|
|
|
|
// 重置调用记录
|
|
call_index = 0;
|
|
for (int i = 0; i < 7; i++) {
|
|
call_order[i] = 0;
|
|
}
|
|
|
|
// 调用 main 函数
|
|
int result = main();
|
|
|
|
// 验证返回值
|
|
EXPECT_EQ(result, 0);
|
|
|
|
// 验证所有函数都被调用
|
|
EXPECT_EQ(call_index, 7);
|
|
|
|
// 验证调用顺序(按 main 函数中的顺序)
|
|
EXPECT_EQ(call_order[0], 1); // test_null_pointer
|
|
EXPECT_EQ(call_order[1], 2); // test_array_out_of_bounds
|
|
EXPECT_EQ(call_order[2], 3); // test_uninitialized_var
|
|
EXPECT_EQ(call_order[3], 4); // test_memory_leak
|
|
EXPECT_EQ(call_order[4], 5); // test_double_free
|
|
EXPECT_EQ(call_order[5], 6); // test_file_leak
|
|
EXPECT_EQ(call_order[6], 7); // test_unused_code
|
|
|
|
// 恢复原始函数
|
|
test_null_pointer = original_null_pointer;
|
|
test_array_out_of_bounds = original_array_out_of_bounds;
|
|
test_uninitialized_var = original_uninitialized_var;
|
|
test_memory_leak = original_memory_leak;
|
|
test_double_free = original_double_free;
|
|
test_file_leak = original_file_leak;
|
|
test_unused_code = original_unused_code;
|
|
}
|
|
|
|
// 测试 main 函数在异常情况下的行为
|
|
TEST(MainTest, MainFunctionReturnsZeroOnNormalExecution) {
|
|
// 直接测试 main 函数返回值
|
|
int result = main();
|
|
|
|
// main 函数应该返回 0
|
|
EXPECT_EQ(result, 0);
|
|
}
|
|
|
|
// 测试 main 函数不会抛出异常
|
|
TEST(MainTest, MainFunctionDoesNotThrow) {
|
|
// 确保 main 函数不会抛出异常
|
|
EXPECT_NO_THROW({
|
|
main();
|
|
});
|
|
}
|
|
|
|
// 测试 main 函数多次调用的稳定性
|
|
TEST(MainTest, MainFunctionCanBeCalledMultipleTimes) {
|
|
// 多次调用 main 函数,确保不会崩溃
|
|
for (int i = 0; i < 3; i++) {
|
|
EXPECT_NO_THROW({
|
|
int result = main();
|
|
EXPECT_EQ(result, 0);
|
|
});
|
|
}
|
|
}
|
|
|
|
// 测试 main 函数在内存受限环境下的行为
|
|
TEST(MainTest, MainFunctionHandlesMemoryConstraints) {
|
|
// 这个测试验证 main 函数在正常内存条件下能正常工作
|
|
// 注意:我们无法直接模拟内存不足,但可以验证函数不会过度分配内存
|
|
|
|
// 记录初始内存状态(简化版本)
|
|
std::ifstream status_file("/proc/self/status");
|
|
long initial_vm_size = 0;
|
|
|
|
if (status_file.is_open()) {
|
|
std::string line;
|
|
while (std::getline(status_file, line)) {
|
|
if (line.find("VmSize:") == 0) {
|
|
sscanf(line.c_str(), "VmSize: %ld", &initial_vm_size);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 调用 main 函数
|
|
int result = main();
|
|
EXPECT_EQ(result, 0);
|
|
|
|
// 检查内存使用情况(简化检查)
|
|
// 注意:由于测试函数可能分配内存,我们只做基本验证
|
|
if (initial_vm_size > 0) {
|
|
std::ifstream status_file2("/proc/self/status");
|
|
long final_vm_size = 0;
|
|
|
|
if (status_file2.is_open()) {
|
|
std::string line;
|
|
while (std::getline(status_file2, line)) {
|
|
if (line.find("VmSize:") == 0) {
|
|
sscanf(line.c_str(), "VmSize: %ld", &final_vm_size);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 验证内存使用在合理范围内(允许一定增长)
|
|
EXPECT_LE(final_vm_size, initial_vm_size * 2);
|
|
}
|
|
}
|
|
|
|
// 主函数,运行所有测试
|
|
int main(int argc, char **argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
} |