App-Sqitch
view release on metacpan or search on metacpan
'Check one change with to arg';
is_deeply +MockOutput->get_info, [
[__x 'Checking {destination}', destination => $engine->destination],
], 'Notification of the check should be emitted';
is_deeply +MockOutput->get_emit, [
[__ 'Check successful'],
], 'Success should be emitted';
is_deeply +MockOutput->get_comment, [], 'Should have no comments';
is_deeply $engine->seen, [
["deployed_changes", undef],
["change_id_for", {
change_id => undef,
change => 'roles',
tag => undef,
project => 'sql',
}],
["change_id_offset_from_id", ['0539182819c1f0cb50dc4558f4f80b1a538a01b2', 0]],
], 'Should have searched offsets';
# The check should be fine if we start at the second change
# (check should honor the `from` argument)
push @resolved => $changes[1]->id;
throws_ok {
$engine->check(
$changes[1]->format_name_with_tags,
undef,
)
} 'App::Sqitch::X', 'Should get error for one divergent script hash with from arg';
is $@->ident, 'check', 'Failed check ident should be "check"';
is $@->exitval, 1, 'No planned changes exitval should be 1';
is $@->message, __ 'Failed one check',
'Failed check message should be correct';
is_deeply +MockOutput->get_info, [
[__x 'Checking {destination}', destination => $engine->destination],
], 'Notification of the check should be emitted';
is_deeply +MockOutput->get_emit, [
[__x 'Script signatures diverge at change {change}',
change => $check_changes[1]->format_name_with_tags],
], 'Divergent change info should be emitted';
is_deeply $engine->seen, [
["deployed_changes", undef],
["change_id_for", {
change_id => undef,
change => 'users ',
tag => 'alpha',
project => 'sql',
}],
["change_id_offset_from_id", ['25cfff05d28c898f5c37263e2559fe75e239003c', 0]],
["latest_change_id", undef],
], 'Should have searched offsets and the latest change ID';
##############################################################################
# Test lock_destination().
# Test check().
$mock_engine->unmock('lock_destination');
can_ok $engine, 'lock_destination';
is $engine->lock_timeout, 60, 'Lock timeout should be 60 seconds';
# First let the try lock succeed.
$try_lock_ret = 1;
$engine->_locked(0);
ok $engine->lock_destination, 'Lock destination';
is $engine->_locked, 1, 'Should be locked';
is_deeply $engine->seen, [], 'wait_lock should not have been called';
is_deeply +MockOutput->get_info, [], 'Should have emitted no info';
# Now let the lock fail and fall back on waiting for the lock.
$try_lock_ret = 0;
$wait_lock_ret = 1;
$engine->_locked(0);
ok $engine->lock_destination, 'Lock destination';
is $engine->_locked, 1, 'Should be locked again';
is_deeply $engine->seen, ['wait_lock'], 'wait_lock should have been called';
is_deeply +MockOutput->get_info, [[__x(
'Blocked by another instance of Sqitch working on {dest}; waiting {secs} seconds...',
dest => $engine->destination,
secs => $engine->lock_timeout,
)]], 'Should have notified user of waiting for lock';
# Another attempt to lock should be a no-op.
ok $engine->lock_destination, 'Lock destination again';
is_deeply $engine->seen, [], 'wait_lock should not have been called';
is_deeply +MockOutput->get_info, [], 'Should again have emitted no info';
# Now have it time out.
$try_lock_ret = 0;
$wait_lock_ret = 0;
$engine->_locked(0);
$engine->lock_timeout(0.1);
throws_ok { $engine->lock_destination } 'App::Sqitch::X',
'Should get error for lock timeout';
is $@->ident, 'engine', 'Lock timeout error ident should be "engine"';
is $@->exitval, 2, 'Lock timeout error exitval should be 2';
is $@->message, __x(
'Timed out waiting {secs} seconds for another instance of Sqitch to finish work on {dest}',
dest => $engine->destination,
secs => $engine->lock_timeout,
), 'Lock timeout error message should be correct';
is_deeply +MockOutput->get_info, [[__x(
'Blocked by another instance of Sqitch working on {dest}; waiting {secs} seconds...',
dest => $engine->destination,
secs => $engine->lock_timeout,
)]], 'Should have notified user of waiting for lock';
is_deeply $engine->seen, ['wait_lock'], 'wait_lock should have been called';
##############################################################################
# Test _to_idx()
$mock_whu->mock(latest_change_id => 2);
is $engine->_to_idx, $plan->count-1,
'Should get last index when there is a latest change ID';
$mock_whu->unmock('latest_change_id');
##############################################################################
# Test _handle_lookup_index() with change names not in the plan.
throws_ok { $engine->_handle_lookup_index('foo', [qw(x y)]) } 'App::Sqitch::X',
'Should die on too many IDs';
is $@->ident, 'engine', 'Too many IDs ident should be "engine"';
is $@->message, __('Change Lookup Failed'),
'Too many IDs message should be correct';
is_deeply +MockOutput->get_vent, [
[__x(
'Change "{change}" is ambiguous. Please specify a tag-qualified change:',
change => 'foo',
)],
[ ' * ', 'bugaboo' ],
[ ' * ', 'bugaboo' ],
], 'Too many IDs error should have been vented';
##############################################################################
# Test planned_deployed_common_ancestor_id.
is $engine->planned_deployed_common_ancestor_id,
'0539182819c1f0cb50dc4558f4f80b1a538a01b2',
'Test planned_deployed_common_ancestor_id';
##############################################################################
# Test default implementations.
is $engine->key, 'whu', 'Should have key';
is $engine->driver, $engine->key, 'Driver should be the same as engine';
ok $CLASS->try_lock, 'Default try_lock should return true by default';
is $CLASS->begin_work, $CLASS, 'Default begin_work should return self';
is $CLASS->finish_work, $CLASS, 'Default finish_work should return self';
__END__
diag $_->format_name_with_tags for @changes;
diag '======';
diag $_->format_name_with_tags for $plan->changes;
( run in 0.396 second using v1.01-cache-2.11-cpan-63c85eba8c4 )