App-karr
view release on metacpan or search on metacpan
t/202-foundation-chain-executor.t view on Meta::CPAN
like $out, qr/the planner is wanted/,
'and the tick says so out loud, because no planner runs from here yet';
# The control: the same chain against a board where the precheck holds.
my $ok_repo = make_repo();
seed_board( $ok_repo, { status => 'todo' } );
write_karr( $ok_repo, command => write_agent($ok_repo), max_runtime => 60 );
my $ok_hub = make_repo();
chain_store($ok_hub)->write_chain( [
{ id => 1, kind => 'ticket', repo => "$ok_repo", ticket => 1,
precheck => 'ticket_status == todo' },
] );
tick($ok_hub);
is_deeply [ runs_of($ok_repo) ], ['1'],
'and with the same precheck holding, the very same step does run';
};
subtest 'a ticket step whose card is not on the board is stale, not run' => sub {
my $repo = make_repo();
seed_board( $repo, { status => 'todo' } );
write_karr( $repo, command => write_agent($repo), max_runtime => 60 );
my $hub = make_repo();
chain_store($hub)->write_chain( [
{ id => 1, kind => 'ticket', repo => "$repo", ticket => 99 },
] );
tick($hub);
ok !path($repo)->child('runs.log')->exists, 'no agent was started';
my $step = step_of( $hub, 1 );
is $step->{state}, 'stale', 'a plan about a card that is gone is out of date';
like $step->{stale_reason}, qr/ticket 99 is not on the board/,
'and says which card it could not find';
};
# ---------------------------------------------------------------------------
# What a failure does to the DAG
# ---------------------------------------------------------------------------
subtest 'a failed step stops its own branch and nothing else' => sub {
my $repo = make_repo();
my $hub = make_repo();
my $after = path($repo)->child('after');
my $other = path($repo)->child('other');
chain_store($hub)->write_chain( [
{ id => 1, kind => 'shell', repo => "$repo", command => 'exit 3' },
{ id => 2, kind => 'shell', repo => "$repo", needs => [1],
command => "echo after >> '$after'" },
{ id => 3, kind => 'shell', repo => "$repo", command => "echo other >> '$other'" },
] );
my ( $out ) = tick($hub);
is step_of( $hub, 1 )->{state}, 'failed', 'the step that exited non-zero failed';
is step_of( $hub, 1 )->{result}{exit}, 3, 'with the exit code recorded';
is step_of( $hub, 2 )->{state}, 'pending',
'its dependent never became ready -- ready_steps releases a step only when '
. 'everything it needs is DONE, so the branch prunes itself and nobody has '
. 'to compute a cascade';
ok !$after->exists, 'and it certainly did not run';
is step_of( $hub, 3 )->{state}, 'done',
'a step on another branch is unaffected: that is what the missing edge means';
is_deeply [ lines_of($other) ], ['other'], 'and it ran';
my ( $planner ) = grep { $_->{event} eq 'planner' } log_of($hub);
is $planner->{step}, '1', 'the planner is wanted for the step that failed';
is $planner->{policy}, 'plan', 'under the on_stall policy the spec writes';
like $out, qr/the planner is wanted for step\(s\) 1/,
'and the operator is told, since the operator is the planner until there '
. 'is one';
};
# ---------------------------------------------------------------------------
# Not every non-run is a failure
# ---------------------------------------------------------------------------
subtest 'a broken agent command requeues its step instead of failing it' => sub {
my $repo = make_repo();
seed_board( $repo, { status => 'todo' } );
write_karr( $repo, command => 'exit 7', max_runtime => 60 );
my $hub = make_repo();
chain_store($hub)->write_chain( [
{ id => 1, kind => 'ticket', repo => "$repo", ticket => 1 },
] );
my ( $out ) = tick($hub);
my $step = step_of( $hub, 1 );
is $step->{state}, 'pending',
'a rate-limited or broken agent command says nothing about the plan, so '
. 'the step goes back rather than down';
is $step->{attempts}, 1, 'the attempt is still counted';
ok !defined $step->{started}, 'and the claim is cleared';
like $out, qr/requeued/, 'the tick says it requeued it';
};
subtest 'a disabled board requeues a shell step, it does not fail it' => sub {
my $repo = make_repo();
my $hub = make_repo();
my $marker = path($repo)->child('marker');
seed_board( $repo, { status => 'todo' } );
board_store($repo)->set_foundation_enabled( 0, 'parked on purpose' );
chain_store($hub)->write_chain( [
{ id => 1, kind => 'shell', repo => "$repo", command => "echo x >> '$marker'" },
] );
tick($hub);
ok !$marker->exists,
'the board-level disable wins over a planned step: it is synchronised '
. 'board state, and "no automated runs here" does not get smaller because '
. 'the run was planned in the hub';
is step_of( $hub, 1 )->{state}, 'pending',
'pending, not failed -- whoever disabled the board is who can enable it';
};
subtest 'a repository this machine does not have is left alone entirely' => sub {
my $hub = make_repo();
( run in 1.036 second using v1.01-cache-2.11-cpan-e7c6538aa59 )