initial commit

This commit is contained in:
nexusverypro
2026-07-03 02:00:27 +01:00
parent 85fa958433
commit 3192afe07d
18 changed files with 1592 additions and 0 deletions

16
tests/CMakeLists.txt Normal file
View File

@@ -0,0 +1,16 @@
file(GLOB TEST_FILES CONFIGURE_DEPENDS "*.cpp")
foreach(TEST_FILE ${TEST_FILES})
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
add_executable(${TEST_NAME} ${TEST_FILE})
target_link_libraries(${TEST_NAME} PRIVATE radhook)
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
add_custom_command(TARGET ${TEST_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:radhook>
$<TARGET_FILE_DIR:${TEST_NAME}>
)
endforeach()

18
tests/test_basic.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
using Fn = int(*)();
int main() {
RadHookHandle h = nullptr;
auto r = RadHookCreate((void*)fn, (void*)detour, &h);
assert(r == RadHookResult::Success);
assert(RadHookIsValid(h));
RadHookDestroy(h);
return 0;
}

View File

@@ -0,0 +1,24 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
using Fn = int(*)();
int main() {
RadHookHandle h = nullptr;
RadHookCreate((void*)fn, (void*)detour, &h);
assert(RadHookIsEnabled(h));
RadHookDisable(h);
assert(!RadHookIsEnabled(h));
RadHookEnable(h);
assert(RadHookIsEnabled(h));
RadHookDestroy(h);
return 0;
}

View File

@@ -0,0 +1,30 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
using Fn = int(*)();
int main() {
RadHookHandle h = nullptr;
RadHookCreate((void*)fn, (void*)detour, &h);
// must trigger detour
assert(fn() == 1337);
// disable restores original
RadHookDisable(h);
assert(fn() == 42);
// re-enable restores hook
RadHookEnable(h);
assert(fn() == 1337);
// trampoline correctness
auto orig = RadHookGetOriginalAs<Fn>(h);
assert(orig() == 42);
RadHookDestroy(h);
}

View File

@@ -0,0 +1,19 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle h = nullptr;
// invalid detour
auto r1 = RadHookCreate((void*)fn, nullptr, &h);
assert(r1 != RadHookResult::Success);
// invalid target
auto r2 = RadHookCreate(nullptr, (void*)detour, &h);
assert(r2 != RadHookResult::Success);
return 0;
}

View File

@@ -0,0 +1,19 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle h = nullptr;
// invalid detour
assert(RadHookCreate((void*)fn, nullptr, &h) != RadHookResult::Success);
// invalid target
assert(RadHookCreate(nullptr, (void*)detour, &h) != RadHookResult::Success);
// invalid handle operations
assert(RadHookEnable(nullptr) == RadHookResult::InvalidHandle || RadHookEnable(nullptr) != RadHookResult::Success);
assert(RadHookDisable(nullptr) == RadHookResult::InvalidHandle || RadHookDisable(nullptr) != RadHookResult::Success);
}

23
tests/test_lifecycle.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle h = nullptr;
// destroy before create safety
assert(RadHookDestroy(nullptr) != RadHookResult::Success);
RadHookCreate((void*)fn, (void*)detour, &h);
RadHookDestroy(h);
// use after destroy safety
assert(RadHookEnable(h) != RadHookResult::Success);
assert(RadHookDisable(h) != RadHookResult::Success);
assert(RadHookIsValid(h) == false || true); // depends on implementation
return 0;
}

View File

@@ -0,0 +1,21 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle h = nullptr;
RadHookCreate((void*)fn, (void*)detour, &h);
for (int i = 0; i < 10000; i++) {
RadHookEnable(h);
assert(fn() == 1337);
RadHookDisable(h);
assert(fn() == 42);
}
RadHookDestroy(h);
}

56
tests/test_stability.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include <cassert>
#include <vector>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle handles[200];
size_t count = 0;
// create many hooks
for (int i = 0; i < 200; i++) {
RadHookHandle h = nullptr;
auto r = RadHookCreate(
(void*)fn,
(void*)detour,
&h
);
assert(r == RadHookResult::Success);
assert(h != nullptr);
handles[count++] = h;
}
// enumerate
RadHookHandle listed[200];
size_t listedCount = RadHookEnumerate(listed, 200);
assert(listedCount == 200);
// every created handle must still be valid
for (size_t i = 0; i < count; i++) {
assert(RadHookIsValid(handles[i]));
}
// destroy half of them
for (size_t i = 0; i < count; i += 2) {
RadHookDestroy(handles[i]);
}
// validate
for (size_t i = 0; i < count; i++) {
if (i % 2 == 0) {
assert(!RadHookIsValid(handles[i]));
} else {
assert(RadHookIsValid(handles[i]));
}
}
// final enumeration must not return destroyed hooks
size_t finalCount = RadHookEnumerate(listed, 200);
assert(finalCount == 100);
return 0;
}

View File

@@ -0,0 +1,20 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
RadHookHandle h = nullptr;
assert(RadHookCreate((void*)fn, (void*)detour, &h) == RadHookResult::Success);
// idempotent enable/disable behavior
assert(RadHookEnable(h) != RadHookResult::Unknown);
assert(RadHookEnable(h) == RadHookResult::AlreadyEnabled || RadHookIsEnabled(h));
assert(RadHookDisable(h) != RadHookResult::Unknown);
assert(!RadHookIsEnabled(h) || RadHookDisable(h) == RadHookResult::AlreadyDisabled);
RadHookDestroy(h);
}

View File

@@ -0,0 +1,19 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
int main() {
for (int i = 0; i < 1000; i++) {
RadHookHandle h = nullptr;
auto r = RadHookCreate((void*)fn, (void*)detour, &h);
assert(r == RadHookResult::Success);
RadHookEnable(h);
RadHookDisable(h);
RadHookDestroy(h);
}
}

22
tests/test_trampoline.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include <cassert>
#include "radhook/radhook.h"
static int fn() { return 42; }
static int detour() { return 1337; }
using Fn = int(*)();
int main() {
RadHookHandle h = nullptr;
RadHookCreate((void*)fn, (void*)detour, &h);
auto orig = RadHookGetOriginalAs<Fn>(h);
assert(orig != nullptr);
// trampoline must bypass hook
assert(orig() == 42);
RadHookDestroy(h);
return 0;
}