API-Docker
view release on metacpan or search on metacpan
t/images_build_prune.t view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use FindBin;
use lib "$FindBin::Bin/lib";
use Test::API::Docker::Mock;
use API::Docker;
# karr k25 -- images->build_prune, POST /build/prune. Clears the BuildKit
# build cache, which is a different store from the dangling images
# images->prune deletes.
#
# The parameter that needs watching is keep-storage: the engine spells it
# with a hyphen, and the transport's _uri_encode must leave that alone rather
# than percent-encoding it into keep%2Dstorage. An unquoted
# `keep-storage => $n` is not even valid Perl -- the fat comma only quotes a
# bareword identifier -- so keep_storage is the documented spelling and the
# wire name is accepted beside it.
#
# Measured against the rootless Podman socket (5.4.2, API 1.41): Podman does
# not implement the endpoint at all. POST /build/prune answers 404 Not Found
# with a text/plain body of "Not Found" -- not the JSON {"message":...} shape
# its other errors use -- at /build/prune, /v1.41/build/prune,
# /v1.47/build/prune and /v4.0.0/libpod/build/prune alike.
check_live_access();
# See t/images_tar.t for why this exists.
package Test::BuildPrune::FakeTransport;
use Moo;
extends 'API::Docker';
has canned => (is => 'rw', default => sub {
[200, 'OK', {}, '{"CachesDeleted":["abc"],"SpaceReclaimed":1024}'] });
has _sink => (is => 'rw');
sub _build__socket {
my ($self) = @_;
my $sink = '';
$self->_sink(\$sink);
open my $fh, '>', \$sink or die "open: $!";
return $fh;
}
sub _read_response { return $_[0]->canned }
sub written { return ${ $_[0]->_sink } }
package main;
sub fake_client {
return Test::BuildPrune::FakeTransport->new(
host => 'unix:///nonexistent.sock',
api_version => '1.41',
);
}
sub request_line {
my ($t) = @_;
my ($line) = $t->written =~ /\A(\S+ [^\r\n]+) HTTP\/1\.1\r\n/;
return $line;
}
# ---------------------------------------------------------------------------
subtest 'build_prune is a different endpoint from prune' => sub {
plan skip_all => 'route assertions are fixture-only' if is_live();
my @paths;
my $docker = test_docker(
'POST /build/prune' => sub { push @paths, $_[1]; { CachesDeleted => ['abc'], SpaceReclaimed => 1024 } },
'POST /images/prune' => sub { push @paths, $_[1]; { ImagesDeleted => [], SpaceReclaimed => 7 } },
);
my $cache = $docker->images->build_prune;
my $dangling = $docker->images->prune;
is_deeply \@paths, [ '/build/prune', '/images/prune' ],
'build_prune hits /build/prune and prune still hits /images/prune';
is $cache->{SpaceReclaimed}, 1024, 'the build cache result comes back raw';
is_deeply $cache->{CachesDeleted}, ['abc'], 'including CachesDeleted';
is $dangling->{SpaceReclaimed}, 7, 'and prune is untouched by any of it';
};
# ---------------------------------------------------------------------------
subtest 'keep-storage keeps its hyphen on the wire' => sub {
my $t = fake_client();
$t->images->build_prune(keep_storage => 5368709120);
is request_line($t), 'POST /v1.41/build/prune?keep-storage=5368709120',
'keep_storage is sent under the hyphenated name the engine expects';
unlike request_line($t), qr/keep%2Dstorage/i,
'the query encoder did not percent-encode the hyphen';
unlike request_line($t), qr/keep_storage/,
'and the underscore spelling never reaches the daemon';
$t->images->build_prune('keep-storage' => 42);
is request_line($t), 'POST /v1.41/build/prune?keep-storage=42',
'the wire name is accepted as the option name too';
};
subtest 'all and filters' => sub {
my $t = fake_client();
$t->images->build_prune(all => 1);
is request_line($t), 'POST /v1.41/build/prune?all=1',
'a true all is sent as 1';
$t->images->build_prune(all => 0);
is request_line($t), 'POST /v1.41/build/prune?all=0',
'a false all is sent as 0 rather than dropped';
$t->images->build_prune;
( run in 1.033 second using v1.01-cache-2.11-cpan-364913b4093 )