MISSING=INCLUDE/EXCLUDE works
[pspp] / tests / perl-module.at
index 8920b31a1a84c62b9122e82ffa685e9783fd0850..244b1b9999dc537457a6176f3a8eb7b6271f14d3 100644 (file)
@@ -1,34 +1,49 @@
 dnl PSPP - a program for statistical analysis.
 dnl PSPP - a program for statistical analysis.
-dnl Copyright (C) 2017 Free Software Foundation, Inc.
-dnl 
+dnl Copyright (C) 2017, 2020, 2021 Free Software Foundation, Inc.
+dnl
 dnl This program is free software: you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
 dnl the Free Software Foundation, either version 3 of the License, or
 dnl (at your option) any later version.
 dnl This program is free software: you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
 dnl the Free Software Foundation, either version 3 of the License, or
 dnl (at your option) any later version.
-dnl 
+dnl
 dnl This program is distributed in the hope that it will be useful,
 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 dnl GNU General Public License for more details.
 dnl This program is distributed in the hope that it will be useful,
 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 dnl GNU General Public License for more details.
-dnl 
+dnl
 dnl You should have received a copy of the GNU General Public License
 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
 dnl
 AT_BANNER([Perl module tests])
 
 dnl You should have received a copy of the GNU General Public License
 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
 dnl
 AT_BANNER([Perl module tests])
 
+m4_divert_push([PREPARE_TESTS])
+# Find the Address Sanitizer library that PSPP is linked against, if any.
+# If it exists, it needs to be preloaded when we run Perl.
+asan_lib=$("$abs_top_builddir/libtool" --mode=execute ldd \
+               "$abs_top_builddir/src/ui/terminal/pspp" 2>/dev/null \
+          | grep asan \
+          | awk '{print $3}')
+if test -e "$asan_lib"; then
+    USING_ASAN=:
+else
+    USING_ASAN=false
+    asan_lib=
+fi
+
 dnl This command can be used to run with the PSPP Perl module after it has been
 dnl built (with "make") but before it has been installed.  The -I options are
 dnl equivalent to "use ExtUtils::testlib;" inside the Perl program, but it does
 dnl not need to be run with the perl-module build directory as the current
 dnl working directory.
 dnl This command can be used to run with the PSPP Perl module after it has been
 dnl built (with "make") but before it has been installed.  The -I options are
 dnl equivalent to "use ExtUtils::testlib;" inside the Perl program, but it does
 dnl not need to be run with the perl-module build directory as the current
 dnl working directory.
-dnl
-dnl XXX "libtool --mode=execute" is probably better than setting
-dnl LD_LIBRARY_PATH.
-m4_define([RUN_PERL_MODULE],
-  [LD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
-   DYLD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
-   $PERL -I$abs_top_builddir/perl-module/blib/arch \
-         -I$abs_top_builddir/perl-module/blib/lib])
+run_perl_module () {
+    LD_PRELOAD="$asan_lib":"$LD_PRELOAD" \
+    LD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
+    DYLD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
+    ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=false" \
+    $PERL -I"$abs_top_builddir/perl-module/blib/arch" \
+          -I"$abs_top_builddir/perl-module/blib/lib" "$@"
+}
+m4_divert_pop([PREPARE_TESTS])
 
 AT_SETUP([Perl create system file])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
 
 AT_SETUP([Perl create system file])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
@@ -54,7 +69,7 @@ AT_DATA([test.pl],
    die "accept legal variable name" if !ref $var0;
    die if $d->get_var_cnt () != 1;
 
    die "accept legal variable name" if !ref $var0;
    die if $d->get_var_cnt () != 1;
 
-   my $var1 = PSPP::Var->new ($d, "money", 
+   my $var1 = PSPP::Var->new ($d, "money",
                              (fmt=>PSPP::Fmt::DOLLAR,
                               width=>4, decimals=>2) );
    die "cappet valid format" if !ref $var1;
                              (fmt=>PSPP::Fmt::DOLLAR,
                               width=>4, decimals=>2) );
    die "cappet valid format" if !ref $var1;
@@ -67,7 +82,7 @@ AT_DATA([test.pl],
 
    $sysfile->close ();
 ])
 
    $sysfile->close ();
 ])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
 AT_DATA([dump-dict.sps],
   [GET FILE='testfile.sav'.
 DISPLAY FILE LABEL.
 AT_DATA([dump-dict.sps],
   [GET FILE='testfile.sav'.
 DISPLAY FILE LABEL.
@@ -83,9 +98,9 @@ Table: Documents
 These Documents
 
 Table: Variables
 These Documents
 
 Table: Variables
-Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
-legal,1,,Scale,Input,8,Right,F9.2,F9.2,
-money,2,,Scale,Input,8,Right,DOLLAR6.2,DOLLAR6.2,
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+legal,1,Scale,Input,8,Right,F9.2,F9.2
+money,2,Scale,Input,8,Right,DOLLAR6.2,DOLLAR6.2
 
 dump-dict.sps:5: note: SHOW: WEIGHT is money.
 ])
 
 dump-dict.sps:5: note: SHOW: WEIGHT is money.
 ])
@@ -101,16 +116,16 @@ AT_DATA([test.pl],
     my $d = PSPP::Dict->new();
     PSPP::Var->new ($d, "id",
                    (
     my $d = PSPP::Dict->new();
     PSPP::Var->new ($d, "id",
                    (
-                    fmt=>PSPP::Fmt::F, 
-                    width=>2, 
+                    fmt=>PSPP::Fmt::F,
+                    width=>2,
                     decimals=>0
                     )
                    );
 
     PSPP::Var->new ($d, "name",
                           (
                     decimals=>0
                     )
                    );
 
     PSPP::Var->new ($d, "name",
                           (
-                           fmt=>PSPP::Fmt::A, 
-                           width=>20, 
+                           fmt=>PSPP::Fmt::A,
+                           width=>20,
                            )
                           );
 
                            )
                           );
 
@@ -139,7 +154,7 @@ AT_DATA([test.pl],
 
     # Don't close.  We want to test that the destructor does that.
 ]])
 
     # Don't close.  We want to test that the destructor does that.
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
 AT_DATA([dump-dicts.sps],
   [GET FILE='testfile.sav'.
 DISPLAY DICTIONARY.
 AT_DATA([dump-dicts.sps],
   [GET FILE='testfile.sav'.
 DISPLAY DICTIONARY.
@@ -155,9 +170,9 @@ LIST.
 ])
 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0], [dnl
 Table: Variables
 ])
 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0], [dnl
 Table: Variables
-Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
-id,1,,Scale,Input,8,Right,F2.0,F2.0,
-name,2,,Nominal,Input,20,Left,A20,A20,
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+id,1,Scale,Input,8,Right,F2.0,F2.0
+name,2,Nominal,Input,20,Left,A20,A20
 
 Table: File Label
 Label,This is the file label
 
 Table: File Label
 Label,This is the file label
@@ -170,9 +185,9 @@ id,name
 34,frederick
 
 Table: Variables
 34,frederick
 
 Table: Variables
-Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
-id,1,,Scale,Input,8,Right,F2.0,F2.0,
-name,2,,Nominal,Input,20,Left,A20,A20,
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+id,1,Scale,Input,8,Right,F2.0,F2.0
+name,2,Nominal,Input,20,Left,A20,A20
 
 Table: File Label
 Label,This is the file label
 
 Table: File Label
 Label,This is the file label
@@ -196,7 +211,7 @@ AT_DATA([test.pl],
     my $dict = PSPP::Dict->new();
     die "dictionary creation" if !ref $dict;
 
     my $dict = PSPP::Dict->new();
     die "dictionary creation" if !ref $dict;
 
-    my $int = PSPP::Var->new ($dict, "integer", 
+    my $int = PSPP::Var->new ($dict, "integer",
                              (width=>8, decimals=>0) );
 
     $int->set_label ("My Integer");
                              (width=>8, decimals=>0) );
 
     $int->set_label ("My Integer");
@@ -207,7 +222,7 @@ AT_DATA([test.pl],
     $int->add_value_label (1, "Unity");
     $int->add_value_label (2, "Duality");
 
     $int->add_value_label (1, "Unity");
     $int->add_value_label (2, "Duality");
 
-    my $str = PSPP::Var->new ($dict, "string", 
+    my $str = PSPP::Var->new ($dict, "string",
                              (fmt=>PSPP::Fmt::A, width=>8) );
 
 
                              (fmt=>PSPP::Fmt::A, width=>8) );
 
 
@@ -217,7 +232,7 @@ AT_DATA([test.pl],
 
     $str->set_missing_values ("this", "that");
 
 
     $str->set_missing_values ("this", "that");
 
-    my $longstr = PSPP::Var->new ($dict, "longstring", 
+    my $longstr = PSPP::Var->new ($dict, "longstring",
                              (fmt=>PSPP::Fmt::A, width=>9) );
 
 
                              (fmt=>PSPP::Fmt::A, width=>9) );
 
 
@@ -231,7 +246,7 @@ AT_DATA([test.pl],
 
     $sysfile->close ();
 ]])
 
     $sysfile->close ();
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0], [], [stderr])
+AT_CHECK([run_perl_module test.pl], [0], [], [stderr])
 cat stderr
 AT_DATA([dump-dict.sps],
   [GET FILE='testfile.sav'.
 cat stderr
 AT_DATA([dump-dict.sps],
   [GET FILE='testfile.sav'.
@@ -269,8 +284,8 @@ my $sysfile ;
 
        PSPP::Var->new ($d, "id",
                        (
 
        PSPP::Var->new ($d, "id",
                        (
-                        fmt=>PSPP::Fmt::F, 
-                        width=>2, 
+                        fmt=>PSPP::Fmt::F,
+                        width=>2,
                         decimals=>0
                         )
                        );
                         decimals=>0
                         )
                        );
@@ -281,7 +296,7 @@ my $sysfile ;
     my $res = $sysfile->append_case ([3]);
     print "Dictionary survives sysfile\n" if $res;
 ]])
     my $res = $sysfile->append_case ([3]);
     print "Dictionary survives sysfile\n" if $res;
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
   [Dictionary survives sysfile
 ])
 AT_CLEANUP
   [Dictionary survives sysfile
 ])
 AT_CLEANUP
@@ -359,7 +374,7 @@ AT_DATA([test.pl],
        print "\n";
     }
 ]])
        print "\n";
     }
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
   [Variable 0 is "string", label is "A Short String Variable"
 Value Labels:
 1111     => ones
   [Variable 0 is "string", label is "A Short String Variable"
 Value Labels:
 1111     => ones
@@ -437,7 +452,7 @@ AT_DATA([test.pl],
 
     $output->close ();
 ]])
 
     $output->close ();
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
 AT_DATA([dump-dicts.sps],
   [GET FILE='sample.sav'.
 DISPLAY DICTIONARY.
 AT_DATA([dump-dicts.sps],
   [GET FILE='sample.sav'.
 DISPLAY DICTIONARY.
@@ -467,9 +482,7 @@ A Short String Variable,1111,ones
 A Numeric Variable,1,Unity
 ,2,Duality
 ,3,Thripality
 A Numeric Variable,1,Unity
 ,2,Duality
 ,3,Thripality
-
-Footnotes:
-a,User-missing value
+Footnote: a. User-missing value
 
 Table: Variable and Dataset Attributes
 Variable and Name,,Value
 
 Table: Variable and Dataset Attributes
 Variable and Name,,Value
@@ -504,9 +517,7 @@ A Short String Variable,1111,ones
 A Numeric Variable,1,Unity
 ,2,Duality
 ,3,Thripality
 A Numeric Variable,1,Unity
 ,2,Duality
 ,3,Thripality
-
-Footnotes:
-a,User-missing value
+Footnote: a. User-missing value
 
 Table: Variable and Dataset Attributes
 Variable and Name,,Value
 
 Table: Variable and Dataset Attributes
 Variable and Name,,Value
@@ -559,7 +570,7 @@ AT_DATA([test.pl],
     print "Formatted string is \"$formatted\"\n";
     print "Perl representation is \"$str\"\n";
 ]])
     print "Formatted string is \"$formatted\"\n";
     print "Perl representation is \"$str\"\n";
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
   [[Formatted string is "11-SEP-2001 08:20"
 Perl representation is "Tue Sep 11 08:20:00 2001"
 ]])
   [[Formatted string is "11-SEP-2001 08:20"
 Perl representation is "Tue Sep 11 08:20:00 2001"
 ]])
@@ -577,7 +588,7 @@ AT_DATA([test.pl],
     die "Returns undef on opening failure" if ref $sf;
     print $PSPP::errstr, "\n";
 ]])
     die "Returns undef on opening failure" if ref $sf;
     print $PSPP::errstr, "\n";
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
   [[An error occurred while opening `no-such-file.sav': No such file or directory.
 ]],
   [[Name "PSPP::errstr" used only once: possible typo at test.pl line 8.
   [[An error occurred while opening `no-such-file.sav': No such file or directory.
 ]],
   [[Name "PSPP::errstr" used only once: possible typo at test.pl line 8.
@@ -610,24 +621,24 @@ AT_DATA([test.pl],
     die "Missing Value Negative Num"
         if PSPP::value_is_missing ($val, $numericvar);
 
     die "Missing Value Negative Num"
         if PSPP::value_is_missing ($val, $numericvar);
 
-    @c = $sf->get_next_case (); 
-    @c = $sf->get_next_case (); 
+    @c = $sf->get_next_case ();
+    @c = $sf->get_next_case ();
 
     $val = $c[0];
     die "Missing Value Positive"
         if !PSPP::value_is_missing ($val, $stringvar);
 
 
     $val = $c[0];
     die "Missing Value Positive"
         if !PSPP::value_is_missing ($val, $stringvar);
 
-    @c = $sf->get_next_case (); 
+    @c = $sf->get_next_case ();
     $val = $c[2];
     die "Missing Value Positive SYS"
         if !PSPP::value_is_missing ($val, $numericvar);
 
     $val = $c[2];
     die "Missing Value Positive SYS"
         if !PSPP::value_is_missing ($val, $numericvar);
 
-    @c = $sf->get_next_case (); 
+    @c = $sf->get_next_case ();
     $val = $c[2];
     die "Missing Value Positive Num"
         if !PSPP::value_is_missing ($val, $numericvar);
 ]])
     $val = $c[2];
     die "Missing Value Positive Num"
         if !PSPP::value_is_missing ($val, $numericvar);
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
 AT_CLEANUP
 
 AT_SETUP([Perl custom attributes])
 AT_CLEANUP
 
 AT_SETUP([Perl custom attributes])
@@ -653,7 +664,7 @@ AT_DATA([test.pl],
        print map "$_\n", join ', ', @$ll;
     }
 ]])
        print map "$_\n", join ', ', @$ll;
     }
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
   [[$@Role =>0
 colour =>blue, pink, violet
 nationality =>foreign
   [[$@Role =>0
 colour =>blue, pink, violet
 nationality =>foreign
@@ -662,11 +673,17 @@ size =>large
 AT_CLEANUP
 
 AT_SETUP([Perl Pspp.t])
 AT_CLEANUP
 
 AT_SETUP([Perl Pspp.t])
+AT_KEYWORDS([slow])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
 # Skip this test if Perl's Text::Diff module is not installed.
 AT_CHECK([perl -MText::Diff -e '' || exit 77])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
 # Skip this test if Perl's Text::Diff module is not installed.
 AT_CHECK([perl -MText::Diff -e '' || exit 77])
-AT_CHECK([RUN_PERL_MODULE $abs_top_builddir/perl-module/t/Pspp.t], [0],
-  [[1..37
+# Skip this test if Perl's Memory::Usage module is not installed.
+AT_CHECK([perl -MMemory::Usage -e '' || exit 77])
+# Skip this test if Address Sanitizer is in use because it will
+# screw up memory accounting and look like a leak.
+AT_SKIP_IF([$USING_ASAN])
+AT_CHECK([run_perl_module "$abs_top_builddir/perl-module/t/Pspp.t"], [0],
+  [[1..38
 ok 1 - use PSPP;
 ok 2 - Dictionary Creation
 ok 3
 ok 1 - use PSPP;
 ok 2 - Dictionary Creation
 ok 3
@@ -705,5 +722,6 @@ ok 34 - Missing Value Positive SYS
 ok 35 - Missing Value Positive Num
 ok 36 - Custom Attributes
 ok 37 - Case count
 ok 35 - Missing Value Positive Num
 ok 36 - Custom Attributes
 ok 37 - Case count
+ok 38 - Memory management of append_case
 ]],[ignore])
 AT_CLEANUP
 ]],[ignore])
 AT_CLEANUP