/* * @file service_registry_test.cpp * @brief ServiceRegistry unit tests (supplement to host_api_test): register, * query, version check, unregister, null-pointer safety, re-registration. * ServiceRegistry 单元测试(host_api_test 补充):注册、查询、版本检查、取消注册、空指针安全、重新注册。 * Copyright (c) 2026 dstalk contributors. GPLv3. */ #include #include #include "service_registry.hpp" // ---- 轻量断言 ---- static int g_failures = 0; // Lightweight assertion helper: increments g_failures counter on failure #define TCHECK(cond, msg) do { \ if (cond) { \ std::cout << "[OK] " << (msg) << "\n"; \ } else { \ std::cerr << "[FAIL] " << (msg) << "\n"; \ g_failures++; \ } \ } while (0) // ServiceRegistry 补充测试:空名称/虚表拒绝、完整生命周期(注册→查询→取消注册→查询为空)、 // 取消注册空指针安全、取消注册后重新注册、空名称查询。 // ServiceRegistry supplement tests: null-name/vtable rejection, full lifecycle // (register->query->unregister->query nullptr), unregister nullptr safety, // re-registration after unregister, and query with nullptr name. int main() { std::cout << "=== dstalk service_registry unit tests (supplement) ===\n\n"; // ==================================================================== // Test 1: register_service(nullptr name) → -1 // ==================================================================== { dstalk::ServiceRegistry reg; void* vt = reinterpret_cast(0x10); int r = reg.register_service(nullptr, 1, vt); TCHECK(r == -1, "register_service(nullptr name) returns -1"); } // ==================================================================== // Test 2: register_service(nullptr vtable) → -1 // ==================================================================== { dstalk::ServiceRegistry reg; int r = reg.register_service("valid_name", 1, nullptr); TCHECK(r == -1, "register_service(nullptr vtable) returns -1"); } // ==================================================================== // Test 3: 完整生命周期 — register → query → unregister → query(nullptr) // Test 3: full lifecycle — register → query → unregister → query(nullptr) // ==================================================================== { dstalk::ServiceRegistry reg; void* vt = reinterpret_cast(0xDEAD); int r = reg.register_service("life", 3, vt); TCHECK(r == 0, "register_service(\"life\",3) returns 0"); void* q1 = reg.query_service("life", 2); TCHECK(q1 == vt, "query_service(\"life\",2) returns vtable after register"); reg.unregister_service("life"); void* q2 = reg.query_service("life", 1); TCHECK(q2 == nullptr, "query_service(\"life\",1) returns nullptr after unregister"); } // ==================================================================== // Test 4: unregister_service(nullptr name) 不崩溃(安全空操作) // Test 4: unregister_service(nullptr name) does not crash (safe no-op) // ==================================================================== { dstalk::ServiceRegistry reg; reg.unregister_service(nullptr); std::cout << "[OK] unregister_service(nullptr) did not crash\n"; } // ==================================================================== // Test 5: 注册后重新注册同名 → 先 unregister 再 register 成功 // Test 5: re-register same name after unregister → succeeds // ==================================================================== { dstalk::ServiceRegistry reg; void* vt1 = reinterpret_cast(0xA); void* vt2 = reinterpret_cast(0xB); reg.register_service("reborn", 1, vt1); reg.unregister_service("reborn"); int r = reg.register_service("reborn", 2, vt2); TCHECK(r == 0, "register_service after unregister same name returns 0"); void* q = reg.query_service("reborn", 2); TCHECK(q == vt2, "query_service after re-register returns new vtable"); } // ==================================================================== // Test 6: query_service(nullptr name) → nullptr // ==================================================================== { dstalk::ServiceRegistry reg; void* q = reg.query_service(nullptr, 1); TCHECK(q == nullptr, "query_service(nullptr name) returns nullptr"); } // ==================================================================== // 结果 / Result // ==================================================================== std::cout << "\n"; if (g_failures == 0) { std::cout << "=== All service_registry tests passed ===\n"; return 0; } else { std::cerr << "=== " << g_failures << " service_registry test(s) FAILED ===\n"; return 1; } }