App-FuguWeb
view release on metacpan or search on metacpan
t/fuguweb/rotate.t view on Meta::CPAN
Fugu::File->write( "$root/.fuguwebrc", <<'RC' );
site = Example
nav "index.html" {
label = Home
}
page "index.html" {
title = Home
body = index.body.html
}
RC
return $root;
}
# _rotate($root):
# A rotation over the description of the project, with the
# bootstrap words that a first mint needs.
sub _rotate ($root)
{
my $reason;
my $config = App::FuguWeb::Config->load( root => $root,
error => \$reason )
or die "load $root: $reason\n";
return App::FuguWeb::Rotate->new(
config => $config,
org => $ORG,
url => $URL,
);
}
# _mint($root, %args), _promote($root, %args):
# One step over a fresh rotation, so each step reads the
# description that the step before it wrote.
sub _mint ( $root, %args )
{
my $rotate = _rotate($root);
my $facts = $rotate->mint( purpose => 'release', %args );
return ( $facts, $rotate->error );
}
sub _promote ( $root, %args )
{
my $rotate = _rotate($root);
my $facts = $rotate->promote( purpose => 'release', %args );
return ( $facts, $rotate->error );
}
# _run(@argv):
# Drive the real command in process, and answer the exit code
# with what it wrote.
sub _run (@argv)
{
my ( $out, $err ) = ( '', '' );
open my $saved_out, '>&', \*STDOUT or die "Cannot save stdout: $!";
open my $saved_err, '>&', \*STDERR or die "Cannot save stderr: $!";
close STDOUT;
close STDERR;
open STDOUT, '>', \$out or die 'Cannot capture stdout';
open STDERR, '>', \$err or die 'Cannot capture stderr';
my $exit = eval { App::FuguWeb::CLI->run(@argv) };
my $died = $@;
close STDOUT;
close STDERR;
open STDOUT, '>&', $saved_out or die "Cannot restore stdout: $!";
open STDERR, '>&', $saved_err or die "Cannot restore stderr: $!";
die $died if $died;
return ( $exit, $out, $err );
}
# _verifies($root, $stem):
# True when the published key of the stem verifies the manifest
# pair of the key directory.
sub _verifies ( $root, $stem )
{
my $dir = "$root/web/keys";
my $signify = Fugu::Signify->new( keys => ["$dir/$stem.pub"] );
return $signify->verify( "$dir/SHA256", "$dir/SHA256.sig" ) ? 1 : 0;
}
# _problems($root):
# What App::FuguWeb::Keys reports about the directory.
sub _problems ($root)
{
my $reason;
my $config = App::FuguWeb::Config->load( root => $root,
error => \$reason )
or return ("load: $reason");
return App::FuguWeb::Keys->new( config => $config )->problems;
}
subtest 'the first mint bootstraps and signs its own manifest' => sub {
my $root = _site();
my ( $facts, $error ) =
_mint( $root, secret => "$root/k1.sec" );
ok( $facts, 'the mint succeeds' ) or diag($error);
return unless $facts;
is( $facts->{name}, 'fugubsd-1-release.pub', 'the name of the key' );
is( $facts->{serial}, 1, 'the serial starts at 1' );
# WEB-ROTATE-3. The purpose held no current key.
is( $facts->{status}, 'current', 'the first key is current at once' );
# WEB-ROTATE-15. The keys block and the first key block
# arrive together, and the block carries the published prefix.
my $rc = Fugu::File->read("$root/.fuguwebrc");
like( $rc, qr/^keys "keys" \{$/m, 'the description takes a keys block' );
like( $rc, qr/^\torg = \Q$ORG\E$/m, 'with the organization word' );
like( $rc, qr/^\turl = \Q$URL\E$/m, 'and the published prefix' );
like(
$rc,
qr/^key "fugubsd-1-release" \{\n\tstatus = current$/m,
'and the block of the first key'
);
# WEB-ROTATE-6. The one exception: this key signs for itself.
ok( _verifies( $root, 'fugubsd-1-release' ),
'the published key verifies the manifest' );
# WEB-ROTATE-2. The private half takes no group mode and no
( run in 1.553 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )