Developer-Dashboard
view release on metacpan or search on metacpan
t/94-dockercompose-coverage.t view on Meta::CPAN
# multi-file merge resolving a service correctly, only on `config` having
# already done so once, up front.
# ---------------------------------------------------------------------------
my $logbin = File::Spec->catdir( $home, 'logbin' );
make_path($logbin);
my $invocation_log = File::Spec->catfile( $home, 'docker-invocations.log' );
mkfile(
File::Spec->catfile( $logbin, 'docker' ), <<"STUB" );
#!/bin/sh
printf '%s\\n' "\$*" >> '$invocation_log'
last=''
for a in "\$\@"; do last="\$a"; done
if [ "\$last" = 'config' ]; then
case "\${P40_COMPOSE_OUTPUT:-valid}" in
malformed) printf 'services: [\\n' ;;
scalar) printf '%s\\n' '[]' ;;
no_services) printf '%s\\n' '{}' ;;
invalid_services) printf '%s\\n' 'services: []' ;;
empty_service) printf '%s\\n' 'services:' ' "": {}' ;;
dot_service) printf '%s\\n' 'services:' ' ".": {}' ;;
dotdot_service) printf '%s\\n' 'services:' ' "..": {}' ;;
unsafe_service) printf '%s\\n' 'services:' ' "../outside": {}' ;;
*) printf 'services:\\n merged-marker:\\n image: stub\\n' ;;
esac
fi
exit 0
STUB
chmod 0755, File::Spec->catfile( $logbin, 'docker' );
{
unlink $invocation_log if -e $invocation_log;
my $old = getcwd();
chdir $repo or die $!;
local $ENV{PATH} = "$logbin:$ENV{PATH}";
my $result = $docker->run(
addons => ['mailhog'],
args => [ 'config', 'app' ],
modes => ['dev'],
services => ['worker'],
);
chdir $old or die $!;
is( $result->{exit_code}, 0, 'run with multiple layers still succeeds' );
open my $log_fh, '<', $invocation_log or die "Unable to read $invocation_log: $!";
my @lines = <$log_fh>;
close $log_fh;
chomp @lines;
ok( scalar(@lines) >= 2, 'run invokes docker at least twice: once to materialize, once to execute' )
or diag( explain \@lines );
like( $lines[0], qr/(?:^| )config$/, 'first invocation is the materialize-via-config call' );
ok( ( grep { /-f / } $lines[0] ), 'the materialize call carries the original multi -f layers' )
or diag( explain \@lines );
my $final_call = $lines[-1];
my @f_flags = ( $final_call =~ /-f (\S+)/g );
is( scalar(@f_flags), 1, 'the executed call passes exactly one -f, pointing at the merged file' )
or diag( explain \@lines );
ok( -f $f_flags[0], 'the single -f file the executed call names actually exists on disk' );
my $merged_content = do { local ( @ARGV, $/ ) = $f_flags[0]; <> };
like( $merged_content, qr/merged-marker/, 'the merged file holds the materialized config, not a raw layer file' );
like( $final_call, qr/ app$/, 'the executed call still carries the original passthrough args (app)' );
}
# Operational commands must retain the invocation Compose root after layered
# files are materialized into a temporary merged file. Without an explicit
# project directory, Compose derives relative paths and the default project
# name from that temporary file instead of the user's local Compose project.
{
my $old = getcwd();
chdir $repo or die $!;
local $ENV{PATH} = "$logbin:$ENV{PATH}";
for my $action (
[ up => [ 'up', '-d', 'app' ] ],
[ build => [ 'build', 'app' ] ],
[ down => ['down'] ],
) {
unlink $invocation_log if -e $invocation_log;
my ( $label, $args ) = @{$action};
my $result = $docker->run( args => $args );
is( $result->{exit_code}, 0, "$label operation succeeds after layered config materialization" );
open my $log_fh, '<', $invocation_log or die "Unable to read $invocation_log: $!";
my @lines = <$log_fh>;
close $log_fh;
chomp @lines;
like( $lines[0] || '', qr/--project-directory \Q$repo\E/, "$label materialization uses the invocation Compose directory" );
my $final_call = $lines[-1] || '';
like(
$final_call,
qr/--project-directory \Q$repo\E/,
"$label operation keeps the invocation directory as Compose project directory",
);
like( $final_call, qr/(?:^| )\Q$label\E(?: |$)/, "$label operation remains the requested Compose action" );
}
chdir $old or die $!;
}
{
my $custom_project_dir = File::Spec->catdir( $home, 'explicit-compose-project' );
make_path($custom_project_dir);
my $old = getcwd();
chdir $repo or die $!;
local $ENV{PATH} = "$logbin:$ENV{PATH}";
for my $project_option (
[ separate => [ '--project-directory', $custom_project_dir ] ],
[ equals => [ "--project-directory=$custom_project_dir" ] ],
) {
unlink $invocation_log if -e $invocation_log;
my ( $label, $option_args ) = @{$project_option};
$docker->run( args => [ @{$option_args}, 'up', 'app' ] );
open my $log_fh, '<', $invocation_log or die "Unable to read $invocation_log: $!";
my @lines = <$log_fh>;
close $log_fh;
chomp @lines;
like( $lines[0] || '', qr/--project-directory(?:=| )\Q$custom_project_dir\E/, "explicit $label project directory also applies while materializing" );
my $final_call = $lines[-1] || '';
( run in 0.494 second using v1.01-cache-2.11-cpan-ac8be02dad9 )