219 lines
5.8 KiB
C++
219 lines
5.8 KiB
C++
|
|
#include "app.hpp"
|
|||
|
|
#include <cassert>
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <thread>
|
|||
|
|
#include <chrono>
|
|||
|
|
#include <string>
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 测试 CSU-01 DataReceiver 的数据包解析功能。
|
|||
|
|
*
|
|||
|
|
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
|
|||
|
|
* 规则:验证按协议拆包、异常日志等功能。
|
|||
|
|
*/
|
|||
|
|
void testDataReceiverParsing() {
|
|||
|
|
std::cout << "[单元测试] testDataReceiverParsing ... ";
|
|||
|
|
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> outputQueue;
|
|||
|
|
dataflow::DataReceiver receiver(outputQueue);
|
|||
|
|
|
|||
|
|
std::vector<std::string> mockData = {
|
|||
|
|
"Hello",
|
|||
|
|
"World"
|
|||
|
|
};
|
|||
|
|
receiver.setMockDataSource(mockData);
|
|||
|
|
receiver.start();
|
|||
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|||
|
|
receiver.stop();
|
|||
|
|
|
|||
|
|
assert(receiver.getReceivedCount() == 2);
|
|||
|
|
assert(receiver.getErrorCount() == 0);
|
|||
|
|
|
|||
|
|
std::string data1, data2;
|
|||
|
|
assert(outputQueue.tryPop(data1));
|
|||
|
|
assert(outputQueue.tryPop(data2));
|
|||
|
|
assert(!outputQueue.tryPop(data1)); // 队列应为空
|
|||
|
|
|
|||
|
|
std::cout << "PASS" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 测试 CSU-02 DataProcessor 的数据校验功能。
|
|||
|
|
*
|
|||
|
|
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
|
|||
|
|
* 规则:验证解析校验和错误处理逻辑。
|
|||
|
|
*/
|
|||
|
|
void testDataProcessorValidation() {
|
|||
|
|
std::cout << "[单元测试] testDataProcessorValidation ... ";
|
|||
|
|
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> inputQueue;
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> outputQueue;
|
|||
|
|
dataflow::DataProcessor processor(inputQueue, outputQueue);
|
|||
|
|
|
|||
|
|
processor.start();
|
|||
|
|
|
|||
|
|
// 推送有效数据
|
|||
|
|
inputQueue.push("Valid data packet");
|
|||
|
|
inputQueue.push("Another valid data");
|
|||
|
|
|
|||
|
|
// 推送空数据(应被丢弃)
|
|||
|
|
inputQueue.push("");
|
|||
|
|
|
|||
|
|
// 推送超长数据(应被丢弃)
|
|||
|
|
std::string longData(1025, 'A');
|
|||
|
|
inputQueue.push(longData);
|
|||
|
|
|
|||
|
|
// 等待处理
|
|||
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|||
|
|
processor.stop();
|
|||
|
|
|
|||
|
|
// 验证统计
|
|||
|
|
assert(processor.getProcessedCount() == 2);
|
|||
|
|
assert(processor.getDiscardedCount() == 2);
|
|||
|
|
assert(processor.getErrorCount() == 0);
|
|||
|
|
|
|||
|
|
// 验证输出队列内容
|
|||
|
|
std::string processed;
|
|||
|
|
assert(outputQueue.tryPop(processed));
|
|||
|
|
assert(processed.find("[PROCESSED:") == 0);
|
|||
|
|
assert(processed.find("Valid data packet") != std::string::npos);
|
|||
|
|
|
|||
|
|
assert(outputQueue.tryPop(processed));
|
|||
|
|
assert(processed.find("Another valid data") != std::string::npos);
|
|||
|
|
|
|||
|
|
std::cout << "PASS" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 测试 CSU-03 DataStorage 的数据存储功能。
|
|||
|
|
*
|
|||
|
|
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
|
|||
|
|
* 规则:验证数据入库和异常处理逻辑。
|
|||
|
|
*/
|
|||
|
|
void testDataStorage() {
|
|||
|
|
std::cout << "[单元测试] testDataStorage ... ";
|
|||
|
|
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> inputQueue;
|
|||
|
|
dataflow::DataStorage storage(inputQueue);
|
|||
|
|
|
|||
|
|
storage.start();
|
|||
|
|
|
|||
|
|
inputQueue.push("Record 1");
|
|||
|
|
inputQueue.push("Record 2");
|
|||
|
|
inputQueue.push("Record 3");
|
|||
|
|
|
|||
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|||
|
|
storage.stop();
|
|||
|
|
|
|||
|
|
assert(storage.getStoredCount() == 3);
|
|||
|
|
assert(storage.getErrorCount() == 0);
|
|||
|
|
assert(storage.getStorageSize() == 3);
|
|||
|
|
|
|||
|
|
auto allData = storage.getAllStoredData();
|
|||
|
|
assert(allData.size() == 3);
|
|||
|
|
assert(allData[0] == "Record 1");
|
|||
|
|
assert(allData[1] == "Record 2");
|
|||
|
|
assert(allData[2] == "Record 3");
|
|||
|
|
|
|||
|
|
std::cout << "PASS" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 测试 ThreadSafeQueue 的基本功能。
|
|||
|
|
*/
|
|||
|
|
void testThreadSafeQueue() {
|
|||
|
|
std::cout << "[单元测试] testThreadSafeQueue ... ";
|
|||
|
|
|
|||
|
|
dataflow::ThreadSafeQueue<int> queue;
|
|||
|
|
|
|||
|
|
assert(queue.empty());
|
|||
|
|
assert(queue.size() == 0);
|
|||
|
|
|
|||
|
|
queue.push(10);
|
|||
|
|
queue.push(20);
|
|||
|
|
queue.push(30);
|
|||
|
|
|
|||
|
|
assert(!queue.empty());
|
|||
|
|
assert(queue.size() == 3);
|
|||
|
|
|
|||
|
|
int val;
|
|||
|
|
assert(queue.tryPop(val));
|
|||
|
|
assert(val == 10);
|
|||
|
|
assert(queue.size() == 2);
|
|||
|
|
|
|||
|
|
assert(queue.tryPop(val));
|
|||
|
|
assert(val == 20);
|
|||
|
|
|
|||
|
|
assert(queue.tryPop(val));
|
|||
|
|
assert(val == 30);
|
|||
|
|
|
|||
|
|
assert(!queue.tryPop(val));
|
|||
|
|
assert(queue.empty());
|
|||
|
|
|
|||
|
|
// 测试 clear
|
|||
|
|
queue.push(1);
|
|||
|
|
queue.push(2);
|
|||
|
|
queue.clear();
|
|||
|
|
assert(queue.empty());
|
|||
|
|
|
|||
|
|
std::cout << "PASS" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 测试完整管道:接收→处理→存储。
|
|||
|
|
*
|
|||
|
|
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
|
|||
|
|
* 规则:验证 CSU-01 到 CSU-03 的完整协同工作。
|
|||
|
|
*/
|
|||
|
|
void testFullPipeline() {
|
|||
|
|
std::cout << "[集成测试] testFullPipeline ... ";
|
|||
|
|
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> queue01to02;
|
|||
|
|
dataflow::ThreadSafeQueue<std::string> queue02to03;
|
|||
|
|
|
|||
|
|
dataflow::DataReceiver receiver(queue01to02);
|
|||
|
|
dataflow::DataProcessor processor(queue01to02, queue02to03);
|
|||
|
|
dataflow::DataStorage storage(queue02to03);
|
|||
|
|
|
|||
|
|
std::vector<std::string> mockData = {
|
|||
|
|
"Pipeline test data 1",
|
|||
|
|
"Pipeline test data 2",
|
|||
|
|
"" // 空数据应被丢弃
|
|||
|
|
};
|
|||
|
|
receiver.setMockDataSource(mockData);
|
|||
|
|
|
|||
|
|
receiver.start();
|
|||
|
|
processor.start();
|
|||
|
|
storage.start();
|
|||
|
|
|
|||
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|||
|
|
|
|||
|
|
receiver.stop();
|
|||
|
|
processor.stop();
|
|||
|
|
storage.stop();
|
|||
|
|
|
|||
|
|
assert(receiver.getReceivedCount() == 3);
|
|||
|
|
assert(processor.getProcessedCount() == 2);
|
|||
|
|
assert(processor.getDiscardedCount() == 1);
|
|||
|
|
assert(storage.getStoredCount() == 2);
|
|||
|
|
|
|||
|
|
auto stored = storage.getAllStoredData();
|
|||
|
|
assert(stored.size() == 2);
|
|||
|
|
assert(stored[0].find("Pipeline test data 1") != std::string::npos);
|
|||
|
|
assert(stored[1].find("Pipeline test data 2") != std::string::npos);
|
|||
|
|
|
|||
|
|
std::cout << "PASS" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int main() {
|
|||
|
|
std::cout << "=== 测试套件执行开始 ===" << std::endl;
|
|||
|
|
|
|||
|
|
testThreadSafeQueue();
|
|||
|
|
testDataReceiverParsing();
|
|||
|
|
testDataProcessorValidation();
|
|||
|
|
testDataStorage();
|
|||
|
|
testFullPipeline();
|
|||
|
|
|
|||
|
|
std::cout << "\n=== 所有测试通过 === (0)" << std::endl;
|
|||
|
|
return 0;
|
|||
|
|
}
|