2026-09-20 12:18:52 +08:00
|
|
|
#include "workflow_fixture.hpp"
|
|
|
|
|
struct FailedPlaceDriver : Simulator {
|
|
|
|
|
void send(const GoalRequest& q) override {
|
|
|
|
|
Simulator::send(q);
|
2026-09-20 13:36:48 +08:00
|
|
|
if(q.skill==Skill::PLACE){auto& event=events.back();event.native_status=NativeStatus::ABORTED;event.result.code=ResultCode::FAILED;event.result.error_code="VLA_EXECUTION_FAILED";}
|
2026-09-20 12:18:52 +08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
int main(){
|
|
|
|
|
Fixture config("settlement_config");FailedPlaceDriver driver;ContextStore context;
|
|
|
|
|
ActiveGoalRegistry registry(driver,Fixture::test_root()+"/settlement.journal");unsigned deliveries=0;
|
|
|
|
|
StageRunner runner(config.task,config.site,driver,registry,context,[&](const std::string&,unsigned,const std::string&){++deliveries;return true;});
|
|
|
|
|
Workflow flow(runner);TickStatus status=TickStatus::RUNNING;unsigned i=0;
|
|
|
|
|
for(;i<200&&status==TickStatus::RUNNING;++i){driver.now=1000000+i*1000000;runner.update_safety({true,true,driver.sensor_holding,driver.now,driver.now+1000000000});status=flow.tick(SteadyTime{}+Milliseconds(i),driver.now);}
|
|
|
|
|
assert(status==TickStatus::FAILURE);assert(deliveries==0);
|
|
|
|
|
runner.halt(SteadyTime{}+Milliseconds(i));
|
2026-09-20 13:36:48 +08:00
|
|
|
runner.update_safety({true,false,driver.sensor_holding,driver.now,driver.now+1000000000});
|
|
|
|
|
assert(runner.settle(SteadyTime{}+Milliseconds(i),driver.now)==TickStatus::RUNNING);
|
2026-09-20 12:18:52 +08:00
|
|
|
// Settlement is read-only except for the idempotent business receipt.
|
|
|
|
|
for(status=TickStatus::RUNNING;i<300&&status==TickStatus::RUNNING;++i){driver.now=1000000+i*1000000;runner.update_safety({true,true,driver.sensor_holding,driver.now,driver.now+1000000000});status=runner.settle(SteadyTime{}+Milliseconds(i),driver.now);}
|
2026-09-20 13:36:48 +08:00
|
|
|
assert(status==TickStatus::SUCCESS);assert(deliveries==1);assert(runner.error_code()=="VLA_EXECUTION_FAILED");
|
2026-09-20 12:18:52 +08:00
|
|
|
unsigned place=0,verify=0;for(const auto&q:driver.sent){place+=q.skill==Skill::PLACE;verify+=q.skill==Skill::VERIFY_PLACE;}
|
|
|
|
|
assert(place==1&&verify==1);assert(runner.empty_verified(driver.now));
|
|
|
|
|
assert(runner.settle(SteadyTime{}+Milliseconds(i),driver.now)==TickStatus::SUCCESS);assert(deliveries==1);
|
|
|
|
|
std::cout<<"failed place settlement records verified delivery without motion retry\n";
|
|
|
|
|
}
|