Minion-Backend-Pg91
view release on metacpan or search on metacpan
use Mojo::Base -strict;
BEGIN { $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll' }
use Test::More;
plan skip_all => 'set TEST_ONLINE to enable this test' unless $ENV{TEST_ONLINE};
use Minion;
use Mojo::IOLoop;
use Sys::Hostname 'hostname';
use Time::HiRes qw(time usleep);
use Mojo::Util 'dumper';
# Isolate tests
require Mojo::Pg;
my $pg = Mojo::Pg->new($ENV{TEST_ONLINE});
$pg->db->query('drop schema if exists minion_test cascade');
$pg->db->query('create schema minion_test');
my $minion = Minion->new(Pg91 => $ENV{TEST_ONLINE});
$minion->backend->pg->search_path(['minion_test']);
# Nothing to repair
my $worker = $minion->repair->worker;
isa_ok $worker->minion->app, 'Mojolicious', 'has default application';
# Migrate up and down
is $minion->backend->pg->migrations->active, 15, 'active version is 15';
is $minion->backend->pg->migrations->migrate(0)->active, 0,
'active version is 0';
is $minion->backend->pg->migrations->migrate->active, 15,
'active version is 15';
# Register and unregister
$worker->register;
like $worker->info->{started}, qr/^[\d.]+$/, 'has timestamp';
my $notified = $worker->info->{notified};
like $notified, qr/^[\d.]+$/, 'has timestamp';
my $id = $worker->id;
is $worker->register->id, $id, 'same id';
usleep 50000;
ok $worker->register->info->{notified} > $notified, 'new timestamp';
is $worker->unregister->info, undef, 'no information';
my $host = hostname;
is $worker->register->info->{host}, $host, 'right host';
is $worker->info->{pid}, $$, 'right pid';
is $worker->unregister->info, undef, 'no information';
# Repair missing worker
$minion->add_task(test => sub { });
my $worker2 = $minion->worker->register;
isnt $worker2->id, $worker->id, 'new id';
$id = $minion->enqueue('test');
my $job = $worker2->dequeue(0);
is $job->id, $id, 'right id';
is $worker2->info->{jobs}[0], $job->id, 'right id';
$id = $worker2->id;
undef $worker2;
is $job->info->{state}, 'active', 'job is still active';
ok !!$minion->backend->worker_info($id), 'is registered';
$minion->backend->pg->db->query(
"update minion_workers
set notified = now() - interval '1 second' * ? where id = ?",
$minion->missing_after + 1, $id
);
$minion->repair;
ok !$minion->backend->worker_info($id), 'not registered';
like $job->info->{finished}, qr/^[\d.]+$/, 'has finished timestamp';
is $job->info->{state}, 'failed', 'job is no longer active';
is $job->info->{result}, 'Worker went away', 'right result';
# Repair abandoned job
$worker->register;
$id = $minion->enqueue('test');
$job = $worker->dequeue(0);
is $job->id, $id, 'right id';
$worker->unregister;
$minion->repair;
ok $job->finish, 'job finished';
ok !$worker->dequeue(0), 'parents are not ready yet';
ok $job2->fail, 'job failed';
ok !$worker->dequeue(0), 'parents are not ready yet';
ok $job2->retry, 'job retried';
$job2 = $worker->dequeue(0);
is $job2->id, $id2, 'right id';
ok $job2->finish, 'job finished';
$job = $worker->dequeue(0);
is $job->id, $id3, 'right id';
is_deeply $job->info->{children}, [], 'right children';
is_deeply $job->info->{parents}, [$id, $id2], 'right parents';
is $minion->stats->{finished_jobs}, 2, 'two finished jobs';
is $minion->repair->stats->{finished_jobs}, 2, 'two finished jobs';
ok $job->finish, 'job finished';
is $minion->stats->{finished_jobs}, 3, 'three finished jobs';
is $minion->repair->stats->{finished_jobs}, 0, 'no finished jobs';
$id = $minion->enqueue(test => [] => {parents => [-1]});
ok !$worker->dequeue(0), 'job with missing parent will never be ready';
$minion->repair;
like $minion->job($id)->info->{finished}, qr/^[\d.]+$/,
'has finished timestamp';
is $minion->job($id)->info->{state}, 'failed', 'right state';
is $minion->job($id)->info->{result}, 'Parent went away', 'right result';
$worker->unregister;
# Worker remote control commands
$worker = $minion->worker->register->process_commands;
$worker2 = $minion->worker->register;
my @commands;
$_->add_command(test_id => sub { push @commands, shift->id })
for $worker, $worker2;
$worker->add_command(test_args => sub { shift and push @commands, [@_] })
->register;
ok $minion->backend->broadcast('test_id', [], [$worker->id]), 'sent command';
ok $minion->backend->broadcast('test_id', [], [$worker->id, $worker2->id]),
'sent command';
$worker->process_commands->register;
$worker2->process_commands;
if (0) {
note "Commands: " . dumper(\@commands);
is_deeply \@commands, [$worker->id, $worker->id, $worker2->id],
'right structure';
}
@commands = ();
ok $minion->backend->broadcast('test_id'), 'sent command';
ok $minion->backend->broadcast('test_whatever'), 'sent command';
ok $minion->backend->broadcast('test_args', [23], []), 'sent command';
ok $minion->backend->broadcast('test_args', [1, [2], {3 => 'three'}],
[$worker->id]),
'sent command';
$_->process_commands for $worker, $worker2;
is_deeply \@commands,
[$worker->id, [23], [1, [2], {3 => 'three'}], $worker2->id],
'right structure';
$_->unregister for $worker, $worker2;
ok !$minion->backend->broadcast('test_id', []), 'command not sent';
# Clean up once we are done
$pg->db->query('drop schema minion_test cascade');
done_testing();
( run in 0.772 second using v1.01-cache-2.11-cpan-9581c071862 )