diff options
author | Russ Allbery <eagle@eyrie.org> | 2016-04-25 20:20:15 -0700 |
---|---|---|
committer | Russ Allbery <eagle@eyrie.org> | 2016-04-25 20:20:15 -0700 |
commit | 8f46d7aa9f0e448e16964168c92c3dcb9340f229 (patch) | |
tree | f6948f0a09c49ef98b738d5594b42b799d55a0ff /tests | |
parent | ade3aee596ecbde002be026d93454da6ab3e1678 (diff) |
Update to rra-c-util 6.0 and C TAP Harness 4.0
Update to rra-c-util 6.0:
* Remove all remaining uses of strlcpy and strlcat.
* Fix the Perl docs/synopsis.t test to be less UNIX-specific.
* Make util/network/server-t more robust against missing IPv6.
Update to C TAP Harness 4.0:
* Use C_TAP_SOURCE and C_TAP_BUILD instead of SOURCE and BUILD.
Diffstat (limited to 'tests')
29 files changed, 814 insertions, 651 deletions
diff --git a/tests/HOWTO b/tests/README index b94985d..ef91452 100644 --- a/tests/HOWTO +++ b/tests/README @@ -70,18 +70,20 @@ Writing TAP Tests One of the special features of C TAP Harness is the environment that it sets up for your test cases. If your test program is called under - the runtests driver, the environment variables SOURCE and BUILD will - be set to the top of the test directory in the source tree and the top - of the build tree, respectively. You can use those environment - variables to locate additional test data, programs and libraries built - as part of your software build, and other supporting information - needed by tests. + the runtests driver, the environment variables C_TAP_SOURCE and + C_TAP_BUILD will be set to the top of the test directory in the source + tree and the top of the build tree, respectively. You can use those + environment variables to locate additional test data, programs and + libraries built as part of your software build, and other supporting + information needed by tests. The C and shell TAP libraries support a test_file_path() function, which looks for a file under the build tree and then under the source - tree, using the BUILD and SOURCE environment variables, and return the - full path to the file. This can be used to locate supporting data - files. + tree, using the C_TAP_BUILD and C_TAP_SOURCE environment variables, + and return the full path to the file. This can be used to locate + supporting data files. They also support a test_tmpdir() function + that returns a directory that can be used for temporary files during + tests. Perl @@ -190,15 +192,15 @@ Writing TAP Tests your test suite area. It can then be loaded by tests written in shell using the environment set up by runtests with: - . "$SOURCE"/tap/libtap.sh + . "$C_TAP_SOURCE"/tap/libtap.sh Here is a complete test case written in shell which produces the same output as the TAP sample above: #!/bin/sh - . "$SOURCE"/tap/libtap.sh - cd "$BUILD" + . "$C_TAP_SOURCE"/tap/libtap.sh + cd "$C_TAP_BUILD" plan 4 ok 'the first test' true @@ -240,7 +242,7 @@ License This file is part of the documentation of C TAP Harness, which can be found at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. - Copyright 2010 Russ Allbery <eagle@eyrie.org> + Copyright 2010, 2016 Russ Allbery <eagle@eyrie.org> Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright diff --git a/tests/TESTS b/tests/TESTS index c8e4662..062e5de 100644 --- a/tests/TESTS +++ b/tests/TESTS @@ -19,8 +19,6 @@ portable/inet_ntop portable/mkstemp portable/setenv portable/snprintf -portable/strlcat -portable/strlcpy server/accept server/acl server/acl/localgroup diff --git a/tests/client/remctl-t b/tests/client/remctl-t index a26347c..cd94c42 100755 --- a/tests/client/remctl-t +++ b/tests/client/remctl-t @@ -3,14 +3,15 @@ # Test suite for the remctl command-line client. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2006, 2007, 2009, 2011, 2012, 2014 # The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. -. "$SOURCE/tap/libtap.sh" -. "$SOURCE/tap/kerberos.sh" -. "$SOURCE/tap/remctl.sh" +. "${C_TAP_SOURCE}/tap/libtap.sh" +. "${C_TAP_SOURCE}/tap/kerberos.sh" +. "${C_TAP_SOURCE}/tap/remctl.sh" # Test setup. kerberos_setup @@ -19,11 +20,11 @@ if [ $? != 0 ] ; then else plan 14 fi -remctl="$BUILD/../client/remctl" +remctl="$C_TAP_BUILD/../client/remctl" if [ ! -x "$remctl" ] ; then bail "can't locate remctl client binary" fi -remctld_start "$BUILD/../server/remctld" "$BUILD/data/conf-simple" +remctld_start "$C_TAP_BUILD/../server/remctld" "$C_TAP_BUILD/data/conf-simple" # Now, we can finally run our tests. ok_program "basic" 0 "hello world" \ diff --git a/tests/data/generate-krb5-conf b/tests/data/generate-krb5-conf index c81b18a..47489bb 100755 --- a/tests/data/generate-krb5-conf +++ b/tests/data/generate-krb5-conf @@ -9,6 +9,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2006, 2007, 2008, 2010, 2011 # The Board of Trustees of the Leland Stanford Junior University # @@ -33,8 +34,8 @@ set -e # Load the test library. -. "$SOURCE/tap/libtap.sh" -cd "$BUILD" +. "$C_TAP_SOURCE/tap/libtap.sh" +cd "$C_TAP_BUILD" # If there is no default realm specified on the command line, we leave the # realm information alone. diff --git a/tests/docs/pod-spelling-t b/tests/docs/pod-spelling-t index 7b61c86..0b93f8d 100755 --- a/tests/docs/pod-spelling-t +++ b/tests/docs/pod-spelling-t @@ -6,6 +6,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2012, 2013, 2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -31,7 +32,7 @@ use 5.006; use strict; use warnings; -use lib "$ENV{SOURCE}/tap/perl"; +use lib "$ENV{C_TAP_SOURCE}/tap/perl"; use Test::More; use Test::RRA qw(skip_unless_author use_prereq); diff --git a/tests/docs/pod-t b/tests/docs/pod-t index 53f9925..7955306 100755 --- a/tests/docs/pod-t +++ b/tests/docs/pod-t @@ -7,6 +7,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2012, 2013, 2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -32,7 +33,7 @@ use 5.006; use strict; use warnings; -use lib "$ENV{SOURCE}/tap/perl"; +use lib "$ENV{C_TAP_SOURCE}/tap/perl"; use Test::More; use Test::RRA qw(skip_unless_automated use_prereq); diff --git a/tests/perl/module-version-t b/tests/perl/module-version-t index c845635..4a45e77 100755 --- a/tests/perl/module-version-t +++ b/tests/perl/module-version-t @@ -14,86 +14,21 @@ use 5.006; use strict; use warnings; -use Carp qw(croak); -use File::Find qw(find); -use Getopt::Long qw(GetOptions); -use Test::More; - -# SOURCE may not be set if we're running this script manually to update -# version numbers. Only load the Test::RRA modules if it is set, enabling us -# to find those modules. +# C_TAP_SOURCE may not be set if we're running this script manually to update +# version numbers. If it isn't, assume we're being run from the top of the +# tree. BEGIN { - if ($ENV{SOURCE}) { - unshift(@INC, "$ENV{SOURCE}/tap/perl"); - require Test::RRA; - require Test::RRA::Automake; + if ($ENV{C_TAP_SOURCE}) { + unshift(@INC, "$ENV{C_TAP_SOURCE}/tap/perl"); + } else { + unshift(@INC, 'tests/tap/perl'); } } -# A regular expression matching a $VERSION string in a module. $1 will -# contain all of the line contents prior to the actual version string, $2 will -# contain the version itself, and $3 will contain the rest of the line. -our $REGEX_VERSION = qr{ - ( # prefix ($1) - \A .* # any prefix, such as "our" - [\$*] # scalar or typeglob - [\w\:\']*\b # optional package name - VERSION\b # version variable - \s* = \s* # assignment - [\"\']? # optional leading quote - ) - ( [\d._]+ ) # the version number itself ($2) - ( # suffix ($3) - [\"\']? # optional trailing quote - \s* - ; - ) -}xms; - -# Find all the Perl modules shipped in this package, if any, and returns the -# list of file names. -# -# $dir - The root directory to search, perl/lib by default -# -# Returns: List of file names -sub module_files { - my ($dir) = @_; - $dir ||= 'perl/lib'; - return if !-d $dir; - my @files; - my $wanted = sub { - if ($_ eq 'blib') { - $File::Find::prune = 1; - return; - } - if (m{ [.] pm \z }xms) { - push(@files, $File::Find::name); - } - return; - }; - find($wanted, $dir); - return @files; -} - -# Given a module file, read it for the $VERSION string and return the value. -# -# $file - File to check, which should be a Perl module -# -# Returns: The version of the module -# Throws: Text exception on I/O failure or inability to find $VERSION -sub module_version { - my ($file) = @_; - open(my $data, q{<}, $file) or die "$0: cannot open $file: $!\n"; - while (defined(my $line = <$data>)) { - if ($line =~ $REGEX_VERSION) { - my ($prefix, $version, $suffix) = ($1, $2, $3); - close($data) or die "$0: error reading from $file: $!\n"; - return $version; - } - } - close($data) or die "$0: error reading from $file: $!\n"; - die "$0: cannot find version number in $file\n"; -} +use Getopt::Long qw(GetOptions); +use Test::RRA qw(skip_unless_automated); +use Test::RRA::Automake qw(automake_setup); +use Test::RRA::ModuleVersion qw(test_module_versions update_module_versions); # Return the current version and, optionally, the package name from the NEWS # file. Munges the version to be appropriate for Perl if necessary. @@ -102,8 +37,15 @@ sub module_version { # List: The version number and the package name # Throws: Text exception if NEWS is not found or doesn't contain a version sub news_version { - my ($package, $version); - open(my $news, q{<}, 'NEWS') or die "$0: cannot open NEWS: $!\n"; + my ($package, $version, $news); + for my $path ('NEWS', '../NEWS') { + if (-f $path) { + open($news, q{<}, $path) or die "$0: cannot open $path: $!\n"; + } + } + if (!$news) { + die "$0: cannot find NEWS file\n"; + } SCAN: while (defined(my $line = <$news>)) { ## no critic (RegularExpressions::ProhibitEscapedMetacharacters) @@ -127,105 +69,32 @@ sub news_version { return wantarray ? ($version, $package) : $version; } -# Given a module file and the new version for that module, update the version -# in that module to the new one. -# -# $file - Perl module file whose version should be updated -# $version - The new version number -# -# Returns: undef -# Throws: Text exception on I/O failure or inability to find $VERSION -sub update_module_version { - my ($file, $version) = @_; - open(my $in, q{<}, $file) or die "$0: cannot open $file: $!\n"; - open(my $out, q{>}, "$file.new") - or die "$0: cannot create $file.new: $!\n"; - - # Scan for the version and replace it. - SCAN: - while (defined(my $line = <$in>)) { - if ($line =~ s{ $REGEX_VERSION }{$1$version$3}xms) { - print {$out} $line or die "$0: cannot write to $file.new: $!\n"; - last SCAN; - } - print {$out} $line or die "$0: cannot write to $file.new: $!\n"; - } - - # Copy the rest of the input file to the output file. - print {$out} <$in> or die "$0: cannot write to $file.new: $!\n"; - close($out) or die "$0: cannot flush $file.new: $!\n"; - close($in) or die "$0: error reading from $file: $!\n"; - - # All done. Rename the new file over top of the old file. - rename("$file.new", $file) - or die "$0: cannot rename $file.new to $file: $!\n"; - return; -} - -# Act as a test suite. Find all of the Perl modules in the package, if any, -# and check that the version for each module matches the version from the NEWS -# file. Reports results with Test::More and sets up a plan based on the -# number of modules found. -# -# Returns: undef -# Throws: Text exception on fatal errors -sub test_versions { - my ($news_version, $package) = news_version(); - - # For rra-c-util, check the TAP modules instead of a perl directory. - my $dir = ($package eq 'rra-c-util') ? 'tests/tap/perl' : 'perl/lib'; - my @modules = module_files($dir); - - # Output the plan. Skip the test if there were no modules found. - if (@modules) { - plan tests => scalar(@modules); - } else { - plan skip_all => 'No Perl modules found'; - return; - } +# Parse command-line arguments. +my $update; +Getopt::Long::config('bundling', 'no_ignore_case'); +GetOptions('update|u' => \$update) or exit 1; - # For each module, get the module version and compare. - for my $module (@modules) { - my $module_version = module_version($module); - is($module_version, $news_version, "Version for $module"); - } - return; +# If we're not updating, set up for Automake testing. Otherwise, we assume +# we're running from the top of the source tree. +if (!$update) { + automake_setup(); } -# Update the versions of all modules to the current version from the NEWS -# file. -# -# Returns: undef -# Throws: Text exception on fatal errors -sub update_versions { - my ($version, $package) = news_version(); - my $dir = ($package eq 'rra-c-util') ? 'tests/tap/perl' : 'perl/lib'; - my @modules = module_files($dir); - for my $module (@modules) { - update_module_version($module, $version); - } - return; -} +# Get the package name and version. +my ($version, $package) = news_version(); -# If SOURCE is set, skip the test unless automated testing is enabled and use -# automake_setup to change directories to the top of the source tree. We -# don't do this unconditionally since we want to support being run with the -# --update option outside of the test suite. -if ($ENV{SOURCE}) { - Test::RRA::skip_unless_automated('Module version tests'); - Test::RRA::Automake::automake_setup(); -} +# rra-c-util itself checks the versions of the testing support modules instead +# of an embedded tree of Perl modules. +my $root = ($package eq 'rra-c-util') ? 'tests/tap/perl' : 'perl/lib'; # Main routine. We run as either a test suite or as a script to update all of # the module versions, selecting based on whether we got the -u / --update # command-line option. -my $update; -Getopt::Long::config('bundling', 'no_ignore_case'); -GetOptions('update|u' => \$update) or exit 1; if ($update) { - update_versions(); + update_module_versions($root, $version); } else { - test_versions(); + skip_unless_automated('Module version tests'); + test_module_versions($root, $version); } exit 0; __END__ @@ -247,21 +116,23 @@ Perl 5.6.2 or later. =head1 DESCRIPTION -This script has a dual purpose as either a test script or a utility -script. The intent is to assist with maintaining consistent versions -between a larger primarily C project and any embedded Perl modules. - -As a test, it reads the current version of a package from the F<NEWS> file -and then looks for any Perl modules in F<perl/lib>. (As a special -exception, if the package name as determined from the F<NEWS> file is -C<rra-c-util>, it looks for Perl modules in F<tests/tap/perl> instead.) -If it finds any, it checks that the version number of the Perl module -matches the version number of the package from the F<NEWS> file. These -test results are reported with Test::More, suitable for any TAP harness. - -As a utility script, when run with the B<--update> option, it similarly -finds all Perl modules in F<perl/lib> (or F<tests/tap/perl> per above) and -then rewrites their version setting to match the version of the package as +This script has a dual purpose as either a test script or a utility script. +The intent is to assist with maintaining consistent versions between a larger +primarily C project and any embedded Perl modules, supporting both the package +keyword syntax introduced in Perl 5.12 or the older explicit setting of a +$VERSION variable. + +As a test, it reads the current version of a package from the F<NEWS> file and +then looks for any Perl modules in F<perl/lib>. (As a special exception, if +the package name as determined from the F<NEWS> file is C<rra-c-util>, it +looks for Perl modules in F<tests/tap/perl> instead.) If it finds any, it +checks that the version number of the Perl module matches the version number +of the package from the F<NEWS> file. These test results are reported with +Test::More, suitable for any TAP harness. + +As a utility script, when run with the B<--update> option, it similarly finds +all Perl modules in F<perl/lib> (or F<tests/tap/perl> per above) and then +rewrites their version setting to match the version of the package as determined from the F<NEWS> file. =head1 OPTIONS @@ -270,9 +141,9 @@ determined from the F<NEWS> file. =item B<-u>, B<--update> -Rather than test the Perl modules for the correct version, update all -Perl modules found in the tree under F<perl/lib> to the current version -from the NEWS file. +Rather than test the Perl modules for the correct version, update all Perl +modules found in the tree under F<perl/lib> to the current version from the +NEWS file. =back @@ -282,32 +153,31 @@ Russ Allbery <eagle@eyrie.org> =head1 COPYRIGHT AND LICENSE -Copyright 2014 Russ Allbery <eagle@eyrie.org> +Copyright 2014, 2016 Russ Allbery <eagle@eyrie.org> -Copyright 2013 The Board of Trustees of the Leland Stanford Junior -University +Copyright 2013 The Board of Trustees of the Leland Stanford Junior University -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. =head1 SEE ALSO -This module is maintained in the rra-c-util package. The current version -is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. +This module is maintained in the rra-c-util package. The current version is +available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. =cut diff --git a/tests/portable/strlcat-t.c b/tests/portable/strlcat-t.c deleted file mode 100644 index 58aba58..0000000 --- a/tests/portable/strlcat-t.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * strlcat test suite. - * - * The canonical version of this file is maintained in the rra-c-util package, - * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. - * - * Written by Russ Allbery <eagle@eyrie.org> - * - * The authors hereby relinquish any claim to any copyright that they may have - * in this work, whether granted under contract or by operation of law or - * international treaty, and hereby commit to the public, at large, that they - * shall not, at any time in the future, seek to enforce any copyright in this - * work against any person or entity, or prevent any person or entity from - * copying, publishing, distributing or creating derivative works of this - * work. - */ - -#include <config.h> -#include <portable/system.h> - -#include <tests/tap/basic.h> - -size_t test_strlcat(char *, const char *, size_t); - - -int -main(void) -{ - char buffer[10] = ""; - - plan(27); - - is_int(3, test_strlcat(buffer, "foo", sizeof(buffer)), - "strlcat into empty buffer"); - is_string("foo", buffer, "...with right output"); - is_int(7, test_strlcat(buffer, " bar", sizeof(buffer)), - "...and append more"); - is_string("foo bar", buffer, "...and output is still correct"); - is_int(9, test_strlcat(buffer, "!!", sizeof(buffer)), - "...and append to buffer limit"); - is_string("foo bar!!", buffer, "...output is still correct"); - is_int(10, test_strlcat(buffer, "!", sizeof(buffer)), - "...append one more character"); - is_string("foo bar!!", buffer, "...and output didn't change"); - ok(buffer[9] == '\0', "...buffer still nul-terminated"); - buffer[0] = '\0'; - is_int(11, test_strlcat(buffer, "hello world", sizeof(buffer)), - "append single long string"); - is_string("hello wor", buffer, "...string truncates properly"); - ok(buffer[9] == '\0', "...buffer still nul-terminated"); - buffer[0] = '\0'; - is_int(7, test_strlcat(buffer, "sausage", 5), "lie about buffer length"); - is_string("saus", buffer, "...contents are correct"); - is_int(14, test_strlcat(buffer, "bacon eggs", sizeof(buffer)), - "...add more up to real size"); - is_string("sausbacon", buffer, "...and result is correct"); - - /* Make sure that with a size of 0, the destination isn't changed. */ - is_int(11, test_strlcat(buffer, "!!", 0), "no change with size of 0"); - is_string("sausbacon", buffer, "...and content is the same"); - - /* Now play with empty strings. */ - is_int(9, test_strlcat(buffer, "", 0), - "correct count when appending empty string"); - is_string("sausbacon", buffer, "...and contents are unchanged"); - buffer[0] = '\0'; - is_int(0, test_strlcat(buffer, "", sizeof(buffer)), - "correct count when appending empty string to empty buffer"); - is_string("", buffer, "...and buffer content is correct"); - is_int(3, test_strlcat(buffer, "foo", 2), "append to length 2 buffer"); - is_string("f", buffer, "...and got only a single character"); - ok(buffer[1] == '\0', "...and buffer is still nul-terminated"); - is_int(1, test_strlcat(buffer, "", sizeof(buffer)), - "append an empty string"); - ok(buffer[1] == '\0', "...and buffer is still nul-terminated"); - - return 0; -} diff --git a/tests/portable/strlcat.c b/tests/portable/strlcat.c deleted file mode 100644 index 8983bd8..0000000 --- a/tests/portable/strlcat.c +++ /dev/null @@ -1,2 +0,0 @@ -#define TESTING 1 -#include <portable/strlcat.c> diff --git a/tests/portable/strlcpy-t.c b/tests/portable/strlcpy-t.c deleted file mode 100644 index 6652a7c..0000000 --- a/tests/portable/strlcpy-t.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * strlcpy test suite. - * - * The canonical version of this file is maintained in the rra-c-util package, - * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. - * - * Written by Russ Allbery <eagle@eyrie.org> - * - * The authors hereby relinquish any claim to any copyright that they may have - * in this work, whether granted under contract or by operation of law or - * international treaty, and hereby commit to the public, at large, that they - * shall not, at any time in the future, seek to enforce any copyright in this - * work against any person or entity, or prevent any person or entity from - * copying, publishing, distributing or creating derivative works of this - * work. - */ - -#include <config.h> -#include <portable/system.h> - -#include <tests/tap/basic.h> - -size_t test_strlcpy(char *, const char *, size_t); - - -int -main(void) -{ - char buffer[10]; - - plan(23); - - is_int(3, test_strlcpy(buffer, "foo", sizeof(buffer)), "simple strlcpy"); - is_string("foo", buffer, "...result is correct"); - is_int(9, test_strlcpy(buffer, "hello wor", sizeof(buffer)), - "strlcpy exact length of buffer"); - is_string("hello wor", buffer, "...result is correct"); - is_int(10, test_strlcpy(buffer, "world hell", sizeof(buffer)), - "strlcpy one more than buffer length"); - is_string("world hel", buffer, "...result is correct"); - ok(buffer[9] == '\0', "...buffer is nul-terminated"); - is_int(11, test_strlcpy(buffer, "hello world", sizeof(buffer)), - "strlcpy more than buffer length"); - is_string("hello wor", buffer, "...result is correct"); - ok(buffer[9] == '\0', "...buffer is nul-terminated"); - - /* Make sure that with a size of 0, the destination isn't changed. */ - is_int(3, test_strlcpy(buffer, "foo", 0), "buffer unchanged if size 0"); - is_string("hello wor", buffer, "...contents still the same"); - - /* Now play with empty strings. */ - is_int(0, test_strlcpy(buffer, "", 0), "copy empty string with size 0"); - is_string("hello wor", buffer, "...buffer unchanged"); - is_int(0, test_strlcpy(buffer, "", sizeof(buffer)), - "copy empty string into full buffer"); - is_string("", buffer, "...buffer now empty string"); - is_int(3, test_strlcpy(buffer, "foo", 2), - "copy string into buffer of size 2"); - is_string("f", buffer, "...got one character"); - ok(buffer[1] == '\0', "...buffer is nul-terminated"); - is_int(0, test_strlcpy(buffer, "", 1), - "copy empty string into buffer of size 1"); - ok(buffer[0] == '\0', "...buffer is empty string"); - - /* Finally, check using strlcpy as strlen. */ - is_int(3, test_strlcpy(NULL, "foo", 0), "use strlcpy as strlen"); - is_int(11, test_strlcpy(NULL, "hello world", 0), "...again"); - - return 0; -} diff --git a/tests/portable/strlcpy.c b/tests/portable/strlcpy.c deleted file mode 100644 index d444595..0000000 --- a/tests/portable/strlcpy.c +++ /dev/null @@ -1,2 +0,0 @@ -#define TESTING 1 -#include <portable/strlcpy.c> diff --git a/tests/runtests.c b/tests/runtests.c index 42a73ea..e3aad0c 100644 --- a/tests/runtests.c +++ b/tests/runtests.c @@ -48,11 +48,11 @@ * output. This is intended for use with failing tests so that the person * running the test suite can get more details about what failed. * - * If built with the C preprocessor symbols SOURCE and BUILD defined, C TAP - * Harness will export those values in the environment so that tests can find - * the source and build directory and will look for tests under both - * directories. These paths can also be set with the -b and -s command-line - * options, which will override anything set at build time. + * If built with the C preprocessor symbols C_TAP_SOURCE and C_TAP_BUILD + * defined, C TAP Harness will export those values in the environment so that + * tests can find the source and build directory and will look for tests under + * both directories. These paths can also be set with the -b and -s + * command-line options, which will override anything set at build time. * * If the -v option is given, or the C_TAP_VERBOSE environment variable is set, * display the full output of each test as it runs rather than showing a @@ -63,7 +63,7 @@ * Harness <http://www.eyrie.org/~eagle/software/c-tap-harness/>. * * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, - * 2014, 2015 Russ Allbery <eagle@eyrie.org> + * 2014, 2015, 2016 Russ Allbery <eagle@eyrie.org> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -135,15 +135,17 @@ /* * The source and build versions of the tests directory. This is used to set - * the SOURCE and BUILD environment variables and find test programs, if set. - * Normally, this should be set as part of the build process to the test - * subdirectories of $(abs_top_srcdir) and $(abs_top_builddir) respectively. + * the C_TAP_SOURCE and C_TAP_BUILD environment variables (and the SOURCE and + * BUILD environment variables set for backward compatibility) and find test + * programs, if set. Normally, this should be set as part of the build + * process to the test subdirectories of $(abs_top_srcdir) and + * $(abs_top_builddir) respectively. */ -#ifndef SOURCE -# define SOURCE NULL +#ifndef C_TAP_SOURCE +# define C_TAP_SOURCE NULL #endif -#ifndef BUILD -# define BUILD NULL +#ifndef C_TAP_BUILD +# define C_TAP_BUILD NULL #endif /* Test status codes. */ @@ -1479,8 +1481,9 @@ test_single(const char *program, const char *source, const char *build) /* - * Main routine. Set the SOURCE and BUILD environment variables and then, - * given a file listing tests, run each test listed. + * Main routine. Set the C_TAP_SOURCE, C_TAP_BUILD, SOURCE, and BUILD + * environment variables and then, given a file listing tests, run each test + * listed. */ int main(int argc, char *argv[]) @@ -1489,13 +1492,15 @@ main(int argc, char *argv[]) int status = 0; int single = 0; enum test_verbose verbose = CONCISE; + char *c_tap_source_env = NULL; + char *c_tap_build_env = NULL; char *source_env = NULL; char *build_env = NULL; const char *program; const char *shortlist; const char *list = NULL; - const char *source = SOURCE; - const char *build = BUILD; + const char *source = C_TAP_SOURCE; + const char *build = C_TAP_BUILD; struct testlist *tests; program = argv[0]; @@ -1537,13 +1542,23 @@ main(int argc, char *argv[]) if (getenv("C_TAP_VERBOSE") != NULL) verbose = VERBOSE; - /* Set SOURCE and BUILD environment variables. */ + /* + * Set C_TAP_SOURCE and C_TAP_BUILD environment variables. Also set + * SOURCE and BUILD for backward compatibility, although we're trying to + * migrate to the ones with a C_TAP_* prefix. + */ if (source != NULL) { + c_tap_source_env = concat("C_TAP_SOURCE=", source, (const char *) 0); + if (putenv(c_tap_source_env) != 0) + sysdie("cannot set C_TAP_SOURCE in the environment"); source_env = concat("SOURCE=", source, (const char *) 0); if (putenv(source_env) != 0) sysdie("cannot set SOURCE in the environment"); } if (build != NULL) { + c_tap_build_env = concat("C_TAP_BUILD=", build, (const char *) 0); + if (putenv(c_tap_build_env) != 0) + sysdie("cannot set C_TAP_BUILD in the environment"); build_env = concat("BUILD=", build, (const char *) 0); if (putenv(build_env) != 0) sysdie("cannot set BUILD in the environment"); @@ -1568,11 +1583,15 @@ main(int argc, char *argv[]) /* For valgrind cleanliness, free all our memory. */ if (source_env != NULL) { + putenv((char *) "C_TAP_SOURCE="); putenv((char *) "SOURCE="); + free(c_tap_source_env); free(source_env); } if (build_env != NULL) { + putenv((char *) "C_TAP_BUILD="); putenv((char *) "BUILD="); + free(c_tap_build_env); free(build_env); } exit(status); diff --git a/tests/server/acl-t.c b/tests/server/acl-t.c index fa4e885..9b6f347 100644 --- a/tests/server/acl-t.c +++ b/tests/server/acl-t.c @@ -2,7 +2,7 @@ * Test suite for the server ACL checking. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2015 Russ Allbery <eagle@eyrie.org> + * Copyright 2015, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2007, 2008, 2009, 2010, 2012, 2014 * The Board of Trustees of the Leland Stanford Junior University * Copyright 2008 Carnegie Mellon University @@ -65,8 +65,8 @@ main(void) const char *acls[5]; plan(78); - if (chdir(getenv("SOURCE")) < 0) - sysbail("can't chdir to SOURCE"); + if (chdir(getenv("C_TAP_SOURCE")) < 0) + sysbail("can't chdir to C_TAP_SOURCE"); rule.file = (char *) "TEST"; rule.acls = (char **) acls; diff --git a/tests/server/config-t.c b/tests/server/config-t.c index 6ddbc79..6959f47 100644 --- a/tests/server/config-t.c +++ b/tests/server/config-t.c @@ -49,8 +49,8 @@ main(void) struct config *config; plan(49); - if (chdir(getenv("SOURCE")) < 0) - sysbail("can't chdir to SOURCE"); + if (chdir(getenv("C_TAP_SOURCE")) < 0) + sysbail("can't chdir to C_TAP_SOURCE"); config = server_config_load("data/conf-test"); ok(config != NULL, "config loaded"); diff --git a/tests/server/misc-t b/tests/server/misc-t index 3b0df42..9afc30a 100755 --- a/tests/server/misc-t +++ b/tests/server/misc-t @@ -8,9 +8,9 @@ # # See LICENSE for licensing terms. -. "$SOURCE/tap/libtap.sh" -. "$SOURCE/tap/kerberos.sh" -. "$SOURCE/tap/remctl.sh" +. "${C_TAP_SOURCE}/tap/libtap.sh" +. "${C_TAP_SOURCE}/tap/kerberos.sh" +. "${C_TAP_SOURCE}/tap/remctl.sh" # Test setup. kerberos_setup @@ -19,11 +19,11 @@ if [ $? != 0 ] ; then else plan 7 fi -remctl="$BUILD/../client/remctl" +remctl="$C_TAP_BUILD/../client/remctl" if [ ! -x "$remctl" ] ; then bail "can't locate remctl client binary" fi -remctld_start "$BUILD/../server/remctld" "$BUILD/data/conf-simple" +remctld_start "$C_TAP_BUILD/../server/remctld" "$C_TAP_BUILD/data/conf-simple" # Run the tests. ok_program "file descriptors closed properly on server" 0 "Okay" \ diff --git a/tests/tap/basic.c b/tests/tap/basic.c index 4f8be04..68b0d95 100644 --- a/tests/tap/basic.c +++ b/tests/tap/basic.c @@ -12,7 +12,7 @@ * This file is part of C TAP Harness. The current version plus supporting * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. * - * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015 + * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Russ Allbery <eagle@eyrie.org> * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013, 2014 * The Board of Trustees of the Leland Stanford Junior University @@ -820,17 +820,17 @@ bstrndup(const char *s, size_t n) /* - * Locate a test file. Given the partial path to a file, look under BUILD and - * then SOURCE for the file and return the full path to the file. Returns - * NULL if the file doesn't exist. A non-NULL return should be freed with - * test_file_path_free(). + * Locate a test file. Given the partial path to a file, look under + * C_TAP_BUILD and then C_TAP_SOURCE for the file and return the full path to + * the file. Returns NULL if the file doesn't exist. A non-NULL return + * should be freed with test_file_path_free(). */ char * test_file_path(const char *file) { char *base; char *path = NULL; - const char *envs[] = { "BUILD", "SOURCE", NULL }; + const char *envs[] = { "C_TAP_BUILD", "C_TAP_SOURCE", NULL }; int i; for (i = 0; envs[i] != NULL; i++) { @@ -860,7 +860,7 @@ test_file_path_free(char *path) /* - * Create a temporary directory, tmp, under BUILD if set and the current + * Create a temporary directory, tmp, under C_TAP_BUILD if set and the current * directory if it does not. Returns the path to the temporary directory in * newly allocated memory, and calls bail on any failure. The return value * should be freed with test_tmpdir_free. @@ -875,7 +875,7 @@ test_tmpdir(void) const char *build; char *path = NULL; - build = getenv("BUILD"); + build = getenv("C_TAP_BUILD"); if (build == NULL) build = "."; path = concat(build, "/tmp", (const char *) 0); diff --git a/tests/tap/basic.h b/tests/tap/basic.h index 4ecaaec..db3f848 100644 --- a/tests/tap/basic.h +++ b/tests/tap/basic.h @@ -4,7 +4,7 @@ * This file is part of C TAP Harness. The current version plus supporting * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. * - * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015 + * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Russ Allbery <eagle@eyrie.org> * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2014 * The Board of Trustees of the Leland Stanford Junior University @@ -137,16 +137,16 @@ char *bstrndup(const char *, size_t) __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); /* - * Find a test file under BUILD or SOURCE, returning the full path. The - * returned path should be freed with test_file_path_free(). + * Find a test file under C_TAP_BUILD or C_TAP_SOURCE, returning the full + * path. The returned path should be freed with test_file_path_free(). */ char *test_file_path(const char *file) __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); void test_file_path_free(char *path); /* - * Create a temporary directory relative to BUILD and return the path. The - * returned path should be freed with test_tmpdir_free. + * Create a temporary directory relative to C_TAP_BUILD and return the path. + * The returned path should be freed with test_tmpdir_free(). */ char *test_tmpdir(void) __attribute__((__malloc__, __warn_unused_result__)); diff --git a/tests/tap/kerberos.sh b/tests/tap/kerberos.sh index e970ae5..7c9fc77 100644 --- a/tests/tap/kerberos.sh +++ b/tests/tap/kerberos.sh @@ -9,6 +9,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2009, 2010, 2011, 2012 # The Board of Trustees of the Leland Stanford Junior University # @@ -30,8 +31,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -# We use test_tmpdir. -. "${SOURCE}/tap/libtap.sh" +. "${C_TAP_SOURCE}/tap/libtap.sh" # Set up Kerberos, including the ticket cache environment variable. Bail out # if not successful, return 0 if successful, and return 1 if Kerberos is not diff --git a/tests/tap/libtap.sh b/tests/tap/libtap.sh index 9731032..1403505 100644 --- a/tests/tap/libtap.sh +++ b/tests/tap/libtap.sh @@ -10,7 +10,7 @@ # <http://www.eyrie.org/~eagle/software/c-tap-harness/>. # # Written by Russ Allbery <eagle@eyrie.org> -# Copyright 2009, 2010, 2011, 2012 Russ Allbery <eagle@eyrie.org> +# Copyright 2009, 2010, 2011, 2012, 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2006, 2007, 2008, 2013 # The Board of Trustees of the Leland Stanford Junior University # @@ -212,32 +212,32 @@ diag () { echo '#' "$@" } -# Search for the given file first in $BUILD and then in $SOURCE and echo the -# path where the file was found, or the empty string if the file wasn't -# found. +# Search for the given file first in $C_TAP_BUILD and then in $C_TAP_SOURCE +# and echo the path where the file was found, or the empty string if the file +# wasn't found. # # This macro uses puts, so don't run it using backticks inside double quotes # or bizarre quoting behavior will happen with Solaris sh. test_file_path () { - if [ -n "$BUILD" ] && [ -f "$BUILD/$1" ] ; then - puts "$BUILD/$1" - elif [ -n "$SOURCE" ] && [ -f "$SOURCE/$1" ] ; then - puts "$SOURCE/$1" + if [ -n "$C_TAP_BUILD" ] && [ -f "$C_TAP_BUILD/$1" ] ; then + puts "$C_TAP_BUILD/$1" + elif [ -n "$C_TAP_SOURCE" ] && [ -f "$C_TAP_SOURCE/$1" ] ; then + puts "$C_TAP_SOURCE/$1" else echo '' fi } -# Create $BUILD/tmp for use by tests for storing temporary files and return -# the path (via standard output). +# Create $C_TAP_BUILD/tmp for use by tests for storing temporary files and +# return the path (via standard output). # # This macro uses puts, so don't run it using backticks inside double quotes # or bizarre quoting behavior will happen with Solaris sh. test_tmpdir () { - if [ -z "$BUILD" ] ; then + if [ -z "$C_TAP_BUILD" ] ; then tap_tmpdir="./tmp" else - tap_tmpdir="$BUILD"/tmp + tap_tmpdir="$C_TAP_BUILD"/tmp fi if [ ! -d "$tap_tmpdir" ] ; then mkdir "$tap_tmpdir" || bail "Error creating $tap_tmpdir" diff --git a/tests/tap/perl/Test/RRA.pm b/tests/tap/perl/Test/RRA.pm index 3870cc1..44586a2 100644 --- a/tests/tap/perl/Test/RRA.pm +++ b/tests/tap/perl/Test/RRA.pm @@ -31,7 +31,7 @@ BEGIN { # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '5.09'; + $VERSION = '6.00'; } # Skip this test unless author tests are requested. Takes a short description @@ -128,7 +128,7 @@ __END__ =for stopwords Allbery Allbery's DESC bareword sublicense MERCHANTABILITY NONINFRINGEMENT -rra-c-util +rra-c-util CPAN =head1 NAME @@ -151,46 +151,45 @@ Test::RRA - Support functions for Perl tests =head1 DESCRIPTION -This module collects utility functions that are useful for Perl test -scripts. It assumes Russ Allbery's Perl module layout and test -conventions and will only be useful for other people if they use the -same conventions. +This module collects utility functions that are useful for Perl test scripts. +It assumes Russ Allbery's Perl module layout and test conventions and will +only be useful for other people if they use the same conventions. =head1 FUNCTIONS -None of these functions are imported by default. The ones used by a -script should be explicitly imported. +None of these functions are imported by default. The ones used by a script +should be explicitly imported. =over 4 =item skip_unless_author(DESC) -Checks whether AUTHOR_TESTING is set in the environment and skips the -whole test (by calling C<plan skip_all> from Test::More) if it is not. -DESC is a description of the tests being skipped. A space and C<only run -for author> will be appended to it and used as the skip reason. +Checks whether AUTHOR_TESTING is set in the environment and skips the whole +test (by calling C<plan skip_all> from Test::More) if it is not. DESC is a +description of the tests being skipped. A space and C<only run for author> +will be appended to it and used as the skip reason. =item skip_unless_automated(DESC) -Checks whether AUTHOR_TESTING, AUTOMATED_TESTING, or RELEASE_TESTING are -set in the environment and skips the whole test (by calling C<plan -skip_all> from Test::More) if they are not. This should be used by tests -that should not run during end-user installs of the module, but which -should run as part of CPAN smoke testing and release testing. +Checks whether AUTHOR_TESTING, AUTOMATED_TESTING, or RELEASE_TESTING are set +in the environment and skips the whole test (by calling C<plan skip_all> from +Test::More) if they are not. This should be used by tests that should not run +during end-user installs of the module, but which should run as part of CPAN +smoke testing and release testing. DESC is a description of the tests being skipped. A space and C<normally skipped> will be appended to it and used as the skip reason. =item use_prereq(MODULE[, VERSION][, IMPORT ...]) -Attempts to load MODULE with the given VERSION and import arguments. If -this fails for any reason, the test will be skipped (by calling C<plan -skip_all> from Test::More) with a skip reason saying that MODULE is -required for the test. +Attempts to load MODULE with the given VERSION and import arguments. If this +fails for any reason, the test will be skipped (by calling C<plan skip_all> +from Test::More) with a skip reason saying that MODULE is required for the +test. VERSION will be passed to C<use> as a version bareword if it looks like a -version number. The remaining IMPORT arguments will be passed as the -value of an array. +version number. The remaining IMPORT arguments will be passed as the value of +an array. =back @@ -203,33 +202,33 @@ Russ Allbery <eagle@eyrie.org> Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior University -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. =head1 SEE ALSO Test::More(3), Test::RRA::Automake(3), Test::RRA::Config(3) -This module is maintained in the rra-c-util package. The current version -is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. +This module is maintained in the rra-c-util package. The current version is +available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. -The functions to control when tests are run use environment variables -defined by the L<Lancaster +The functions to control when tests are run use environment variables defined +by the L<Lancaster Consensus|https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/lancaster-consensus.md>. =cut diff --git a/tests/tap/perl/Test/RRA/Automake.pm b/tests/tap/perl/Test/RRA/Automake.pm index b820b7b..f3e680b 100644 --- a/tests/tap/perl/Test/RRA/Automake.pm +++ b/tests/tap/perl/Test/RRA/Automake.pm @@ -7,8 +7,9 @@ # require closely following the conventions implemented by the rra-c-util # utility collection. # -# All the functions here assume that BUILD and SOURCE are set in the -# environment. This is normally done via the C TAP Harness runtests wrapper. +# All the functions here assume that C_TAP_BUILD and C_TAP_SOURCE are set in +# the environment. This is normally done via the C TAP Harness runtests +# wrapper. package Test::RRA::Automake; @@ -34,9 +35,9 @@ BEGIN { $PERL_BLIB_ARCH = File::Spec->catdir(qw(perl blib arch)); $PERL_BLIB_LIB = File::Spec->catdir(qw(perl blib lib)); - # If BUILD is set, we can come up with better values. - if (defined($ENV{BUILD})) { - my ($vol, $dirs) = File::Spec->splitpath($ENV{BUILD}, 1); + # If C_TAP_BUILD is set, we can come up with better values. + if (defined($ENV{C_TAP_BUILD})) { + my ($vol, $dirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1); my @dirs = File::Spec->splitdir($dirs); pop(@dirs); $PERL_BLIB_ARCH = File::Spec->catdir(@dirs, qw(perl blib arch)); @@ -62,13 +63,13 @@ BEGIN { # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '5.09'; + $VERSION = '6.00'; } # Perl directories to skip globally for perl_dirs. We ignore the perl # directory if it exists since, in my packages, it is treated as a Perl module # distribution and has its own standalone test suite. -my @GLOBAL_SKIP = qw(.git perl); +my @GLOBAL_SKIP = qw(.git _build perl); # The temporary directory created by test_tmpdir, if any. If this is set, # attempt to remove the directory stored here on program exit (but ignore @@ -76,28 +77,35 @@ my @GLOBAL_SKIP = qw(.git perl); my $TMPDIR; # Perform initial test setup for running a Perl test in an Automake package. -# This verifies that BUILD and SOURCE are set and then changes directory to -# the SOURCE directory by default. Sets LD_LIBRARY_PATH if the $LIBRARY_PATH -# configuration option is set. Calls BAIL_OUT if BUILD or SOURCE are missing -# or if anything else fails. +# This verifies that C_TAP_BUILD and C_TAP_SOURCE are set and then changes +# directory to the C_TAP_SOURCE directory by default. Sets LD_LIBRARY_PATH if +# the $LIBRARY_PATH configuration option is set. Calls BAIL_OUT if +# C_TAP_BUILD or C_TAP_SOURCE are missing or if anything else fails. # # $args_ref - Reference to a hash of arguments to configure behavior: -# chdir_build - If set to a true value, changes to BUILD instead of SOURCE +# chdir_build - If set to a true value, changes to C_TAP_BUILD instead of +# C_TAP_SOURCE # # Returns: undef sub automake_setup { my ($args_ref) = @_; - # Bail if BUILD or SOURCE are not set. - if (!$ENV{BUILD}) { - BAIL_OUT('BUILD not defined (run under runtests)'); + # Bail if C_TAP_BUILD or C_TAP_SOURCE are not set. + if (!$ENV{C_TAP_BUILD}) { + BAIL_OUT('C_TAP_BUILD not defined (run under runtests)'); } - if (!$ENV{SOURCE}) { - BAIL_OUT('SOURCE not defined (run under runtests)'); + if (!$ENV{C_TAP_SOURCE}) { + BAIL_OUT('C_TAP_SOURCE not defined (run under runtests)'); } - # BUILD or SOURCE will be the test directory. Change to the parent. - my $start = $args_ref->{chdir_build} ? $ENV{BUILD} : $ENV{SOURCE}; + # C_TAP_BUILD or C_TAP_SOURCE will be the test directory. Change to the + # parent. + my $start; + if ($args_ref->{chdir_build}) { + $start = $ENV{C_TAP_BUILD}; + } else { + $start = $ENV{C_TAP_SOURCE}; + } my ($vol, $dirs) = File::Spec->splitpath($start, 1); my @dirs = File::Spec->splitdir($dirs); pop(@dirs); @@ -116,8 +124,9 @@ sub automake_setup { my $root = File::Spec->catpath($vol, File::Spec->catdir(@dirs), q{}); chdir($root) or BAIL_OUT("cannot chdir to $root: $!"); - # If BUILD is a subdirectory of SOURCE, add it to the global ignore list. - my ($buildvol, $builddirs) = File::Spec->splitpath($ENV{BUILD}, 1); + # If C_TAP_BUILD is a subdirectory of C_TAP_SOURCE, add it to the global + # ignore list. + my ($buildvol, $builddirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1); my @builddirs = File::Spec->splitdir($builddirs); pop(@builddirs); if ($buildvol eq $vol && @builddirs == @dirs + 1) { @@ -206,9 +215,9 @@ sub perl_dirs { return @dirs; } -# Find a configuration file for the test suite. Searches relative to BUILD -# first and then SOURCE and returns whichever is found first. Calls BAIL_OUT -# if the file could not be found. +# Find a configuration file for the test suite. Searches relative to +# C_TAP_BUILD first and then C_TAP_SOURCE and returns whichever is found +# first. Calls BAIL_OUT if the file could not be found. # # $file - Partial path to the file # @@ -216,7 +225,7 @@ sub perl_dirs { sub test_file_path { my ($file) = @_; BASE: - for my $base ($ENV{BUILD}, $ENV{SOURCE}) { + for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}) { next if !defined($base); if (-f "$base/$file") { return "$base/$file"; @@ -236,11 +245,16 @@ sub test_tmpdir { my $path; # If we already figured out what directory to use, reuse the same path. - # Otherwise, create a directory relative to BUILD if set. + # Otherwise, create a directory relative to C_TAP_BUILD if set. if (defined($TMPDIR)) { $path = $TMPDIR; } else { - my $base = defined($ENV{BUILD}) ? $ENV{BUILD} : File::Spec->curdir; + my $base; + if (defined($ENV{C_TAP_BUILD})) { + $base = $ENV{C_TAP_BUILD}; + } else { + $base = File::Spec->curdir; + } $path = File::Spec->catdir($base, 'tmp'); } @@ -271,8 +285,8 @@ END { __END__ =for stopwords -Allbery Automake Automake-aware Automake-based rra-c-util ARGS -subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT umask +Allbery Automake Automake-aware Automake-based rra-c-util ARGS subdirectories +sublicense MERCHANTABILITY NONINFRINGEMENT umask =head1 NAME @@ -292,75 +306,88 @@ Test::RRA::Automake - Automake-aware support functions for Perl tests =head1 DESCRIPTION This module collects utility functions that are useful for test scripts -written in Perl and included in a C Automake-based package. They assume -the layout of a package that uses rra-c-util and C TAP Harness for the -test structure. +written in Perl and included in a C Automake-based package. They assume the +layout of a package that uses rra-c-util and C TAP Harness for the test +structure. Loading this module will also add the directories C<perl/blib/arch> and -C<perl/blib/lib> to the Perl library search path, relative to BUILD if -that environment variable is set. This is harmless for C Automake -projects that don't contain an embedded Perl module, and for those -projects that do, this will allow subsequent C<use> calls to find modules -that are built as part of the package build process. +C<perl/blib/lib> to the Perl library search path, relative to C_TAP_BUILD if +that environment variable is set. This is harmless for C Automake projects +that don't contain an embedded Perl module, and for those projects that do, +this will allow subsequent C<use> calls to find modules that are built as part +of the package build process. The automake_setup() function should be called before calling any other functions provided by this module. =head1 FUNCTIONS -None of these functions are imported by default. The ones used by a -script should be explicitly imported. On failure, all of these functions -call BAIL_OUT (from Test::More). +None of these functions are imported by default. The ones used by a script +should be explicitly imported. On failure, all of these functions call +BAIL_OUT (from Test::More). =over 4 =item automake_setup([ARGS]) -Verifies that the BUILD and SOURCE environment variables are set and -then changes directory to the top of the source tree (which is one -directory up from the SOURCE path, since SOURCE points to the top of -the tests directory). +Verifies that the C_TAP_BUILD and C_TAP_SOURCE environment variables are set +and then changes directory to the top of the source tree (which is one +directory up from the C_TAP_SOURCE path, since C_TAP_SOURCE points to the top +of the tests directory). -If ARGS is given, it should be a reference to a hash of configuration -options. Only one option is supported: C<chdir_build>. If it is set -to a true value, automake_setup() changes directories to the top of -the build tree instead. +If ARGS is given, it should be a reference to a hash of configuration options. +Only one option is supported: C<chdir_build>. If it is set to a true value, +automake_setup() changes directories to the top of the build tree instead. =item perl_dirs([ARGS]) Returns a list of directories that may contain Perl scripts that should be -tested by test scripts that test all Perl in the source tree (such as -syntax or coding style checks). The paths will be simple directory names -relative to the current directory or two-part directory names under the -F<tests> directory. (Directories under F<tests> are broken out separately -since it's common to want to apply different policies to different -subdirectories of F<tests>.) - -If ARGS is given, it should be a reference to a hash of configuration -options. Only one option is supported: C<skip>, whose value should be a -reference to an array of additional top-level directories or directories -starting with C<tests/> that should be skipped. +tested by test scripts that test all Perl in the source tree (such as syntax +or coding style checks). The paths will be simple directory names relative to +the current directory or two-part directory names under the F<tests> +directory. (Directories under F<tests> are broken out separately since it's +common to want to apply different policies to different subdirectories of +F<tests>.) + +If ARGS is given, it should be a reference to a hash of configuration options. +Only one option is supported: C<skip>, whose value should be a reference to an +array of additional top-level directories or directories starting with +C<tests/> that should be skipped. =item test_file_path(FILE) -Given FILE, which should be a relative path, locates that file relative to -the test directory in either the source or build tree. FILE will be -checked for relative to the environment variable BUILD first, and then -relative to SOURCE. test_file_path() returns the full path to FILE or -calls BAIL_OUT if FILE could not be found. +Given FILE, which should be a relative path, locates that file relative to the +test directory in either the source or build tree. FILE will be checked for +relative to the environment variable C_TAP_BUILD first, and then relative to +C_TAP_SOURCE. test_file_path() returns the full path to FILE or calls +BAIL_OUT if FILE could not be found. =item test_tmpdir() -Create a temporary directory for tests to use for transient files and -return the path to that directory. The directory is created relative to -the BUILD environment variable, which must be set. Permissions on the +Create a temporary directory for tests to use for transient files and return +the path to that directory. The directory is created relative to the +C_TAP_BUILD environment variable, which must be set. Permissions on the directory are set using the current umask. test_tmpdir() returns the full -path to the temporary directory or calls BAIL_OUT if it could not be -created. +path to the temporary directory or calls BAIL_OUT if it could not be created. -The directory is automatically removed if possible on program exit. -Failure to remove the directory on exit is reported with diag() and -otherwise ignored. +The directory is automatically removed if possible on program exit. Failure +to remove the directory on exit is reported with diag() and otherwise ignored. + +=back + +=head1 ENVIRONMENT + +=over 4 + +=item C_TAP_BUILD + +The root of the tests directory in Automake build directory for this package, +used to find files as documented above. + +=item C_TAP_SOURCE + +The root of the tests directory in the source tree for this package, used to +find files as documented above. =back @@ -370,37 +397,36 @@ Russ Allbery <eagle@eyrie.org> =head1 COPYRIGHT AND LICENSE -Copyright 2014 Russ Allbery <eagle@eyrie.org> +Copyright 2014, 2015 Russ Allbery <eagle@eyrie.org> -Copyright 2013 The Board of Trustees of the Leland Stanford Junior -University +Copyright 2013 The Board of Trustees of the Leland Stanford Junior University -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. =head1 SEE ALSO Test::More(3), Test::RRA(3), Test::RRA::Config(3) +This module is maintained in the rra-c-util package. The current version is +available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. + The C TAP Harness test driver and libraries for TAP-based C testing are available from L<http://www.eyrie.org/~eagle/software/c-tap-harness/>. -This module is maintained in the rra-c-util package. The current version -is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. - =cut diff --git a/tests/tap/perl/Test/RRA/Config.pm b/tests/tap/perl/Test/RRA/Config.pm index 7c29f1a..ba96f4e 100644 --- a/tests/tap/perl/Test/RRA/Config.pm +++ b/tests/tap/perl/Test/RRA/Config.pm @@ -27,22 +27,23 @@ BEGIN { @ISA = qw(Exporter); @EXPORT_OK = qw( $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH - $MINIMUM_VERSION %MINIMUM_VERSION @POD_COVERAGE_EXCLUDE @STRICT_IGNORE - @STRICT_PREREQ + $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE + @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ ); # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '5.09'; + $VERSION = '6.00'; } -# If BUILD or SOURCE are set in the environment, look for data/perl.conf under -# those paths for a C Automake package. Otherwise, look in t/data/perl.conf -# for a standalone Perl module. Don't use Test::RRA::Automake since it may -# not exist. +# If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for +# data/perl.conf under those paths for a C Automake package. Otherwise, look +# in t/data/perl.conf for a standalone Perl module or tests/data/perl.conf for +# Perl tests embedded in a larger distribution. Don't use Test::RRA::Automake +# since it may not exist. our $PATH; -for my $base ($ENV{BUILD}, $ENV{SOURCE}, 't') { +for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}, 't', 'tests') { next if !defined($base); my $path = "$base/data/perl.conf"; if (-r $path) { @@ -61,6 +62,7 @@ our @CRITIC_IGNORE; our $LIBRARY_PATH; our $MINIMUM_VERSION = '5.008'; our %MINIMUM_VERSION; +our @MODULE_VERSION_IGNORE; our @POD_COVERAGE_EXCLUDE; our @STRICT_IGNORE; our @STRICT_PREREQ; @@ -75,8 +77,8 @@ if (!do($PATH)) { __END__ =for stopwords -Allbery rra-c-util Automake perlcritic .libs namespace subdirectory -sublicense MERCHANTABILITY NONINFRINGEMENT +Allbery rra-c-util Automake perlcritic .libs namespace subdirectory sublicense +MERCHANTABILITY NONINFRINGEMENT regexes =head1 NAME @@ -89,19 +91,17 @@ Test::RRA::Config - Perl test configuration =head1 DESCRIPTION -Test::RRA::Config encapsulates per-package configuration for generic Perl -test programs that are shared between multiple packages using the -rra-c-util infrastructure. It handles locating and loading the test -configuration file for both C Automake packages and stand-alone Perl -modules. +Test::RRA::Config encapsulates per-package configuration for generic Perl test +programs that are shared between multiple packages using the rra-c-util +infrastructure. It handles locating and loading the test configuration file +for both C Automake packages and stand-alone Perl modules. Test::RRA::Config looks for a file named F<data/perl.conf> relative to the -root of the test directory. That root is taken from the environment -variables BUILD or SOURCE (in that order) if set, which will be the case -for C Automake packages using C TAP Harness. If neither is set, it -expects the root of the test directory to be a directory named F<t> -relative to the current directory, which will be the case for stand-alone -Perl modules. +root of the test directory. That root is taken from the environment variables +C_TAP_BUILD or C_TAP_SOURCE (in that order) if set, which will be the case for +C Automake packages using C TAP Harness. If neither is set, it expects the +root of the test directory to be a directory named F<t> relative to the +current directory, which will be the case for stand-alone Perl modules. The following variables are supported: @@ -109,70 +109,75 @@ The following variables are supported: =item $COVERAGE_LEVEL -The coverage level achieved by the test suite for Perl test coverage -testing using Test::Strict, as a percentage. The test will fail if test -coverage less than this percentage is achieved. If not given, defaults -to 100. +The coverage level achieved by the test suite for Perl test coverage testing +using Test::Strict, as a percentage. The test will fail if test coverage less +than this percentage is achieved. If not given, defaults to 100. =item @COVERAGE_SKIP_TESTS Directories under F<t> whose tests should be skipped when doing coverage -testing. This can be tests that won't contribute to coverage or tests -that don't run properly under Devel::Cover for some reason (such as ones -that use taint checking). F<docs> and F<style> will always be skipped -regardless of this setting. +testing. This can be tests that won't contribute to coverage or tests that +don't run properly under Devel::Cover for some reason (such as ones that use +taint checking). F<docs> and F<style> will always be skipped regardless of +this setting. =item @CRITIC_IGNORE -Additional directories to ignore when doing recursive perlcritic testing. -The contents of this directory must be either top-level directory names or +Additional directories to ignore when doing recursive perlcritic testing. The +contents of this directory must be either top-level directory names or directory names starting with F<tests/>. =item $LIBRARY_PATH Add this directory (or a F<.libs> subdirectory) relative to the top of the -source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules. -This may be required to pick up libraries that are used by in-tree Perl -modules so that Perl scripts can pass a syntax check. +source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules. This +may be required to pick up libraries that are used by in-tree Perl modules so +that Perl scripts can pass a syntax check. =item $MINIMUM_VERSION -Default minimum version requirement for included Perl scripts. If not -given, defaults to 5.008. +Default minimum version requirement for included Perl scripts. If not given, +defaults to 5.008. =item %MINIMUM_VERSION Minimum version exceptions for specific directories. The keys should be minimum versions of Perl to enforce. The value for each key should be a -reference to an array of either top-level directory names or directory -names starting with F<tests/>. All files in those directories will have -that minimum Perl version constraint imposed instead of $MINIMUM_VERSION. +reference to an array of either top-level directory names or directory names +starting with F<tests/>. All files in those directories will have that +minimum Perl version constraint imposed instead of $MINIMUM_VERSION. + +=item @MODULE_VERSION_IGNORE + +File names to ignore when checking that all modules in a distribution have the +same version. Sometimes, some specific modules need separate, special version +handling, such as modules defining database schemata for DBIx::Class, and +can't follow the version of the larger package. =item @POD_COVERAGE_EXCLUDE Regexes that match method names that should be excluded from POD coverage -testing. Normally, all methods have to be documented in the POD for a -Perl module, but methods matching any of these regexes will be considered -private and won't require documentation. +testing. Normally, all methods have to be documented in the POD for a Perl +module, but methods matching any of these regexes will be considered private +and won't require documentation. =item @STRICT_IGNORE -Additional directories to ignore when doing recursive Test::Strict testing -for C<use strict> and C<use warnings>. The contents of this directory -must be either top-level directory names or directory names starting with -F<tests/>. +Additional directories to ignore when doing recursive Test::Strict testing for +C<use strict> and C<use warnings>. The contents of this directory must be +either top-level directory names or directory names starting with F<tests/>. =item @STRICT_PREREQ A list of Perl modules that have to be available in order to do meaningful Test::Strict testing. If any of the modules cannot be loaded via C<use>, -Test::Strict checking will be skipped. There is currently no way to -require specific versions of the modules. +Test::Strict checking will be skipped. There is currently no way to require +specific versions of the modules. =back -No variables are exported by default, but the variables can be imported -into the local namespace to avoid long variable names. +No variables are exported by default, but the variables can be imported into +the local namespace to avoid long variable names. =head1 AUTHOR @@ -180,34 +185,36 @@ Russ Allbery <eagle@eyrie.org> =head1 COPYRIGHT AND LICENSE +Copyright 2015, 2016 Russ Allbery <eagle@eyrie.org> + Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior University -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. =head1 SEE ALSO -perlcritic(1), Test::MinimumVersion(3), Test::RRA(3), -Test::RRA::Automake(3), Test::Strict(3) +perlcritic(1), Test::MinimumVersion(3), Test::RRA(3), Test::RRA::Automake(3), +Test::Strict(3) -This module is maintained in the rra-c-util package. The current version -is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. +This module is maintained in the rra-c-util package. The current version is +available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. The C TAP Harness test driver and libraries for TAP-based C testing are available from L<http://www.eyrie.org/~eagle/software/c-tap-harness/>. diff --git a/tests/tap/perl/Test/RRA/ModuleVersion.pm b/tests/tap/perl/Test/RRA/ModuleVersion.pm new file mode 100644 index 0000000..9ddaebe --- /dev/null +++ b/tests/tap/perl/Test/RRA/ModuleVersion.pm @@ -0,0 +1,295 @@ +# Check Perl module versions for consistency. +# +# This module contains the common code for testing and updating Perl module +# versions for consistency within a Perl module distribution and within a +# larger package that contains both Perl modules and other code. + +package Test::RRA::ModuleVersion; + +use 5.006; +use strict; +use warnings; + +use Exporter; +use File::Find qw(find); +use Test::More; +use Test::RRA::Config qw(@MODULE_VERSION_IGNORE); + +# For Perl 5.006 compatibility. +## no critic (ClassHierarchies::ProhibitExplicitISA) + +# Declare variables that should be set in BEGIN for robustness. +our (@EXPORT_OK, @ISA, $VERSION); + +# Set $VERSION and everything export-related in a BEGIN block for robustness +# against circular module loading (not that we load any modules, but +# consistency is good). +BEGIN { + @ISA = qw(Exporter); + @EXPORT_OK = qw(test_module_versions update_module_versions); + + # This version should match the corresponding rra-c-util release, but with + # two digits for the minor version, including a leading zero if necessary, + # so that it will sort properly. + $VERSION = '6.00'; +} + +# A regular expression matching the version string for a module using the +# package syntax from Perl 5.12 and later. $1 will contain all of the line +# contents prior to the actual version string, $2 will contain the version +# itself, and $3 will contain the rest of the line. +our $REGEX_VERSION_PACKAGE = qr{ + ( # prefix ($1) + \A \s* # whitespace + package \s+ # package keyword + [\w\:\']+ \s+ # package name + ) + ( v? [\d._]+ ) # the version number itself ($2) + ( # suffix ($3) + \s* ; + ) +}xms; + +# A regular expression matching a $VERSION string in a module. $1 will +# contain all of the line contents prior to the actual version string, $2 will +# contain the version itself, and $3 will contain the rest of the line. +our $REGEX_VERSION_OLD = qr{ + ( # prefix ($1) + \A .* # any prefix, such as "our" + [\$*] # scalar or typeglob + [\w\:\']*\b # optional package name + VERSION\b # version variable + \s* = \s* # assignment + ) + [\"\']? # optional leading quote + ( v? [\d._]+ ) # the version number itself ($2) + [\"\']? # optional trailing quote + ( # suffix ($3) + \s* + ; + ) +}xms; + +# Find all the Perl modules shipped in this package, if any, and returns the +# list of file names. +# +# $dir - The root directory to search +# +# Returns: List of file names +sub _module_files { + my ($dir) = @_; + return if !-d $dir; + my @files; + my %ignore = map { $_ => 1 } @MODULE_VERSION_IGNORE; + my $wanted = sub { + if ($_ eq 'blib') { + $File::Find::prune = 1; + return; + } + if (m{ [.] pm \z }xms && !$ignore{$File::Find::name}) { + push(@files, $File::Find::name); + } + return; + }; + find($wanted, $dir); + return @files; +} + +# Given a module file, read it for the version value and return the value. +# +# $file - File to check, which should be a Perl module +# +# Returns: The version of the module +# Throws: Text exception on I/O failure or inability to find version +sub _module_version { + my ($file) = @_; + open(my $data, q{<}, $file) or die "$0: cannot open $file: $!\n"; + while (defined(my $line = <$data>)) { + if ( $line =~ $REGEX_VERSION_PACKAGE + || $line =~ $REGEX_VERSION_OLD) + { + my ($prefix, $version, $suffix) = ($1, $2, $3); + close($data) or die "$0: error reading from $file: $!\n"; + return $version; + } + } + close($data) or die "$0: error reading from $file: $!\n"; + die "$0: cannot find version number in $file\n"; +} + +# Given a module file and the new version for that module, update the version +# in that module to the new one. +# +# $file - Perl module file whose version should be updated +# $version - The new version number +# +# Returns: undef +# Throws: Text exception on I/O failure or inability to find version +sub _update_module_version { + my ($file, $version) = @_; + open(my $in, q{<}, $file) or die "$0: cannot open $file: $!\n"; + open(my $out, q{>}, "$file.new") + or die "$0: cannot create $file.new: $!\n"; + + # If the version starts with v, use it without quotes. Otherwise, quote + # it to prevent removal of trailing zeroes. + if ($version !~ m{ \A v }xms) { + $version = "'$version'"; + } + + # Scan for the version and replace it. + SCAN: + while (defined(my $line = <$in>)) { + if ( $line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms + || $line =~ s{ $REGEX_VERSION_OLD }{$1$version$3}xms) + { + print {$out} $line or die "$0: cannot write to $file.new: $!\n"; + last SCAN; + } + print {$out} $line or die "$0: cannot write to $file.new: $!\n"; + } + + # Copy the rest of the input file to the output file. + print {$out} <$in> or die "$0: cannot write to $file.new: $!\n"; + close($out) or die "$0: cannot flush $file.new: $!\n"; + close($in) or die "$0: error reading from $file: $!\n"; + + # All done. Rename the new file over top of the old file. + rename("$file.new", $file) + or die "$0: cannot rename $file.new to $file: $!\n"; + return; +} + +# Act as a test suite. Find all of the Perl modules under the provided root, +# if any, and check that the version for each module matches the version. +# Reports results with Test::More and sets up a plan based on the number of +# modules found. +# +# $root - Directory under which to look for Perl modules +# $version - The version all those modules should have +# +# Returns: undef +# Throws: Text exception on fatal errors +sub test_module_versions { + my ($root, $version) = @_; + my @modules = _module_files($root); + + # Output the plan. Skip the test if there were no modules found. + if (@modules) { + plan tests => scalar(@modules); + } else { + plan skip_all => 'No Perl modules found'; + return; + } + + # For each module, get the module version and compare. + for my $module (@modules) { + my $module_version = _module_version($module); + is($module_version, $version, "Version for $module"); + } + return; +} + +# Update the versions of all modules to the current distribution version. +# +# $root - Directory under which to look for Perl modules +# $version - The version all those modules should have +# +# Returns: undef +# Throws: Text exception on fatal errors +sub update_module_versions { + my ($root, $version) = @_; + my @modules = _module_files($root); + for my $module (@modules) { + _update_module_version($module, $version); + } + return; +} + +1; +__END__ + +=for stopwords +Allbery sublicense MERCHANTABILITY NONINFRINGEMENT rra-c-util versioning + +=head1 NAME + +Test::RRA::ModuleVersion - Check Perl module versions for consistency + +=head1 SYNOPSIS + + use Test::RRA::ModuleVersion + qw(test_module_versions update_module_versions); + + # Ensure all modules under perl/lib have a version of 3.12. + test_module_versions('perl/lib', '3.12'); + + # Update the version of those modules to 3.12. + update_module_versions('perl/lib', 3.12'); + +=head1 DESCRIPTION + +This module provides functions to test and update the versions of Perl +modules. It helps with enforcing consistency of versioning across all modules +in a Perl distribution or embedded in a larger project containing non-Perl +code. The calling script provides the version with which to be consistent +and the root directory under which modules are found. + +=head1 FUNCTIONS + +None of these functions are imported by default. The ones used by a script +should be explicitly imported. + +=over 4 + +=item test_module_versions(ROOT, VERSION) + +Tests the version of all Perl modules under ROOT to ensure they match VERSION, +reporting the results with Test::More. If the test configuration loaded by +Test::RRA::Config contains a @MODULE_VERSION_EXCLUDE variable, the module +files listed there will be ignored for this test. This function also sets up +a plan based on the number of modules, so should be the only testing function +called in a test script. + +=item update_module_versions(ROOT, VERSION) + +Update the version of all Perl modules found under ROOT to VERSION, except for +any listed in a @MODULE_VERSION_EXCLUDE variable set in the test configuration +loaded by Test::RRA::Config. + +=back + +=head1 AUTHOR + +Russ Allbery <eagle@eyrie.org> + +=head1 COPYRIGHT AND LICENSE + +Copyright 2016 Russ Allbery <eagle@eyrie.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +=head1 SEE ALSO + +Test::More(3), Test::RRA::Config(3) + +This module is maintained in the rra-c-util package. The current version +is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>. + +=cut diff --git a/tests/tap/remctl.sh b/tests/tap/remctl.sh index 0a511a0..efbd234 100644 --- a/tests/tap/remctl.sh +++ b/tests/tap/remctl.sh @@ -9,6 +9,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2009, 2012 # The Board of Trustees of the Leland Stanford Junior University # @@ -30,6 +31,8 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +. "${C_TAP_SOURCE}/tap/libtap.sh" + # Start remctld. Takes the path to remctld, which may be found via configure, # and the path to the configuration file. remctld_start () { @@ -45,7 +48,7 @@ remctld_start () { ( "$VALGRIND" --log-file=valgrind.%p --leak-check=full "$1" -m \ -p 14373 -s "$tap_principal" -P "$tap_pidfile" -f "$2" -d -S -F \ -k "$tap_keytab" &) - [ -f "$BUILD/data/remctld.pid" ] || sleep 5 + [ -f "$tap_pidfile" ] || sleep 5 else ( "$1" -m -p 14373 -s "$tap_principal" -P "$tap_pidfile" -f "$2" \ -d -S -F -k "$tap_keytab" &) diff --git a/tests/util/network/addr-ipv4-t.c b/tests/util/network/addr-ipv4-t.c index cb7e31d..a4fccd0 100644 --- a/tests/util/network/addr-ipv4-t.c +++ b/tests/util/network/addr-ipv4-t.c @@ -5,7 +5,7 @@ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2005, 2013 Russ Allbery <eagle@eyrie.org> + * Copyright 2005, 2013, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2009, 2010, 2011, 2012, 2013 * The Board of Trustees of the Leland Stanford Junior University * @@ -55,14 +55,16 @@ is_addr_compare(bool expected, const char *a, const char *b, const char *mask) int main(void) { - int status; + int flag, status; + socklen_t flaglen; struct addrinfo *ai, *ai2; struct addrinfo hints; char addr[INET6_ADDRSTRLEN]; + socket_type fd; static const char *port = "119"; /* Set up the plan. */ - plan(29); + plan(31); /* Get a sockaddr to use for subsequent tests. */ memset(&hints, 0, sizeof(hints)); @@ -123,5 +125,21 @@ main(void) is_addr_compare(0, "127.0.0.1", "127.0.0.1", "1p"); is_addr_compare(0, "127.0.0.1", "127.0.0.1", "-1"); is_addr_compare(0, "127.0.0.1", "127.0.0.1", "33"); + + /* Test setting various socket options. */ + fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_IP); + if (fd == INVALID_SOCKET) + sysbail("cannot create socket"); + network_set_reuseaddr(fd); +#ifdef SO_REUSEADDR + flag = 0; + flaglen = sizeof(flag); + is_int(0, getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen), + "Getting SO_REUSEADDR works"); + is_int(1, flag, "...and it is set"); +#else + skip_block(2, "SO_REUSEADDR not supported"); +#endif + close(fd); return 0; } diff --git a/tests/util/network/addr-ipv6-t.c b/tests/util/network/addr-ipv6-t.c index 4c408fd..99809b4 100644 --- a/tests/util/network/addr-ipv6-t.c +++ b/tests/util/network/addr-ipv6-t.c @@ -5,7 +5,7 @@ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2005, 2013 Russ Allbery <eagle@eyrie.org> + * Copyright 2005, 2013, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2009, 2010, 2011, 2012, 2013 * The Board of Trustees of the Leland Stanford Junior University * @@ -57,11 +57,13 @@ is_addr_compare(bool expected, const char *a, const char *b, const char *mask) int main(void) { - int status; + int flag, status; + socklen_t flaglen; struct addrinfo *ai4, *ai6; struct addrinfo hints; char addr[INET6_ADDRSTRLEN]; char *p; + socket_type fd; static const char *port = "119"; static const char *ipv6_addr = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210"; @@ -70,7 +72,7 @@ main(void) #endif /* Set up the plan. */ - plan(28); + plan(34); /* Get IPv4 and IPv6 sockaddrs to use for subsequent tests. */ memset(&hints, 0, sizeof(hints)); @@ -142,5 +144,42 @@ main(void) is_addr_compare(0, "ffff::1", "7fff::1", "-1"); is_addr_compare(0, "ffff::1", "ffff::1", "-1"); is_addr_compare(0, "ffff::1", "ffff::1", "129"); + + /* Test setting various socket options. */ + fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_IP); + if (fd == INVALID_SOCKET) + sysbail("cannot create socket"); + network_set_reuseaddr(fd); +#ifdef SO_REUSEADDR + flag = 0; + flaglen = sizeof(flag); + is_int(0, getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen), + "Getting SO_REUSEADDR works"); + is_int(1, flag, "...and it is set"); +#else + skip_block(2, "SO_REUSEADDR not supported"); +#endif + network_set_v6only(fd); +#ifdef IPV6_V6ONLY + flag = 0; + flaglen = sizeof(flag); + is_int(0, getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, &flaglen), + "Getting IPV6_V6ONLY works"); + is_int(1, flag, "...and it is set"); +#else + skip_block(2, "IPV6_V6ONLY not supported"); +#endif + network_set_freebind(fd); +#ifdef IP_FREEBIND + flag = 0; + flaglen = sizeof(flag); + is_int(0, getsockopt(fd, IPPROTO_IP, IP_FREEBIND, &flag, &flaglen), + "Getting IP_FREEBIND works"); + is_int(1, flag, "...and it is set"); +#else + skip_block(2, "IP_FREEBIND not supported"); +#endif + close(fd); + return 0; } diff --git a/tests/util/network/server-t.c b/tests/util/network/server-t.c index 3d2847b..87c0946 100644 --- a/tests/util/network/server-t.c +++ b/tests/util/network/server-t.c @@ -5,7 +5,7 @@ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2005, 2013 Russ Allbery <eagle@eyrie.org> + * Copyright 2005, 2013, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2009, 2010, 2011, 2012, 2013 * The Board of Trustees of the Leland Stanford Junior University * @@ -37,6 +37,7 @@ #include <signal.h> #include <tests/tap/basic.h> +#include <util/fdflag.h> #include <util/macros.h> #include <util/messages.h> #include <util/network.h> @@ -54,21 +55,41 @@ static bool ipv6_works(void) { - socket_type fd; + socket_type fd, client, server; - /* Create the socket. If this works, ipv6 is supported. */ + /* + * Create the socket and then try to connect to it with a short timeout + * and accept it on the server side. If this works, IPv6 is supported. + */ fd = network_bind_ipv6(SOCK_STREAM, "::1", 11119); if (fd != INVALID_SOCKET) { - close(fd); - return true; + fdflag_nonblocking(fd, true); + client = network_connect_host("::1", 11119, NULL, 1); + if (client == INVALID_SOCKET) { + close(fd); + if (socket_errno == ETIMEDOUT || socket_errno == ENETUNREACH) + return false; + } else { + server = accept(fd, NULL, NULL); + close(fd); + if (server == INVALID_SOCKET) { + close(client); + if (socket_errno == EAGAIN || socket_errno == EWOULDBLOCK) + return false; + } else { + close(server); + close(client); + return true; + } + } } /* IPv6 not recognized, indicating no support. */ - if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) + if (socket_errno == EAFNOSUPPORT || socket_errno == EPROTONOSUPPORT) return false; /* IPv6 is recognized but we can't actually use it. */ - if (errno == EADDRNOTAVAIL) + if (socket_errno == EADDRNOTAVAIL) return false; /* @@ -187,9 +208,16 @@ test_server_accept(socket_type fd) { socket_type client; + /* If there are firewalls that block connections, we could hang here. */ + alarm(5); + + /* Accept the connection and writes from the client. */ client = accept(fd, NULL, NULL); test_server_connection(client); socket_close(fd); + + /* Cancel the alarm. */ + alarm(0); } @@ -212,6 +240,10 @@ test_server_accept_any(socket_type fds[], unsigned int count) struct sockaddr *saddr; socklen_t slen; + /* If there are firewalls that block connections, we could hang here. */ + alarm(5); + + /* Accept the connection and writes from the client. */ slen = sizeof(struct sockaddr_storage); saddr = bcalloc(1, slen); client = network_accept_any(fds, count, saddr, &slen); @@ -223,6 +255,9 @@ test_server_accept_any(socket_type fds[], unsigned int count) free(saddr); for (i = 0; i < count; i++) socket_close(fds[i]); + + /* Cancel the alarm. */ + alarm(0); } diff --git a/tests/util/tokens-t.c b/tests/util/tokens-t.c index 5190b7c..5bf0f18 100644 --- a/tests/util/tokens-t.c +++ b/tests/util/tokens-t.c @@ -144,8 +144,8 @@ main(void) alarm(20); plan(12); - if (chdir(getenv("BUILD")) < 0) - sysbail("can't chdir to BUILD"); + if (chdir(getenv("C_TAP_BUILD")) < 0) + sysbail("can't chdir to C_TAP_BUILD"); unlink("server-ready"); child = fork(); diff --git a/tests/util/xmalloc-t b/tests/util/xmalloc-t index af604ed..5c78c02 100755 --- a/tests/util/xmalloc-t +++ b/tests/util/xmalloc-t @@ -6,7 +6,7 @@ # which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> -# Copyright 2000, 2001, 2006, 2014 Russ Allbery <eagle@eyrie.org> +# Copyright 2000, 2001, 2006, 2014, 2016 Russ Allbery <eagle@eyrie.org> # Copyright 2008, 2009, 2010, 2012 # The Board of Trustees of the Leland Stanford Junior University # @@ -28,8 +28,8 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -. "$SOURCE/tap/libtap.sh" -cd "$BUILD/util" +. "$C_TAP_SOURCE/tap/libtap.sh" +cd "$C_TAP_BUILD/util" # Run an xmalloc test. Takes the description, the expectd exit status, the # output, and the arguments. |