]> The Tcpdump Group git mirrors - tcpdump/blob - tests/testfuncs.pm
use perl hashes for configuration, rather than YAML things
[tcpdump] / tests / testfuncs.pm
1 #!/usr/bin/perl
2
3 # expects to be run from the top directory, with "tests" subdirectory.
4
5 sub runtest {
6 local($name, $input, $output, $options) = @_;
7 my $r;
8
9 $outputbase = basename($output);
10 my $coredump = false;
11 my $status = 0;
12 my $linecount = 0;
13 my $rawstderrlog = "tests/NEW/${outputbase}.raw.stderr";
14 my $stderrlog = "tests/NEW/${outputbase}.stderr";
15 my $diffstat = 0;
16 my $errdiffstat = 0;
17
18 if ($^O eq 'MSWin32') {
19 $r = system "..\\windump -# -n -r $input $options 2>NUL | sed 's/\\r//' | tee tests/NEW/$outputbase | diff $output - >tests/DIFF/$outputbase.diff";
20 # need to do same as below for Cygwin.
21 }
22 else {
23 # we used to do this as a nice pipeline, but the problem is that $r fails to
24 # to be set properly if the tcpdump core dumps.
25 $r = system "$TCPDUMP 2>${rawstderrlog} -# -n -r $input $options >tests/NEW/${outputbase}";
26 if($r == -1) {
27 # failed to start due to error.
28 $status = $!;
29 }
30 if($r != 0) {
31 $coredump = false;
32 $status = 0;
33 # this means tcpdump failed.
34 open(OUTPUT, ">>"."tests/NEW/$outputbase") || die "fail to open $outputbase\n";
35 if( $r & 128 ) {
36 $coredump = $r & 127;
37 }
38 if( WIFEXITED($r)) {
39 $status = WEXITSTATUS($r);
40 }
41
42 if($coredump || $status) {
43 printf OUTPUT "EXIT CODE %08x: dump:%d code: %d\n", $r, $coredump, $status;
44 } else {
45 printf OUTPUT "EXIT CODE %08x\n", $r;
46 }
47 close(OUTPUT);
48 $r = 0;
49 }
50 if($r == 0) {
51 $r = system "cat tests/NEW/$outputbase | diff $output - >tests/DIFF/$outputbase.diff";
52 $diffstat = WEXITSTATUS($r);
53 }
54
55 # process the file, sanitize "reading from" line, and count lines
56 $linecount = 0;
57 open(ERRORRAW, "<" . $rawstderrlog);
58 open(ERROROUT, ">" . $stderrlog);
59 while(<ERRORRAW>) {
60 next if /^$/; # blank lines are boring
61 if(/^(reading from file )(.*)(,.*)$/) {
62 my $filename = basename($2);
63 print ERROROUT "${1}${filename}${3}\n";
64 next;
65 }
66 print ERROROUT;
67 $linecount++;
68 }
69 close(ERROROUT);
70 close(ERRORRAW);
71
72 if ( -f "$output.stderr" ) {
73 $nr = system "cat $stderrlog | diff $output.stderr - >tests/DIFF/$outputbase.stderr.diff";
74 if($r == 0) {
75 $r = $nr;
76 }
77 $errdiffstat = WEXITSTATUS($nr);
78 }
79
80 if($r == 0) {
81 if($linecount == 0 && $status == 0) {
82 unlink($stderrlog);
83 } else {
84 $errdiffstat = 1;
85 }
86 }
87
88 #print sprintf("END: %08x\n", $r);
89 }
90
91 if($r == 0) {
92 if($linecount == 0) {
93 printf " %-40s: passed\n", $name;
94 } else {
95 printf " %-40s: passed with error messages:\n", $name;
96 system "cat $stderrlog";
97 }
98 unlink "tests/DIFF/$outputbase.diff";
99 return 0;
100 }
101 # must have failed!
102 printf " %-40s: TEST FAILED(exit core=%d/diffstat=%d,%d/r=%d)", $name, $coredump, $diffstat, $errdiffstat, $r;
103 open FOUT, '>>tests/failure-outputs.txt';
104 printf FOUT "\nFailed test: $name\n\n";
105 close FOUT;
106 if(-f "tests/DIFF/$outputbase.diff") {
107 system "cat tests/DIFF/$outputbase.diff >> tests/failure-outputs.txt";
108 }
109
110 if($r == -1) {
111 print " (failed to execute: $!)\n";
112 return(30);
113 }
114
115 # this is not working right, $r == 0x8b00 when there is a core dump.
116 # clearly, we need some platform specific perl magic to take this apart, so look for "core"
117 # too.
118 # In particular, on Solaris 10 SPARC an alignment problem results in SIGILL,
119 # a core dump and $r set to 0x00008a00 ($? == 138 in the shell).
120 if($r & 127 || -f "core") {
121 my $with = ($r & 128) ? 'with' : 'without';
122 if(-f "core") {
123 $with = "with";
124 }
125 printf " (terminated with signal %u, %s coredump)", ($r & 127), $with;
126 if($linecount == 0) {
127 print "\n";
128 } else {
129 print " with error messages:\n";
130 system "cat $stderrlog";
131 }
132 return(($r & 128) ? 10 : 20);
133 }
134 if($linecount == 0) {
135 print "\n";
136 } else {
137 print " with error messages:\n";
138 system "cat $stderrlog";
139 }
140 }
141
142 1;