Apache-Test
view release on metacpan or search on metacpan
lib/Apache/TestConfig.pm view on Meta::CPAN
package Apache::TestConfig;
use strict;
use warnings FATAL => 'all';
use constant WIN32 => $^O eq 'MSWin32';
use constant OSX => $^O eq 'darwin';
use constant CYGWIN => $^O eq 'cygwin';
use constant NETWARE => $^O eq 'NetWare';
use constant SOLARIS => $^O eq 'solaris';
use constant AIX => $^O eq 'aix';
use constant WINFU => WIN32 || NETWARE;
use constant COLOR => ($ENV{APACHE_TEST_COLOR} && -t STDOUT) ? 1 : 0;
use constant DEFAULT_PORT => 8529;
use constant IS_MOD_PERL_2 =>
eval { require mod_perl2 } || 0;
use constant IS_MOD_PERL_2_BUILD => IS_MOD_PERL_2 &&
eval { require Apache2::Build && Apache2::Build::IS_MOD_PERL_BUILD() };
use constant IS_APACHE_TEST_BUILD =>
grep { -e "$_/lib/Apache/TestConfig.pm" }
qw(Apache-Test . .. ../Apache-Test);
use lib ();
use File::Copy ();
use File::Find qw(finddepth);
use File::Basename qw(dirname);
use File::Path ();
use File::Spec::Functions qw(catfile abs2rel splitdir canonpath
catdir file_name_is_absolute devnull);
use Cwd qw(fastcwd);
use Socket ();
use Symbol ();
use Apache::TestConfigPerl ();
use Apache::TestConfigParse ();
use Apache::TestTrace;
use Apache::TestServer ();
use Apache::TestRun ();
use vars qw(%Usage);
%Usage = (
top_dir => 'top-level directory (default is $PWD)',
t_dir => 'the t/ test directory (default is $top_dir/t)',
t_conf => 'the conf/ test directory (default is $t_dir/conf)',
t_logs => 'the logs/ test directory (default is $t_dir/logs)',
t_state => 'the state/ test directory (default is $t_dir/state)',
t_pid_file => 'location of the pid file (default is $t_logs/httpd.pid)',
t_conf_file => 'test httpd.conf file (default is $t_conf/httpd.conf)',
src_dir => 'source directory to look for mod_foos.so',
serverroot => 'ServerRoot (default is $t_dir)',
documentroot => 'DocumentRoot (default is $ServerRoot/htdocs',
port => 'Port [port_number|select] (default ' . DEFAULT_PORT . ')',
servername => 'ServerName (default is localhost)',
user => 'User to run test server as (default is $USER)',
group => 'Group to run test server as (default is $GROUP)',
bindir => 'Apache bin/ dir (default is apxs -q BINDIR)',
sbindir => 'Apache sbin/ dir (default is apxs -q SBINDIR)',
httpd => 'server to use for testing (default is $bindir/httpd)',
target => 'name of server binary (default is apxs -q TARGET)',
apxs => 'location of apxs (default is from Apache2::BuildConfig)',
startup_timeout => 'seconds to wait for the server to start (default is 60)',
httpd_conf => 'inherit config from this file (default is apxs derived)',
httpd_conf_extra => 'inherit additional config from this file',
minclients => 'minimum number of concurrent clients (default is 1)',
maxclients => 'maximum number of concurrent clients (default is minclients+1)',
threadsperchild => 'number of threads per child when using threaded MPMs (default is 10)',
limitrequestline => 'global LimitRequestLine setting (default is 128)',
perlpod => 'location of perl pod documents (for testing downloads)',
proxyssl_url => 'url for testing ProxyPass / https (default is localhost)',
sslca => 'location of SSL CA (default is $t_conf/ssl/ca)',
sslcaorg => 'SSL CA organization to use for tests (default is asf)',
sslproto => 'SSL/TLS protocol version(s) to test',
libmodperl => 'path to mod_perl\'s .so (full or relative to LIBEXECDIR)',
defines => 'values to add as -D defines (for example, "VAR1 VAR2")',
(map { $_ . '_module_name', "$_ module name"} qw(cgi ssl thread access auth php)),
);
my %filepath_conf_opts = map { $_ => 1 }
qw(top_dir t_dir t_conf t_logs t_state t_pid_file t_conf_file src_dir serverroot
documentroot bindir sbindir httpd apxs httpd_conf httpd_conf_extra
perlpod sslca libmodperl);
sub conf_opt_is_a_filepath {
my $opt = shift;
$opt && exists $filepath_conf_opts{$opt};
}
sub usage {
for my $hash (\%Usage) {
for (sort keys %$hash){
printf " -%-18s %s\n", $_, $hash->{$_};
}
}
}
sub filter_args {
my($args, $wanted_args) = @_;
my(@pass, %keep);
my @filter = @$args;
if (ref($filter[0])) {
push @pass, shift @filter;
}
while (@filter) {
my $key = shift @filter;
# optinal - or -- prefix
if (defined $key && $key =~ /^-?-?(.+)/ && exists $wanted_args->{$1}) {
if (@filter) {
$keep{$1} = shift @filter;
}
else {
die "key $1 requires a matching value";
}
}
else {
push @pass, $key;
}
}
return (\@pass, \%keep);
}
my %passenv = map { $_,1 } qw{
APACHE_TEST_APXS
APACHE_TEST_HTTPD
APACHE_TEST_GROUP
APACHE_TEST_USER
APACHE_TEST_PORT
};
sub passenv {
\%passenv;
}
sub passenv_makestr {
my @vars;
for (sort keys %passenv) {
lib/Apache/TestConfig.pm view on Meta::CPAN
"supplied all the needed information to run the tests. " .
"Please post lib/Apache2/BuildConfig.pm along with the " .
"bug report";
}
$self->clean(1);
error "You must explicitly specify -httpd and/or -apxs options, " .
"or set \$ENV{APACHE_TEST_HTTPD} and \$ENV{APACHE_TEST_APXS}, " .
"or set your \$PATH to include the httpd and apxs binaries.";
Apache::TestRun::exit_perl(1);
}
else {
debug "Using httpd: $vars->{httpd}";
}
$self->inherit_config; #see TestConfigParse.pm
$self->configure_httpd_eapi; #must come after inherit_config
$self->default_module(cgi => [qw(mod_cgi mod_cgid)]);
$self->default_module(thread => [qw(worker threaded)]);
$self->default_module(ssl => [qw(mod_ssl)]);
$self->default_module(access => [qw(mod_access mod_authz_host)]);
$self->default_module(auth => [qw(mod_auth mod_auth_basic)]);
$self->default_module(php => [qw(sapi_apache2 mod_php4 mod_php5)]);
$self->{server}->post_config;
return $self;
}
sub default_module {
my($self, $name, $choices) = @_;
my $mname = $name . '_module_name';
unless ($self->{vars}->{$mname}) {
($self->{vars}->{$mname}) = grep {
$self->{modules}->{"$_.c"};
} @$choices;
$self->{vars}->{$mname} ||= $choices->[0];
}
$self->{vars}->{$name . '_module'} =
$self->{vars}->{$mname} . '.c'
}
sub configure_apxs {
my $self = shift;
$self->{APXS} = $self->default_apxs;
return unless $self->{APXS};
$self->{APXS} =~ s{/}{\\}g if WIN32;
my $vars = $self->{vars};
$vars->{bindir} ||= $self->apxs('BINDIR', 1);
$vars->{sbindir} ||= $self->apxs('SBINDIR');
$vars->{target} ||= $self->apxs('TARGET');
$vars->{conf_dir} ||= $self->apxs('SYSCONFDIR');
if ($vars->{conf_dir}) {
$vars->{httpd_conf} ||= catfile $vars->{conf_dir}, 'httpd.conf';
}
}
sub configure_httpd {
my $self = shift;
my $vars = $self->{vars};
debug "configuring httpd";
$vars->{target} ||= (WIN32 ? 'Apache.EXE' : 'httpd');
unless ($vars->{httpd}) {
#sbindir should be bin/ with the default layout
#but its eaiser to workaround apxs than fix apxs
for my $dir (map { $vars->{$_} } qw(sbindir bindir)) {
next unless defined $dir;
my $httpd = catfile $dir, $vars->{target};
next unless -x $httpd;
$vars->{httpd} = $httpd;
last;
}
$vars->{httpd} ||= $self->default_httpd;
}
if ($vars->{httpd}) {
my @chunks = splitdir $vars->{httpd};
#handle both $prefix/bin/httpd and $prefix/Apache.exe
for (1,2) {
pop @chunks;
last unless @chunks;
$self->{httpd_basedir} = catfile @chunks;
last if -d "$self->{httpd_basedir}/bin";
}
}
#cleanup httpd droppings
my $sem = catfile $vars->{t_logs}, 'apache_runtime_status.sem';
unless (-e $sem) {
$self->clean_add_file($sem);
}
}
sub configure_httpd_eapi {
my $self = shift;
my $vars = $self->{vars};
#deal with EAPI_MM_CORE_PATH if defined.
if (defined($self->{httpd_defines}->{EAPI_MM_CORE_PATH})) {
my $path = $self->{httpd_defines}->{EAPI_MM_CORE_PATH};
#ensure the directory exists
my @chunks = splitdir $path;
pop @chunks; #the file component of the path
$path = catdir @chunks;
unless (file_name_is_absolute $path) {
$path = catdir $vars->{serverroot}, $path;
}
$self->gendir($path);
}
}
sub configure_proxy {
my $self = shift;
my $vars = $self->{vars};
#if we proxy to ourselves, must bump the maxclients
if ($vars->{proxy} =~ /^on$/i) {
unless ($vars->{maxclients_preset}) {
$vars->{minclients}++;
$vars->{maxclients}++;
$vars->{maxspare}++;
$vars->{startserversthreadedmpm} ++;
$vars->{minclientsthreadedmpm} += $vars->{threadsperchild};
$vars->{maxclientsthreadedmpm} += $vars->{threadsperchild};
lib/Apache/TestConfig.pm view on Meta::CPAN
$group;
}
sub default_user {
return if WINFU;
my $uid = $>;
my $user = $ENV{APACHE_TEST_USER} || (getpwuid($uid) || "#$uid");
if ($user eq 'root') {
my $other = (getpwnam('nobody'))[0];
if ($other) {
$user = $other;
}
else {
die "cannot run tests as User root";
#XXX: prompt for another username
}
}
return $user;
}
sub default_serveradmin {
my $vars = shift->{vars};
join '@', ($vars->{user} || 'unknown'), $vars->{servername};
}
sub default_apxs {
my $self = shift;
return $self->{vars}->{apxs} if $self->{vars}->{apxs};
if (my $build_config = $self->modperl_build_config()) {
return $build_config->{MP_APXS};
}
if ($ENV{APACHE_TEST_APXS}) {
return $ENV{APACHE_TEST_APXS};
}
# look in PATH as a last resort
if (my $apxs = which('apxs')) {
return $apxs;
} elsif ($apxs = which('apxs2')) {
return $apxs;
}
return;
}
sub default_httpd {
my $self = shift;
my $vars = $self->{vars};
if (my $build_config = $self->modperl_build_config()) {
if (my $p = $build_config->{MP_AP_PREFIX}) {
for my $bindir (qw(bin sbin)) {
my $httpd = catfile $p, $bindir, $vars->{target};
return $httpd if -e $httpd;
# The executable on Win32 in Apache/2.2 is httpd.exe,
# so try that if Apache.exe doesn't exist
if (WIN32) {
$httpd = catfile $p, $bindir, 'httpd.EXE';
if (-e $httpd) {
$vars->{target} = 'httpd.EXE';
return $httpd;
}
}
}
}
}
if ($ENV{APACHE_TEST_HTTPD}) {
return $ENV{APACHE_TEST_HTTPD};
}
# look in PATH as a last resort
if (my $httpd = which('httpd')) {
return $httpd;
} elsif ($httpd = which('httpd2')) {
return $httpd;
} elsif ($httpd = which('apache')) {
return $httpd;
} elsif ($httpd = which('apache2')) {
return $httpd;
}
return;
}
my $localhost;
sub default_localhost {
my $localhost_addr = pack('C4', 127, 0, 0, 1);
gethostbyaddr($localhost_addr, Socket::AF_INET()) || 'localhost';
}
sub default_servername {
my $self = shift;
$localhost ||= $self->default_localhost;
die "Can't figure out the default localhost's server name"
unless $localhost;
}
# memoize the selected value (so we make sure that the same port is used
# via select). The problem is that select_first_port() is called 3 times after
# -clean, and it's possible that a lower port will get released
# between calls, leading to various places in the test suite getting a
# different base port selection.
#
# XXX: There is still a problem if two t/TEST's configure at the same
# time, so they both see the same port free, but only the first one to
# bind() will actually get the port. So there is a need in another
# check and reconfiguration just before the server starts.
#
my $port_memoized;
sub select_first_port {
my $self = shift;
my $port ||= $port_memoized || $ENV{APACHE_TEST_PORT}
|| $self->{vars}{port} || DEFAULT_PORT;
# memoize
$port_memoized = $port;
return $port unless $port eq 'select';
# port select mode: try to find another available port, take into
# account that each instance of the test suite may use more than
# one port for virtual hosts, therefore try to check ports in big
# steps (20?).
my $step = 20;
my $tries = 20;
$port = DEFAULT_PORT;
until (Apache::TestServer->port_available($port)) {
unless (--$tries) {
error "no ports available";
error "tried ports @{[DEFAULT_PORT]} - $port in $step increments";
return 0;
}
$port += $step;
}
info "the default base port is used, using base port $port instead"
unless $port == DEFAULT_PORT;
# memoize
$port_memoized = $port;
return $port;
}
my $remote_addr;
sub our_remote_addr {
my $self = shift;
my $name = $self->default_servername;
my $iaddr = (gethostbyname($name))[-1];
unless (defined $iaddr) {
error "Can't resolve host: '$name' (check /etc/hosts)";
exit 1;
}
$remote_addr ||= Socket::inet_ntoa($iaddr);
}
sub default_loopback {
'127.0.0.1';
}
sub port {
my($self, $module) = @_;
unless ($module) {
( run in 2.079 seconds using v1.01-cache-2.11-cpan-2398b32b56e )