App-karr

 view release on metacpan or  search on metacpan

t/177-expired-claim-takeover.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use lib 't/lib';
use TestGit qw( require_git_c );
require_git_c();
use TestKarr qw( run_karr );
use File::Temp qw( tempdir );
use JSON::MaybeXS qw( decode_json );

# Ticket #177, the behavioural half of #176. An expired claim no longer blocks
# anybody -- that is what claim_timeout is *for*, and this test does not try to
# take it back. What it pins is that stepping over one is no longer silent.
#
# Before this change the two halves of the same mismatch answered completely
# differently:
#
#   live claim, other name      refused, exit 1, "Task 1 is claimed by <A>"
#   expired claim, other name   "Handed off task 1 -> review", exit 0, card
#                               re-stamped to <B>, nothing said anywhere
#
# So the one signal that names the previous holder disappeared exactly when it
# was most useful: an agent that lost its own claim name (#176, `karr agentname`
# mints a fresh one per call) got a success instead of the hint, and
# karr-foundation -- which attributes stalls per claim name -- had its
# attribution moved to a name nobody held, with no record that the card had ever
# belonged to someone else.
#
# App::karr::Role::ClaimTimeout::check_claim now records the override and the
# commands emit it after the write lands, the way
# App::karr::Role::DependencyCheck already reports unsatisfied dependencies:
# STDERR for humans, the `expired_claim` pair under --json, silenced by --quiet.
# Return value and exit code are deliberately unchanged.

# In-process runner (t/lib/TestKarr.pm): same ($cwd, @argv) signature and
# { exit, stdout, stderr } return as the open3 helper this file used to carry,
# dispatched through the shared App::karr::Dispatch path. KARR_TEST_SUBPROC=1
# restores the old open3 path.
sub _run_karr { return run_karr(@_) }

# Always a throwaway repo; never the developer's real board.
sub _setup_repo {
    my (%opt) = @_;
    my $repo = tempdir( CLEANUP => 1 );
    system( 'git', 'init', '-q', $repo ) == 0 or die 'git init failed';
    system( 'git', '-C', $repo, 'config', 'user.email', 'test@example.com' ) == 0
      or die 'git config failed';
    system( 'git', '-C', $repo, 'config', 'user.name', 'Test User' ) == 0
      or die 'git config failed';

    my $init = _run_karr( $repo, 'init', '--name', 'Ticket177 Board' );
    is( $init->{exit}, 0, 'karr init succeeds' ) or diag $init->{stderr};

    if ( $opt{claim_timeout} ) {
        my $cfg = _run_karr( $repo, 'config', 'set', 'claim_timeout',
            $opt{claim_timeout} );
        is( $cfg->{exit}, 0, "claim_timeout set to $opt{claim_timeout}" )
          or diag $cfg->{stderr};
    }

    for my $n ( 1 .. ( $opt{tasks} || 1 ) ) {
        my $rv = _run_karr( $repo, 'create', "Task $n" );
        is( $rv->{exit}, 0, "task $n created" ) or diag $rv->{stderr};
    }

    return $repo;
}

my $HOLDER  = 'agent-holder';
my $TAKEOVER = 'agent-takeover';

# The one sentence every command has to produce, whoever is stepping over the
# claim -- including the two that pass no claimant at all.
sub _trace_re {
    my ( $id, $holder ) = @_;
    return qr/task \Q$id\E: overriding the expired claim held by \Q$holder\E/;
}

subtest 'an expired claim taken over by another name is reported' => sub {
    my $repo = _setup_repo( claim_timeout => '1s', tasks => 6 );

    my $claim = _run_karr( $repo, 'move', '1,2,3,4,5,6', 'in-progress',
        '--claim', $HOLDER );
    is( $claim->{exit}, 0, 'all six tasks claimed by the holder' )
      or diag $claim->{stderr};

    # One sleep for the whole subtest: every claim above was stamped before it,
    # so every card below is expired by the same wait.
    sleep 2;



( run in 1.423 second using v1.01-cache-2.11-cpan-85d3896f969 )