1#ifndef SAFEHERON_SGX_TEST_FRAMEWORK_H
2#define SAFEHERON_SGX_TEST_FRAMEWORK_H
7#include <unordered_map>
18namespace testframework_t {
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"
31 : std::runtime_error(FormatMsg(msg, file, line, func)) {
35 static std::string FormatMsg(
const std::string& msg,
const char* file,
int line,
const char* func) {
37 ":" + std::to_string(line) +
" in " + func +
"()";
70 getSuites()[suiteName].emplace_back(testName, func);
86 const auto& suites = getSuites();
87 if (suites.find(suiteName) == suites.end()) {
93 size_t passed = 0, failed = 0;
98 for (
const auto& [name, test] : suites.at(suiteName)) {
103 auto duration = end - start;
107 }
catch (
const std::exception& ex) {
109 auto duration = end - start;
111 " %-30s: %s (Time: %lldms)\n",
112 name, ex.what(), duration);
116 auto duration = end - start;
118 " %-30s: Unknown exception (Time: %lldms)\n",
143 size_t totalPassed = 0, totalFailed = 0;
147 for (
const auto& [suiteName, tests] : getSuites()) {
150 size_t passed = 0, failed = 0;
152 for (
const auto& [name, test] : tests) {
157 auto duration = end - start;
159 " %-30s (Time: %lldms)\n",
162 }
catch (
const std::exception& ex) {
164 auto duration = end - start;
166 " %-30s: %s (Time: %lldms)\n",
167 name, ex.what(), duration);
171 auto duration = end - start;
173 " %-30s: Unknown exception (Time: %lldms)\n",
179 totalPassed += passed;
180 totalFailed += failed;
194 totalPassed, totalFailed);
195 return totalFailed > 0 ? -1 : 0;
199 using Test = std::pair<const char*, TestFunc>;
200 using SuiteMap = std::unordered_map<std::string, std::vector<Test>>;
202 static SuiteMap& getSuites() {
203 static SuiteMap suites;
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); \
217 } suiteName##_##testName##_register; \
218 void suiteName##_##testName()
220#define ASSERT_TRUE(expr) \
223 throw ssgx::testframework_t::InternalAssertionException("ASSERT_TRUE failed: " #expr, __FILE__, __LINE__, \
228#define ASSERT_FALSE(expr) \
231 throw ssgx::testframework_t::InternalAssertionException("ASSERT_FALSE failed: " #expr, __FILE__, __LINE__, \
236#define ASSERT_EQ(a, b) \
238 if (!((a) == (b))) { \
239 throw ssgx::testframework_t::InternalAssertionException("ASSERT_EQ failed: " #a " == " #b, __FILE__, \
240 __LINE__, __func__); \
244#define ASSERT_NE(a, b) \
246 if (!((a) != (b))) { \
247 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NE failed: " #a " != " #b, __FILE__, \
248 __LINE__, __func__); \
252#define ASSERT_LT(a, b) \
254 if (!((a) < (b))) { \
255 throw ssgx::testframework_t::InternalAssertionException("ASSERT_LT failed: " #a " < " #b, __FILE__, \
256 __LINE__, __func__); \
260#define ASSERT_LE(a, b) \
262 if (!((a) <= (b))) { \
263 throw ssgx::testframework_t::InternalAssertionException("ASSERT_LE failed: " #a " <= " #b, __FILE__, \
264 __LINE__, __func__); \
268#define ASSERT_GT(a, b) \
270 if (!((a) > (b))) { \
271 throw ssgx::testframework_t::InternalAssertionException("ASSERT_GT failed: " #a " > " #b, __FILE__, \
272 __LINE__, __func__); \
276#define ASSERT_GE(a, b) \
278 if (!((a) >= (b))) { \
279 throw ssgx::testframework_t::InternalAssertionException("ASSERT_GE failed: " #a " >= " #b, __FILE__, \
280 __LINE__, __func__); \
284#define ASSERT_NEAR(a, b, abs_error) \
286 if (std::abs((a) - (b)) > abs_error) { \
287 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NEAR failed: " #a " ~= " #b, __FILE__, \
288 __LINE__, __func__); \
292#define ASSERT_STR_EQ(a, b) \
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__); \
301#define ASSERT_STR_NE(a, b) \
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__); \
310#define ASSERT_BYTES_EQ(a, b) \
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__); \
320#define ASSERT_BYTES_NE(a, b) \
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__); \
330#define ASSERT_MEM_EQ(ptr1, len1, ptr2, len2) \
332 if ((len1) != (len2)) { \
333 throw ssgx::testframework_t::InternalAssertionException( \
334 "ASSERT_MEM_EQ failed: Memory blocks have different lengths", __FILE__, __LINE__, __func__); \
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__); \
342#define ASSERT_MEM_NE(ptr1, len1, ptr2, len2) \
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__); \
350#define ASSERT_THROW(expr, exception_type) \
354 throw ssgx::testframework_t::InternalAssertionException("ASSERT_THROW failed: No exception thrown", \
355 __FILE__, __LINE__, __func__); \
356 } catch (const exception_type&) { \
358 throw ssgx::testframework_t::InternalAssertionException( \
359 "ASSERT_THROW failed: Wrong exception type thrown", __FILE__, __LINE__, __func__); \
363#define ASSERT_NO_THROW(expr) \
368 throw ssgx::testframework_t::InternalAssertionException("ASSERT_NO_THROW failed: Exception thrown", \
369 __FILE__, __LINE__, __func__); \
375 ssgx::utils_t::Printf(ANSI_ESCAPE_CODE_GREEN "[SUCCEED]" ANSI_ESCAPE_CODE_RESET \
376 " %s:%d in %s()\n", __FILE__, __LINE__, __func__); \
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