Safeheron-SGX-Native-Development-Framework v1.2.0
Loading...
Searching...
No Matches
ssgx_testframework_t.h
Go to the documentation of this file.
1#ifndef SAFEHERON_SGX_TEST_FRAMEWORK_H
2#define SAFEHERON_SGX_TEST_FRAMEWORK_H
3
4#include <functional>
5#include <stdexcept>
6#include <string>
7#include <unordered_map>
8#include <vector>
9
10#include "ssgx_utils_t.h"
11
12namespace ssgx {
18namespace testframework_t {
19
20#define ANSI_ESCAPE_CODE_RESET "\033[0m"
21#define ANSI_ESCAPE_CODE_RED "\033[31m"
22#define ANSI_ESCAPE_CODE_GREEN "\033[32m"
23#define ANSI_ESCAPE_CODE_YELLOW "\033[33m"
24#define ANSI_ESCAPE_CODE_BLUE "\033[34m"
25
29struct InternalAssertionException : public std::runtime_error {
30 InternalAssertionException(const std::string& msg, const char* file, int line, const char* func)
31 : std::runtime_error(FormatMsg(msg, file, line, func)) {
32 }
33
34 private:
35 static std::string FormatMsg(const std::string& msg, const char* file, int line, const char* func) {
36 return std::string(ANSI_ESCAPE_CODE_RED "[ASSERT FAILED]" ANSI_ESCAPE_CODE_RESET " ") + msg + " @ " + file +
37 ":" + std::to_string(line) + " in " + func + "()";
38 }
39};
40
41
52 public:
53 using TestFunc = std::function<void()>;
54
69 static void AddTest(const char* suiteName, const char* testName, TestFunc func) {
70 getSuites()[suiteName].emplace_back(testName, func);
71 }
72
85 static void RunSuite(const char* suiteName) {
86 const auto& suites = getSuites();
87 if (suites.find(suiteName) == suites.end()) {
89 suiteName);
90 return;
91 }
92
93 size_t passed = 0, failed = 0;
94
96 ANSI_ESCAPE_CODE_BLUE "\n========== Running Suite: %s ==========\n" ANSI_ESCAPE_CODE_RESET, suiteName);
97
98 for (const auto& [name, test] : suites.at(suiteName)) {
100 try {
101 test();
103 auto duration = end - start;
105 name, duration);
106 ++passed;
107 } catch (const std::exception& ex) {
109 auto duration = end - start;
111 " %-30s: %s (Time: %lldms)\n",
112 name, ex.what(), duration);
113 ++failed;
114 } catch (...) {
116 auto duration = end - start;
118 " %-30s: Unknown exception (Time: %lldms)\n",
119 name, duration);
120 ++failed;
121 }
122 }
123
124 ssgx::utils_t::Printf(ANSI_ESCAPE_CODE_BLUE "========== Suite Summary ==========\n" ANSI_ESCAPE_CODE_RESET);
126 "Failed: %zu\n" ANSI_ESCAPE_CODE_RESET,
127 passed, failed);
128 }
129
142 static int RunAllSuites() {
143 size_t totalPassed = 0, totalFailed = 0;
144 ssgx::utils_t::Printf(ANSI_ESCAPE_CODE_BLUE "\n========== Running All Test Suites "
145 "==========\n" ANSI_ESCAPE_CODE_RESET);
146
147 for (const auto& [suiteName, tests] : getSuites()) {
148 ssgx::utils_t::Printf(ANSI_ESCAPE_CODE_BLUE "\n---------- Suite: %s ----------\n" ANSI_ESCAPE_CODE_RESET,
149 suiteName.c_str());
150 size_t passed = 0, failed = 0;
151
152 for (const auto& [name, test] : tests) {
154 try {
155 test();
157 auto duration = end - start;
159 " %-30s (Time: %lldms)\n",
160 name, duration);
161 ++passed;
162 } catch (const std::exception& ex) {
164 auto duration = end - start;
166 " %-30s: %s (Time: %lldms)\n",
167 name, ex.what(), duration);
168 ++failed;
169 } catch (...) {
171 auto duration = end - start;
173 " %-30s: Unknown exception (Time: %lldms)\n",
174 name, duration);
175 ++failed;
176 }
177 }
178
179 totalPassed += passed;
180 totalFailed += failed;
181
183 suiteName.c_str());
185 "Failed: %zu\n" ANSI_ESCAPE_CODE_RESET,
186 passed, failed);
187 }
188
190 "\n========== All Suites Summary ==========\n" ANSI_ESCAPE_CODE_RESET);
193 "Total Failed: %zu\n" ANSI_ESCAPE_CODE_RESET,
194 totalPassed, totalFailed);
195 return totalFailed > 0 ? -1 : 0;
196 }
197
198 private:
199 using Test = std::pair<const char*, TestFunc>;
200 using SuiteMap = std::unordered_map<std::string, std::vector<Test>>;
201
202 static SuiteMap& getSuites() {
203 static SuiteMap suites;
204 return suites;
205 }
206};
207
208}; // namespace testframework_t
209}; // namespace ssgx
210
211#define TEST(suiteName, testName) \
212 void suiteName##_##testName(); \
213 struct suiteName##_##testName##_Register { \
214 suiteName##_##testName##_Register() { \
215 ssgx::testframework_t::TestManager::AddTest(#suiteName, #testName, suiteName##_##testName); \
216 } \
217 } suiteName##_##testName##_register; \
218 void suiteName##_##testName()
219
220#define ASSERT_TRUE(expr) \
221 do { \
222 if (!(expr)) { \
223 throw ssgx::testframework_t::InternalAssertionException("ASSERT_TRUE failed: " #expr, __FILE__, __LINE__, \
224 __func__); \
225 } \
226 } while (0)
227
228#define ASSERT_FALSE(expr) \
229 do { \
230 if ((expr)) { \
231 throw ssgx::testframework_t::InternalAssertionException("ASSERT_FALSE failed: " #expr, __FILE__, __LINE__, \
232 __func__); \
233 } \
234 } while (0)
235
236#define ASSERT_EQ(a, b) \
237 do { \
238 if (!((a) == (b))) { \
239 throw ssgx::testframework_t::InternalAssertionException("ASSERT_EQ failed: " #a " == " #b, __FILE__, \
240 __LINE__, __func__); \
241 } \
242 } while (0)
243
244#define ASSERT_NE(a, b) \
245 do { \
246 if (!((a) != (b))) { \
247 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NE failed: " #a " != " #b, __FILE__, \
248 __LINE__, __func__); \
249 } \
250 } while (0)
251
252#define ASSERT_LT(a, b) \
253 do { \
254 if (!((a) < (b))) { \
255 throw ssgx::testframework_t::InternalAssertionException("ASSERT_LT failed: " #a " < " #b, __FILE__, \
256 __LINE__, __func__); \
257 } \
258 } while (0)
259
260#define ASSERT_LE(a, b) \
261 do { \
262 if (!((a) <= (b))) { \
263 throw ssgx::testframework_t::InternalAssertionException("ASSERT_LE failed: " #a " <= " #b, __FILE__, \
264 __LINE__, __func__); \
265 } \
266 } while (0)
267
268#define ASSERT_GT(a, b) \
269 do { \
270 if (!((a) > (b))) { \
271 throw ssgx::testframework_t::InternalAssertionException("ASSERT_GT failed: " #a " > " #b, __FILE__, \
272 __LINE__, __func__); \
273 } \
274 } while (0)
275
276#define ASSERT_GE(a, b) \
277 do { \
278 if (!((a) >= (b))) { \
279 throw ssgx::testframework_t::InternalAssertionException("ASSERT_GE failed: " #a " >= " #b, __FILE__, \
280 __LINE__, __func__); \
281 } \
282 } while (0)
283
284#define ASSERT_NEAR(a, b, abs_error) \
285 do { \
286 if (std::abs((a) - (b)) > abs_error) { \
287 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NEAR failed: " #a " ~= " #b, __FILE__, \
288 __LINE__, __func__); \
289 } \
290 } while (0)
291
292#define ASSERT_STR_EQ(a, b) \
293 do { \
294 if (std::string(a) != std::string(b)) { \
295 throw ssgx::testframework_t::InternalAssertionException("ASSERT_STR_EQ failed: \"" + std::string(a) + \
296 "\" != \"" + std::string(b) + "\"", \
297 __FILE__, __LINE__, __func__); \
298 } \
299 } while (0)
300
301#define ASSERT_STR_NE(a, b) \
302 do { \
303 if (std::string(a) == std::string(b)) { \
304 throw ssgx::testframework_t::InternalAssertionException("ASSERT_STR_NE failed: \"" + std::string(a) + \
305 "\" == \"" + std::string(b) + "\"", \
306 __FILE__, __LINE__, __func__); \
307 } \
308 } while (0)
309
310#define ASSERT_BYTES_EQ(a, b) \
311 do { \
312 if ((a).size() != (b).size() || std::memcmp((a).data(), (b).data(), (a).size()) != 0) { \
313 throw ssgx::testframework_t::InternalAssertionException( \
314 "ASSERT_BYTES_EQ failed: \"" + std::string((a).begin(), (a).end()) + "\" != \"" + \
315 std::string((b).begin(), (b).end()) + "\"", \
316 __FILE__, __LINE__, __func__); \
317 } \
318 } while (0)
319
320#define ASSERT_BYTES_NE(a, b) \
321 do { \
322 if ((a).size() == (b).size() && std::memcmp((a).data(), (b).data(), (a).size()) == 0) { \
323 throw ssgx::testframework_t::InternalAssertionException( \
324 "ASSERT_BYTES_NE failed: \"" + std::string((a).begin(), (a).end()) + "\" == \"" + \
325 std::string((b).begin(), (b).end()) + "\"", \
326 __FILE__, __LINE__, __func__); \
327 } \
328 } while (0)
329
330#define ASSERT_MEM_EQ(ptr1, len1, ptr2, len2) \
331 do { \
332 if ((len1) != (len2)) { \
333 throw ssgx::testframework_t::InternalAssertionException( \
334 "ASSERT_MEM_EQ failed: Memory blocks have different lengths", __FILE__, __LINE__, __func__); \
335 } \
336 if (std::memcmp((ptr1), (ptr2), (len1)) != 0) { \
337 throw ssgx::testframework_t::InternalAssertionException( \
338 "ASSERT_MEM_EQ failed: Memory blocks are not equal", __FILE__, __LINE__, __func__); \
339 } \
340 } while (0)
341
342#define ASSERT_MEM_NE(ptr1, len1, ptr2, len2) \
343 do { \
344 if ((len1) == (len2) && std::memcmp((ptr1), (ptr2), (len1)) == 0) { \
345 throw ssgx::testframework_t::InternalAssertionException("ASSERT_MEM_NE failed: Memory blocks are equal", \
346 __FILE__, __LINE__, __func__); \
347 } \
348 } while (0)
349
350#define ASSERT_THROW(expr, exception_type) \
351 do { \
352 try { \
353 expr; \
354 throw ssgx::testframework_t::InternalAssertionException("ASSERT_THROW failed: No exception thrown", \
355 __FILE__, __LINE__, __func__); \
356 } catch (const exception_type&) { \
357 } catch (...) { \
358 throw ssgx::testframework_t::InternalAssertionException( \
359 "ASSERT_THROW failed: Wrong exception type thrown", __FILE__, __LINE__, __func__); \
360 } \
361 } while (0)
362
363#define ASSERT_NO_THROW(expr) \
364 do { \
365 try { \
366 expr; \
367 } catch (...) { \
368 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NO_THROW failed: Exception thrown", \
369 __FILE__, __LINE__, __func__); \
370 } \
371 } while (0)
372
373#define SUCCEED() \
374 do { \
375 ssgx::utils_t::Printf(ANSI_ESCAPE_CODE_GREEN "[SUCCEED]" ANSI_ESCAPE_CODE_RESET \
376 " %s:%d in %s()\n", __FILE__, __LINE__, __func__); \
377 } while (0)
378
379#endif // SAFEHERON_SGX_TEST_FRAMEWORK_H
Manages registration and execution of test cases grouped into suites.
Definition ssgx_testframework_t.h:51
static int RunAllSuites()
Executes all registered test suites and their test cases.
Definition ssgx_testframework_t.h:142
static void AddTest(const char *suiteName, const char *testName, TestFunc func)
Registers a test case with the framework.
Definition ssgx_testframework_t.h:69
std::function< void()> TestFunc
Definition ssgx_testframework_t.h:53
static void RunSuite(const char *suiteName)
Executes all registered test cases within a specific test suite.
Definition ssgx_testframework_t.h:85
static int64_t NowInMilliseconds()
Returns the current time in milliseconds since the UNIX epoch.
int Printf(const char *fmt,...)
Print formatted data to stdout.
Definition ssgx_attestation_t.h:6
#define ANSI_ESCAPE_CODE_GREEN
Definition ssgx_testframework_t.h:22
#define ANSI_ESCAPE_CODE_RED
Definition ssgx_testframework_t.h:21
#define ANSI_ESCAPE_CODE_BLUE
Definition ssgx_testframework_t.h:24
#define ANSI_ESCAPE_CODE_RESET
Definition ssgx_testframework_t.h:20
Internal exceptions thrown by the test framework.
Definition ssgx_testframework_t.h:29
InternalAssertionException(const std::string &msg, const char *file, int line, const char *func)
Definition ssgx_testframework_t.h:30