| # 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::TestHarness; |
| |
| use strict; |
| use warnings FATAL => 'all'; |
| |
| use Test::Harness (); |
| use Apache::Test (); |
| use Apache::TestSort (); |
| use Apache::TestTrace; |
| use File::Spec::Functions qw(catfile catdir); |
| use File::Find qw(finddepth); |
| use File::Basename qw(dirname); |
| |
| sub inc_fixup { |
| # use blib |
| unshift @INC, map "blib/$_", qw(lib arch); |
| |
| # fix all relative library locations |
| for (@INC) { |
| $_ = "../$_" unless m,^(/)|([a-f]:),i; |
| } |
| } |
| |
| #skip tests listed in t/SKIP |
| sub skip { |
| my($self, $file) = @_; |
| $file ||= catfile Apache::Test::vars('serverroot'), 'SKIP'; |
| |
| return unless -e $file; |
| |
| my $fh = Symbol::gensym(); |
| open $fh, $file or die "open $file: $!"; |
| my @skip; |
| local $_; |
| |
| while (<$fh>) { |
| chomp; |
| s/^\s+//; s/\s+$//; s/^\#.*//; |
| next unless $_; |
| s/\*/.*/g; |
| push @skip, $_; |
| } |
| |
| close $fh; |
| return join '|', @skip; |
| } |
| |
| #test if all.t would skip tests or not |
| { |
| my $source_lib = ''; |
| |
| sub run_t { |
| my($self, $file) = @_; |
| my $ran = 0; |
| |
| if (Apache::TestConfig::IS_APACHE_TEST_BUILD and !length $source_lib) { |
| # so we can find Apache/Test.pm from both the perl-framework/ |
| # and Apache-Test/ |
| |
| my $top_dir = Apache::Test::vars('top_dir'); |
| foreach my $lib (catfile($top_dir, qw(Apache-Test lib)), |
| catfile($top_dir, qw(.. Apache-Test lib)), |
| catfile($top_dir, 'lib')) { |
| |
| if (-d $lib) { |
| info "adding source lib $lib to \@INC"; |
| $source_lib = qq[-Mlib="$lib"]; |
| last; |
| } |
| } |
| } |
| |
| my $cmd = qq[$^X $source_lib $file]; |
| |
| my $h = Symbol::gensym(); |
| open $h, "$cmd|" or die "open $cmd: $!"; |
| |
| local $_; |
| while (<$h>) { |
| if (/^1\.\.(\d)/) { |
| $ran = $1; |
| last; |
| } |
| } |
| |
| close $h; |
| |
| $ran; |
| } |
| } |
| |
| #if a directory has an all.t test |
| #skip all tests in that directory if all.t prints "1..0\n" |
| sub prune { |
| my($self, @tests) = @_; |
| my(@new_tests, %skip_dirs); |
| |
| foreach my $test (@tests) { |
| next if $test =~ /\.#/; # skip temp emacs files |
| my $dir = dirname $test; |
| if ($test =~ m:\Wall\.t$:) { |
| unless (__PACKAGE__->run_t($test)) { |
| $skip_dirs{$dir} = 1; |
| @new_tests = grep { m:\Wall\.t$: || |
| not $skip_dirs{dirname $_} } @new_tests; |
| push @new_tests, $test; |
| } |
| } |
| elsif (!$skip_dirs{$dir}) { |
| push @new_tests, $test; |
| } |
| } |
| |
| @new_tests; |
| } |
| |
| sub get_tests { |
| my $self = shift; |
| my $args = shift; |
| my @tests = (); |
| |
| my $base = -d 't' ? catdir('t', '.') : '.'; |
| |
| my $ts = $args->{tests} || []; |
| |
| if (@$ts) { |
| for (@$ts) { |
| if (-d $_) { |
| push(@tests, sort <$base/$_/*.t>); |
| } |
| else { |
| $_ .= ".t" unless /\.t$/; |
| push(@tests, $_); |
| } |
| } |
| } |
| else { |
| if ($args->{tdirs}) { |
| push @tests, map { sort <$base/$_/*.t> } @{ $args->{tdirs} }; |
| } |
| else { |
| finddepth(sub { |
| return unless /\.t$/; |
| my $t = catfile $File::Find::dir, $_; |
| my $dotslash = catfile '.', ""; |
| $t =~ s:^\Q$dotslash::; |
| push @tests, $t |
| }, $base); |
| @tests = sort @tests; |
| } |
| } |
| |
| @tests = $self->prune(@tests); |
| |
| if (my $skip = $self->skip) { |
| # Allow / \ and \\ path delimiters in SKIP file |
| $skip =~ s![/\\\\]+![/\\\\]!g; |
| |
| @tests = grep { not /(?:$skip)/ } @tests; |
| } |
| |
| Apache::TestSort->run(\@tests, $args); |
| |
| #when running 't/TEST t/dir' shell tab completion adds a / |
| #dir//foo output is annoying, fix that. |
| s:/+:/:g for @tests; |
| |
| return @tests; |
| } |
| |
| sub run { |
| my $self = shift; |
| my $args = shift || {}; |
| |
| $Test::Harness::verbose ||= $args->{verbose}; |
| |
| if (my(@subtests) = @{ $args->{subtests} || [] }) { |
| $ENV{HTTPD_TEST_SUBTESTS} = "@subtests"; |
| } |
| |
| Test::Harness::runtests($self->get_tests($args, @_)); |
| } |
| |
| 1; |