App-FuguBench

 view release on metacpan or  search on metacpan

t/fugubench/get.t  view on Meta::CPAN

#!/usr/bin/env perl
# ex:ts=8 sw=4:
# The stub of the install address, web/get (DIST-INSTALL-3 to
# DIST-INSTALL-6).
#
# Each case runs web/get as a child of /bin/sh. The whole PATH of the
# child is the bin directory of a temporary tree, and that directory
# holds the stub downloader of the case, or no downloader at all. So
# no case reaches the network, and each case reads and writes inside
# its own tree.
#
# A stub prints the install script of its case, and that script
# writes the marker file of the tree. The marker is the proof that sh
# ran the fetched text.

use v5.34;
use warnings;
use experimental 'signatures';
no feature qw(indirect multidimensional bareword_filehandles);

use Test::More;
use File::Basename qw(basename);
use File::Temp     qw(tempdir);
use FindBin        qw($RealBin);
use lib "$RealBin/../../lib";

use Fugu::File;
use Fugu::Process;

my $root = "$RealBin/../..";
my $get  = "$root/web/get";

# The release tarball holds t/fugubench and no web directory.
plan skip_all => 'no web/get' unless -f $get;

# The URL that the stub fetches. GitHub resolves the latest release
# at the moment of the fetch, so no release changes the website.
my $URL =
    'https://github.com/FuguBSD/FuguBench/releases/latest/download/install.sh';

# The line bound of the stub (DIST-INSTALL-5). A visitor reads the
# file before the visitor runs it, and one screen holds it.
my $MAX_LINES = 30;

# The argument list that the stub builds for each downloader
# (DIST-INSTALL-4). curl takes -f, so an HTTP error writes no error
# page, and -L, so it follows the redirect of the latest-release
# path. wget takes --tries=1, so no retry appends to standard output.
# Each tool writes the body to standard output.
my %COMMAND = (
	curl => "curl -fsSL $URL",
	wget => "wget -q --tries=1 -O - $URL",
	ftp  => "ftp -V -o - $URL",
);

# The value that the install script writes into the marker. It holds
# a backslash, because a transport that reads an escape changes it:
# the echo of a POSIX shell turns \t into a tab, and printf '%s'
# leaves the two bytes alone.
my $TOKEN = 'in\tstalled';

# The commands that the bin directory of a tree holds beside the
# stub. web/get runs sh, and a host whose sh holds no printf builtin
# needs printf. A stub prints its script with cat.
my @LINKED = qw(sh printf cat);

# _tree():
#	One temporary tree, with a bin directory as the whole PATH of
#	a child. A command of @LINKED that this host lacks stays out,
#	and the case that needs it then fails on its own.
sub _tree ()
{
	my $tree = tempdir( CLEANUP => 1 );
	mkdir "$tree/bin" or die "mkdir $tree/bin";

	for my $name (@LINKED) {
		my $path = Fugu::Process->find_command($name) or next;
		symlink $path, "$tree/bin/" . basename($path)
		    or die "symlink $path";
	}

	return $tree;
}

# _stub($tree, $name, @body):
#	One stub downloader in the bin directory of the tree. The stub
#	records its own command line in the log, and it then runs the
#	body lines of its case.
sub _stub ( $tree, $name, @body )
{
	my $path = "$tree/bin/$name";
	my $text = join "\n", '#!/bin/sh',
	    qq{echo "$name \$*" >> '$tree/log'}, @body, q{};
	Fugu::File->write( $path, $text, mode => 0755 ) or die "write $path";

	return;
}

# _install($tree):
#	One install script of two lines. The lines set a variable that
#	holds a backslash, and write it to the marker with printf. A
#	marker with the exact bytes proves that every byte of the
#	script reached sh.
sub _install ($tree)
{
	return "token='$TOKEN'\n"
	    . "printf '%s\\n' \"\$token\" > '$tree/marker'\n";
}

# _print($tree, $text):
#	The body line of a stub that prints one install script. The
#	test writes the text into the tree, so no quoting of a stub
#	reaches the text.
sub _print ( $tree, $text )
{
	Fugu::File->write( "$tree/script", $text )
	    or die "write $tree/script";



( run in 1.299 second using v1.01-cache-2.11-cpan-54e63673c56 )