332 lines
11 KiB
Perl
332 lines
11 KiB
Perl
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You 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
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# 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.
|
|
#
|
|
package Apache::TestRunPHP;
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
|
|
use File::Spec::Functions qw(catfile canonpath);
|
|
|
|
use Apache::TestRun ();
|
|
use Apache::TestConfigParse ();
|
|
use Apache::TestTrace;
|
|
use Apache::TestConfigPHP ();
|
|
use Apache::TestHarnessPHP ();
|
|
|
|
use vars qw($VERSION);
|
|
$VERSION = '1.00'; # make CPAN.pm's r() version scanner happy
|
|
|
|
use File::Spec::Functions qw(catfile);
|
|
|
|
# subclass of Apache::TestRun that configures php things
|
|
use vars qw(@ISA);
|
|
@ISA = qw(Apache::TestRun);
|
|
|
|
sub start {
|
|
my $self = shift;
|
|
|
|
# point php to our own php.ini file
|
|
$ENV{PHPRC} = catfile $self->{test_config}->{vars}->{serverroot},
|
|
'conf';
|
|
|
|
$self->SUPER::start(@_);
|
|
}
|
|
|
|
sub new_test_config {
|
|
my $self = shift;
|
|
|
|
Apache::TestConfigPHP->new($self->{conf_opts});
|
|
}
|
|
|
|
sub configure_php {
|
|
my $self = shift;
|
|
|
|
my $test_config = $self->{test_config};
|
|
|
|
$test_config->postamble_register(qw(configure_php_inc
|
|
configure_php_ini
|
|
configure_php_functions
|
|
configure_php_tests));
|
|
}
|
|
|
|
sub configure {
|
|
my $self = shift;
|
|
|
|
$self->configure_php;
|
|
|
|
$self->SUPER::configure;
|
|
}
|
|
|
|
#if Apache::TestRun refreshes config in the middle of configure
|
|
#we need to re-add php configure hooks
|
|
sub refresh {
|
|
my $self = shift;
|
|
$self->SUPER::refresh;
|
|
$self->configure_php;
|
|
}
|
|
|
|
my @request_opts = qw(get post head);
|
|
|
|
sub run_tests {
|
|
my $self = shift;
|
|
|
|
my $test_opts = {
|
|
verbose => $self->{opts}->{verbose},
|
|
tests => $self->{tests},
|
|
order => $self->{opts}->{order},
|
|
subtests => $self->{subtests} || [],
|
|
};
|
|
|
|
if (grep { exists $self->{opts}->{$_} } @request_opts) {
|
|
run_request($self->{test_config}, $self->{opts});
|
|
}
|
|
else {
|
|
Apache::TestHarnessPHP->run($test_opts)
|
|
if $self->{opts}->{'run-tests'};
|
|
}
|
|
}
|
|
|
|
sub split_test_args {
|
|
my($self) = @_;
|
|
|
|
my(@tests);
|
|
my $top_dir = $self->{test_config}->{vars}->{top_dir};
|
|
my $t_dir = $self->{test_config}->{vars}->{t_dir};
|
|
|
|
my $argv = $self->{argv};
|
|
my @leftovers = ();
|
|
for (@$argv) {
|
|
my $arg = $_;
|
|
# need the t/ (or t\) for stat-ing, but don't want to include
|
|
# it in test output
|
|
$arg =~ s@^(?:\.[\\/])?t[\\/]@@;
|
|
my $file = catfile $t_dir, $arg;
|
|
if (-d $file and $_ ne '/') {
|
|
my @files = <$file/*.t>;
|
|
push @files, <$file/*.php>;
|
|
my $remove = catfile $top_dir, "";
|
|
if (@files) {
|
|
push @tests, map { s,^\Q$remove,,; $_ } @files;
|
|
next;
|
|
}
|
|
}
|
|
else {
|
|
if (($file =~ /\.t$/ || $file =~ /\.php$/) and -e $file) {
|
|
push @tests, "t/$arg";
|
|
next;
|
|
}
|
|
elsif (-e "$file.t") {
|
|
push @tests, "t/$arg.t";
|
|
next;
|
|
}
|
|
elsif (/^[\d.]+$/) {
|
|
my @t = $_;
|
|
#support range of subtests: t/TEST t/foo/bar 60..65
|
|
if (/^(\d+)\.\.(\d+)$/) {
|
|
@t = $1..$2;
|
|
}
|
|
|
|
push @{ $self->{subtests} }, @t;
|
|
next;
|
|
}
|
|
}
|
|
push @leftovers, $_;
|
|
}
|
|
|
|
$self->{tests} = [ map { canonpath($_) } @tests ];
|
|
$self->{argv} = \@leftovers;
|
|
}
|
|
1;
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Apache::TestRunPHP - configure and run a PHP-based test suite
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Apache::TestRunPHP;
|
|
Apache::TestRunPHP->new->run(@ARGV);
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
The C<Apache::TestRunPHP> package controls the configuration and
|
|
running of the test suite for PHP-based tests. It's a subclass
|
|
of C<Apache::TestRun> and similar in function to C<Apache::TestRunPerl>.
|
|
|
|
Refer to the C<Apache::TestRun> manpage for information on the
|
|
available API.
|
|
|
|
=head1 EXAMPLE
|
|
|
|
C<TestRunPHP> works almost identially to C<TestRunPerl>, but in
|
|
case you are new to C<Apache-Test> here is a quick getting started
|
|
guide. be sure to see the links at the end of this document for
|
|
places to find additional details.
|
|
|
|
because C<Apache-Test> is a Perl-based testing framework we start
|
|
from a C<Makefile.PL>, which should have the following lines (in
|
|
addition to the standard C<Makefile.PL> parts):
|
|
|
|
use Apache::TestMM qw(test clean);
|
|
use Apache::TestRunPHP ();
|
|
|
|
Apache::TestMM::filter_args();
|
|
|
|
Apache::TestRunPHP->generate_script();
|
|
|
|
C<generate_script()> will create a script named C<t/TEST>, the gateway
|
|
to the Perl testing harness and what is invoked when you call
|
|
C<make test>. C<filter_args()> accepts some C<Apache::Test>-specific
|
|
arguments and passes them along. for example, to point to a specific
|
|
C<httpd> installation you would invoke C<Makefile.PL> as follows
|
|
|
|
$ perl Makefile.PL -httpd /my/local/apache/bin/httpd
|
|
|
|
and C</my/local/apache/bin/httpd> will be propagated throughout the
|
|
rest of the process. note that PHP needs to be active within Apache
|
|
prior to configuring the test framework as shown above, either by
|
|
virtue of PHP being compiled into the C<httpd> binary statically or
|
|
through an active C<LoadModule> statement within the configuration
|
|
located in C</my/local/apache/conf/httpd.conf>. Other required modules
|
|
are the (very common) mod_alias and mod_env.
|
|
|
|
now, like with C<Apache::TestRun> and C<Apache::TestRunPerl>, you can
|
|
place client-side Perl test scripts under C<t/>, such as C<t/01basic.t>,
|
|
and C<Apache-Test> will run these scripts when you call C<make test>.
|
|
however, what makes C<Apache::TestRunPHP> unique is some added magic
|
|
specifically tailored to a PHP environment. here are the mechanics.
|
|
|
|
C<Apache::TestRunPHP> will look for PHP test scripts in that match
|
|
the following pattern
|
|
|
|
t/response/TestFoo/bar.php
|
|
|
|
where C<Foo> and C<bar> can be anything you like, and C<t/response/Test*>
|
|
is case sensitive. when this format is adhered to, C<Apache::TestRunPHP>
|
|
will create an associated Perl test script called C<t/foo/bar.t>, which
|
|
will be executed when you call C<make test>. all C<bar.t> does is issue
|
|
a simple GET to C<bar.php>, leaving the actual testing to C<bar.php>. in
|
|
essence, you can forget that C<bar.t> even exists.
|
|
|
|
what does C<bar.php> look like? here is an example:
|
|
|
|
<?php
|
|
print "1..1\n";
|
|
print "ok 1\n"
|
|
?>
|
|
|
|
if it looks odd, that's ok because it is. I could explain to you exactly
|
|
what this means, but it isn't important to understand the gory details.
|
|
instead, it is sufficient to understand that when C<Apache::Test> calls
|
|
C<bar.php> it feeds the results directly to C<Test::Harness>, a module
|
|
that comes with every Perl installation, and C<Test::Harness> expects
|
|
what it receives to be formated in a very specific way. by itself, all
|
|
of this is pretty useless, so C<Apache::Test> provides PHP testers with
|
|
something much better. here is a much better example:
|
|
|
|
<?php
|
|
# import the Test::More emulation layer
|
|
# see
|
|
# http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm
|
|
# for Perl's documentation - these functions should behave
|
|
# in the same way
|
|
require 'test-more.php';
|
|
|
|
# plan() the number of tests
|
|
plan(6);
|
|
|
|
# call ok() for each test you plan
|
|
ok ('foo' == 'foo', 'foo is equal to foo');
|
|
ok ('foo' != 'foo', 'foo is not equal to foo');
|
|
|
|
# ok() can be other things as well
|
|
is ('bar', 'bar', 'bar is bar');
|
|
is ('baz', 'bar', 'baz is baz');
|
|
isnt ('bar', 'beer', 'bar is not beer');
|
|
like ('bar', '/ar$/', 'bar matches ar$');
|
|
|
|
diag("printing some debugging information");
|
|
|
|
# whoops! one too many tests. I wonder what will happen...
|
|
is ('biff', 'biff', 'baz is a baz');
|
|
?>
|
|
|
|
the include library C<test-more.php> is automatically generated by
|
|
C<Apache::TestConfigPHP> and configurations tweaked in such a
|
|
a way that your PHP scripts can find it without issue. the
|
|
functions provided by C<test-more.php> are equivalent in name and
|
|
function to those in C<Test::More>, a standard Perl testing
|
|
library, so you can see that manpage for details on the syntax
|
|
and functionality of each.
|
|
|
|
at this point, we have enough in place to run some tests from
|
|
PHP-land - a C<Makefile.PL> to configure Apache for us, and
|
|
a PHP script in C<t/response/TestFoo/bar.php> to send some
|
|
results out to the testing engine. issuing C<make test>
|
|
would start Apache, issue the request to C<bar.php>, generate
|
|
a report, and shut down Apache. the report would look like
|
|
something like this after running the tests in verbose mode
|
|
(eg C<make test TEST_VERBOSE=1>):
|
|
|
|
t/php/bar....1..6
|
|
ok 1 - foo is equal to foo
|
|
not ok 2 - foo is not equal to foo
|
|
# Failed test (/src/devel/perl-php-test/t/response/TestFoo/bar.php at line 13)
|
|
ok 3 - bar is bar
|
|
not ok 4 - baz is baz
|
|
# Failed test (/src/devel/perl-php-test/t/response/TestFoo/bar.php at line 17)
|
|
# got: 'baz'
|
|
# expected: 'bar'
|
|
ok 5 - bar is not beer
|
|
ok 6 - bar matches ar$
|
|
# printing some debugging information
|
|
ok 7 - baz is a baz
|
|
FAILED tests 2, 4, 7
|
|
Failed 3/6 tests, 50.00% okay
|
|
Failed Test Stat Wstat Total Fail Failed List of Failed
|
|
-------------------------------------------------------------------------------
|
|
t/php/bar.t 6 3 50.00% 2 4 7
|
|
Failed 1/1 test scripts, 0.00% okay. 1/6 subtests failed, 83.33% okay.
|
|
|
|
note that the actual test file that was run was C<t/php/bar.t>. this
|
|
file is autogenerated based on the C<t/response/TestFoo/bar.php>
|
|
pattern of your PHP script. C<t/php/bar.t> happens to be written in
|
|
Perl, but you really don't need to worry about it too much.
|
|
|
|
as an interesting aside, if you are using perl-5.8.3 or later you can
|
|
actually create your own C<t/foo.php> client-side scripts and they
|
|
will be run via php (using our C<php.ini>). but more on that later...
|
|
|
|
=head1 SEE ALSO
|
|
|
|
the best source of information about using Apache-Test with
|
|
PHP (at this time) is probably the talk given at ApacheCon 2004
|
|
(L<http://xrl.us/phpperl>), as well as the code from the talk
|
|
(L<http://xrl.us/phpperlcode>). there is also the online tutorial
|
|
L<http://perl.apache.org/docs/general/testing/testing.html>
|
|
which has all of the mod_perl-specific syntax and features have been
|
|
ported to PHP with this class.
|
|
|
|
=head1 AUTHOR
|
|
|
|
C<Apache-Test> is a community effort, maintained by a group of
|
|
dedicated volunteers.
|
|
|
|
Questions can be asked at the test-dev <at> httpd.apache.org list
|
|
For more information see: http://httpd.apache.org/test/.
|
|
|
|
=cut
|