You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by do...@apache.org on 2001/04/02 10:59:56 UTC
cvs commit: modperl-2.0/Apache-Test/lib/Apache TestRun.pm
dougm 01/04/02 01:59:56
Added: Apache-Test/lib/Apache TestRun.pm
Log:
methods to drive the tests
Revision Changes Path
1.1 modperl-2.0/Apache-Test/lib/Apache/TestRun.pm
Index: TestRun.pm
===================================================================
package Apache::TestRun;
use strict;
use warnings FATAL => 'all';
use Apache::TestConfig ();
use Apache::TestRequest ();
use Apache::TestHarness ();
use File::Spec::Functions qw(catfile);
use Getopt::Long qw(GetOptions);
my @std_run = qw(start-httpd run-tests stop-httpd);
my @others = qw(verbose configure clean help ping);
my @flag_opts = (@std_run, @others);
my @list_opts = qw(preamble postamble);
my @hash_opts = qw(header);
my @exit_opts = qw(clean help ping debug);
my @request_opts = qw(get head post);
my %usage = (
'start-httpd' => 'start the test server',
'run-tests' => 'run the tests',
'stop-httpd' => 'stop the test server',
'verbose' => 'verbose output',
'configure' => 'force regeneration of httpd.conf',
'clean' => 'remove all generated test files',
'help' => 'display this message',
'preamble' => 'config to add at the beginning of httpd.conf',
'postamble' => 'config to add at the end of httpd.conf',
'ping' => 'test if server is running or port in use',
'debug' => 'start server under debugger (e.g. gdb)',
'header' => "add headers to (".join('|', @request_opts).") request",
(map { $_, "\U$_\E url" } @request_opts),
);
sub new {
my $class = shift;
bless {
tests => [],
@_,
}, $class;
}
#split arguments into test files/dirs and options
#take extra care if -e, the file matches /\.t$/
# if -d, the dir contains .t files
#so we dont slurp arguments that are not tests, example:
# httpd $HOME/apache-2.0/bin/httpd
sub split_args {
my($self, $argv) = @_;
my(@tests, @args);
for (@$argv) {
my $arg = $_;
#need the t/ for stat-ing, but dont want to include it in test output
$arg =~ s:^t/::;
my $t_dir = catfile qw(.. t);
my $file = catfile $t_dir, $arg;
if (-d $file and $_ ne '/') {
my @files = <$file/*.t>;
if (@files) {
my $remove = catfile $t_dir, "";
push @tests, map { s,^\Q$remove,,; $_ } @files;
next;
}
}
else {
if ($file =~ /\.t$/ and -e $file) {
push @tests, "$arg";
next;
}
elsif (-e "$file.t") {
push @tests, "$arg.t";
next;
}
}
push @args, $_;
}
#default HEAD|GET to /
for (my $i = 0; $i < @args; $i++) {
if ($args[$i] =~ /^-(get|head)/) {
unless ($args[$i+1] and $args[$i+1] =~ m:^/:) {
splice @args, $i+1, 0, '/';
}
last;
}
}
$self->{tests} = \@tests;
$self->{args} = \@args;
}
sub passenv {
my $passenv = Apache::TestConfig->passenv;
for (keys %$passenv) {
return 1 if $ENV{$_};
}
0;
}
sub getopts {
my($self, $argv) = @_;
$self->split_args($argv);
#dont count test files/dirs as @ARGV arguments
local *ARGV = $self->{args};
my(%opts, %vopts, %conf_opts);
GetOptions(\%opts, @flag_opts, @exit_opts,
(map "$_=s", @request_opts),
(map { ("$_=s", $vopts{$_} ||= []) } @list_opts),
(map { ("$_=s", $vopts{$_} ||= {}) } @hash_opts));
$opts{$_} = $vopts{$_} for keys %vopts;
#force regeneration of httpd.conf if commandline args want to modify it
$opts{configure} ||=
(grep { $opts{$_}->[0] } qw(preamble postamble)) ||
@ARGV || $self->passenv() || (! -e 'conf/httpd.conf');
while (my($key, $val) = splice @ARGV, 0, 2) {
$conf_opts{lc $key} = $val;
}
if ($opts{configure}) {
$conf_opts{save} = 1;
}
else {
$conf_opts{thaw} = 1;
}
#propagate some values
for (qw(verbose)) {
$conf_opts{$_} = $opts{$_};
}
$self->{opts} = \%opts;
$self->{conf_opts} = \%conf_opts;
}
sub default_run_opts {
my $self = shift;
my($opts, $tests) = ($self->{opts}, $self->{tests});
unless (grep { $opts->{$_} } @std_run, @request_opts) {
if (@$tests && $self->{server}->ping) {
#if certain tests are specified and server is running, dont restart
$opts->{'run-tests'} = 1;
}
else {
#default is server-server run-tests stop-server
$opts->{$_} = 1 for @std_run;
}
}
}
my $caught_sig_int = 0;
sub install_sighandlers {
my $self = shift;
my($server, $opts) = ($self->{server}, $self->{opts});
$SIG{__DIE__} = sub {
return unless $_[0] =~ /^Failed/i; #dont catch Test::ok failures
$server->stop(1) if $opts->{'start-httpd'};
$server->failed_msg("error running tests");
};
$SIG{INT} = sub {
if ($caught_sig_int++) {
print "\ncaught SIGINT\n";
exit;
}
print "\nhalting tests\n";
$server->stop if $opts->{'start-httpd'};
exit;
};
}
sub configure_opts {
my $self = shift;
my($test_config, $opts) = ($self->{test_config}, $self->{opts});
my $preamble = sub { shift->preamble($opts->{preamble}) };
my $postamble = sub { shift->postamble($opts->{postamble}) };
$test_config->preamble_register($preamble);
$test_config->postamble_register($postamble);
}
sub configure_modperl {
my $self = shift;
my $test_config = $self->{test_config};
$test_config->preamble_register(qw(configure_libmodperl));
$test_config->postamble_register(qw(configure_inc
configure_pm_tests
configure_startup_pl));
}
sub configure {
my $self = shift;
return unless $self->{conf_opts}->{save}; #cache generated config
$self->configure_modperl;
$self->configure_opts;
my $test_config = $self->{test_config};
$test_config->generate_httpd_conf;
$test_config->save;
}
sub try_exit_opts {
my $self = shift;
for (@exit_opts) {
next unless $self->{opts}->{$_};
my $method = "opt_$_";
$self->$method();
exit;
}
if ($self->{opts}->{'stop-httpd'}) {
$self->{server}->stop;
exit;
}
}
sub start {
my $self = shift;
my $test_config = $self->{test_config};
unless ($test_config->{vars}->{httpd}) {
print "no test server configured, please specify an httpd or ";
print $test_config->{MP_APXS} ?
"an apxs other than $test_config->{MP_APXS}" : "apxs";
print "\nor put either in your PATH\n";
exit 1;
}
if ($self->{opts}->{'start-httpd'}) {
exit 1 unless $self->{server}->start;
}
}
sub run_tests {
my $self = shift;
my $test_opts = {
verbose => $self->{opts}->{verbose},
tests => $self->{tests},
};
if (grep { $self->{opts}->{$_} } @request_opts) {
run_request($self->{test_config}, $self->{opts});
}
else {
Apache::TestHarness->run($test_opts)
if $self->{opts}->{'run-tests'};
}
}
sub stop {
my $self = shift;
$self->{server}->stop if $self->{opts}->{'stop-httpd'};
}
sub new_test_config {
my $self = shift;
Apache::TestConfig->new($self->{conf_opts});
}
sub run {
my $self = shift;
my(@argv) = @_;
Apache::TestHarness->chdir_t;
$self->getopts(\@argv);
$self->{test_config} = $self->new_test_config;
$self->{server} = $self->{test_config}->server;
local($SIG{__DIE__}, $SIG{INT});
$self->install_sighandlers;
$self->try_exit_opts;
$self->configure;
$self->default_run_opts;
$self->start;
$self->run_tests;
$self->stop;
}
sub run_request {
my($test_config, $opts) = @_;
my @args = %{ $opts->{header} };
my $wanted_args = Apache::TestRequest::wanted_args();
while (my($key, $val) = each %{ $test_config->{vars} }) {
next unless $wanted_args->{$key};
push @args, $key, $val;
}
for (@request_opts) {
next unless $opts->{$_};
my $method = \&{"Apache::TestRequest::\U$_"};
my $res = $method->($opts->{$_}, @args);
print Apache::TestRequest::to_string($res);
}
}
sub opt_clean {
my($self) = @_;
my $test_config = $self->{test_config};
$test_config->server->stop;
$test_config->clean;
}
sub opt_ping {
my($self) = @_;
my $test_config = $self->{test_config};
my $server = $test_config->server;
my $pid = $server->ping;
my $name = $server->{name};
if ($pid) {
if ($pid == -1) {
print "port $test_config->{vars}->{port} is in use, ",
"but cannot determine server pid\n";
}
else {
my $version = $server->{version};
print "server $name running (pid=$pid, version=$version)\n";
}
return;
}
print "no server is running on $name\n";
}
sub opt_debug {
my $self = shift;
my $server = $self->{server};
$server->stop;
$server->start_debugger;
}
sub opt_help {
my $self = shift;
print <<EOM;
usage: TEST [options ...]
where options include:
EOM
while (my($key, $val) = each %usage) {
printf " -%-16s %s\n", $key, $val;
}
print "\n configuration options:\n";
Apache::TestConfig->usage;
}
1;