- Introduced a new Python script `check_agents_metadata.py` for validating agent metadata, including YAML parsing, rating ranges, and cross-references. - Added usage instructions and exit codes for the script. - Created a new markdown file `模块目录和功能说明.md` to outline the directory structure and functionality of the modules. - Added a text file `说明此文件不可AI修改.txt` to specify that certain files should not be modified by AI, including important information about the `dstalk` framework and its modules.
124 lines
5.2 KiB
C++
124 lines
5.2 KiB
C++
/*
|
||
* @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 <cstring>
|
||
#include <iostream>
|
||
|
||
#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<void*>(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<void*>(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<void*>(0xA);
|
||
void* vt2 = reinterpret_cast<void*>(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;
|
||
}
|
||
}
|