1#!/usr/bin/env perl
2# Copyright (c) 2006 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
3# Use is subject to license terms.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; version 2 of the License.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1335  USA
17
18use File::Find;
19use Getopt::Long;
20
21use strict;
22
23sub run_cmd (@);
24
25my %dispatch = (
26    "run" => \&run_cmd,
27);
28
29=head1 NAME
30
31unit - Run unit tests in directory
32
33=head1 SYNOPSIS
34
35  unit [--[no]big] [--[no]verbose] run [tests to run]
36
37=cut
38
39my $big= $ENV{'MYTAP_CONFIG'} eq 'big';
40
41my $opt_verbose;
42my $result = GetOptions (
43  "big!"        => \$big,
44  "verbose!"    => \$opt_verbose,
45);
46
47$ENV{'MYTAP_CONFIG'} = $big ? 'big' : '';
48
49my $cmd = shift;
50
51if (defined $cmd && exists $dispatch{$cmd}) {
52    $dispatch{$cmd}->(@ARGV);
53} else {
54    print "Unknown command", (defined $cmd ? " $cmd" : ""), ".\n";
55    print "Available commands are: ", join(", ", keys %dispatch), "\n";
56}
57
58=head2 run
59
60Run all unit tests in the current directory and all subdirectories.
61
62=cut
63
64BEGIN {
65    # Test::Harness have been extensively rewritten in newer perl
66    # versions and is now just a backward compatibility wrapper
67    # (with a bug causing the HARNESS_PERL_SWITCHES to be mangled)
68    # Prefer to use TAP::Harness directly if available
69    if (eval "use TAP::Harness; 1") {
70        eval 'sub NEW_HARNESS { 1 }';
71        warn "using TAP::Harness";
72    } else {
73        eval "use Test::Harness; 1" or  die "couldn't find Test::Harness!";
74        eval 'sub NEW_HARNESS { 0 }';
75    }
76}
77
78sub _find_test_files (@) {
79    my @dirs = @_;
80    my @files;
81    find sub {
82        $File::Find::prune = 1 if /^(SCCS|\.libs)$/;
83        push(@files, $File::Find::name) if -x _ && (/-t\z/ || /-t\.exe\z/);
84    }, @dirs;
85    return @files;
86}
87
88sub run_cmd (@) {
89    my @files;
90
91    # If no directories were supplied, we add all directories in the
92    # current directory except 'mytap' since it is not part of the
93    # test suite.
94    if (@_ == 0) {
95      # Ignore these directories
96      my @ignore = qw(mytap SCCS);
97
98      # Build an expression from the directories above that tests if a
99      # directory should be included in the list or not.
100      my $ignore = join(' && ', map { '$_ ne ' . "'$_'"} @ignore);
101
102      # Open and read the directory. Filter out all files, hidden
103      # directories, and directories named above.
104      opendir(DIR, ".") or die "Cannot open '.': $!\n";
105      @_ = grep { -d $_ && $_ !~ /^\..*/ && eval $ignore } readdir(DIR);
106      closedir(DIR);
107    }
108
109    print "Running tests: @_\n";
110
111    foreach my $name (@_) {
112        push(@files, _find_test_files $name) if -d $name;
113        push(@files, $name) if -f $name;
114    }
115
116    if (@files > 0) {
117        # Removing the first './' from the file names
118        foreach (@files) { s!^\./!! }
119
120        if (NEW_HARNESS())
121        {
122          my %args = ( exec => [ ], verbosity => $opt_verbose );
123          my $harness = TAP::Harness->new( \%args );
124          $harness->runtests(@files);
125        }
126        else
127        {
128          $ENV{'HARNESS_VERBOSE'} =  $opt_verbose;
129          $ENV{'HARNESS_PERL_SWITCHES'} .= ' -e "exec @ARGV"';
130          $ENV{'HARNESS_OPTIONS'}="j4";
131          $Test::Harness::Timer = 1;
132          runtests(@files);
133        }
134    }
135}
136