feat(test): 阶段1收尾 — 数据中心单元测试34项全通过
- test_datacenter.cpp: 34 条测试覆盖生命周期、5种信号注册/控制、 out延迟回调、yk同步控制、ao SBO流程、param多区定值、 信号查询、类型工具(19种)、事件队列、异步管理 - COMPLETION.md: 记录阶段0/1完成事项清单 - x86 测试: 34 pass, 0 fail - ARM 交叉编译: 10/10 模块全通过
This commit is contained in:
parent
7dd7572f46
commit
ac4a183a60
|
|
@ -0,0 +1,54 @@
|
|||
# RTU_ALL_AI 开发完成事项清单
|
||||
|
||||
> 日期: 2026-07-07
|
||||
|
||||
---
|
||||
|
||||
## 阶段 0:基础设施
|
||||
|
||||
| 任务 | 模块 | 状态 |
|
||||
|------|------|:----:|
|
||||
| 搭建构建系统 | `release/linux.mk`, `makefile`, `build.sh`, `copy_headers.sh` | ✅ |
|
||||
| 创建 myBase.h 基础定义 | `release/inc/myBase.h` | ✅ |
|
||||
| 实现侵入式链表 | `liblist` | ✅ |
|
||||
| 实现日志系统 | `liblog` | ✅ |
|
||||
| 实现基础工具函数(65个) | `libfunc` | ✅ |
|
||||
|
||||
## 阶段 1:数据基础设施
|
||||
|
||||
| 任务 | 模块 | 状态 |
|
||||
|------|------|:----:|
|
||||
| 实现 MD5 摘要算法 | `libmd5` | ✅ |
|
||||
| 实现 xxHash 快速哈希 | `libmy_xxhash` | ✅ |
|
||||
| 实现 cJSON 解析 | `libcJSON` | ✅ |
|
||||
| 实现命令处理框架 | `libcmd` | ✅ |
|
||||
| 实现 XML 解析 | `libxml` | ✅ |
|
||||
| 实现数据中心(15文件拆分) | `libdatacenter` | ✅ |
|
||||
| 实现任务调度 | `libtask` | ✅ |
|
||||
| 单元测试 | `test_datacenter.cpp`(34项全通过) | ✅ |
|
||||
| x86 编译验证 | 10/10 模块全通过 | ✅ |
|
||||
| ARM 交叉编译验证 | 10/10 模块全通过 | ✅ |
|
||||
|
||||
## 阶段 2:通讯与协议
|
||||
|
||||
| 任务 | 模块 | 状态 |
|
||||
|------|------|:----:|
|
||||
| 通讯抽象层 | `libcomm` | ⬜ |
|
||||
| Modbus 协议栈 | `libmodbus` | ⬜ |
|
||||
| IEC 60870-5-104 | `lib60870` | ⬜ |
|
||||
| IEC 点表解析 | `libiec` | ⬜ |
|
||||
| Modbus 主站管理 | `libmodbus_m` | ⬜ |
|
||||
| 通讯通道解码 | `libcom_decode` | ⬜ |
|
||||
| Web 管理服务 | `libweb_server` | ⬜ |
|
||||
| 主程序入口 | `RTU` | ⬜ |
|
||||
|
||||
## 阶段 3:系统集成
|
||||
|
||||
| 任务 | 模块 | 状态 |
|
||||
|------|------|:----:|
|
||||
| 端到端集成测试 | — | ⬜ |
|
||||
| README 文档 | — | ⬜ |
|
||||
|
||||
## 阶段 4(预留)
|
||||
|
||||
ICP67 / IEC61850 MMS / MQTT / 嵌入式HTTP / PLC / 内部协议 —— 全部 ⬜
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* @file test_datacenter.cpp
|
||||
* @brief 数据中心模块单元测试
|
||||
* @details 覆盖:生命周期、5 种信号注册/链接、out 延迟回调、yk 同步控制、
|
||||
* ao SBO 流程、param 多区定值、信号查询、类型工具、事件队列
|
||||
*/
|
||||
#include "myDatacenter.h"
|
||||
#include "myBase.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
/* ===== 测试辅助 ===== */
|
||||
|
||||
static int g_pass = 0;
|
||||
static int g_fail = 0;
|
||||
|
||||
#define TEST(name) \
|
||||
do \
|
||||
{ \
|
||||
printf(" TEST: %s ... ", name); \
|
||||
} while (0)
|
||||
|
||||
#define OK() \
|
||||
do \
|
||||
{ \
|
||||
printf("OK\n"); \
|
||||
g_pass++; \
|
||||
} while (0)
|
||||
|
||||
#define FAIL(msg) \
|
||||
do \
|
||||
{ \
|
||||
printf("FAIL: %s\n", msg); \
|
||||
g_fail++; \
|
||||
} while (0)
|
||||
|
||||
/* ===== 回调测试变量 ===== */
|
||||
|
||||
static int g_out_changed = 0;
|
||||
static int g_yk_changed = 0;
|
||||
static int g_ao_changed = 0;
|
||||
static int g_param_changed = 0;
|
||||
static int g_soe_received = 0;
|
||||
|
||||
static void on_out_changed(const char *saddr, uint8_t data_type,
|
||||
const void *p_new, const void *p_old)
|
||||
{
|
||||
(void)saddr;
|
||||
(void)data_type;
|
||||
(void)p_new;
|
||||
(void)p_old;
|
||||
|
||||
g_out_changed++;
|
||||
}
|
||||
|
||||
static void on_yk_changed(const char *saddr, dc_ctrl_step_t step,
|
||||
uint8_t data_type, uint8_t zone,
|
||||
const void *p_data)
|
||||
{
|
||||
(void)saddr;
|
||||
(void)step;
|
||||
(void)data_type;
|
||||
(void)zone;
|
||||
(void)p_data;
|
||||
|
||||
g_yk_changed++;
|
||||
}
|
||||
|
||||
static void on_ao_changed(const char *saddr, dc_ctrl_step_t step,
|
||||
uint8_t data_type, uint8_t zone,
|
||||
const void *p_data)
|
||||
{
|
||||
(void)saddr;
|
||||
(void)step;
|
||||
(void)data_type;
|
||||
(void)zone;
|
||||
(void)p_data;
|
||||
|
||||
g_ao_changed++;
|
||||
}
|
||||
|
||||
static void on_param_changed(const char *saddr, dc_ctrl_step_t step,
|
||||
uint8_t data_type, uint8_t zone,
|
||||
const void *p_data)
|
||||
{
|
||||
(void)saddr;
|
||||
(void)step;
|
||||
(void)data_type;
|
||||
(void)zone;
|
||||
(void)p_data;
|
||||
|
||||
g_param_changed++;
|
||||
}
|
||||
|
||||
static void on_soe_pop(void *p_data)
|
||||
{
|
||||
(void)p_data;
|
||||
|
||||
g_soe_received++;
|
||||
}
|
||||
|
||||
/* ===== 测试用例 ===== */
|
||||
|
||||
/**
|
||||
* @brief 测试 1:生命周期
|
||||
*/
|
||||
static void test_lifecycle(void)
|
||||
{
|
||||
TEST("dc_init()");
|
||||
{
|
||||
int r = dc_init(NULL);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("init failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_init() double");
|
||||
{
|
||||
int r = dc_init(NULL);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("double init should return OK");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_cleanup()");
|
||||
{
|
||||
dc_cleanup();
|
||||
|
||||
/* re-init for following tests */
|
||||
dc_init(NULL);
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 2:out 信号注册 + 设值 + 延迟回调
|
||||
*/
|
||||
static void test_out_signal(void)
|
||||
{
|
||||
int yc_val = 100;
|
||||
|
||||
TEST("dc_signal_out()");
|
||||
{
|
||||
int r = dc_signal_out("RPC1:YC:1", "test yc", DATA_TYPE_S32,
|
||||
&yc_val, "protocol");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("register failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_out() duplicate");
|
||||
{
|
||||
int r = dc_signal_out("RPC1:YC:1", "dup", DATA_TYPE_S32,
|
||||
&yc_val, "protocol");
|
||||
|
||||
if (DC_ERR_EXISTS != r)
|
||||
{
|
||||
FAIL("duplicate should return EXISTS");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_out_link_with_callback()");
|
||||
{
|
||||
void *p = NULL;
|
||||
|
||||
g_out_changed = 0;
|
||||
int r = dc_signal_out_link_with_callback("RPC1:YC:1", &p,
|
||||
on_out_changed, "web");
|
||||
|
||||
if (DC_OK != r || p != &yc_val)
|
||||
{
|
||||
FAIL("link failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_set_out_signal_val() + dc_run_100ms()");
|
||||
{
|
||||
g_out_changed = 0;
|
||||
yc_val = 200;
|
||||
int r = dc_set_out_signal_val("RPC1:YC:1", &yc_val, "protocol");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("set val failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* 回路阻断:protocol 自身不会被回调 */
|
||||
dc_run_100ms();
|
||||
|
||||
if (g_out_changed != 1)
|
||||
{
|
||||
char msg[64];
|
||||
|
||||
snprintf(msg, sizeof(msg), "cb count=%d, expected 1", g_out_changed);
|
||||
FAIL(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 3:in 信号注册
|
||||
*/
|
||||
static void test_in_signal(void)
|
||||
{
|
||||
TEST("dc_signal_in()");
|
||||
{
|
||||
void *p = NULL;
|
||||
int r = dc_signal_in("RPC1:YC:1:in", "test in", "RPC1:YC:1",
|
||||
&p, "protocol");
|
||||
|
||||
if (DC_OK != r || !p)
|
||||
{
|
||||
FAIL("in register failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_in() bad link");
|
||||
{
|
||||
void *p = NULL;
|
||||
int r = dc_signal_in("RPC1:YC:99:in", "bad", "RPC1:YC:99",
|
||||
&p, "protocol");
|
||||
|
||||
if (DC_ERR_NOTFOUND != r)
|
||||
{
|
||||
FAIL("bad link should return NOTFOUND");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 4:yk 信号 + 同步控制
|
||||
*/
|
||||
static void test_yk_signal(void)
|
||||
{
|
||||
uint8_t yk_val = 0;
|
||||
|
||||
TEST("dc_signal_yk()");
|
||||
{
|
||||
int r = dc_signal_yk("RPC1:YK:1", "test yk", DATA_TYPE_U8,
|
||||
DC_CTRL_DIRECT, &yk_val, on_yk_changed, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("yk register failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_yk_set_status() DIRECT");
|
||||
{
|
||||
g_yk_changed = 0;
|
||||
dc_ctrl_t ctrl = {};
|
||||
|
||||
ctrl.type = DC_CTRL_DIRECT;
|
||||
ctrl.data_type = DATA_TYPE_U8;
|
||||
|
||||
uint8_t v = 1;
|
||||
int r = dc_signal_yk_set_status("RPC1:YK:1", DC_STEP_DIRECT,
|
||||
&ctrl, &v, "protocol");
|
||||
|
||||
if (DC_OK != r || yk_val != 1)
|
||||
{
|
||||
FAIL("yk set failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_yk_changed != 1)
|
||||
{
|
||||
FAIL("yk callback not triggered");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* 回路阻断:web 自身 */ OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_yk_set_status() SBO flow");
|
||||
{
|
||||
g_yk_changed = 0;
|
||||
dc_ctrl_t ctrl = {};
|
||||
|
||||
ctrl.type = DC_CTRL_SBO;
|
||||
ctrl.data_type = DATA_TYPE_U8;
|
||||
ctrl.p_data = malloc(1);
|
||||
*(uint8_t *)ctrl.p_data = 2;
|
||||
|
||||
uint8_t sel_val = 2;
|
||||
int r = dc_signal_yk_set_status("RPC1:YK:1", DC_STEP_SELECT,
|
||||
&ctrl, &sel_val, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("SBO SELECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* DIRECT with matching value */
|
||||
r = dc_signal_yk_set_status("RPC1:YK:1", DC_STEP_DIRECT,
|
||||
&ctrl, &sel_val, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("SBO DIRECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
free(ctrl.p_data);
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 5:ao 信号 + SBO 控制
|
||||
*/
|
||||
static void test_ao_signal(void)
|
||||
{
|
||||
float ao_val = 0.0f;
|
||||
|
||||
TEST("dc_signal_ao()");
|
||||
{
|
||||
int r = dc_signal_ao("RPC1:AO:1", "test ao", DATA_TYPE_F32,
|
||||
DC_CTRL_SBO, &ao_val, on_ao_changed, "protocol");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("ao register failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_ao_set_val() SBO");
|
||||
{
|
||||
g_ao_changed = 0;
|
||||
dc_ctrl_t ctrl = {};
|
||||
|
||||
ctrl.type = DC_CTRL_SBO;
|
||||
ctrl.data_type = DATA_TYPE_F32;
|
||||
ctrl.p_data = malloc(4);
|
||||
*(float *)ctrl.p_data = 3.14f;
|
||||
|
||||
float v = 3.14f;
|
||||
int r = dc_signal_ao_set_val("RPC1:AO:1", DC_STEP_SELECT,
|
||||
&ctrl, &v, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("ao SELECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
r = dc_signal_ao_set_val("RPC1:AO:1", DC_STEP_DIRECT,
|
||||
&ctrl, &v, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("ao DIRECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
if (g_ao_changed < 2)
|
||||
{
|
||||
FAIL("ao callback not triggered");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ctrl->step should be reset to READY */
|
||||
if (ctrl.step != DC_STEP_READY)
|
||||
{
|
||||
FAIL("ctrl step not reset to READY");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_ao_set_val_without_check()");
|
||||
{
|
||||
g_ao_changed = 0;
|
||||
float v = 2.71f;
|
||||
int r = dc_signal_ao_set_val_without_check("RPC1:AO:1", DATA_TYPE_F32,
|
||||
&v, "protocol");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("ao set without check failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 6:param 多区定值
|
||||
*/
|
||||
static void test_param_signal(void)
|
||||
{
|
||||
uint32_t p1 = 10;
|
||||
uint32_t p2 = 20;
|
||||
void *parr[2] = {&p1, &p2};
|
||||
|
||||
TEST("dc_signal_param()");
|
||||
{
|
||||
int r = dc_signal_param("RPC1:PARAM:1", "test param", DATA_TYPE_U32,
|
||||
DC_CTRL_SBO, parr, 2, on_param_changed, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("param register failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_signal_param_set_val() zone 0");
|
||||
{
|
||||
g_param_changed = 0;
|
||||
dc_ctrl_t ctrl = {};
|
||||
|
||||
ctrl.type = DC_CTRL_SBO;
|
||||
ctrl.data_type = DATA_TYPE_U32;
|
||||
ctrl.p_data = malloc(4);
|
||||
*(uint32_t *)ctrl.p_data = 55;
|
||||
|
||||
uint32_t v = 55;
|
||||
int r = dc_signal_param_set_val("RPC1:PARAM:1", DC_STEP_SELECT,
|
||||
&ctrl, 0, &v, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("param SELECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
r = dc_signal_param_set_val("RPC1:PARAM:1", DC_STEP_DIRECT,
|
||||
&ctrl, 0, &v, "web");
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("param DIRECT failed");
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
free(ctrl.p_data);
|
||||
|
||||
if (p1 != 55)
|
||||
{
|
||||
FAIL("zone0 not updated");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 7:信号查询
|
||||
*/
|
||||
static void test_query(void)
|
||||
{
|
||||
TEST("dc_get_out_signal_info()");
|
||||
{
|
||||
char desc[64] = {0};
|
||||
uint8_t dt = 0;
|
||||
void *p = NULL;
|
||||
int r = dc_get_out_signal_info("RPC1:YC:1", desc, 64, &dt, &p);
|
||||
|
||||
if (DC_OK != r || dt != DATA_TYPE_S32)
|
||||
{
|
||||
FAIL("query out failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_get_signal_count()");
|
||||
{
|
||||
int n = dc_get_signal_count("out");
|
||||
|
||||
if (n < 1)
|
||||
{
|
||||
FAIL("out count should be >= 1");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
n = dc_get_signal_count("param");
|
||||
|
||||
if (n < 1)
|
||||
{
|
||||
FAIL("param count should be >= 1");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_get_signal_info_by_id()");
|
||||
{
|
||||
char saddr[64] = {0};
|
||||
char desc[64] = {0};
|
||||
char dtstr[32] = {0};
|
||||
uint8_t ct = 0;
|
||||
int r = dc_get_signal_info_by_id("out", 0, saddr, 64, desc, 64,
|
||||
dtstr, 32, &ct, NULL, 0);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("get by id failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_get_signal_val()");
|
||||
{
|
||||
uint32_t v = 42;
|
||||
char buf[32] = {0};
|
||||
int r = dc_get_signal_val(&v, DATA_TYPE_U32, buf, 32);
|
||||
|
||||
if (DC_OK != r || 0 != strcmp(buf, "42"))
|
||||
{
|
||||
FAIL("val to str failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 8:类型工具
|
||||
*/
|
||||
static void test_type_util(void)
|
||||
{
|
||||
TEST("dc_get_type_name()");
|
||||
{
|
||||
const char *n = dc_get_type_name(DATA_TYPE_F32);
|
||||
|
||||
if (0 != strcmp(n, "float"))
|
||||
{
|
||||
FAIL("type name mismatch");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_get_type_id_by_name()");
|
||||
{
|
||||
uint8_t id = dc_get_type_id_by_name("uint32_t");
|
||||
|
||||
if (DATA_TYPE_U32 != id)
|
||||
{
|
||||
FAIL("type id mismatch");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_get_type_len()");
|
||||
{
|
||||
if (4 != dc_get_type_len(DATA_TYPE_F32))
|
||||
{
|
||||
FAIL("float len should be 4");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (8 != dc_get_type_len(DATA_TYPE_D64))
|
||||
{
|
||||
FAIL("double len should be 8");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_create_data + dc_destroy_data");
|
||||
{
|
||||
void *p = dc_create_data(DATA_TYPE_S32);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
FAIL("create data failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dc_destroy_data(p, DATA_TYPE_S32);
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_copy_val + dc_compare_val");
|
||||
{
|
||||
int a = 10;
|
||||
int b = 0;
|
||||
|
||||
dc_copy_val(&b, &a, DATA_TYPE_S32);
|
||||
|
||||
if (b != 10)
|
||||
{
|
||||
FAIL("copy val failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != dc_compare_val(&a, &b, DATA_TYPE_S32))
|
||||
{
|
||||
FAIL("compare equal failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
b = 20;
|
||||
|
||||
if (-1 != dc_compare_val(&a, &b, DATA_TYPE_S32))
|
||||
{
|
||||
FAIL("compare unequal failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_set_val_from_str()");
|
||||
{
|
||||
float f = 0.0f;
|
||||
int r = dc_set_val_from_str(&f, DATA_TYPE_F32, "3.14");
|
||||
|
||||
if (DC_OK != r || f < 3.13f || f > 3.15f)
|
||||
{
|
||||
FAIL("set from str failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_set_val_from_str() IP");
|
||||
{
|
||||
uint8_t ip[4] = {0};
|
||||
int r = dc_set_val_from_str(ip, DATA_TYPE_IP, "192.168.1.1");
|
||||
|
||||
if (DC_OK != r || ip[0] != 192 || ip[1] != 168 || ip[2] != 1 || ip[3] != 1)
|
||||
{
|
||||
FAIL("IP parse failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 9:事件队列
|
||||
*/
|
||||
static void test_event_queue(void)
|
||||
{
|
||||
TEST("dc_event_queue_push + register");
|
||||
{
|
||||
int r = dc_event_register_queue_pop(on_soe_pop);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("register pop failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_soe_received = 0;
|
||||
|
||||
int dummy = 99;
|
||||
r = dc_event_queue_push(&dummy);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("event push failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* 消耗队列 */
|
||||
dc_run_100ms();
|
||||
|
||||
if (g_soe_received < 1)
|
||||
{
|
||||
FAIL("event not consumed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_disturb_dd_queue_push");
|
||||
{
|
||||
int dummy = 1;
|
||||
int r = dc_disturb_dd_queue_push(&dummy);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("disturb push failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_fault_queue_push");
|
||||
{
|
||||
int dummy = 1;
|
||||
int r = dc_fault_queue_push(&dummy);
|
||||
|
||||
if (DC_OK != r)
|
||||
{
|
||||
FAIL("fault push failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测试 10:异步管理
|
||||
*/
|
||||
static void test_async_mgmt(void)
|
||||
{
|
||||
TEST("dc_async_pending_count()");
|
||||
{
|
||||
int n = dc_async_pending_count();
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
FAIL("pending count failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_async_set_default_timeout()");
|
||||
{
|
||||
dc_async_set_default_timeout(5000);
|
||||
OK();
|
||||
}
|
||||
|
||||
TEST("dc_param_cfg_changed()");
|
||||
{
|
||||
int r = dc_param_cfg_changed();
|
||||
|
||||
if (r < 0)
|
||||
{
|
||||
FAIL("cfg changed failed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OK();
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 入口 ===== */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("=== test_datacenter ===\n\n");
|
||||
|
||||
/* 初始化 */
|
||||
dc_init(NULL);
|
||||
|
||||
/* 信号注册 */
|
||||
test_out_signal();
|
||||
test_in_signal();
|
||||
test_yk_signal();
|
||||
test_ao_signal();
|
||||
test_param_signal();
|
||||
|
||||
/* 查询 */
|
||||
test_query();
|
||||
|
||||
/* 工具 */
|
||||
test_type_util();
|
||||
|
||||
/* 事件队列 */
|
||||
test_event_queue();
|
||||
|
||||
/* 异步管理 */
|
||||
test_async_mgmt();
|
||||
|
||||
/* 清理 */
|
||||
dc_cleanup();
|
||||
|
||||
/* 生命周期 */
|
||||
dc_init(NULL);
|
||||
test_lifecycle();
|
||||
dc_cleanup();
|
||||
|
||||
/* 结果 */
|
||||
printf("\n=== result: %d pass, %d fail ===\n", g_pass, g_fail);
|
||||
|
||||
return (g_fail > 0) ? 1 : 0;
|
||||
}
|
||||
Loading…
Reference in New Issue