The test suite driver program.

This commit is contained in:
Russ Allbery 2003-07-07 01:52:33 +00:00
parent 82d778e02f
commit 52843273a2

236
tests/run-tests Executable file
View file

@ -0,0 +1,236 @@
#! /usr/bin/perl -w
$ID = q$Id$;
#
# run-tests -- Test signcontrol and pgpverify.
#
# Written by Russ Allbery <rra@stanford.edu>
# This work is hereby placed in the public domain by its author.
use strict;
use vars qw($ID);
##############################################################################
# Test suite preparation
##############################################################################
# Find a program on the user's path.
sub find_program {
my ($program) = @_;
my @path = split (/:/, $ENV{PATH});
for (@path) {
return "$_/$program" if -x "$_/$program";
}
return $program;
}
# Given the path to the PGP program to use, generate a fixed version of
# pgpverify in the current directory. Takes care of a few other things, like
# making sure that there's a temporary directory for it to put its files.
# Expects to find normal pgpverify up one directory.
sub fix_pgpverify {
my ($path) = @_;
my $gpg = ($path =~ /gpgv$/);
mkdir ('tmp', 0755);
open (BASIC, "../pgpverify") or die "Can't open ../pgpverify: $!\n";
open (FIXED, "> pgpverify") or die "Can't create pgpverify: $!\n";
while (<BASIC>) {
s%^\# \$gpgv = \'.*%\$gpgv = '$path';% if $gpg;
s%^\$pgp = \'.*%\$pgp = '$path';% unless $gpg;
s%^\# \$keyring = \'.*%\$keyring = './keyring';%;
s%^\$tmpdir = \".*%\$tmpdir = './tmp';%;
s%^\$syslog_method = \'.*%\$syslog_method = '';%;
print FIXED;
}
close BASIC;
close FIXED;
chmod (0755, 'pgpverify');
}
# Given the path to the PGP program to use, generate a fixed version of
# signcontrol in the current directory. It also sets up signcontrol to sign
# example.* control messages with the testing key. Expects to find the normal
# signcontrol up one level.
sub fix_signcontrol {
my ($path) = @_;
open (BASIC, "../signcontrol") or die "Can't open ../signcontrol: $!\n";
open (FIXED, "> signcontrol") or die "Can't create signcontrol: $!\n";
while (<BASIC>) {
s/INSERT_YOUR_PGP_USERID/testing/;
s%^\$pgppassfile = \'.*%\$pgppassfile = 'keyring/passphrase';%;
s/^\$pgp = \".*/\$pgp = '$path';/;
s%^\$pgplock = .*%\$pgplock = 'keyring/passphrase';%;
s/YOUR_ADDRESS_AND_NAME/Test Signer <test\@example.com>/;
s/ADDRESS_FOR_Approved_HEADER/test\@example.com/;
s/FULL_HOST_NAME/example.com/;
s/HIERARCHIES/example/;
print FIXED;
}
close BASIC;
close FIXED;
chmod (0755, 'signcontrol');
}
##############################################################################
# Individual tests
##############################################################################
# Run pgpverify on a given file, expecting the given signer. Warn if
# something goes wrong and return true on success and false on failure.
sub pgpverify {
my ($file, $expected) = @_;
my $signer = `./pgpverify < $file`;
chomp $signer;
if ($? == 0 && $signer eq $expected) {
return 1;
} else {
print "pgpverify exited with status ", ($? >> 8), "\n" if $? != 0;
print "pgpverify said the signer was $signer\n" if $signer;
return 0;
}
}
##############################################################################
# Test suite
##############################################################################
# Running totals.
my $tests = 0;
my $failed = 0;
# Tell signcontrol where to find the PGP keyrings.
$ENV{PGPPATH} = './keyring';
$ENV{GNUPGHOME} = './keyring';
# Set up pgpverify to use PGP first.
my $pgp = find_program ('pgp');
fix_pgpverify ($pgp);
# Check the signature on sample.control.
if (pgpverify ('../sample.control', 'news.announce.newgroups')) {
print "PASS: pgpverify-pgp\n";
} else {
print "FAIL: pgpverify-pgp\n";
$failed++;
}
$tests++;
# Now, try with GnuPG.
my $gpgv = find_program ('gpgv');
fix_pgpverify ($gpgv);
# Check the signature on sample.control.
if (pgpverify ('../sample.control', 'news.announce.newgroups')) {
print "PASS: pgpverify-gpg\n";
} else {
print "FAIL: pgpverify-gpg\n";
$failed++;
}
$tests++;
# Sign a message with signcontrol.
fix_signcontrol ($pgp);
my $status = system ('./signcontrol < ./messages/newgroup > signed');
if ($? == 0) {
print "PASS: signcontrol-pgp\n";
} else {
print "signcontrol exited with status ", ($? >> 8), "\n";
print "FAIL: signcontrol-pgp\n";
$failed++;
}
$tests++;
# We still have a GnuPG pgpverify, so check cross-compatibility.
if (pgpverify ('./signed', 'testing')) {
print "PASS: signcontrol-pgp-gpg\n";
} else {
print "FAIL: signcontrol-pgp-gpg\n";
$failed++;
}
$tests++;
# Switch to a PGP pgpverify and check again.
fix_pgpverify ($pgp);
if (pgpverify ('./signed', 'testing')) {
print "PASS: signcontrol-pgp-pgp\n";
} else {
print "FAIL: signcontrol-pgp-pgp\n";
$failed++;
}
$tests++;
# Check with an old copy of pgpverify to make sure that the generated
# signatures still verify properly with a pgpverify that uses attached
# signatures.
my $signer = `./pgpverify-old $pgp < ./signed`;
chomp $signer;
if ($? == 0 && $signer eq 'testing') {
print "PASS: signcontrol-pgp-old\n";
} else {
print "pgpverify exited with status ", ($? >> 8), "\n" if $? != 0;
print "pgpverify said the signer was $signer\n" if $signer;
print "FAIL: signcontrol-pgp-old\n";
$failed++;
}
$tests++;
# Switch to a GnuPG signcontrol and try again.
my $gpg = find_program ('gpg');
fix_signcontrol ($gpg);
$status = system ('./signcontrol < ./messages/newgroup > signed');
if ($? == 0) {
print "PASS: signcontrol-gpg\n";
} else {
print "signcontrol exited with status ", ($? >> 8), "\n";
print "FAIL: signcontrol-gpg\n";
$failed++;
}
$tests++;
# This will only verify with a GnuPG pgpverify.
fix_pgpverify ($gpgv);
if (pgpverify ('./signed', 'testing')) {
print "PASS: signcontrol-gpg-gpg\n";
} else {
print "FAIL: signcontrol-gpg-gpg\n";
$failed++;
}
$tests++;
# Generate signed messages with News::Article.
system ('./sign-newsart', './messages/newgroup');
# Verify both with the GnuPG pgpverify.
if (pgpverify ('./signed.pgp', 'testing')) {
print "PASS: news-article-pgp-gpg\n";
} else {
print "FAIL: news-article-pgp-gpg\n";
$failed++;
}
$tests++;
if (pgpverify ('./signed.gpg', 'testing')) {
print "PASS: news-article-gpg-gpg\n";
} else {
print "FAIL: news-article-gpg-gpg\n";
$failed++;
}
$tests++;
# Switch to the PGP pgpverify and verify just the PGP one.
fix_pgpverify ($pgp);
if (pgpverify ('./signed.pgp', 'testing')) {
print "PASS: news-article-pgp-pgp\n";
} else {
print "FAIL: news-article-pgp-pgp\n";
$failed++;
}
$tests++;
# Print out a summary of the tests.
unlink ('pgpverify', 'signcontrol', 'signed', 'signed.pgp', 'signed.gpg')
unless $failed > 0;
if ($failed == 0) {
print "All $tests tests passed\n";
} else {
print "Failed $failed tests out of $tests total\n";
exit 1;
}