1#include "test.h"
2#include <gtest/gtest.h>
3
4#include <base/logger.h>
5#include <base/system.h>
6#include <engine/storage.h>
7
8#include <algorithm>
9
10CTestInfo::CTestInfo()
11{
12 const ::testing::TestInfo *pTestInfo =
13 ::testing::UnitTest::GetInstance()->current_test_info();
14
15 // Typed tests have test names like "TestName/0" and "TestName/1", which would result in invalid filenames.
16 // Replace the string after the first slash with the name of the typed test and use hyphen instead of slash.
17 char aTestCaseName[128];
18 str_copy(dst&: aTestCaseName, src: pTestInfo->test_case_name());
19 for(int i = 0; i < str_length(str: aTestCaseName); i++)
20 {
21 if(aTestCaseName[i] == '/')
22 {
23 aTestCaseName[i] = '-';
24 aTestCaseName[i + 1] = '\0';
25 str_append(dst&: aTestCaseName, src: pTestInfo->type_param());
26 break;
27 }
28 }
29 str_format(buffer: m_aFilenamePrefix, buffer_size: sizeof(m_aFilenamePrefix), format: "%s.%s-%d",
30 aTestCaseName, pTestInfo->name(), pid());
31 Filename(pBuffer: m_aFilename, BufferLength: sizeof(m_aFilename), pSuffix: ".tmp");
32}
33
34void CTestInfo::Filename(char *pBuffer, size_t BufferLength, const char *pSuffix)
35{
36 str_format(buffer: pBuffer, buffer_size: BufferLength, format: "%s%s", m_aFilenamePrefix, pSuffix);
37}
38
39IStorage *CTestInfo::CreateTestStorage()
40{
41 bool Error = fs_makedir(path: m_aFilename);
42 EXPECT_FALSE(Error);
43 if(Error)
44 {
45 return nullptr;
46 }
47 return CreateTempStorage(pDirectory: m_aFilename);
48}
49
50class CTestInfoPath
51{
52public:
53 bool m_IsDirectory;
54 char m_aData[IO_MAX_PATH_LENGTH];
55
56 bool operator<(const CTestInfoPath &Other) const
57 {
58 if(m_IsDirectory != Other.m_IsDirectory)
59 {
60 return m_IsDirectory < Other.m_IsDirectory;
61 }
62 return str_comp(a: m_aData, b: Other.m_aData) < 0;
63 }
64};
65
66class CTestCollectData
67{
68public:
69 char m_aCurrentDir[IO_MAX_PATH_LENGTH];
70 std::vector<CTestInfoPath> *m_pvEntries;
71};
72
73int TestCollect(const char *pName, int IsDir, int Unused, void *pUser)
74{
75 CTestCollectData *pData = (CTestCollectData *)pUser;
76
77 if(str_comp(a: pName, b: ".") == 0 || str_comp(a: pName, b: "..") == 0)
78 {
79 return 0;
80 }
81
82 CTestInfoPath Path;
83 Path.m_IsDirectory = IsDir;
84 str_format(buffer: Path.m_aData, buffer_size: sizeof(Path.m_aData), format: "%s/%s", pData->m_aCurrentDir, pName);
85 pData->m_pvEntries->push_back(x: Path);
86 if(Path.m_IsDirectory)
87 {
88 CTestCollectData DataRecursive;
89 str_copy(dst: DataRecursive.m_aCurrentDir, src: Path.m_aData, dst_size: sizeof(DataRecursive.m_aCurrentDir));
90 DataRecursive.m_pvEntries = pData->m_pvEntries;
91 fs_listdir(dir: DataRecursive.m_aCurrentDir, cb: TestCollect, type: 0, user: &DataRecursive);
92 }
93 return 0;
94}
95
96void TestDeleteTestStorageFiles(const char *pPath)
97{
98 std::vector<CTestInfoPath> vEntries;
99 CTestCollectData Data;
100 str_copy(dst: Data.m_aCurrentDir, src: pPath, dst_size: sizeof(Data.m_aCurrentDir));
101 Data.m_pvEntries = &vEntries;
102 fs_listdir(dir: Data.m_aCurrentDir, cb: TestCollect, type: 0, user: &Data);
103
104 CTestInfoPath Path;
105 Path.m_IsDirectory = true;
106 str_copy(dst: Path.m_aData, src: Data.m_aCurrentDir, dst_size: sizeof(Path.m_aData));
107 vEntries.push_back(x: Path);
108
109 // Sorts directories after files.
110 std::sort(first: vEntries.begin(), last: vEntries.end());
111
112 // Don't delete too many files.
113 ASSERT_LE(vEntries.size(), 10);
114 for(auto &Entry : vEntries)
115 {
116 if(Entry.m_IsDirectory)
117 {
118 ASSERT_FALSE(fs_removedir(Entry.m_aData));
119 }
120 else
121 {
122 ASSERT_FALSE(fs_remove(Entry.m_aData));
123 }
124 }
125}
126
127CTestInfo::~CTestInfo()
128{
129 if(!::testing::Test::HasFailure() && m_DeleteTestStorageFilesOnSuccess)
130 {
131 TestDeleteTestStorageFiles(pPath: m_aFilename);
132 }
133}
134
135int main(int argc, const char **argv)
136{
137 CCmdlineFix CmdlineFix(&argc, &argv);
138 log_set_global_logger_default();
139 ::testing::InitGoogleTest(argc: &argc, argv: const_cast<char **>(argv));
140 net_init();
141 if(secure_random_init())
142 {
143 fprintf(stderr, format: "random init failed\n");
144 return 1;
145 }
146 int Result = RUN_ALL_TESTS();
147 secure_random_uninit();
148 return Result;
149}
150