382 lines
10 KiB
Markdown
382 lines
10 KiB
Markdown
# Agent-2 (A2) 功能验证指南
|
||
|
||
## 验证环境准备
|
||
|
||
### 依赖注入配置
|
||
确保在 `Program.cs` 或 `Startup.cs` 中正确注册了以下服务:
|
||
|
||
```csharp
|
||
// 状态机服务
|
||
services.AddSingleton<IRuntimeStateMachineService, AdvancedRuntimeStateMachineService>();
|
||
|
||
// 规则引擎服务
|
||
services.AddSingleton<IRuleEngineService, AdvancedRuleEngineService>();
|
||
|
||
// 人工干预服务
|
||
services.AddSingleton<IManualOverrideService, ManualOverrideService>();
|
||
|
||
// 报警系统服务
|
||
services.AddSingleton<IAlarmSystemService, AlarmSystemService>();
|
||
```
|
||
|
||
## 功能验证步骤
|
||
|
||
### 1. 规则引擎验证 (A2-T01)
|
||
|
||
#### 数量检查验证
|
||
```csharp
|
||
// 测试数据
|
||
var inference = new InferenceResultDto
|
||
{
|
||
Detections = new List<InferenceDetectionDto>
|
||
{
|
||
new() { ClassName = "product", Confidence = 0.9 },
|
||
new() { ClassName = "product", Confidence = 0.8 },
|
||
new() { ClassName = "defect", Confidence = 0.7 }
|
||
}
|
||
};
|
||
|
||
// 测试数量规则
|
||
var quantityRule = new RuleCondition
|
||
{
|
||
Type = ConditionType.QuantityCheck,
|
||
Operator = "range",
|
||
ExpectedValue = "2-4"
|
||
};
|
||
|
||
// 预期结果:true (实际数量为3,在范围2-4内)
|
||
```
|
||
|
||
#### 位置检查验证
|
||
```csharp
|
||
// 测试位置规则
|
||
var positionRule = new RuleCondition
|
||
{
|
||
Type = ConditionType.PositionCheck,
|
||
Parameter = "product",
|
||
Operator = "all",
|
||
ExpectedValue = "100,100,50" // 圆形范围:中心(100,100),半径50
|
||
};
|
||
|
||
// 预期结果:取决于检测对象的实际位置
|
||
```
|
||
|
||
#### 顺序检查验证
|
||
```csharp
|
||
// 测试顺序规则
|
||
var sequenceRule = new RuleCondition
|
||
{
|
||
Type = ConditionType.SequenceCheck,
|
||
Operator = "y_position",
|
||
ExpectedValue = "part1>part2>part3"
|
||
};
|
||
|
||
// 预期结果:取决于检测对象的Y坐标顺序
|
||
```
|
||
|
||
### 2. 状态机验证 (A2-T02)
|
||
|
||
#### 状态转换验证
|
||
```csharp
|
||
// 初始化状态机
|
||
var stateMachine = serviceProvider.GetService<IRuntimeStateMachineService>();
|
||
var initResult = stateMachine.TriggerInitialize();
|
||
Assert.IsTrue(initResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Initializing, stateMachine.GetCurrentState());
|
||
|
||
// 完成初始化
|
||
var initializedResult = stateMachine.TriggerInitialized();
|
||
Assert.IsTrue(initializedResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Idle, stateMachine.GetCurrentState());
|
||
|
||
// 启动系统
|
||
var startResult = stateMachine.TriggerStart();
|
||
Assert.IsTrue(startResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Ready, stateMachine.GetCurrentState());
|
||
|
||
// 产品进入
|
||
var productResult = stateMachine.TriggerProductEntered();
|
||
Assert.IsTrue(productResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.LayerIdentifying, stateMachine.GetCurrentState());
|
||
```
|
||
|
||
#### 守卫条件验证
|
||
```csharp
|
||
// 测试非法状态转换
|
||
var currentState = stateMachine.GetCurrentState();
|
||
var canPause = stateMachine.CanExecuteOperation(StateTrigger.Pause);
|
||
|
||
// 在Ready状态下应该不能暂停
|
||
Assert.AreEqual(RuntimeState.Ready, currentState);
|
||
Assert.IsFalse(canPause);
|
||
```
|
||
|
||
### 3. 人工干预验证 (A2-T03)
|
||
|
||
#### 权限校验验证
|
||
```csharp
|
||
var overrideService = serviceProvider.GetService<IManualOverrideService>();
|
||
var sessionId = Guid.NewGuid();
|
||
var operatorId = "operator1";
|
||
|
||
// 测试权限获取
|
||
var permissionResult = await overrideService.GetOverridePermissionAsync(sessionId, operatorId);
|
||
Assert.IsTrue(permissionResult.IsSuccess);
|
||
Assert.IsTrue(permissionResult.Data.HasPermission);
|
||
```
|
||
|
||
#### 干预执行验证
|
||
```csharp
|
||
// 创建干预请求
|
||
var overrideRequest = new ManualOverrideRequest
|
||
{
|
||
RequestId = Guid.NewGuid(),
|
||
SessionId = sessionId,
|
||
OperatorId = operatorId,
|
||
OperatorName = "测试操作员",
|
||
OverrideType = OverrideType.Release,
|
||
Reason = "测试放行操作"
|
||
};
|
||
|
||
// 执行干预
|
||
var overrideResult = await overrideService.ExecuteManualOverrideAsync(overrideRequest);
|
||
Assert.IsTrue(overrideResult.IsSuccess);
|
||
Assert.AreEqual(OverrideStatus.Overridden, overrideResult.Data.OverrideStatus);
|
||
```
|
||
|
||
### 4. 报警系统验证 (A2-T04)
|
||
|
||
#### 报警触发验证
|
||
```csharp
|
||
var alarmService = serviceProvider.GetService<IAlarmSystemService>();
|
||
|
||
// 创建报警请求
|
||
var alarmRequest = new AlarmRequest
|
||
{
|
||
RequestId = Guid.NewGuid(),
|
||
AlarmType = AlarmType.RuleViolation,
|
||
AlarmLevel = AlarmLevel.High,
|
||
Title = "测试报警",
|
||
Description = "这是一个测试报警",
|
||
SessionId = sessionId,
|
||
RelatedLayer = 1,
|
||
ExtendedProperties = new Dictionary<string, object>
|
||
{
|
||
["rule_number"] = "RULE-001"
|
||
}
|
||
};
|
||
|
||
// 触发报警
|
||
var alarmResult = await alarmService.TriggerAlarmAsync(alarmRequest);
|
||
Assert.IsTrue(alarmResult.IsSuccess);
|
||
Assert.AreEqual(AlarmStatus.Active, alarmResult.Data.AlarmStatus);
|
||
```
|
||
|
||
#### 报警生命周期验证
|
||
```csharp
|
||
var alarmId = alarmResult.Data.AlarmId;
|
||
|
||
// 确认报警
|
||
var confirmResult = await alarmService.ConfirmAlarmAsync(new AlarmConfirmRequest
|
||
{
|
||
AlarmId = alarmId,
|
||
ConfirmUser = "测试用户",
|
||
ConfirmReason = "确认测试报警"
|
||
});
|
||
Assert.IsTrue(confirmResult.IsSuccess);
|
||
Assert.AreEqual(AlarmStatus.Confirmed, confirmResult.Data.AlarmStatus);
|
||
|
||
// 清除报警
|
||
var clearResult = await alarmService.ClearAlarmAsync(new AlarmClearRequest
|
||
{
|
||
AlarmId = alarmId,
|
||
ClearUser = "测试用户",
|
||
ClearReason = "清除测试报警"
|
||
});
|
||
Assert.IsTrue(clearResult.IsSuccess);
|
||
Assert.AreEqual(AlarmStatus.Cleared, clearResult.Data.AlarmStatus);
|
||
|
||
// 恢复报警
|
||
var recoveryResult = await alarmService.SetAlarmRecoveryStatusAsync(new AlarmRecoveryRequest
|
||
{
|
||
AlarmId = alarmId,
|
||
Status = RecoveryStatus.ManualRecovered,
|
||
RecoveryUser = "测试用户",
|
||
RecoveryReason = "手动恢复测试报警"
|
||
});
|
||
Assert.IsTrue(recoveryResult.IsSuccess);
|
||
Assert.AreEqual(AlarmStatus.Recovered, recoveryResult.Data.AlarmStatus);
|
||
```
|
||
|
||
## 验收标准检查
|
||
|
||
### ✅ 非法状态迁移被拦截并有可读错误
|
||
```csharp
|
||
// 测试非法状态转换
|
||
var illegalResult = stateMachine.TriggerTransition(StateTrigger.Pause, "非法暂停");
|
||
Assert.IsFalse(illegalResult.IsSuccess);
|
||
Assert.IsTrue(illegalResult.Message.Contains("不允许"));
|
||
```
|
||
|
||
### ✅ NG触发后能进入锁定态并支持人工处理
|
||
```csharp
|
||
// 触发NG
|
||
var ngResult = stateMachine.TriggerNgDetected("测试NG");
|
||
Assert.IsTrue(ngResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.NgLocked, stateMachine.GetCurrentState());
|
||
|
||
// 人工干预
|
||
var interventionResult = stateMachine.TriggerManualIntervention("人工干预");
|
||
Assert.IsTrue(interventionResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.ManualIntervening, stateMachine.GetCurrentState());
|
||
|
||
// 完成干预
|
||
var completeResult = stateMachine.TriggerTransition(StateTrigger.ManualInterventionCompleted, "干预完成");
|
||
Assert.IsTrue(completeResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Running, stateMachine.GetCurrentState());
|
||
```
|
||
|
||
### ✅ 报警事件可查询完整生命周期
|
||
```csharp
|
||
// 查询报警生命周期
|
||
var lifecycleResult = await alarmService.GetAlarmLifecycleAsync(alarmId);
|
||
Assert.IsTrue(lifecycleResult.IsSuccess);
|
||
Assert.IsNotNull(lifecycleResult.Data);
|
||
Assert.AreEqual(sessionId, lifecycleResult.Data.SessionId);
|
||
Assert.AreEqual(1, lifecycleResult.Data.Layer);
|
||
Assert.AreEqual("RULE-001", lifecycleResult.Data.RuleNumber);
|
||
|
||
// 查询生命周期历史
|
||
var historyResult = await alarmService.GetAlarmLifecycleHistoryAsync(sessionId);
|
||
Assert.IsTrue(historyResult.IsSuccess);
|
||
Assert.IsTrue(historyResult.Data.Count > 0);
|
||
```
|
||
|
||
## 性能验证
|
||
|
||
### 并发测试
|
||
```csharp
|
||
// 并发触发多个报警
|
||
var tasks = new List<Task<Result<AlarmResult>>>();
|
||
for (int i = 0; i < 100; i++)
|
||
{
|
||
var request = new AlarmRequest
|
||
{
|
||
RequestId = Guid.NewGuid(),
|
||
AlarmType = AlarmType.RuleViolation,
|
||
AlarmLevel = AlarmLevel.Medium,
|
||
Title = $"并发测试报警 {i}",
|
||
SessionId = Guid.NewGuid()
|
||
};
|
||
tasks.Add(alarmService.TriggerAlarmAsync(request));
|
||
}
|
||
|
||
var results = await Task.WhenAll(tasks);
|
||
Assert.IsTrue(results.All(r => r.IsSuccess));
|
||
```
|
||
|
||
### 内存使用验证
|
||
```csharp
|
||
// 检查内存使用情况
|
||
var beforeMemory = GC.GetTotalMemory(true);
|
||
|
||
// 执行大量操作
|
||
for (int i = 0; i < 1000; i++)
|
||
{
|
||
var request = new AlarmRequest { /* ... */ };
|
||
await alarmService.TriggerAlarmAsync(request);
|
||
}
|
||
|
||
var afterMemory = GC.GetTotalMemory(true);
|
||
var memoryIncrease = afterMemory - beforeMemory;
|
||
|
||
// 内存增长应该在合理范围内
|
||
Assert.IsTrue(memoryIncrease < 50 * 1024 * 1024); // 小于50MB
|
||
```
|
||
|
||
## 日志验证
|
||
|
||
### 日志级别检查
|
||
确保所有重要操作都有相应的日志记录:
|
||
- **Information**:正常操作流程
|
||
- **Warning**:异常情况但系统可继续运行
|
||
- **Error**:错误情况需要关注
|
||
- **Debug**:详细的调试信息
|
||
|
||
### 日志内容检查
|
||
确保日志包含必要的上下文信息:
|
||
- 操作类型和参数
|
||
- 用户身份和权限
|
||
- 状态转换前后对比
|
||
- 错误详细信息和堆栈
|
||
|
||
## 故障恢复验证
|
||
|
||
### 状态机故障恢复
|
||
```csharp
|
||
// 触发故障
|
||
var faultResult = stateMachine.TriggerFault("测试故障");
|
||
Assert.IsTrue(faultResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Faulted, stateMachine.GetCurrentState());
|
||
|
||
// 故障恢复
|
||
var recoveryResult = stateMachine.TriggerFaultRecovered("故障恢复");
|
||
Assert.IsTrue(recoveryResult.IsSuccess);
|
||
Assert.AreEqual(RuntimeState.Running, stateMachine.GetCurrentState());
|
||
```
|
||
|
||
### 服务重启恢复
|
||
验证服务重启后能正确恢复状态:
|
||
- 保存关键状态到持久化存储
|
||
- 服务启动时正确加载历史状态
|
||
- 未完成的操作能够正确处理
|
||
|
||
## 集成验证
|
||
|
||
### 服务间协作验证
|
||
验证各服务之间的协作是否正常:
|
||
- 规则引擎与状态机的集成
|
||
- 人工干预与状态机的集成
|
||
- 报警系统与规则引擎的集成
|
||
- 报警系统与状态机的集成
|
||
|
||
### 端到端流程验证
|
||
验证完整的业务流程:
|
||
1. 系统启动 → 初始化 → 就绪
|
||
2. 产品进入 → 层识别 → 规则检查
|
||
3. 发现问题 → 触发报警 → 人工干预
|
||
4. 问题解决 → 状态恢复 → 继续运行
|
||
|
||
## 验证报告模板
|
||
|
||
```
|
||
# Agent-2 功能验证报告
|
||
|
||
## 验证环境
|
||
- .NET版本:
|
||
- 操作系统:
|
||
- 测试时间:
|
||
|
||
## 验证结果
|
||
- A2-T01 规则引擎:✅ 通过 / ❌ 失败
|
||
- A2-T02 状态机:✅ 通过 / ❌ 失败
|
||
- A2-T03 人工干预:✅ 通过 / ❌ 失败
|
||
- A2-T04 报警系统:✅ 通过 / ❌ 失败
|
||
|
||
## 发现的问题
|
||
1. 问题描述:
|
||
- 严重程度:
|
||
- 影响范围:
|
||
- 解决方案:
|
||
|
||
## 性能指标
|
||
- 平均响应时间:
|
||
- 内存使用:
|
||
- 并发处理能力:
|
||
|
||
## 改进建议
|
||
1. 功能改进:
|
||
2. 性能优化:
|
||
3. 安全加固:
|
||
```
|