added new test in --enable-valgrind mode to collect suspect functions
authorMichael Rash <mbr@cipherdyne.org>
Sun, 8 Jul 2012 19:30:35 +0000 (15:30 -0400)
committerMichael Rash <mbr@cipherdyne.org>
Sun, 8 Jul 2012 19:30:35 +0000 (15:30 -0400)
test/test-fwknop.pl

index a34d5b3..76ac585 100755 (executable)
@@ -71,7 +71,10 @@ my $test_include = '';
 my @tests_to_include = ();
 my $test_exclude = '';
 my @tests_to_exclude = ();
+my %valgrind_suspect_functions = ();
 my $list_mode = 0;
+my $diff_dir1 = '';
+my $diff_dir2 = '';
 my $loopback_intf = '';
 my $anonymize_results = 0;
 my $current_test_file = "$output_dir/init";
@@ -115,7 +118,10 @@ exit 1 unless GetOptions(
     'List-mode'         => \$list_mode,
     'enable-valgrind'   => \$use_valgrind,
     'valgrind-path=s'   => \$valgrindCmd,
+    'output-dir=s'      => \$output_dir,
     'diff'              => \$diff_mode,
+    'diff-dir1=s'       => \$diff_dir1,
+    'diff-dir2=s'       => \$diff_dir2,
     'help'              => \$help
 );
 
@@ -1239,7 +1245,6 @@ my @tests = (
         'fwknopd_cmdline'  => $default_server_gpg_args,
         'fatal'    => $NO
     },
-
     {
         'category' => 'GnuPG (GPG) SPA',
         'subcategory' => 'server',
@@ -1250,6 +1255,18 @@ my @tests = (
     },
 );
 
+if ($use_valgrind) {
+    push @tests,
+        {
+            'category' => 'valgrind output',
+            'subcategory' => 'suspect functions',
+            'detail'   => '',
+            'err_msg'  => 'could not parse suspect functions',
+            'function' => \&parse_valgrind_suspect_functions,
+            'fatal'    => $NO
+        };
+}
+
 my %test_keys = (
     'category'        => $REQUIRED,
     'subcategory'     => $OPTIONAL,
@@ -1345,7 +1362,8 @@ sub process_include_exclude() {
     if (@tests_to_include) {
         my $found = 0;
         for my $test (@tests_to_include) {
-            if ($msg =~ /$test/) {
+            if ($msg =~ /$test/ or ($use_valgrind
+                    and $msg =~ /valgrind\soutput/)) {
                 $found = 1;
                 last;
             }
@@ -1366,17 +1384,21 @@ sub process_include_exclude() {
 }
 
 sub diff_test_results() {
+
+    $diff_dir1 = "${output_dir}.last" unless $diff_dir2;
+    $diff_dir2 = $output_dir unless $diff_dir1;
+
     die "[*] Need results from a previous run before running --diff"
-        unless -d "${output_dir}.last";
-    die "[*] Current results set does not exist." unless -d $output_dir;
+        unless -d $diff_dir2;
+    die "[*] Current results set does not exist." unless -d $diff_dir1;
 
     my %current_tests  = ();
     my %previous_tests = ();
 
     ### Only diff results for matching tests (parse the logfile to see which
     ### test numbers match across the two test cycles).
-    &build_results_hash(\%current_tests, $output_dir);
-    &build_results_hash(\%previous_tests, "${output_dir}.last");
+    &build_results_hash(\%current_tests, $diff_dir1);
+    &build_results_hash(\%previous_tests, $diff_dir2);
 
     for my $test_msg (sort {$current_tests{$a}{'num'} <=> $current_tests{$b}{'num'}}
                 keys %current_tests) {
@@ -1407,25 +1429,25 @@ sub diff_results() {
     ### remove CMD timestamps
     my $cmd_search_re = qr/^\S+\s.*?\s\d{4}\sCMD\:/;
 
-    for my $file ("${output_dir}.last/${previous_num}.test",
-        "${output_dir}.last/${previous_num}_fwknopd.test",
-        "${output_dir}/${current_num}.test",
-        "${output_dir}/${current_num}_fwknopd.test",
+    for my $file ("$diff_dir1/${previous_num}.test",
+        "$diff_dir1/${previous_num}_fwknopd.test",
+        "$diff_dir2/${current_num}.test",
+        "$diff_dir2/${current_num}_fwknopd.test",
     ) {
         system qq{perl -p -i -e 's|$valgrind_search_re||' $file} if -e $file;
         system qq{perl -p -i -e 's|$cmd_search_re|CMD:|' $file} if -e $file;
     }
 
-    if (-e "${output_dir}.last/${previous_num}.test"
-            and -e "${output_dir}/${current_num}.test") {
-        system "diff -u ${output_dir}.last/${previous_num}.test " .
-            "${output_dir}/${current_num}.test";
+    if (-e "$diff_dir1/${previous_num}.test"
+            and -e "$diff_dir2/${current_num}.test") {
+        system "diff -u $diff_dir1/${previous_num}.test " .
+            "$diff_dir2/${current_num}.test";
     }
 
-    if (-e "${output_dir}.last/${previous_num}_fwknopd.test"
-            and -e "${output_dir}/${current_num}_fwknopd.test") {
-        system "diff -u ${output_dir}.last/${previous_num}_fwknopd.test " .
-            "${output_dir}/${current_num}_fwknopd.test";
+    if (-e "$diff_dir1/${previous_num}_fwknopd.test"
+            and -e "$diff_dir2/${current_num}_fwknopd.test") {
+        system "diff -u $diff_dir1/${previous_num}_fwknopd.test " .
+            "$diff_dir2/${current_num}_fwknopd.test";
     }
 
     return;
@@ -2592,6 +2614,34 @@ sub identify_loopback_intf() {
     return;
 }
 
+sub parse_valgrind_suspect_functions() {
+    for my $file (glob("$output_dir/*.test")) {
+        my $type = 'server';
+        $type = 'client' if $file =~ /\d\.test/;
+        open F, "< $file" or die $!;
+        while (<F>) {
+            ### ==30969==    by 0x4E3983A: fko_set_username (fko_user.c:65)
+            if (/^==.*\sby\s\S+\:\s(.*)/) {
+                $valgrind_suspect_functions{$type}{$1}++;
+            }
+        }
+        close F;
+    }
+
+    open F, ">> $current_test_file" or die $!;
+    for my $type ('client', 'server') {
+        print F "[+] fwknop $type functions:\n";
+        next unless defined $valgrind_suspect_functions{$type};
+        for my $fcn (sort {$valgrind_suspect_functions{$type}{$b}
+                <=> $valgrind_suspect_functions{$type}{$a}} keys %{$valgrind_suspect_functions{$type}}) {
+            printf F "    %5d : %s\n", $valgrind_suspect_functions{$type}{$fcn}, $fcn;
+        }
+        print F "\n";
+    }
+    close F;
+    return 1;
+}
+
 sub is_fw_rule_active() {
     my $test_hr = shift;
 
@@ -2707,3 +2757,44 @@ sub logr() {
     close F;
     return;
 }
+
+sub usage() {
+    print <<_HELP_;
+
+[+] $0 <options>
+
+    -A   --Anonymize-results      - Prepare anonymized results at:
+                                    $tarfile
+    --diff                        - Compare the results of one test run to
+                                    another.  By default this compares output
+                                    in ${output_dir}.last to $output_dir
+    --diff-dir1=<path>            - Left hand side of diff directory path,
+                                    default is: ${output_dir}.last
+    --diff-dir2=<path>            - Right hand side of diff directory path,
+                                    default is: $output_dir
+    --include=<regex>             - Specify a regex to be used over test
+                                    names that must match.
+    --exclude=<regex>             - Specify a regex to be used over test
+                                    names that must not match.
+    --enable-recompile            - Recompile fwknop sources and look for
+                                    compilation warnings.
+    --enable-valgrind             - Run every test underneath valgrind.
+    --List                        - List test names.
+    --loopback-intf=<intf>        - Specify loopback interface name (default
+                                    depends on the OS where the test suite
+                                    is executed).
+    --output-dir=<path>           - Path to output directory, default is:
+                                    $output_dir
+    --fwknop-path=<path>          - Path to fwknop binary, default is:
+                                    $fwknopCmd
+    --fwknopd-path=<path>         - Path to fwknopd binary, default is:
+                                    $fwknopdCmd
+    --libfko-path=<path>          - Path to libfko, default is:
+                                    $libfko_bin
+    --valgrind-path=<path>        - Path to valgrind, default is:
+                                    $valgrindCmd
+    -h   --help                   - Display usage on STDOUT and exit.
+
+_HELP_
+    exit 0;
+}