The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

# Copyright 2001-2004 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use strict;
use warnings FATAL => 'all';
use Config;
sub import {
my $class = shift;
for my $section (@_) {
unless (defined &$section) {
die "unknown Apache::TestMM section: $section";
}
no strict 'refs';
my $sub = "MY::$section";
# Force aliasing, since previous WriteMakefile might have
# moved it
undef &$sub if defined &$sub;
*$sub = \&{$section};
}
}
sub add_dep {
my($string, $targ, $add) = @_;
$$string =~ s/($targ\s+::)/$1 $add /;
}
sub clean {
my $self = shift;
my $string = $self->MM::clean(@_);
add_dep(\$string, clean => 'test_clean');
$string;
}
sub test {
my $env = Apache::TestConfig->passenv_makestr();
my $preamble = Apache::TestConfig::WIN32 ? "" : <<EOF;
PASSENV = $env
EOF
my $cover;
if (eval { require Devel::Cover }) {
my $atdir = File::Spec->catfile($ENV{HOME}, '.apache-test');
$cover = <<"EOF"
testcover :
-\@cover -delete
-HARNESS_PERL_SWITCHES=-MDevel::Cover=+inc,$atdir \\
APACHE_TEST_EXTRA_ARGS=-one-process \$(MAKE) test
-\@cover
EOF
}
else {
$cover = <<'EOF';
testcover :
@echo "Cannot run testcover action unless Devel::Cover is installed"
EOF
}
return $preamble . <<'EOF' . $cover;
TEST_VERBOSE = 0
TEST_FILES =
test_clean :
$(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \
t/TEST $(APACHE_TEST_EXTRA_ARGS) -clean
run_tests :
$(PASSENV) \
$(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \
t/TEST $(APACHE_TEST_EXTRA_ARGS) -bugreport -verbose=$(TEST_VERBOSE) $(TEST_FILES)
test :: pure_all test_clean run_tests
test_config :
$(PASSENV) \
$(FULLPERL) -I$(INST_ARCHLIB) -I$(INST_LIB) \
t/TEST $(APACHE_TEST_EXTRA_ARGS) -conf
cmodules: test_config
cd c-modules && $(MAKE) all
cmodules_clean: test_config
cd c-modules && $(MAKE) clean
EOF
}
sub generate_script {
my $file = shift;
unlink $file if -e $file;
my $body = "BEGIN { eval { require blib && blib->import; } }\n";
$body .= Apache::TestConfig->modperl_2_inc_fixup;
my %args = @Apache::TestMM::Argv;
while (my($k, $v) = each %args) {
$v =~ s/\|/\\|/g;
$body .= "\n\$Apache::TestConfig::Argv{'$k'} = q|$v|;\n";
}
my $in = Symbol::gensym();
open $in, "$file.PL" or die "Couldn't open $file.PL: $!";
{
local $/;
$body .= <$in>;
}
close $in;
info "generating script $file";
Apache::Test::basic_config()->write_perlscript($file, $body);
}
sub filter_args {
my($argv, $vars) =
Apache::TestConfig::filter_args(\@ARGV, \%Apache::TestConfig::Usage);
@ARGV = @$argv;
@Apache::TestMM::Argv = %$vars;
}
1;
=head1 NAME
Apache::TestMM - Provide MakeMaker Wrapper Methods
=head1 SYNOPSIS
require Apache::TestMM;
# import MY::test and MY::clean overrides for MM
Apache::TestMM->import(qw(test clean));
# parse command line args
Apache::TestMM::filter_args();
# autogenerate the script
Apache::TestMM::generate_script('t/TEST');
=head1 DESCRIPTION
C<Apache::TestMM> provides wrappers for the C<ExtUtils::MakeMaker>
craft, making it easier to extend the autogenerated F<Makefile> with
C<Apache::Test>.
=head1 FUNCTIONS
=head2 C<import>
use Apache::TestMM qw(test clean);
or:
Apache::TestMM->import(qw(test clean));
Imports C<MY::> overrides for the default C<ExtUtils::MakeMaker>
I<test> and I<clean> targets, as if you have defined:
sub MY::test {...}
sub MY::clean {...}
in F<Makefile.PL>. C<Apache::TestMM> does this for you so that these Makefile
targets will run the Apache server and the tests for it, and clean up after
its mess.
=head2 C<filter_args>
push @ARGV, '-apxs', $apxs_path;
Apache::TestMM::filter_args();
WriteMakefile(...);
When C<WriteMakefile()> is called it parses C<@ARGV>, hoping to find
special options like C<PREFIX=/home/stas/perl>. C<Apache::Test>
accepts a lot of configuration options of its own. When
C<Apache::TestMM::filter_args()> is called, it removes any
C<Apache::Test>-specific options from C<@ARGV> and stores them
internally, so when C<WriteMakefile()> is called they aren't in
C<@ARGV> and thus won't be processed by C<WriteMakefile()>.
The options can be set when F<Makefile.PL> is called:
% perl Makefile.PL -apxs /path/to/apxs
Or you can push them manually to C<@ARGV> from the code:
push @ARGV, '-apxs', $apxs_path;
When:
Apache::TestMM::generate_script('t/TEST');
is called, C<Apache::Test>-specific options extracted by
C<Apache::TestMM::filter_args()> are written to the autogenerated
file. In our example, the autogenerated F<t/TEST> will include:
%Apache::TestConfig::Argv = qw(apxs /path/to/apxs);
which is going to be used by the C<Apache::Test> runtime.
The other frequently used options are: C<-httpd>, telling where to
find the httpd (usually when the C<-apxs> option is not used),
C<-libmodperl> to use a specific mod_perl shared object (if your
mod_perl is built as DSO), C<-maxclients> to change the default number
of the configured C<MaxClients> directive, C<-port> to start the
server on a specific port, etc. To get the complete list of available
configuration options and their purpose and syntax, run:
% perl -MApache::TestConfig -le 'Apache::TestConfig::usage()'
You may wish to document some of these in your application's F<README>
file, especially the C<-apxs> and C<-httpd> options.
=head2 C<generate_script>
Apache::TestMM::generate_script('t/TEST');
C<generate_script()> accepts the name of the script to generate and
will look for a template with the same name and suffix I<.PL>. So in
our example it'll look for F<t/TEST.PL>. The autogenerated script
F<t/TEST> will include the contents of F<t/TEST.PL>, and special
directives, including any configuration options passed via
C<L<filter_args()|/C_filter_args_>> called from F<Makefile.PL>, special
fixup code, etc. If no argument is passed to C<generate_script()>,
it will create a file named F<t/TEST> by default.
=cut