feat: 实现TCP Server

This commit is contained in:
zimoyin
2026-03-02 21:59:43 +08:00
parent 043306819b
commit a79dfae57d
144 changed files with 15785 additions and 140 deletions
+274
View File
@@ -0,0 +1,274 @@
<?php
namespace tests\flow;
use app\flow\ProcessEngine;
use app\flow\ProcessContext;
use app\flow\config\ProcessConfig;
/**
* 性能测试
* 注意:这些测试主要用于基准测试,不严格断言性能指标
*/
class PerformanceTest extends TestCase
{
/**
* 测试流程执行性能 - 单次执行
*/
public function testSingleExecutionPerformance(): void
{
$engine = ProcessEngine::createStandard();
$context = $this->createContext([
'readerType' => '清洗',
'currentStep' => '',
'endoscopeId' => '',
'morningWashed' => true,
]);
$startTime = microtime(true);
$result = $engine->execute($context);
$endTime = microtime(true);
$executionTime = ($endTime - $startTime) * 1000; // 毫秒
$this->assertSuccess($result);
// 单次执行应该小于 500ms(debug日志有IO开销)
$this->assertLessThan(500, $executionTime, "单次执行时间过长: {$executionTime}ms");
}
/**
* 测试流程执行性能 - 完整流程
*/
public function testCompleteProcessPerformance(): void
{
$engine = ProcessEngine::createStandard();
$steps = [
['readerType' => '清洗', 'prevStep' => '', 'waitTime' => 0],
['readerType' => '漂洗', 'prevStep' => '清洗', 'waitTime' => 400],
['readerType' => '消毒', 'prevStep' => '漂洗', 'waitTime' => 200],
['readerType' => '终末漂洗', 'prevStep' => '消毒', 'waitTime' => 400],
['readerType' => '干燥', 'prevStep' => '终末漂洗', 'waitTime' => 200],
['readerType' => '结束', 'prevStep' => '干燥', 'waitTime' => 300],
];
$startTime = microtime(true);
$batchNo = null;
foreach ($steps as $step) {
$context = $this->createContext([
'readerType' => $step['readerType'],
'currentStep' => $step['prevStep'],
'endoscopeId' => '',
'batchNo' => $batchNo,
'morningWashed' => true,
]);
if ($step['waitTime'] > 0) {
$this->setStepTime($context, $step['prevStep'], $step['waitTime']);
}
$result = $engine->execute($context);
$this->assertSuccess($result);
if ($batchNo === null) {
$batchNo = $result->batchNo;
}
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 完整流程(6步)应该小于 5000ms(debug日志有IO开销)
$this->assertLessThan(5000, $totalTime, "完整流程执行时间过长: {$totalTime}ms");
}
/**
* 测试批次号生成性能
*/
public function testBatchNoGenerationPerformance(): void
{
$context = $this->createContext(['endoscopeId' => '1']);
$startTime = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$context->generateBatchNo();
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 生成1000个批次号应该小于 100ms
$this->assertLessThan(100, $totalTime, "批次号生成时间过长: {$totalTime}ms");
}
/**
* 测试引擎创建性能
*/
public function testEngineCreationPerformance(): void
{
$startTime = microtime(true);
for ($i = 0; $i < 100; $i++) {
ProcessEngine::createStandard();
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 创建100个引擎应该小于 200ms
$this->assertLessThan(200, $totalTime, "引擎创建时间过长: {$totalTime}ms");
}
/**
* 测试配置加载性能
*/
public function testConfigLoadingPerformance(): void
{
$startTime = microtime(true);
for ($i = 0; $i < 1000; $i++) {
new ProcessConfig();
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 创建1000个配置应该小于 100ms
$this->assertLessThan(100, $totalTime, "配置加载时间过长: {$totalTime}ms");
}
/**
* 测试上下文创建性能
*/
public function testContextCreationPerformance(): void
{
$startTime = microtime(true);
for ($i = 0; $i < 10000; $i++) {
ProcessContext::create([
'endoscopeId' => '1',
'endoscopeName' => '测试内镜',
]);
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 创建10000个上下文应该小于 500ms(考虑环境差异)
$this->assertLessThan(500, $totalTime, "上下文创建时间过长: {$totalTime}ms");
}
/**
* 测试策略执行性能
*/
public function testStrategyExecutionPerformance(): void
{
$strategy = new \app\flow\strategies\TimeValidationStrategy();
$node = new \app\flow\nodes\WashNode();
$startTime = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$context = $this->createContext([
'readerType' => '清洗',
'currentStep' => '',
]);
$strategy->execute($context, $node);
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 执行1000次策略应该小于 500ms(考虑环境差异)
$this->assertLessThan(500, $totalTime, "策略执行时间过长: {$totalTime}ms");
}
/**
* 测试内存使用 - 大批量上下文创建
*/
public function testMemoryUsage(): void
{
$memoryBefore = memory_get_usage(true);
$contexts = [];
for ($i = 0; $i < 10000; $i++) {
$contexts[] = ProcessContext::create([
'endoscopeId' => (string)$i,
'endoscopeName' => '测试内镜' . $i,
]);
}
$memoryAfter = memory_get_usage(true);
$memoryUsed = ($memoryAfter - $memoryBefore) / 1024 / 1024; // MB
// 10000个上下文应该使用小于 50MB 内存
$this->assertLessThan(50, $memoryUsed, "内存使用过高: {$memoryUsed}MB");
// 清理
unset($contexts);
}
/**
* 测试并发场景模拟 - 多内镜同时处理
*/
public function testConcurrentProcessingSimulation(): void
{
$engine = ProcessEngine::createStandard();
$startTime = microtime(true);
// 模拟10个内镜同时开始清洗
$results = [];
for ($i = 1; $i <= 10; $i++) {
$context = $this->createContext([
'readerType' => '清洗',
'currentStep' => '',
'endoscopeId' => '',
'morningWashed' => true,
]);
$results[] = $engine->execute($context);
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 10个内镜同时处理应该小于 2000ms(debug日志有IO开销)
$this->assertLessThan(2000, $totalTime, "并发处理时间过长: {$totalTime}ms");
// 所有结果应该成功
foreach ($results as $result) {
$this->assertSuccess($result);
}
}
/**
* 测试责任链遍历性能
*/
public function testChainTraversalPerformance(): void
{
$engine = ProcessEngine::createStandard();
// 使用结束读卡器测试完整链遍历
$context = $this->createContext([
'readerType' => '结束',
'currentStep' => '干燥',
'morningWashed' => true,
]);
$this->setStepTime($context, '干燥', 300);
$startTime = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$testContext = clone $context;
$engine->execute($testContext);
}
$endTime = microtime(true);
$totalTime = ($endTime - $startTime) * 1000; // 毫秒
// 1000次完整链遍历应该小于 30000ms(debug日志有IO开销)
$this->assertLessThan(30000, $totalTime, "链遍历时间过长: {$totalTime}ms");
}
}