|
25 | 25 | # Analyzes test log files to determine: |
26 | 26 | # 1. Overall test status (pass/fail) |
27 | 27 | # 2. Total number of tests run |
28 | | -# 3. Number of passed and failed tests |
29 | | -# 4. Names of failed tests |
| 28 | +# 3. Number of passed, failed, and ignored tests |
| 29 | +# 4. Names of failed and ignored tests |
| 30 | +# 5. Validates test counts for consistency |
30 | 31 | # Results are written to a file for shell script processing. |
31 | 32 | # |
32 | 33 | # Arguments: |
33 | 34 | # log-file Path to test log file (required) |
34 | 35 | # |
35 | 36 | # Input File Format: |
36 | | -# Expects test log files containing either: |
| 37 | +# Expects test log files containing one of the following summary formats: |
37 | 38 | # - "All X tests passed." |
38 | 39 | # - "Y of X tests failed." |
39 | | -# And failed test entries in format: |
| 40 | +# - "X of Y tests passed, Z failed test(s) ignored." |
| 41 | +# - "X of Y tests failed, Z of these failures ignored." |
| 42 | +# |
| 43 | +# And failed or ignored test entries in format: |
40 | 44 | # - "test_name ... FAILED" |
| 45 | +# - "test_name ... failed (ignored)" |
41 | 46 | # |
42 | 47 | # Output File (test_results.txt): |
43 | 48 | # Environment variable format: |
44 | 49 | # STATUS=passed|failed |
45 | 50 | # TOTAL_TESTS=<number> |
46 | 51 | # FAILED_TESTS=<number> |
47 | 52 | # PASSED_TESTS=<number> |
| 53 | +# IGNORED_TESTS=<number> |
48 | 54 | # FAILED_TEST_NAMES=<comma-separated-list> |
| 55 | +# IGNORED_TEST_NAMES=<comma-separated-list> |
49 | 56 | # |
50 | 57 | # Prerequisites: |
51 | 58 | # - Read access to input log file |
52 | 59 | # - Write access to current directory |
53 | 60 | # - Perl 5.x or higher |
54 | 61 | # |
55 | 62 | # Exit Codes: |
56 | | -# 0 - All tests passed |
57 | | -# 1 - Some tests failed (expected failure) |
| 63 | +# 0 - All tests passed, or only ignored failures occurred |
| 64 | +# 1 - Some non-ignored tests failed |
58 | 65 | # 2 - Parse error or cannot access files |
59 | 66 | # |
60 | 67 | # Example Usage: |
61 | 68 | # ./parse_results.pl test_output.log |
62 | 69 | # |
63 | 70 | # Error Handling: |
64 | 71 | # - Validates input file existence and readability |
65 | | -# - Verifies failed test count matches found failures |
| 72 | +# - Verifies failed and ignored test counts match found entries |
66 | 73 | # - Reports parsing errors with detailed messages |
67 | 74 | # |
68 | 75 | # -------------------------------------------------------------------- |
|
97 | 104 | exit PARSE_ERROR; |
98 | 105 | }; |
99 | 106 |
|
100 | | -my ($status, $total_tests, $failed_tests, $passed_tests); |
| 107 | +# Initialize variables |
| 108 | +my ($status, $total_tests, $failed_tests, $ignored_tests, $passed_tests) = ('', 0, 0, 0, 0); |
101 | 109 | my @failed_test_list = (); |
| 110 | +my @ignored_test_list = (); |
102 | 111 |
|
103 | 112 | while (<$fh>) { |
104 | 113 | # Match the summary lines |
105 | 114 | if (/All (\d+) tests passed\./) { |
106 | 115 | $status = 'passed'; |
107 | 116 | $total_tests = $1; |
108 | | - $failed_tests = 0; |
109 | 117 | $passed_tests = $1; |
110 | 118 | } |
| 119 | + elsif (/(\d+) of (\d+) tests passed, (\d+) failed test\(s\) ignored\./) { |
| 120 | + $status = 'passed'; |
| 121 | + $passed_tests = $1; |
| 122 | + $total_tests = $2; |
| 123 | + $ignored_tests = $3; |
| 124 | + } |
111 | 125 | elsif (/(\d+) of (\d+) tests failed\./) { |
112 | 126 | $status = 'failed'; |
113 | 127 | $failed_tests = $1; |
114 | 128 | $total_tests = $2; |
115 | 129 | $passed_tests = $2 - $1; |
116 | 130 | } |
| 131 | + elsif (/(\d+) of (\d+) tests failed, (\d+) of these failures ignored\./) { |
| 132 | + $status = 'failed'; |
| 133 | + $failed_tests = $1 - $3; |
| 134 | + $ignored_tests = $3; |
| 135 | + $total_tests = $2; |
| 136 | + $passed_tests = $2 - $1; |
| 137 | + } |
117 | 138 |
|
118 | 139 | # Capture failed tests |
119 | 140 | if (/^(?:\s+|test\s+)(\S+)\s+\.\.\.\s+FAILED\s+/) { |
120 | 141 | push @failed_test_list, $1; |
121 | 142 | } |
122 | | -} |
123 | | -close($fh); |
124 | 143 |
|
125 | | -unless (defined $status) { |
126 | | - print "Error: Could not find test summary in $file\n"; |
127 | | - exit PARSE_ERROR; |
| 144 | + # Capture ignored tests |
| 145 | + if (/^(?:\s+|test\s+)(\S+)\s+\.\.\.\s+failed \(ignored\)/) { |
| 146 | + push @ignored_test_list, $1; |
| 147 | + } |
128 | 148 | } |
129 | 149 |
|
| 150 | +# Close the log file |
| 151 | +close $fh; |
| 152 | + |
130 | 153 | # Validate failed test count matches found test names |
131 | 154 | if ($status eq 'failed' && scalar(@failed_test_list) != $failed_tests) { |
132 | 155 | print "Error: Found $failed_tests failed tests in summary but found " . scalar(@failed_test_list) . " failed test names\n"; |
|
137 | 160 | exit PARSE_ERROR; |
138 | 161 | } |
139 | 162 |
|
140 | | -# Write results to file |
141 | | -open(my $out, '>', 'test_results.txt') or do { |
142 | | - print "Cannot write results: $!\n"; |
| 163 | +# Validate ignored test count matches found test names |
| 164 | +if ($ignored_tests != scalar(@ignored_test_list)) { |
| 165 | + print "Error: Found $ignored_tests ignored tests in summary but found " . scalar(@ignored_test_list) . " ignored test names\n"; |
| 166 | + print "Ignored test names found:\n"; |
| 167 | + foreach my $test (@ignored_test_list) { |
| 168 | + print " - $test\n"; |
| 169 | + } |
143 | 170 | exit PARSE_ERROR; |
144 | | -}; |
| 171 | +} |
145 | 172 |
|
146 | | -print $out "STATUS=$status\n"; |
147 | | -print $out "TOTAL_TESTS=$total_tests\n"; |
148 | | -print $out "FAILED_TESTS=$failed_tests\n"; |
149 | | -print $out "PASSED_TESTS=$passed_tests\n"; |
| 173 | +# Write results to the results file |
| 174 | +open my $result_fh, '>', 'test_results.txt' or die "Cannot write to results file: $!\n"; |
| 175 | +print $result_fh "STATUS=$status\n"; |
| 176 | +print $result_fh "TOTAL_TESTS=$total_tests\n"; |
| 177 | +print $result_fh "PASSED_TESTS=$passed_tests\n"; |
| 178 | +print $result_fh "FAILED_TESTS=$failed_tests\n"; |
| 179 | +print $result_fh "IGNORED_TESTS=$ignored_tests\n"; |
150 | 180 | if (@failed_test_list) { |
151 | | - print $out "FAILED_TEST_NAMES=" . join(",", @failed_test_list) . "\n"; |
| 181 | + print $result_fh "FAILED_TEST_NAMES=" . join(',', @failed_test_list) . "\n"; |
| 182 | +} |
| 183 | +if (@ignored_test_list) { |
| 184 | + print $result_fh "IGNORED_TEST_NAMES=" . join(',', @ignored_test_list) . "\n"; |
152 | 185 | } |
153 | | -close($out); |
| 186 | +close $result_fh; |
154 | 187 |
|
155 | 188 | # Print to stdout for logging |
156 | 189 | print "Test Results:\n"; |
157 | 190 | print "Status: $status\n"; |
158 | 191 | print "Total Tests: $total_tests\n"; |
159 | 192 | print "Failed Tests: $failed_tests\n"; |
| 193 | +print "Ignored Tests: $ignored_tests\n"; |
160 | 194 | print "Passed Tests: $passed_tests\n"; |
161 | 195 | if (@failed_test_list) { |
162 | 196 | print "Failed Test Names:\n"; |
163 | 197 | foreach my $test (@failed_test_list) { |
164 | 198 | print " - $test\n"; |
165 | 199 | } |
166 | 200 | } |
| 201 | +if (@ignored_test_list) { |
| 202 | + print "Ignored Test Names:\n"; |
| 203 | + foreach my $test (@ignored_test_list) { |
| 204 | + print " - $test\n"; |
| 205 | + } |
| 206 | +} |
167 | 207 |
|
168 | 208 | # Exit with appropriate code |
169 | 209 | if ($status eq 'passed') { |
|
0 commit comments