Files
verify/sdk/cpp/test_main.cpp
T
admin ed4a561704 feat: add application API documentation and C++ SDK
- Add complete API documentation for application integration (docs/API_DOCUMENT.md)
- Fix check-update API to use version ID comparison instead of string comparison
- Add validation: client version must exist in server version list
- Add support for patch/incremental updates with base_version check
- Add C++ SDK with HTTP client, JSON parser, and crypto support
- Add simple_test.cpp for standalone testing on Windows

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 11:58:44 +08:00

362 lines
12 KiB
C++

#include "verify_client.hpp"
#include <iostream>
#include <cassert>
#include <thread>
#include <chrono>
using namespace verify;
// 测试配置
const std::string BASE_URL = "https://gendan.xyz";
const std::string APP_KEY = "your_app_key"; // 需要替换为实际的appKey
const std::string TEST_USERNAME = "test_user_cpp";
const std::string TEST_PASSWORD = "test123456";
const std::string TEST_DEVICE_ID = "cpp_test_device_001";
class TestRunner {
public:
void run() {
std::cout << "========================================\n";
std::cout << "验证平台SDK C++ 测试\n";
std::cout << "========================================\n\n";
// 初始化客户端
testClientCreation();
// 测试应用信息接口
testAppInfo();
// 测试用户注册和登录
testUserRegistration();
testUserLogin();
// 测试账户接口
if (!token_.empty()) {
testAccount();
testHeartbeat();
}
// 测试充值接口
testRecharge();
// 测试设备管理
if (!token_.empty()) {
testDeviceManagement();
}
// 测试云端数据
if (!token_.empty()) {
testCloudData();
}
std::cout << "\n========================================\n";
std::cout << "所有测试完成!\n";
std::cout << "========================================\n";
}
private:
std::unique_ptr<Client> client_;
std::string token_;
uint64_t userId_ = 0;
void testClientCreation() {
std::cout << "[测试] 客户端创建... ";
try {
client_ = std::make_unique<Client>(BASE_URL, APP_KEY);
client_->setTimeout(30);
std::cout << "通过\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
throw;
}
}
void testAppInfo() {
std::cout << "[测试] 获取应用信息... ";
try {
AppConfig config = client_->getAppInfo();
std::cout << "通过\n";
std::cout << " - 应用名称: " << config.name << "\n";
std::cout << " - 计费类型: " << config.billingType << "\n";
std::cout << " - 最大设备数: " << config.maxDevices << "\n";
std::cout << " - 心跳间隔: " << config.heartbeatInterval << "秒\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
std::cout << "[测试] 检查更新... ";
try {
VersionInfo version = client_->checkUpdate("1.0.0");
std::cout << "通过\n";
std::cout << " - 有更新: " << (version.hasUpdate ? "是" : "否") << "\n";
std::cout << " - 最新版本: " << version.latestVersion << "\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
std::cout << "[测试] 获取公告列表... ";
try {
auto announcements = client_->getAnnouncements();
std::cout << "通过 (共" << announcements.size() << "条公告)\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testUserRegistration() {
std::cout << "[测试] 用户注册... ";
try {
// 先尝试登录,如果用户存在则跳过注册
try {
auto result = client_->login(TEST_USERNAME, TEST_PASSWORD, TEST_DEVICE_ID);
userId_ = result["user_id"].get<uint64_t>();
token_ = result["token"].get<std::string>();
std::cout << "用户已存在,跳过注册\n";
return;
} catch (...) {
// 用户不存在,继续注册
}
userId_ = client_->registerUser(
TEST_USERNAME,
TEST_PASSWORD,
TEST_DEVICE_ID,
"C++测试设备",
"windows",
"instance_001"
);
std::cout << "通过 (用户ID: " << userId_ << ")\n";
// 注册后登录
auto result = client_->login(TEST_USERNAME, TEST_PASSWORD, TEST_DEVICE_ID);
token_ = result["token"].get<std::string>();
} catch (const ApiException& e) {
std::cout << "API错误 [" << e.code() << "]: " << e.what() << "\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testUserLogin() {
std::cout << "[测试] 用户登录... ";
try {
auto result = client_->login(TEST_USERNAME, TEST_PASSWORD, TEST_DEVICE_ID);
userId_ = result["user_id"].get<uint64_t>();
token_ = result["token"].get<std::string>();
std::cout << "通过\n";
std::cout << " - 用户ID: " << userId_ << "\n";
std::cout << " - Token: " << token_.substr(0, 30) << "...\n";
} catch (const ApiException& e) {
std::cout << "API错误 [" << e.code() << "]: " << e.what() << "\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testAccount() {
std::cout << "[测试] 获取账户信息... ";
try {
UserInfo info = client_->getAccount(userId_);
std::cout << "通过\n";
std::cout << " - 用户名: " << info.username << "\n";
std::cout << " - 余额: " << info.balance << "\n";
std::cout << " - 状态: " << info.status << "\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testHeartbeat() {
std::cout << "[测试] 心跳上报... ";
try {
auto result = client_->heartbeat(userId_, TEST_DEVICE_ID, "instance_001");
std::cout << "通过\n";
if (result.contains("balance")) {
std::cout << " - 当前余额: " << result["balance"] << "\n";
}
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testRecharge() {
std::cout << "[测试] 卡密充值 (使用无效卡密测试错误处理)... ";
try {
auto result = client_->recharge(TEST_USERNAME, "invalid_card_key_12345", TEST_DEVICE_ID);
std::cout << "未预期的成功\n";
} catch (const ApiException& e) {
std::cout << "通过 (预期错误: " << e.what() << ")\n";
} catch (const std::exception& e) {
std::cout << "通过 (预期错误: " << e.what() << ")\n";
}
}
void testDeviceManagement() {
std::cout << "[测试] 获取设备列表... ";
try {
auto devices = client_->getDevices();
std::cout << "通过 (共" << devices.size() << "台设备)\n";
for (const auto& d : devices) {
std::cout << " - 设备ID: " << d.deviceId << " (" << d.deviceName << ")\n";
}
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
std::cout << "[测试] 获取设备数量... ";
try {
auto result = client_->getDeviceCount(userId_);
std::cout << "通过\n";
std::cout << " - 已绑定: " << result["count"] << "\n";
std::cout << " - 最大数: " << result["max_devices"] << "\n";
std::cout << " - 剩余: " << result["remaining"] << "\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
std::cout << "[测试] 获取实例列表... ";
try {
auto instances = client_->getInstances(userId_);
std::cout << "通过 (共" << instances.size() << "个实例)\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
void testCloudData() {
std::cout << "[测试] 获取云端常量... ";
try {
auto constants = client_->getConstants();
std::cout << "通过 (共" << constants.size() << "个常量)\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
std::cout << "[测试] 获取云端变量... ";
try {
auto variables = client_->getVariables();
std::cout << "通过 (共" << variables.size() << "个变量)\n";
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
};
// 加密测试
void testCrypto() {
std::cout << "\n[测试] 加密功能...\n";
// AES测试
{
std::cout << " [AES加密/解密] ";
try {
Crypto aes(EncryptType::AES, "test_key_12345678");
std::string plaintext = "Hello, World! 你好,世界!";
std::string encrypted = aes.encrypt(plaintext);
std::string decrypted = aes.decrypt(encrypted);
if (decrypted == plaintext) {
std::cout << "通过\n";
std::cout << " 原文: " << plaintext << "\n";
std::cout << " 密文: " << encrypted.substr(0, 50) << "...\n";
} else {
std::cout << "失败: 解密结果不匹配\n";
}
} catch (const CryptoException& e) {
std::cout << "失败: " << e.what() << "\n";
std::cout << " 提示: 请使用 -DUSE_OPENSSL 编译以启用AES加密\n";
}
}
// RC4测试
{
std::cout << " [RC4加密/解密] ";
try {
Crypto rc4(EncryptType::RC4, "rc4_secret_key");
std::string plaintext = "Test RC4 encryption";
std::string encrypted = rc4.encrypt(plaintext);
std::string decrypted = rc4.decrypt(encrypted);
if (decrypted == plaintext) {
std::cout << "通过\n";
} else {
std::cout << "失败: 解密结果不匹配\n";
}
} catch (const std::exception& e) {
std::cout << "失败: " << e.what() << "\n";
}
}
}
// 性能测试
void testPerformance() {
std::cout << "\n[测试] 性能测试...\n";
Client client(BASE_URL, APP_KEY);
client.setTimeout(10);
int successCount = 0;
int failCount = 0;
const int iterations = 10;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
try {
client.getAppInfo();
++successCount;
} catch (...) {
++failCount;
}
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << " - 请求次数: " << iterations << "\n";
std::cout << " - 成功次数: " << successCount << "\n";
std::cout << " - 失败次数: " << failCount << "\n";
std::cout << " - 总耗时: " << duration.count() << "ms\n";
std::cout << " - 平均耗时: " << (duration.count() / iterations) << "ms/请求\n";
}
int main(int argc, char* argv[]) {
std::cout << R"(
╔════════════════════════════════════════════════════════════╗
验证平台 SDK C++ 测试程序
Verify Platform SDK C++ Test
╚════════════════════════════════════════════════════════════╝
)" << "\n";
// 解析命令行参数
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "--help" || arg == "-h") {
std::cout << "用法: " << argv[0] << " [选项]\n";
std::cout << "选项:\n";
std::cout << " --help, -h 显示帮助信息\n";
std::cout << " --crypto 仅测试加密功能\n";
std::cout << " --perf 仅测试性能\n";
return 0;
}
}
try {
// 测试加密
testCrypto();
// 主测试
TestRunner runner;
runner.run();
// 性能测试
testPerformance();
} catch (const std::exception& e) {
std::cerr << "\n错误: " << e.what() << "\n";
return 1;
}
return 0;
}