Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ if(ENET_TEST)
target_link_libraries(enet_test_extra_peers PRIVATE enet_test_interface)
target_compile_definitions(enet_test_extra_peers PRIVATE ENET_USE_MORE_PEERS)

# Test unit
add_executable(enet_test_unit test/units/test_main.c)
target_link_libraries(enet_test_unit PRIVATE enet_test_interface)
target_include_directories(enet_test_unit INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/test/units/include
)
endif()

# -----------------------------
Expand Down
102 changes: 102 additions & 0 deletions test/units/enet_unit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#ifndef ENET_UNIT_H
#define ENET_UNIT_H

#include <stdio.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

typedef struct _ENetTestEntry ENetTestEntry;

typedef void (*ENetUnitTestFunc)(ENetTestEntry *entry);

typedef struct _ENetTestEntry {
const char *name;
ENetUnitTestFunc func;
int failed;
} ENetTestEntry;

#define MAX_TESTS 8096

static ENetTestEntry enet_test_entries[MAX_TESTS];
static int enet_test_count = 0;

#ifdef _WIN32
#define ASSERT_SLEEP(ms) Sleep(ms)
#else
#define ASSERT_SLEEP(ms) usleep(ms * 1000);
#endif

#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define ASSERT_THAT(...) GET_MACRO(__VA_ARGS__, ASSERT_THAT_IMPL3, ASSERT_THAT_IMPL2)(__VA_ARGS__)

#define REGISTER_TEST(f) \
do { \
if (enet_test_count < MAX_TESTS) { \
enet_test_entries[enet_test_count].name = #f; \
enet_test_entries[enet_test_count].func = f; \
enet_test_count++; \
} else { \
fprintf(stderr, "Too many unit tests!\n"); \
} \
} while (0)

#define TEST(func) \
static void test_##func(ENetTestEntry * entry); \
__attribute__((constructor)) static void register_##func(void) { \
REGISTER_TEST(test_##func); \
} \
static void test_##func(ENetTestEntry * entry)

#define ASSERT_THAT_IMPL3(a, b, m) do { \
if ((a) != (b)) { \
entry->failed += 1; \
fprintf(stderr, "%s\n", m); \
fprintf(stderr, "ASSERT_THAT(%s, %s)\n", #a, #b); \
fprintf(stderr, " Expected: %s\n", #b); \
fprintf(stderr, " But was: %s\n", #a); \
fprintf(stderr, "at %s:%d\n", __FILE__, __LINE__); \
return; \
} \
} while (0)

#define ASSERT_THAT_IMPL2(a, b) do { \
if ((a) != (b)) { \
entry->failed += 1; \
fprintf(stderr, "ASSERT_THAT(%s, %s)\n", #a, #b); \
fprintf(stderr, " Expected: %s\n", #b); \
fprintf(stderr, " But was: %s\n", #a); \
fprintf(stderr, "at %s:%d\n", __FILE__, __LINE__); \
return; \
} \
} while (0)

static int run_all_tests(void) {
int failed = 0;
for (int i = 0; i < enet_test_count; ++i) {
ENetTestEntry *entry = &enet_test_entries[i];

fprintf(stdout, "[ RUNNING ] %s\n", entry->name);
fflush(stdout);

entry->func(entry);
fflush(stderr);

if (0 < entry->failed) {
fprintf(stderr, "[ FAILED ] %s\n", entry->name);
fflush(stderr);
} else {
fprintf(stdout, "[ PASSED ] %s\n", entry->name);
fflush(stdout);
}

failed += entry->failed;
}

return failed;
}

#endif
18 changes: 18 additions & 0 deletions test/units/test_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>

#include "enet.h"
#include "enet_unit.h"
#include "test_times.c"

int main() {
if (enet_initialize() != 0) {
printf("An error occurred while initializing ENet.\n");
return 1;
}

int failed = run_all_tests();

enet_deinitialize();

return failed;
}
99 changes: 99 additions & 0 deletions test/units/test_times.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "enet.h"
#include "enet_unit.h"

TEST(ENET_TIME_LESS) {
enet_uint32 a = 1000;
enet_uint32 b = 2000;
// Normal cases
ASSERT_THAT(ENET_TIME_LESS(a, b), true, "ENET_TIME_LESS should return true for a < b");
ASSERT_THAT(ENET_TIME_LESS(a, a), false, "ENET_TIME_LESS should return false for a == b");
ASSERT_THAT(ENET_TIME_LESS(b, a), false, "ENET_TIME_LESS should return false for a > b");

// Cases involving ENET_TIME_OVERFLOW constant
ASSERT_THAT(ENET_TIME_LESS(a, ENET_TIME_OVERFLOW), true,
"ENET_TIME_LESS with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
ASSERT_THAT(ENET_TIME_LESS(ENET_TIME_OVERFLOW, a), false,
"ENET_TIME_LESS with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be false");
ASSERT_THAT(ENET_TIME_LESS(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), false,
"ENET_TIME_LESS with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
}

TEST(ENET_TIME_GREATER) {
enet_uint32 a = 1000;
enet_uint32 b = 2000;
// Normal cases
ASSERT_THAT(ENET_TIME_GREATER(b, a), true, "ENET_TIME_GREATER should return true for a > b");
ASSERT_THAT(ENET_TIME_GREATER(a, a), false, "ENET_TIME_GREATER should return false for a == b");
ASSERT_THAT(ENET_TIME_GREATER(a, b), false, "ENET_TIME_GREATER should return false for a < b");

// Cases involving ENET_TIME_OVERFLOW constant
ASSERT_THAT(ENET_TIME_GREATER(a, ENET_TIME_OVERFLOW), false,
"ENET_TIME_GREATER with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
ASSERT_THAT(ENET_TIME_GREATER(ENET_TIME_OVERFLOW, a), true,
"ENET_TIME_GREATER with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be true");
// ENET_TIME_GREATER is !ENET_TIME_LESS_EQUAL
ASSERT_THAT(ENET_TIME_GREATER(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), false,
"ENET_TIME_GREATER with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
}

TEST(ENET_TIME_LESS_EQUAL) {
enet_uint32 a = 1000;
enet_uint32 b = 2000;
// Normal cases
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, b), true, "ENET_TIME_LESS_EQUAL should return true for a <= b");
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, a), true,
"ENET_TIME_LESS_EQUAL should return true for a <= b (equal)");
ASSERT_THAT(ENET_TIME_LESS_EQUAL(b, a), false,
"ENET_TIME_LESS_EQUAL should return false for a <= b (greater)");

// Cases involving ENET_TIME_OVERFLOW constant
ASSERT_THAT(ENET_TIME_LESS_EQUAL(a, ENET_TIME_OVERFLOW), true,
"ENET_TIME_LESS_EQUAL with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
ASSERT_THAT(ENET_TIME_LESS_EQUAL(ENET_TIME_OVERFLOW, a), false,
"ENET_TIME_LESS_EQUAL with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be false");
ASSERT_THAT(ENET_TIME_LESS_EQUAL(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), true,
"ENET_TIME_LESS_EQUAL with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
}

TEST(ENET_TIME_GREATER_EQUAL) {
enet_uint32 a = 1000;
enet_uint32 b = 2000;
// Normal cases
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(b, a), true, "ENET_TIME_GREATER_EQUAL should return true for a >= b");
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, a), true, "ENET_TIME_GREATER_EQUAL should return true for a >= b (equal)");
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, b), false, "ENET_TIME_GREATER_EQUAL should return false for a >= b (less)");

// Cases involving ENET_TIME_OVERFLOW constant (based on ENET_TIME_GREATER logic)
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(a, ENET_TIME_OVERFLOW), false,
"ENET_TIME_GREATER_EQUAL with a < ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be false");
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(ENET_TIME_OVERFLOW, a), true,
"ENET_TIME_GREATER_EQUAL with a == ENET_TIME_OVERFLOW and b < ENET_TIME_OVERFLOW should be true");
ASSERT_THAT(ENET_TIME_GREATER_EQUAL(ENET_TIME_OVERFLOW, ENET_TIME_OVERFLOW), true,
"ENET_TIME_GREATER_EQUAL with a == ENET_TIME_OVERFLOW and b == ENET_TIME_OVERFLOW should be true");
}

TEST(ENET_TIME_DIFFERENCE) {
// Normal cases
enet_uint32 a = 2000;
enet_uint32 b = 1000;
ASSERT_THAT(ENET_TIME_DIFFERENCE(a, b), 1000,
"ENET_TIME_DIFFERENCE should return the absolute difference for a > b");
ASSERT_THAT(ENET_TIME_DIFFERENCE(b, a), 1000,
"ENET_TIME_DIFFERENCE should return the absolute difference for a < b");
ASSERT_THAT(ENET_TIME_DIFFERENCE(a, a), 0u, "ENET_TIME_DIFFERENCE should return 0 for a == b");

// Case involving ENET_TIME_OVERFLOW constant as per user's example
enet_uint32 c = 1000;
enet_uint32 d = ENET_TIME_OVERFLOW;
ASSERT_THAT(ENET_TIME_DIFFERENCE(c, d), d - c,
"ENET_TIME_DIFFERENCE should return the difference involving ENET_TIME_OVERFLOW");
}

TEST(enet_time_get) {
enet_uint32 firstTime = enet_time_get();
ASSERT_SLEEP(100);
enet_uint32 secondTime = enet_time_get();

ASSERT_THAT(secondTime >= firstTime, true, "enet_time_get should return increasing time");
ASSERT_THAT(secondTime - firstTime > 90, true, "Time difference should be at least ~100ms");
}
Loading