API-Docker
view release on metacpan or search on metacpan
t/streaming_methods.t view on Meta::CPAN
->images->pull(fromImage => 'alpine', tag => '3', on_event => $cb);
},
'images->push' => sub {
my ($cb) = @_;
test_docker('POST /images/x/push' => \@progress)
->images->push('x', on_event => $cb);
},
'images->load' => sub {
my ($cb) = @_;
test_docker('POST /images/load' => \@progress)
->images->load('tar-bytes', on_event => $cb);
},
'plugins->install' => sub {
my ($cb) = @_;
test_docker('POST /plugins/pull' => \@progress)
->plugins->install('vieux/sshfs', privileges => [], on_event => $cb);
},
'plugins->upgrade' => sub {
my ($cb) = @_;
test_docker('POST /plugins/sshfs/upgrade' => \@progress)
->plugins->upgrade('sshfs', privileges => [], on_event => $cb);
},
'plugins->push' => sub {
my ($cb) = @_;
test_docker('POST /plugins/sshfs/push' => \@progress)
->plugins->push('sshfs', on_event => $cb);
},
'containers->attach' => sub {
my ($cb) = @_;
test_docker('POST /containers/abc/attach' => [
{ stream => 'stdout', data => "one\n" },
{ stream => 'stdout', data => "two\n" },
{ stream => 'stderr', data => "three\n" },
# require_running => 0: this case is about the callback contract, not
# about attach's running-container check, and opting out keeps the route
# table down to the one endpoint under test.
])->containers->attach('abc', on_frame => $cb, require_running => 0);
},
);
for my $name (sort keys %case) {
my @got;
my $summary = $case{$name}->(sub {
my ($unit, $stop) = @_;
push @got, $unit;
$stop->() if @got >= 2;
});
is scalar(@got), 2, "$name delivered units one at a time";
is_deeply $summary, { delivered => 2, stopped => 1 },
"$name returned the summary and stopped where the callback said";
}
};
subtest 'the entity classes forward the callback too' => sub {
plan skip_all => 'live mode ignores the route table' if is_live();
# containers_list (karr k101 follow-up): a real capture -- see t/containers.t.
# The logs route names the fixture's own container id exactly, rather than
# a [^/]+ wildcard: Test::API::Docker::Mock's fallback tier used to
# interpolate a route key as an unescaped regex, which is what made a
# wildcard like that "work" here by accident (karr k109, t/mock_harness.t)
# -- now that it is quotemeta'd, a route key means the literal path it
# looks like.
my $docker = test_docker(
'GET /containers/json' => load_fixture('containers_list'),
'GET /containers/b20ac7508d80182ba3cd1cbd006ac10c8a15f4f7590fa89c2078d146caf96555/logs' => [
{ stream => 'stdout', data => "one\n" },
{ stream => 'stdout', data => "two\n" },
],
);
my ($container) = @{ $docker->containers->list };
my @got;
my $summary = $container->logs(follow => 1, on_frame => sub { push @got, $_[0] });
is scalar(@got), 2, 'the container entity->logs streams like the API class';
is_deeply $summary, { delivered => 2, stopped => 0 },
'and hands the same summary back rather than an ArrayRef of frames';
};
# ---------------------------------------------------------------------------
subtest 'live: a callback against the daemon itself' => sub {
plan skip_all => 'set API_DOCKER_TEST_HOST for the live path' unless is_live();
check_live_access();
my $docker = test_docker();
my @got;
# Bounded on purpose. An unbounded feed with no traffic in it would deliver
# nothing and never end, which is a hung suite rather than a failed
# assertion -- the unbounded case is the one to run by hand, under timeout.
my $summary = $docker->system->events(
since => time - 3600,
until => time,
on_event => sub {
my ($event, $stop) = @_;
push @got, $event;
$stop->() if @got >= 3;
},
);
is ref $summary, 'HASH', 'a summary came back from a real daemon';
is $summary->{delivered}, scalar(@got), 'counting what the callback saw';
ok !grep({ ref $_ ne 'HASH' } @got), 'every unit is a decoded event';
};
done_testing;
( run in 1.074 second using v1.01-cache-2.11-cpan-54e63673c56 )