xref: /freebsd/contrib/pam-krb5/tests/tap/perl/Test/RRA/Automake.pm (revision bf6873c5786e333d679a7838d28812febf479a8a)
1*bf6873c5SCy Schubert# Helper functions for Perl test programs in Automake distributions.
2*bf6873c5SCy Schubert#
3*bf6873c5SCy Schubert# This module provides a collection of helper functions used by test programs
4*bf6873c5SCy Schubert# written in Perl and included in C source distributions that use Automake.
5*bf6873c5SCy Schubert# They embed knowledge of how I lay out my source trees and test suites with
6*bf6873c5SCy Schubert# Autoconf and Automake.  They may be usable by others, but doing so will
7*bf6873c5SCy Schubert# require closely following the conventions implemented by the rra-c-util
8*bf6873c5SCy Schubert# utility collection.
9*bf6873c5SCy Schubert#
10*bf6873c5SCy Schubert# All the functions here assume that C_TAP_BUILD and C_TAP_SOURCE are set in
11*bf6873c5SCy Schubert# the environment.  This is normally done via the C TAP Harness runtests
12*bf6873c5SCy Schubert# wrapper.
13*bf6873c5SCy Schubert#
14*bf6873c5SCy Schubert# SPDX-License-Identifier: MIT
15*bf6873c5SCy Schubert
16*bf6873c5SCy Schubertpackage Test::RRA::Automake;
17*bf6873c5SCy Schubert
18*bf6873c5SCy Schubertuse 5.010;
19*bf6873c5SCy Schubertuse base qw(Exporter);
20*bf6873c5SCy Schubertuse strict;
21*bf6873c5SCy Schubertuse warnings;
22*bf6873c5SCy Schubert
23*bf6873c5SCy Schubertuse Exporter;
24*bf6873c5SCy Schubertuse File::Find qw(find);
25*bf6873c5SCy Schubertuse File::Spec;
26*bf6873c5SCy Schubertuse Test::More;
27*bf6873c5SCy Schubertuse Test::RRA::Config qw($LIBRARY_PATH);
28*bf6873c5SCy Schubert
29*bf6873c5SCy Schubert# Used below for use lib calls.
30*bf6873c5SCy Schubertmy ($PERL_BLIB_ARCH, $PERL_BLIB_LIB);
31*bf6873c5SCy Schubert
32*bf6873c5SCy Schubert# Determine the path to the build tree of any embedded Perl module package in
33*bf6873c5SCy Schubert# this source package.  We do this in a BEGIN block because we're going to use
34*bf6873c5SCy Schubert# the results in a use lib command below.
35*bf6873c5SCy SchubertBEGIN {
36*bf6873c5SCy Schubert    $PERL_BLIB_ARCH = File::Spec->catdir(qw(perl blib arch));
37*bf6873c5SCy Schubert    $PERL_BLIB_LIB  = File::Spec->catdir(qw(perl blib lib));
38*bf6873c5SCy Schubert
39*bf6873c5SCy Schubert    # If C_TAP_BUILD is set, we can come up with better values.
40*bf6873c5SCy Schubert    if (defined($ENV{C_TAP_BUILD})) {
41*bf6873c5SCy Schubert        my ($vol, $dirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1);
42*bf6873c5SCy Schubert        my @dirs = File::Spec->splitdir($dirs);
43*bf6873c5SCy Schubert        pop(@dirs);
44*bf6873c5SCy Schubert        $PERL_BLIB_ARCH = File::Spec->catdir(@dirs, qw(perl blib arch));
45*bf6873c5SCy Schubert        $PERL_BLIB_LIB  = File::Spec->catdir(@dirs, qw(perl blib lib));
46*bf6873c5SCy Schubert    }
47*bf6873c5SCy Schubert}
48*bf6873c5SCy Schubert
49*bf6873c5SCy Schubert# Prefer the modules built as part of our source package.  Otherwise, we may
50*bf6873c5SCy Schubert# not find Perl modules while testing, or find the wrong versions.
51*bf6873c5SCy Schubertuse lib $PERL_BLIB_ARCH;
52*bf6873c5SCy Schubertuse lib $PERL_BLIB_LIB;
53*bf6873c5SCy Schubert
54*bf6873c5SCy Schubert# Declare variables that should be set in BEGIN for robustness.
55*bf6873c5SCy Schubertour (@EXPORT_OK, $VERSION);
56*bf6873c5SCy Schubert
57*bf6873c5SCy Schubert# Set $VERSION and everything export-related in a BEGIN block for robustness
58*bf6873c5SCy Schubert# against circular module loading (not that we load any modules, but
59*bf6873c5SCy Schubert# consistency is good).
60*bf6873c5SCy SchubertBEGIN {
61*bf6873c5SCy Schubert    @EXPORT_OK = qw(
62*bf6873c5SCy Schubert        all_files automake_setup perl_dirs test_file_path test_tmpdir
63*bf6873c5SCy Schubert    );
64*bf6873c5SCy Schubert
65*bf6873c5SCy Schubert    # This version should match the corresponding rra-c-util release, but with
66*bf6873c5SCy Schubert    # two digits for the minor version, including a leading zero if necessary,
67*bf6873c5SCy Schubert    # so that it will sort properly.
68*bf6873c5SCy Schubert    $VERSION = '10.00';
69*bf6873c5SCy Schubert}
70*bf6873c5SCy Schubert
71*bf6873c5SCy Schubert# Directories to skip globally when looking for all files, or for directories
72*bf6873c5SCy Schubert# that could contain Perl files.
73*bf6873c5SCy Schubertmy @GLOBAL_SKIP = qw(
74*bf6873c5SCy Schubert    .git .pc _build autom4te.cache build-aux perl/_build perl/blib
75*bf6873c5SCy Schubert);
76*bf6873c5SCy Schubert
77*bf6873c5SCy Schubert# Additional paths to skip when building a list of all files in the
78*bf6873c5SCy Schubert# distribution.  This primarily skips build artifacts that aren't interesting
79*bf6873c5SCy Schubert# to any of the tests.  These match any path component.
80*bf6873c5SCy Schubertmy @FILES_SKIP = qw(
81*bf6873c5SCy Schubert    .deps .dirstamp .libs aclocal.m4 config.h config.h.in config.h.in~
82*bf6873c5SCy Schubert    config.log config.status configure configure~
83*bf6873c5SCy Schubert);
84*bf6873c5SCy Schubert
85*bf6873c5SCy Schubert# The temporary directory created by test_tmpdir, if any.  If this is set,
86*bf6873c5SCy Schubert# attempt to remove the directory stored here on program exit (but ignore
87*bf6873c5SCy Schubert# failure to do so).
88*bf6873c5SCy Schubertmy $TMPDIR;
89*bf6873c5SCy Schubert
90*bf6873c5SCy Schubert# Returns a list of all files in the distribution.
91*bf6873c5SCy Schubert#
92*bf6873c5SCy Schubert# Returns: List of files
93*bf6873c5SCy Schubertsub all_files {
94*bf6873c5SCy Schubert    my @files;
95*bf6873c5SCy Schubert
96*bf6873c5SCy Schubert    # Turn the skip lists into hashes for ease of querying.
97*bf6873c5SCy Schubert    my %skip       = map { $_ => 1 } @GLOBAL_SKIP;
98*bf6873c5SCy Schubert    my %files_skip = map { $_ => 1 } @FILES_SKIP;
99*bf6873c5SCy Schubert
100*bf6873c5SCy Schubert    # Wanted function for find.  Prune anything matching either of the skip
101*bf6873c5SCy Schubert    # lists, or *.lo files, and then add all regular files to the list.
102*bf6873c5SCy Schubert    my $wanted = sub {
103*bf6873c5SCy Schubert        my $file = $_;
104*bf6873c5SCy Schubert        my $path = $File::Find::name;
105*bf6873c5SCy Schubert        $path =~ s{ \A [.]/ }{}xms;
106*bf6873c5SCy Schubert        if ($skip{$path} || $files_skip{$file} || $file =~ m{ [.]lo\z }xms) {
107*bf6873c5SCy Schubert            $File::Find::prune = 1;
108*bf6873c5SCy Schubert            return;
109*bf6873c5SCy Schubert        }
110*bf6873c5SCy Schubert        if (!-d $file) {
111*bf6873c5SCy Schubert            push(@files, $path);
112*bf6873c5SCy Schubert        }
113*bf6873c5SCy Schubert    };
114*bf6873c5SCy Schubert
115*bf6873c5SCy Schubert    # Do the recursive search and return the results.
116*bf6873c5SCy Schubert    find($wanted, q{.});
117*bf6873c5SCy Schubert    return @files;
118*bf6873c5SCy Schubert}
119*bf6873c5SCy Schubert
120*bf6873c5SCy Schubert# Perform initial test setup for running a Perl test in an Automake package.
121*bf6873c5SCy Schubert# This verifies that C_TAP_BUILD and C_TAP_SOURCE are set and then changes
122*bf6873c5SCy Schubert# directory to the C_TAP_SOURCE directory by default.  Sets LD_LIBRARY_PATH if
123*bf6873c5SCy Schubert# the $LIBRARY_PATH configuration option is set.  Calls BAIL_OUT if
124*bf6873c5SCy Schubert# C_TAP_BUILD or C_TAP_SOURCE are missing or if anything else fails.
125*bf6873c5SCy Schubert#
126*bf6873c5SCy Schubert# $args_ref - Reference to a hash of arguments to configure behavior:
127*bf6873c5SCy Schubert#   chdir_build - If set to a true value, changes to C_TAP_BUILD instead of
128*bf6873c5SCy Schubert#                 C_TAP_SOURCE
129*bf6873c5SCy Schubert#
130*bf6873c5SCy Schubert# Returns: undef
131*bf6873c5SCy Schubertsub automake_setup {
132*bf6873c5SCy Schubert    my ($args_ref) = @_;
133*bf6873c5SCy Schubert
134*bf6873c5SCy Schubert    # Bail if C_TAP_BUILD or C_TAP_SOURCE are not set.
135*bf6873c5SCy Schubert    if (!$ENV{C_TAP_BUILD}) {
136*bf6873c5SCy Schubert        BAIL_OUT('C_TAP_BUILD not defined (run under runtests)');
137*bf6873c5SCy Schubert    }
138*bf6873c5SCy Schubert    if (!$ENV{C_TAP_SOURCE}) {
139*bf6873c5SCy Schubert        BAIL_OUT('C_TAP_SOURCE not defined (run under runtests)');
140*bf6873c5SCy Schubert    }
141*bf6873c5SCy Schubert
142*bf6873c5SCy Schubert    # C_TAP_BUILD or C_TAP_SOURCE will be the test directory.  Change to the
143*bf6873c5SCy Schubert    # parent.
144*bf6873c5SCy Schubert    my $start;
145*bf6873c5SCy Schubert    if ($args_ref->{chdir_build}) {
146*bf6873c5SCy Schubert        $start = $ENV{C_TAP_BUILD};
147*bf6873c5SCy Schubert    } else {
148*bf6873c5SCy Schubert        $start = $ENV{C_TAP_SOURCE};
149*bf6873c5SCy Schubert    }
150*bf6873c5SCy Schubert    my ($vol, $dirs) = File::Spec->splitpath($start, 1);
151*bf6873c5SCy Schubert    my @dirs = File::Spec->splitdir($dirs);
152*bf6873c5SCy Schubert    pop(@dirs);
153*bf6873c5SCy Schubert
154*bf6873c5SCy Schubert    # Simplify relative paths at the end of the directory.
155*bf6873c5SCy Schubert    my $ups = 0;
156*bf6873c5SCy Schubert    my $i   = $#dirs;
157*bf6873c5SCy Schubert    while ($i > 2 && $dirs[$i] eq File::Spec->updir) {
158*bf6873c5SCy Schubert        $ups++;
159*bf6873c5SCy Schubert        $i--;
160*bf6873c5SCy Schubert    }
161*bf6873c5SCy Schubert    for (1 .. $ups) {
162*bf6873c5SCy Schubert        pop(@dirs);
163*bf6873c5SCy Schubert        pop(@dirs);
164*bf6873c5SCy Schubert    }
165*bf6873c5SCy Schubert    my $root = File::Spec->catpath($vol, File::Spec->catdir(@dirs), q{});
166*bf6873c5SCy Schubert    chdir($root) or BAIL_OUT("cannot chdir to $root: $!");
167*bf6873c5SCy Schubert
168*bf6873c5SCy Schubert    # If C_TAP_BUILD is a subdirectory of C_TAP_SOURCE, add it to the global
169*bf6873c5SCy Schubert    # ignore list.
170*bf6873c5SCy Schubert    my ($buildvol, $builddirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1);
171*bf6873c5SCy Schubert    my @builddirs = File::Spec->splitdir($builddirs);
172*bf6873c5SCy Schubert    pop(@builddirs);
173*bf6873c5SCy Schubert    if ($buildvol eq $vol && @builddirs == @dirs + 1) {
174*bf6873c5SCy Schubert        while (@dirs && $builddirs[0] eq $dirs[0]) {
175*bf6873c5SCy Schubert            shift(@builddirs);
176*bf6873c5SCy Schubert            shift(@dirs);
177*bf6873c5SCy Schubert        }
178*bf6873c5SCy Schubert        if (@builddirs == 1) {
179*bf6873c5SCy Schubert            push(@GLOBAL_SKIP, $builddirs[0]);
180*bf6873c5SCy Schubert        }
181*bf6873c5SCy Schubert    }
182*bf6873c5SCy Schubert
183*bf6873c5SCy Schubert    # Set LD_LIBRARY_PATH if the $LIBRARY_PATH configuration option is set.
184*bf6873c5SCy Schubert    ## no critic (Variables::RequireLocalizedPunctuationVars)
185*bf6873c5SCy Schubert    if (defined($LIBRARY_PATH)) {
186*bf6873c5SCy Schubert        @builddirs = File::Spec->splitdir($builddirs);
187*bf6873c5SCy Schubert        pop(@builddirs);
188*bf6873c5SCy Schubert        my $libdir = File::Spec->catdir(@builddirs, $LIBRARY_PATH);
189*bf6873c5SCy Schubert        my $path   = File::Spec->catpath($buildvol, $libdir, q{});
190*bf6873c5SCy Schubert        if (-d "$path/.libs") {
191*bf6873c5SCy Schubert            $path .= '/.libs';
192*bf6873c5SCy Schubert        }
193*bf6873c5SCy Schubert        if ($ENV{LD_LIBRARY_PATH}) {
194*bf6873c5SCy Schubert            $ENV{LD_LIBRARY_PATH} .= ":$path";
195*bf6873c5SCy Schubert        } else {
196*bf6873c5SCy Schubert            $ENV{LD_LIBRARY_PATH} = $path;
197*bf6873c5SCy Schubert        }
198*bf6873c5SCy Schubert    }
199*bf6873c5SCy Schubert    return;
200*bf6873c5SCy Schubert}
201*bf6873c5SCy Schubert
202*bf6873c5SCy Schubert# Returns a list of directories that may contain Perl scripts and that should
203*bf6873c5SCy Schubert# be passed to Perl test infrastructure that expects a list of directories to
204*bf6873c5SCy Schubert# recursively check.  The list will be all eligible top-level directories in
205*bf6873c5SCy Schubert# the package except for the tests directory, which is broken out to one
206*bf6873c5SCy Schubert# additional level.  Calls BAIL_OUT on any problems
207*bf6873c5SCy Schubert#
208*bf6873c5SCy Schubert# $args_ref - Reference to a hash of arguments to configure behavior:
209*bf6873c5SCy Schubert#   skip - A reference to an array of directories to skip
210*bf6873c5SCy Schubert#
211*bf6873c5SCy Schubert# Returns: List of directories possibly containing Perl scripts to test
212*bf6873c5SCy Schubertsub perl_dirs {
213*bf6873c5SCy Schubert    my ($args_ref) = @_;
214*bf6873c5SCy Schubert
215*bf6873c5SCy Schubert    # Add the global skip list.  We also ignore the perl directory if it
216*bf6873c5SCy Schubert    # exists since, in my packages, it is treated as a Perl module
217*bf6873c5SCy Schubert    # distribution and has its own standalone test suite.
218*bf6873c5SCy Schubert    my @skip = $args_ref->{skip} ? @{ $args_ref->{skip} } : ();
219*bf6873c5SCy Schubert    push(@skip, @GLOBAL_SKIP, 'perl');
220*bf6873c5SCy Schubert
221*bf6873c5SCy Schubert    # Separate directories to skip under tests from top-level directories.
222*bf6873c5SCy Schubert    my @skip_tests = grep { m{ \A tests/ }xms } @skip;
223*bf6873c5SCy Schubert    @skip = grep { !m{ \A tests }xms } @skip;
224*bf6873c5SCy Schubert    for my $skip_dir (@skip_tests) {
225*bf6873c5SCy Schubert        $skip_dir =~ s{ \A tests/ }{}xms;
226*bf6873c5SCy Schubert    }
227*bf6873c5SCy Schubert
228*bf6873c5SCy Schubert    # Convert the skip lists into hashes for convenience.
229*bf6873c5SCy Schubert    my %skip       = map { $_ => 1 } @skip, 'tests';
230*bf6873c5SCy Schubert    my %skip_tests = map { $_ => 1 } @skip_tests;
231*bf6873c5SCy Schubert
232*bf6873c5SCy Schubert    # Build the list of top-level directories to test.
233*bf6873c5SCy Schubert    opendir(my $rootdir, q{.}) or BAIL_OUT("cannot open .: $!");
234*bf6873c5SCy Schubert    my @dirs = grep { -d && !$skip{$_} } readdir($rootdir);
235*bf6873c5SCy Schubert    closedir($rootdir);
236*bf6873c5SCy Schubert    @dirs = File::Spec->no_upwards(@dirs);
237*bf6873c5SCy Schubert
238*bf6873c5SCy Schubert    # Add the list of subdirectories of the tests directory.
239*bf6873c5SCy Schubert    if (-d 'tests') {
240*bf6873c5SCy Schubert        opendir(my $testsdir, q{tests}) or BAIL_OUT("cannot open tests: $!");
241*bf6873c5SCy Schubert
242*bf6873c5SCy Schubert        # Skip if found in %skip_tests or if not a directory.
243*bf6873c5SCy Schubert        my $is_skipped = sub {
244*bf6873c5SCy Schubert            my ($dir) = @_;
245*bf6873c5SCy Schubert            return 1 if $skip_tests{$dir};
246*bf6873c5SCy Schubert            $dir = File::Spec->catdir('tests', $dir);
247*bf6873c5SCy Schubert            return -d $dir ? 0 : 1;
248*bf6873c5SCy Schubert        };
249*bf6873c5SCy Schubert
250*bf6873c5SCy Schubert        # Build the filtered list of subdirectories of tests.
251*bf6873c5SCy Schubert        my @test_dirs = grep { !$is_skipped->($_) } readdir($testsdir);
252*bf6873c5SCy Schubert        closedir($testsdir);
253*bf6873c5SCy Schubert        @test_dirs = File::Spec->no_upwards(@test_dirs);
254*bf6873c5SCy Schubert
255*bf6873c5SCy Schubert        # Add the tests directory to the start of the directory name.
256*bf6873c5SCy Schubert        push(@dirs, map { File::Spec->catdir('tests', $_) } @test_dirs);
257*bf6873c5SCy Schubert    }
258*bf6873c5SCy Schubert    return @dirs;
259*bf6873c5SCy Schubert}
260*bf6873c5SCy Schubert
261*bf6873c5SCy Schubert# Find a configuration file for the test suite.  Searches relative to
262*bf6873c5SCy Schubert# C_TAP_BUILD first and then C_TAP_SOURCE and returns whichever is found
263*bf6873c5SCy Schubert# first.  Calls BAIL_OUT if the file could not be found.
264*bf6873c5SCy Schubert#
265*bf6873c5SCy Schubert# $file - Partial path to the file
266*bf6873c5SCy Schubert#
267*bf6873c5SCy Schubert# Returns: Full path to the file
268*bf6873c5SCy Schubertsub test_file_path {
269*bf6873c5SCy Schubert    my ($file) = @_;
270*bf6873c5SCy Schubert  BASE:
271*bf6873c5SCy Schubert    for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}) {
272*bf6873c5SCy Schubert        next if !defined($base);
273*bf6873c5SCy Schubert        if (-e "$base/$file") {
274*bf6873c5SCy Schubert            return "$base/$file";
275*bf6873c5SCy Schubert        }
276*bf6873c5SCy Schubert    }
277*bf6873c5SCy Schubert    BAIL_OUT("cannot find $file");
278*bf6873c5SCy Schubert    return;
279*bf6873c5SCy Schubert}
280*bf6873c5SCy Schubert
281*bf6873c5SCy Schubert# Create a temporary directory for tests to use for transient files and return
282*bf6873c5SCy Schubert# the path to that directory.  The directory is automatically removed on
283*bf6873c5SCy Schubert# program exit.  The directory permissions use the current umask.  Calls
284*bf6873c5SCy Schubert# BAIL_OUT if the directory could not be created.
285*bf6873c5SCy Schubert#
286*bf6873c5SCy Schubert# Returns: Path to a writable temporary directory
287*bf6873c5SCy Schubertsub test_tmpdir {
288*bf6873c5SCy Schubert    my $path;
289*bf6873c5SCy Schubert
290*bf6873c5SCy Schubert    # If we already figured out what directory to use, reuse the same path.
291*bf6873c5SCy Schubert    # Otherwise, create a directory relative to C_TAP_BUILD if set.
292*bf6873c5SCy Schubert    if (defined($TMPDIR)) {
293*bf6873c5SCy Schubert        $path = $TMPDIR;
294*bf6873c5SCy Schubert    } else {
295*bf6873c5SCy Schubert        my $base;
296*bf6873c5SCy Schubert        if (defined($ENV{C_TAP_BUILD})) {
297*bf6873c5SCy Schubert            $base = $ENV{C_TAP_BUILD};
298*bf6873c5SCy Schubert        } else {
299*bf6873c5SCy Schubert            $base = File::Spec->curdir;
300*bf6873c5SCy Schubert        }
301*bf6873c5SCy Schubert        $path = File::Spec->catdir($base, 'tmp');
302*bf6873c5SCy Schubert    }
303*bf6873c5SCy Schubert
304*bf6873c5SCy Schubert    # Create the directory if it doesn't exist.
305*bf6873c5SCy Schubert    if (!-d $path) {
306*bf6873c5SCy Schubert        if (!mkdir($path, 0777)) {
307*bf6873c5SCy Schubert            BAIL_OUT("cannot create directory $path: $!");
308*bf6873c5SCy Schubert        }
309*bf6873c5SCy Schubert    }
310*bf6873c5SCy Schubert
311*bf6873c5SCy Schubert    # Store the directory name for cleanup and return it.
312*bf6873c5SCy Schubert    $TMPDIR = $path;
313*bf6873c5SCy Schubert    return $path;
314*bf6873c5SCy Schubert}
315*bf6873c5SCy Schubert
316*bf6873c5SCy Schubert# On program exit, remove $TMPDIR if set and if possible.  Report errors with
317*bf6873c5SCy Schubert# diag but otherwise ignore them.
318*bf6873c5SCy SchubertEND {
319*bf6873c5SCy Schubert    if (defined($TMPDIR) && -d $TMPDIR) {
320*bf6873c5SCy Schubert        local $! = undef;
321*bf6873c5SCy Schubert        if (!rmdir($TMPDIR)) {
322*bf6873c5SCy Schubert            diag("cannot remove temporary directory $TMPDIR: $!");
323*bf6873c5SCy Schubert        }
324*bf6873c5SCy Schubert    }
325*bf6873c5SCy Schubert}
326*bf6873c5SCy Schubert
327*bf6873c5SCy Schubert1;
328*bf6873c5SCy Schubert__END__
329*bf6873c5SCy Schubert
330*bf6873c5SCy Schubert=for stopwords
331*bf6873c5SCy SchubertAllbery Automake Automake-aware Automake-based rra-c-util ARGS subdirectories
332*bf6873c5SCy Schubertsublicense MERCHANTABILITY NONINFRINGEMENT umask
333*bf6873c5SCy Schubert
334*bf6873c5SCy Schubert=head1 NAME
335*bf6873c5SCy Schubert
336*bf6873c5SCy SchubertTest::RRA::Automake - Automake-aware support functions for Perl tests
337*bf6873c5SCy Schubert
338*bf6873c5SCy Schubert=head1 SYNOPSIS
339*bf6873c5SCy Schubert
340*bf6873c5SCy Schubert    use Test::RRA::Automake qw(automake_setup perl_dirs test_file_path);
341*bf6873c5SCy Schubert    automake_setup({ chdir_build => 1 });
342*bf6873c5SCy Schubert
343*bf6873c5SCy Schubert    # Paths to directories that may contain Perl scripts.
344*bf6873c5SCy Schubert    my @dirs = perl_dirs({ skip => [qw(lib)] });
345*bf6873c5SCy Schubert
346*bf6873c5SCy Schubert    # Configuration for Kerberos tests.
347*bf6873c5SCy Schubert    my $keytab = test_file_path('config/keytab');
348*bf6873c5SCy Schubert
349*bf6873c5SCy Schubert=head1 DESCRIPTION
350*bf6873c5SCy Schubert
351*bf6873c5SCy SchubertThis module collects utility functions that are useful for test scripts
352*bf6873c5SCy Schubertwritten in Perl and included in a C Automake-based package.  They assume the
353*bf6873c5SCy Schubertlayout of a package that uses rra-c-util and C TAP Harness for the test
354*bf6873c5SCy Schubertstructure.
355*bf6873c5SCy Schubert
356*bf6873c5SCy SchubertLoading this module will also add the directories C<perl/blib/arch> and
357*bf6873c5SCy SchubertC<perl/blib/lib> to the Perl library search path, relative to C_TAP_BUILD if
358*bf6873c5SCy Schubertthat environment variable is set.  This is harmless for C Automake projects
359*bf6873c5SCy Schubertthat don't contain an embedded Perl module, and for those projects that do,
360*bf6873c5SCy Schubertthis will allow subsequent C<use> calls to find modules that are built as part
361*bf6873c5SCy Schubertof the package build process.
362*bf6873c5SCy Schubert
363*bf6873c5SCy SchubertThe automake_setup() function should be called before calling any other
364*bf6873c5SCy Schubertfunctions provided by this module.
365*bf6873c5SCy Schubert
366*bf6873c5SCy Schubert=head1 FUNCTIONS
367*bf6873c5SCy Schubert
368*bf6873c5SCy SchubertNone of these functions are imported by default.  The ones used by a script
369*bf6873c5SCy Schubertshould be explicitly imported.  On failure, all of these functions call
370*bf6873c5SCy SchubertBAIL_OUT (from Test::More).
371*bf6873c5SCy Schubert
372*bf6873c5SCy Schubert=over 4
373*bf6873c5SCy Schubert
374*bf6873c5SCy Schubert=item all_files()
375*bf6873c5SCy Schubert
376*bf6873c5SCy SchubertReturns a list of all "interesting" files in the distribution that a test
377*bf6873c5SCy Schubertsuite may want to look at.  This excludes various products of the build system,
378*bf6873c5SCy Schubertthe build directory if it's under the source directory, and a few other
379*bf6873c5SCy Schubertuninteresting directories like F<.git>.  The returned paths will be paths
380*bf6873c5SCy Schubertrelative to the root of the package.
381*bf6873c5SCy Schubert
382*bf6873c5SCy Schubert=item automake_setup([ARGS])
383*bf6873c5SCy Schubert
384*bf6873c5SCy SchubertVerifies that the C_TAP_BUILD and C_TAP_SOURCE environment variables are set
385*bf6873c5SCy Schubertand then changes directory to the top of the source tree (which is one
386*bf6873c5SCy Schubertdirectory up from the C_TAP_SOURCE path, since C_TAP_SOURCE points to the top
387*bf6873c5SCy Schubertof the tests directory).
388*bf6873c5SCy Schubert
389*bf6873c5SCy SchubertIf ARGS is given, it should be a reference to a hash of configuration options.
390*bf6873c5SCy SchubertOnly one option is supported: C<chdir_build>.  If it is set to a true value,
391*bf6873c5SCy Schubertautomake_setup() changes directories to the top of the build tree instead.
392*bf6873c5SCy Schubert
393*bf6873c5SCy Schubert=item perl_dirs([ARGS])
394*bf6873c5SCy Schubert
395*bf6873c5SCy SchubertReturns a list of directories that may contain Perl scripts that should be
396*bf6873c5SCy Schuberttested by test scripts that test all Perl in the source tree (such as syntax
397*bf6873c5SCy Schubertor coding style checks).  The paths will be simple directory names relative to
398*bf6873c5SCy Schubertthe current directory or two-part directory names under the F<tests>
399*bf6873c5SCy Schubertdirectory.  (Directories under F<tests> are broken out separately since it's
400*bf6873c5SCy Schubertcommon to want to apply different policies to different subdirectories of
401*bf6873c5SCy SchubertF<tests>.)
402*bf6873c5SCy Schubert
403*bf6873c5SCy SchubertIf ARGS is given, it should be a reference to a hash of configuration options.
404*bf6873c5SCy SchubertOnly one option is supported: C<skip>, whose value should be a reference to an
405*bf6873c5SCy Schubertarray of additional top-level directories or directories starting with
406*bf6873c5SCy SchubertC<tests/> that should be skipped.
407*bf6873c5SCy Schubert
408*bf6873c5SCy Schubert=item test_file_path(FILE)
409*bf6873c5SCy Schubert
410*bf6873c5SCy SchubertGiven FILE, which should be a relative path, locates that file relative to the
411*bf6873c5SCy Schuberttest directory in either the source or build tree.  FILE will be checked for
412*bf6873c5SCy Schubertrelative to the environment variable C_TAP_BUILD first, and then relative to
413*bf6873c5SCy SchubertC_TAP_SOURCE.  test_file_path() returns the full path to FILE or calls
414*bf6873c5SCy SchubertBAIL_OUT if FILE could not be found.
415*bf6873c5SCy Schubert
416*bf6873c5SCy Schubert=item test_tmpdir()
417*bf6873c5SCy Schubert
418*bf6873c5SCy SchubertCreate a temporary directory for tests to use for transient files and return
419*bf6873c5SCy Schubertthe path to that directory.  The directory is created relative to the
420*bf6873c5SCy SchubertC_TAP_BUILD environment variable, which must be set.  Permissions on the
421*bf6873c5SCy Schubertdirectory are set using the current umask.  test_tmpdir() returns the full
422*bf6873c5SCy Schubertpath to the temporary directory or calls BAIL_OUT if it could not be created.
423*bf6873c5SCy Schubert
424*bf6873c5SCy SchubertThe directory is automatically removed if possible on program exit.  Failure
425*bf6873c5SCy Schubertto remove the directory on exit is reported with diag() and otherwise ignored.
426*bf6873c5SCy Schubert
427*bf6873c5SCy Schubert=back
428*bf6873c5SCy Schubert
429*bf6873c5SCy Schubert=head1 ENVIRONMENT
430*bf6873c5SCy Schubert
431*bf6873c5SCy Schubert=over 4
432*bf6873c5SCy Schubert
433*bf6873c5SCy Schubert=item C_TAP_BUILD
434*bf6873c5SCy Schubert
435*bf6873c5SCy SchubertThe root of the tests directory in Automake build directory for this package,
436*bf6873c5SCy Schubertused to find files as documented above.
437*bf6873c5SCy Schubert
438*bf6873c5SCy Schubert=item C_TAP_SOURCE
439*bf6873c5SCy Schubert
440*bf6873c5SCy SchubertThe root of the tests directory in the source tree for this package, used to
441*bf6873c5SCy Schubertfind files as documented above.
442*bf6873c5SCy Schubert
443*bf6873c5SCy Schubert=back
444*bf6873c5SCy Schubert
445*bf6873c5SCy Schubert=head1 AUTHOR
446*bf6873c5SCy Schubert
447*bf6873c5SCy SchubertRuss Allbery <eagle@eyrie.org>
448*bf6873c5SCy Schubert
449*bf6873c5SCy Schubert=head1 COPYRIGHT AND LICENSE
450*bf6873c5SCy Schubert
451*bf6873c5SCy SchubertCopyright 2014-2015, 2018-2021 Russ Allbery <eagle@eyrie.org>
452*bf6873c5SCy Schubert
453*bf6873c5SCy SchubertCopyright 2013 The Board of Trustees of the Leland Stanford Junior University
454*bf6873c5SCy Schubert
455*bf6873c5SCy SchubertPermission is hereby granted, free of charge, to any person obtaining a copy
456*bf6873c5SCy Schubertof this software and associated documentation files (the "Software"), to deal
457*bf6873c5SCy Schubertin the Software without restriction, including without limitation the rights
458*bf6873c5SCy Schubertto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
459*bf6873c5SCy Schubertcopies of the Software, and to permit persons to whom the Software is
460*bf6873c5SCy Schubertfurnished to do so, subject to the following conditions:
461*bf6873c5SCy Schubert
462*bf6873c5SCy SchubertThe above copyright notice and this permission notice shall be included in all
463*bf6873c5SCy Schubertcopies or substantial portions of the Software.
464*bf6873c5SCy Schubert
465*bf6873c5SCy SchubertTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
466*bf6873c5SCy SchubertIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
467*bf6873c5SCy SchubertFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
468*bf6873c5SCy SchubertAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
469*bf6873c5SCy SchubertLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
470*bf6873c5SCy SchubertOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
471*bf6873c5SCy SchubertSOFTWARE.
472*bf6873c5SCy Schubert
473*bf6873c5SCy Schubert=head1 SEE ALSO
474*bf6873c5SCy Schubert
475*bf6873c5SCy SchubertTest::More(3), Test::RRA(3), Test::RRA::Config(3)
476*bf6873c5SCy Schubert
477*bf6873c5SCy SchubertThis module is maintained in the rra-c-util package.  The current version is
478*bf6873c5SCy Schubertavailable from L<https://www.eyrie.org/~eagle/software/rra-c-util/>.
479*bf6873c5SCy Schubert
480*bf6873c5SCy SchubertThe C TAP Harness test driver and libraries for TAP-based C testing are
481*bf6873c5SCy Schubertavailable from L<https://www.eyrie.org/~eagle/software/c-tap-harness/>.
482*bf6873c5SCy Schubert
483*bf6873c5SCy Schubert=cut
484*bf6873c5SCy Schubert
485*bf6873c5SCy Schubert# Local Variables:
486*bf6873c5SCy Schubert# copyright-at-end-flag: t
487*bf6873c5SCy Schubert# End:
488