2026-08-29 01:50:50 +08:00
|
|
|
#include "c_LinkQueue.h"
|
2026-08-30 01:48:03 +08:00
|
|
|
#include "c_Test.h"
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
// 专门用于测试测试的值复制结构体
|
2026-08-29 01:50:50 +08:00
|
|
|
typedef struct {
|
2026-08-30 01:48:03 +08:00
|
|
|
int log_level;
|
|
|
|
|
uint32_t timestamp;
|
|
|
|
|
} LogMessage_t;
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
TEST_CASE(test_link_queue_closure_and_memory_layout) {
|
2026-08-29 01:50:50 +08:00
|
|
|
c_LinkQueue_t queue;
|
|
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
// 初始化一个专门存放 LogMessage_t 结构的泛型单向链式队列
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Init(&queue, sizeof(LogMessage_t), NULL));
|
|
|
|
|
ASSERT_TRUE(c_LinkQueue_IsEmpty(&queue));
|
|
|
|
|
ASSERT_TRUE(queue.head == NULL);
|
|
|
|
|
ASSERT_TRUE(queue.tail == NULL);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
LogMessage_t msg1 = { .log_level = 1, .timestamp = 11111 };
|
|
|
|
|
LogMessage_t msg2 = { .log_level = 2, .timestamp = 22222 };
|
|
|
|
|
LogMessage_t msg3 = { .log_level = 3, .timestamp = 33333 };
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
// 1. 验证入队操作与二级指针空安全合并能力
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Enqueue(&queue, &msg1)); // 第一次插入:head == tail == msg1
|
|
|
|
|
ASSERT_PTR_NOT_NULL(queue.head);
|
|
|
|
|
ASSERT_TRUE(queue.head == queue.tail);
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Enqueue(&queue, &msg2)); // 正常挂接:head->msg1, tail->msg2
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Enqueue(&queue, &msg3)); // 正常挂接:head->msg1, tail->msg3
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
ASSERT_INT_EQ(3, c_LinkQueue_Size(&queue));
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
// 强隔离隔离性检查:修改临时外部变量,内部数据不应被污染
|
|
|
|
|
msg1.log_level = 999;
|
2026-08-29 01:50:50 +08:00
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
// 2. 验证 Peek 窥探能力
|
|
|
|
|
LogMessage_t* peeked = (LogMessage_t*)c_LinkQueue_Peek(&queue);
|
|
|
|
|
ASSERT_PTR_NOT_NULL(peeked);
|
|
|
|
|
ASSERT_INT_EQ(1, peeked->log_level); // 依旧是 1,证明值复制强屏障有效
|
|
|
|
|
|
|
|
|
|
// 3. 【严苛验证变长内存布局的拓扑对齐情况】
|
|
|
|
|
// 根据变长公式寻址:QUEUE_NODE_DATA(node) 必须与抛出的数据指针完全吻合
|
|
|
|
|
ASSERT_TRUE(c_LinkQueueNode_Get(queue.head) == peeked);
|
|
|
|
|
|
|
|
|
|
// 队尾节点的寻址验证
|
|
|
|
|
LogMessage_t* tail_data = c_LinkQueueNode_Get(queue.tail);
|
|
|
|
|
ASSERT_INT_EQ(3, tail_data->log_level);
|
|
|
|
|
|
|
|
|
|
// 4. 出队顺序与先进先出(FIFO)及边界收缩断言 (Dequeue)
|
|
|
|
|
LogMessage_t out_res;
|
|
|
|
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Dequeue(&queue, &out_res));
|
|
|
|
|
ASSERT_INT_EQ(1, out_res.log_level);
|
|
|
|
|
ASSERT_INT_EQ(11111, out_res.timestamp);
|
|
|
|
|
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Dequeue(&queue, &out_res));
|
|
|
|
|
ASSERT_INT_EQ(2, out_res.log_level);
|
|
|
|
|
|
|
|
|
|
// 此时队列只剩最后一个元素 msg3,head 应当等同于 tail
|
|
|
|
|
ASSERT_TRUE(queue.head == queue.tail);
|
|
|
|
|
ASSERT_INT_EQ(1, c_LinkQueue_Size(&queue));
|
|
|
|
|
|
|
|
|
|
// 最后一个元素出队,迫使尾指针恢复到你指定的 0 纯净空空空状态
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OK, c_LinkQueue_Dequeue(&queue, &out_res));
|
|
|
|
|
ASSERT_INT_EQ(3, out_res.log_level);
|
|
|
|
|
|
|
|
|
|
// 终极下溢复位检查
|
|
|
|
|
ASSERT_TRUE(c_LinkQueue_IsEmpty(&queue));
|
|
|
|
|
ASSERT_TRUE(queue.head == NULL);
|
|
|
|
|
ASSERT_TRUE(queue.tail == NULL);
|
|
|
|
|
|
|
|
|
|
// 防御重复下溢出队,应当报错拒绝
|
|
|
|
|
ASSERT_INT_EQ(C_ERR_OUTOFBOUND, c_LinkQueue_Dequeue(&queue, &out_res));
|
2026-08-29 01:50:50 +08:00
|
|
|
|
|
|
|
|
c_LinkQueue_Destroy(&queue);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-30 01:48:03 +08:00
|
|
|
int main(void) {
|
|
|
|
|
TEST_START(C_LinkQueue_Generic_Layout_Tests);
|
|
|
|
|
RUN_TEST(test_link_queue_closure_and_memory_layout);
|
|
|
|
|
TEST_REPORT();
|
|
|
|
|
RETURN_TEST_STATUS;
|
|
|
|
|
}
|
2026-08-29 01:50:50 +08:00
|
|
|
|