App-Ariza.git | xt/ | 06-runner-release.rakutest
use v6.d;
use Test;
use App::Ariza::Resources;
use App::Ariza::Runner;
use App::Ariza::Tools;
=begin comment
This is the live half of the runner pin. The unit suite proves that a
download is rejected when its bytes do not match resources/runner-checksums.txt;
this test proves that the resource itself still describes the immutable assets
published under resources/RUNNER_VERSION.
It deliberately has no offline skip and no alternate URL or local-file
override. mi6 runs xt/ before UploadToZef, so a missing release, a partial
release, stale embedded pins, or changed bytes must stop publication.
prove6 -Ilib xt/06-runner-release.rakutest
=end comment
plan 5;
my @artifacts =
'ariza-runner-windows-aarch64.exe',
'ariza-runner-windows-x86_64.exe';
my %slug-for =
'ariza-runner-windows-aarch64.exe' => 'windows-arm64',
'ariza-runner-windows-x86_64.exe' => 'windows-x86_64';
my $work = $*TMPDIR.add("ariza-runner-release-{$*PID}-{(^1_000_000).pick}");
ensure-dir($work);
END { rm-rf($work) }
my $tag = App::Ariza::Runner.tag;
ok $tag.defined && $tag ~~ /^ 'runner-v' <[0..9]>+ $/,
'resources/RUNNER_VERSION is an exact runner-vN tag';
my %embedded = strict-pins(
App::Ariza::Resources::resource('runner-checksums.txt'));
is-deeply %embedded.keys.sort.List, @artifacts.List,
'the distribution embeds exactly the two runner artefact pins';
my $release-base = App::Ariza::Runner::RELEASE-BASE;
my $published-file = http-download(
"$release-base/$tag/checksums.txt",
$work.add('checksums.txt'));
my %published = strict-pins($published-file);
is-deeply %published.keys.sort.List, @artifacts.List,
'the pinned release publishes checksums for exactly those two artefacts';
is-deeply %published, %embedded,
'the published checksums are identical to the embedded pins';
subtest 'both published executables have the advertised bytes', {
plan +@artifacts;
for @artifacts -> $artifact {
my $slug = %slug-for{$artifact};
my $binary = http-download(
App::Ariza::Runner.url(:$slug, :$tag),
$work.add($artifact));
is sha256-file($binary), %published{$artifact},
"$artifact matches its published sha256";
}
};
# Runner.pins is the production parser: every non-comment line must be one
# complete `<sha256> <artefact>` entry. A repeated filename would otherwise
# collapse in the returned Hash, so additionally require a one-to-one mapping
# between parsed lines and keys; a checksum manifest with duplicate claims is
# not an exact two-artefact release.
sub strict-pins(IO::Path:D $path --> Hash) {
my @entries = $path.slurp.lines
.map(*.trim)
.grep({ .chars && !.starts-with('#') });
my %pins = App::Ariza::Runner.pins($path);
die "ariza: {$path.basename} contains duplicate artefact entries"
unless +%pins == +@entries;
%pins
}