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 | |
10 | CTestInfo::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 | |
34 | void 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 | |
39 | IStorage *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 | |
50 | class CTestInfoPath |
51 | { |
52 | public: |
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 | |
66 | class CTestCollectData |
67 | { |
68 | public: |
69 | char m_aCurrentDir[IO_MAX_PATH_LENGTH]; |
70 | std::vector<CTestInfoPath> *m_pvEntries; |
71 | }; |
72 | |
73 | int 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 | |
96 | void 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 | |
127 | CTestInfo::~CTestInfo() |
128 | { |
129 | if(!::testing::Test::HasFailure() && m_DeleteTestStorageFilesOnSuccess) |
130 | { |
131 | TestDeleteTestStorageFiles(pPath: m_aFilename); |
132 | } |
133 | } |
134 | |
135 | int 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 | |