Skip to content

Commit 77636ba

Browse files
committed
Add unit test framework for ENet library
Set up testing infrastructure to validate core ENet functionality.
1 parent b86517a commit 77636ba

File tree

4 files changed

+243
-0
lines changed

4 files changed

+243
-0
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ if(ENET_TEST)
8989
target_link_libraries(enet_test_extra_peers PRIVATE enet_test_interface)
9090
target_compile_definitions(enet_test_extra_peers PRIVATE ENET_USE_MORE_PEERS)
9191

92+
# Test unit
93+
add_executable(enet_test_unit test/units/test_main.c)
94+
target_link_libraries(enet_test_unit PRIVATE enet_test_interface)
95+
target_include_directories(enet_test_unit INTERFACE
96+
${CMAKE_CURRENT_SOURCE_DIR}/include
97+
${CMAKE_CURRENT_SOURCE_DIR}/test/units/include
98+
)
9299
endif()
93100

94101
# -----------------------------

test/units/enet_unit.h

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#ifndef ENET_UNIT_H
2+
#define ENET_UNIT_H
3+
4+
#include <stdio.h>
5+
6+
#ifdef _WIN32
7+
#include <windows.h>
8+
#else
9+
#include <unistd.h>
10+
#endif
11+
12+
typedef struct _ENetTestEntry ENetTestEntry;
13+
14+
typedef void (*ENetUnitTestFunc)(ENetTestEntry *entry);
15+
16+
typedef struct _ENetTestEntry {
17+
const char *name;
18+
ENetUnitTestFunc func;
19+
int failed;
20+
} ENetTestEntry;
21+
22+
#define MAX_TESTS 8096
23+
24+
static ENetTestEntry enet_test_entries[MAX_TESTS];
25+
static int enet_test_count = 0;
26+
27+
#ifdef _WIN32
28+
#define ASSERT_SLEEP(ms) Sleep(ms)
29+
#else
30+
#define ASSERT_SLEEP(ms) usleep(ms * 1000);
31+
#endif
32+
33+
#define ENET_EXPAND(x) x
34+
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
35+
#define ASSERT_THAT(...) ENET_EXPAND( GET_MACRO(__VA_ARGS__, ASSERT_THAT_IMPL3, ASSERT_THAT_IMPL2)(__VA_ARGS__) )
36+
37+
#define ENET_TEST_REGISTER(f) \
38+
do { \
39+
if (enet_test_count < MAX_TESTS) { \
40+
enet_test_entries[enet_test_count].name = #f; \
41+
enet_test_entries[enet_test_count].func = f; \
42+
enet_test_count++; \
43+
} else { \
44+
fprintf(stderr, "Too many unit tests!\n"); \
45+
} \
46+
} while (0)
47+
48+
#ifdef __GNUC__
49+
#define ENET_TEST_REGISTER_FUNC(func) static void __attribute__((constructor)) func(void)
50+
#elif defined(_MSC_VER)
51+
#pragma section(".CRT$XCU", read)
52+
#define ENET_TEST_REGISTER_FUNC(func) \
53+
static void __cdecl func(void); \
54+
__declspec(allocate(".CRT$XCU")) static void (__cdecl * const func##_ptr)(void) = func; \
55+
static void __cdecl func(void)
56+
#else
57+
#pragma message("WARNING: Please ENET_TEST_REGISTER_FUNC for this compiler")
58+
#define ENET_TEST_REGISTER_FUNC
59+
#endif
60+
61+
#define TEST(func) \
62+
static void enet_test_##func(ENetTestEntry * entry); \
63+
ENET_TEST_REGISTER_FUNC(enet_test_register_##func) { \
64+
ENET_TEST_REGISTER(enet_test_##func); \
65+
} \
66+
static void enet_test_##func(ENetTestEntry * entry)
67+
68+
#define ASSERT_THAT_IMPL3(a, b, m) do { \
69+
if ((a) != (b)) { \
70+
entry->failed += 1; \
71+
fprintf(stderr, "%s\n", m); \
72+
fprintf(stderr, "ASSERT_THAT(%s, %s)\n", #a, #b); \
73+
fprintf(stderr, " Expected: %s\n", #b); \
74+
fprintf(stderr, " But was: %s\n", #a); \
75+
fprintf(stderr, "at %s:%d\n", __FILE__, __LINE__); \
76+
return; \
77+
} \
78+
} while (0)
79+
80+
#define ASSERT_THAT_IMPL2(a, b) do { \
81+
if ((a) != (b)) { \
82+
entry->failed += 1; \
83+
fprintf(stderr, "ASSERT_THAT(%s, %s)\n", #a, #b); \
84+
fprintf(stderr, " Expected: %s\n", #b); \
85+
fprintf(stderr, " But was: %s\n", #a); \
86+
fprintf(stderr, "at %s:%d\n", __FILE__, __LINE__); \
87+
return; \
88+
} \
89+
} while (0)
90+
91+
static int run_all_tests(void) {
92+
int failed = 0;
93+
for (int i = 0; i < enet_test_count; ++i) {
94+
const char* prefix = "enet_test_";
95+
ENetTestEntry *entry = &enet_test_entries[i];
96+
97+
const char *funcName = entry->name + strlen(prefix);
98+
99+
fprintf(stdout, "[ RUNNING ] TEST(%s)\n", funcName);
100+
fflush(stdout);
101+
102+
entry->func(entry);
103+
fflush(stderr);
104+
105+
if (0 < entry->failed) {
106+
fprintf(stderr, "[ FAILED ] TEST(%s)\n", funcName);
107+
fflush(stderr);
108+
} else {
109+
fprintf(stdout, "[ PASSED ] TEST(%s)\n", funcName);
110+
fflush(stdout);
111+
}
112+
113+
failed += entry->failed;
114+
}
115+
116+
return failed;
117+
}
118+
119+
#endif

test/units/test_main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <stdio.h>
2+
3+
#include "enet.h"
4+
#include "enet_unit.h"
5+
#include "test_times.c"
6+
7+
int main() {
8+
if (enet_initialize() != 0) {
9+
printf("An error occurred while initializing ENet.\n");
10+
return 1;
11+
}
12+
13+
int failed = run_all_tests();
14+
15+
enet_deinitialize();
16+
17+
return failed;
18+
}

test/units/test_times.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "enet.h"
2+
#include "enet_unit.h"
3+
4+
TEST(ENET_TIME_LESS) {
5+
enet_uint32 a = 1000;
6+
enet_uint32 b = 2000;
7+
// Normal cases
8+
ASSERT_THAT(ENET_TIME_LESS(a, b), true, "ENET_TIME_LESS should return true for a < b");
9+
ASSERT_THAT(ENET_TIME_LESS(a, a), false, "ENET_TIME_LESS should return false for a == b");
10+
ASSERT_THAT(ENET_TIME_LESS(b, a), false, "ENET_TIME_LESS should return false for a > b");
11+
12+
// Cases involving ENET_TIME_OVERFLOW constant
13+
ASSERT_THAT(ENET_TIME_LESS(a, ENET_TIME_OVERFLOW), true,
14+
"ENET_TIME_LESS with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
15+
ASSERT_THAT(ENET_TIME_LESS(ENET_TIME_OVERFLOW, a), false,
16+
"ENET_TIME_LESS with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be false");
17+
ASSERT_THAT(ENET_TIME_LESS(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), false,
18+
"ENET_TIME_LESS with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
19+
}
20+
21+
TEST(ENET_TIME_GREATER) {
22+
enet_uint32 a = 1000;
23+
enet_uint32 b = 2000;
24+
// Normal cases
25+
ASSERT_THAT(ENET_TIME_GREATER(b, a), true, "ENET_TIME_GREATER should return true for a > b");
26+
ASSERT_THAT(ENET_TIME_GREATER(a, a), false, "ENET_TIME_GREATER should return false for a == b");
27+
ASSERT_THAT(ENET_TIME_GREATER(a, b), false, "ENET_TIME_GREATER should return false for a < b");
28+
29+
// Cases involving ENET_TIME_OVERFLOW constant
30+
ASSERT_THAT(ENET_TIME_GREATER(a, ENET_TIME_OVERFLOW), false,
31+
"ENET_TIME_GREATER with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
32+
ASSERT_THAT(ENET_TIME_GREATER(ENET_TIME_OVERFLOW, a), true,
33+
"ENET_TIME_GREATER with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be true");
34+
// ENET_TIME_GREATER is !ENET_TIME_LESS_EQUAL
35+
ASSERT_THAT(ENET_TIME_GREATER(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), false,
36+
"ENET_TIME_GREATER with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
37+
}
38+
39+
TEST(ENET_TIME_LESS_EQUAL) {
40+
enet_uint32 a = 1000;
41+
enet_uint32 b = 2000;
42+
// Normal cases
43+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, b), true, "ENET_TIME_LESS_EQUAL should return true for a <= b");
44+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, a), true,
45+
"ENET_TIME_LESS_EQUAL should return true for a <= b (equal)");
46+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(b, a), false,
47+
"ENET_TIME_LESS_EQUAL should return false for a <= b (greater)");
48+
49+
// Cases involving ENET_TIME_OVERFLOW constant
50+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, ENET_TIME_OVERFLOW), true,
51+
"ENET_TIME_LESS_EQUAL with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
52+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(ENET_TIME_OVERFLOW, a), false,
53+
"ENET_TIME_LESS_EQUAL with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be false");
54+
ASSERT_THAT(ENET_TIME_LESS_EQUAL(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), true,
55+
"ENET_TIME_LESS_EQUAL with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
56+
}
57+
58+
TEST(ENET_TIME_GREATER_EQUAL) {
59+
enet_uint32 a = 1000;
60+
enet_uint32 b = 2000;
61+
// Normal cases
62+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(b, a), true, "ENET_TIME_GREATER_EQUAL should return true for a >= b");
63+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, a), true, "ENET_TIME_GREATER_EQUAL should return true for a >= b (equal)");
64+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, b), false, "ENET_TIME_GREATER_EQUAL should return false for a >= b (less)");
65+
66+
// Cases involving ENET_TIME_OVERFLOW constant (based on ENET_TIME_GREATER logic)
67+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, ENET_TIME_OVERFLOW), false,
68+
"ENET_TIME_GREATER_EQUAL with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
69+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(ENET_TIME_OVERFLOW, a), true,
70+
"ENET_TIME_GREATER_EQUAL with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be true");
71+
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), true,
72+
"ENET_TIME_GREATER_EQUAL with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
73+
}
74+
75+
TEST(ENET_TIME_DIFFERENCE) {
76+
// Normal cases
77+
enet_uint32 a = 2000;
78+
enet_uint32 b = 1000;
79+
ASSERT_THAT(ENET_TIME_DIFFERENCE(a, b), 1000,
80+
"ENET_TIME_DIFFERENCE should return the absolute difference for a > b");
81+
ASSERT_THAT(ENET_TIME_DIFFERENCE(b, a), 1000,
82+
"ENET_TIME_DIFFERENCE should return the absolute difference for a < b");
83+
ASSERT_THAT(ENET_TIME_DIFFERENCE(a, a), 0u, "ENET_TIME_DIFFERENCE should return 0 for a == b");
84+
85+
// Case involving ENET_TIME_OVERFLOW constant as per user's example
86+
enet_uint32 c = 1000;
87+
enet_uint32 d = ENET_TIME_OVERFLOW;
88+
ASSERT_THAT(ENET_TIME_DIFFERENCE(c, d), d - c,
89+
"ENET_TIME_DIFFERENCE should return the difference involving ENET_TIME_OVERFLOW");
90+
}
91+
92+
TEST(enet_time_get) {
93+
enet_uint32 firstTime = enet_time_get();
94+
ASSERT_SLEEP(100);
95+
enet_uint32 secondTime = enet_time_get();
96+
97+
ASSERT_THAT(secondTime >= firstTime, true, "enet_time_get should return increasing time");
98+
ASSERT_THAT(secondTime - firstTime > 90, true, "Time difference should be at least ~100ms");
99+
}

0 commit comments

Comments
 (0)