e22e1400b5b1ecb564dd12f422d2a65b3d2ea71b
[buildd-scripts.git] / bin / analyze_results
1 #! /usr/bin/perl
2
3 # Script to analyze failed build logs. Look for specific regexps to
4 # classify things
5
6 use strict;
7 use warnings;
8
9 my $logs = "/home/build/logs";
10 my $logs_fail = "$logs/FAIL";
11 my $num_fail = 0;
12 my $existing_bugs = 0;
13
14 # Known failure modes to look for
15 my @logcheck = (
16     {
17         # "rchitecture mismatch" -> should never build on this arch
18         # Stop working on this log at this point
19         string   => 'rchitecture mismatch',
20         message  => 'Architecture mismatch',
21         check    => 1,
22         stop     => 1,
23         timeout  => 0, # This is a real error, not a build timeout
24     },
25     {
26         string   => 'not in arch list or does not match any',
27         message  => 'Architecture mismatch',
28         check    => 1,
29         stop     => 1,
30         timeout  => 0, # This is a real error, not a build timeout
31     },
32     {
33         string   => 'No space left on device',
34         message  => 'Build ran out of disk space',
35         check    => 1,
36         stop     => 1,
37         timeout  => 0, # This is a real error, not a build timeout
38     },
39     {
40         string   => 'aarch64-unknown-linux-gnu',
41         message  => 'Wrong arch detected',
42         check    => 1,
43         stop     => 1,
44         timeout  => 0, # This is a real error, not a build timeout
45     },
46     {
47         string   => 'binutils-aarch64',
48         message  => 'Wrong arch detected',
49         check    => 1,
50         stop     => 1,
51         timeout  => 0, # This is a real error, not a build timeout
52     },
53     {
54         string   => 'lib.linux-aarch64',
55         message  => 'Wrong arch detected',
56         check    => 1,
57         stop     => 1,
58         timeout  => 0, # This is a real error, not a build timeout
59     },
60     {
61         # "binary build with no binary artifacts found" -> no packages
62         # built. Why not picked up already above?.
63         # Stop working on this log at this point
64         string   => 'binary build with no binary artifacts found',
65         message  => 'No binaries built',
66         check    => 1,
67         stop     => 1,
68         timeout  => 0, # This is a real error, not a build timeout
69     },
70     {
71         # "Bus error" -> alignment bug
72         string   => 'Bus error',
73         message  => 'Alignment problem',
74         check    => 1,
75         stop     => 1,
76         timeout  => 0, # This is a real error, not a build timeout
77     },
78     {
79         # "Segmentation fault" -> code problem
80         string   => 'Segmentation fault',
81         pstring  => 'Setting up (\S+)',
82         message  => 'Segmentation fault when installing RESULT',
83         check    => 1,
84         stop     => 1,
85         timeout  => 0, # This is a real error, not a build timeout
86     },
87     {
88         # "Segmentation fault" -> code problem
89         string   => 'Segmentation fault',
90         message  => 'Segmentation fault',
91         check    => 1,
92         stop     => 1,
93         timeout  => 0, # This is a real error, not a build timeout
94     },
95     {
96         # "Illegal instruction" -> bad build target?
97         string   => 'Illegal instruction',
98         pstring  => 'Setting up (\S+)',
99         message  => 'Illegal instruction when installing RESULT',
100         check    => 1,
101         stop     => 1,
102         timeout  => 0, # This is a real error, not a build timeout
103     },
104     {
105         # "Illegal instruction" -> bad build target?
106         string   => 'Illegal instruction',
107         message  => 'Illegal instruction',
108         check    => 1,
109         stop     => 1,
110         timeout  => 0, # This is a real error, not a build timeout
111     },
112     {
113         # Installing build-deps failed
114         string   => 'dpkg: error processing package (\S+)',
115         message  => 'Build-dep failed to install (RESULT)',
116         check    => 1,
117         stop     => 0,
118         timeout  => 0, # This is a real error, not a build timeout
119     },
120     {
121         # Installing build-deps failed
122         string   => 'E: pbuilder-satisfydepends failed.',
123         message  => 'Pbuilder build-deps failed',
124         check    => 1,
125         stop     => 1,
126         timeout  => 0, # This is a real error, not a build timeout
127     },
128     {
129         # Installing build-deps failed
130         string   => 'E: Unmet dependencies',
131         message  => 'Build-deps failed',
132         check    => 1,
133         stop     => 1,
134         timeout  => 0, # This is a real error, not a build timeout
135     },
136     {
137         # Installing build-deps failed
138         string   => 'unsat-dependency: (\S+)',
139         message  => 'Missing build-dep (RESULT)',
140         check    => 1,
141         stop     => 1,
142         timeout  => 0, # This is a real error, not a build timeout
143     },
144     {
145         # Build failed - missing build-dep?
146         string   => 'build dependencies/conflicts unsatisfied',
147         message  => 'Build-deps not satisfiable',
148         check    => 1,
149         stop     => 1,
150         timeout  => 0, # This is a real error, not a build timeout
151     },
152     {
153         # Build failed - missing build-dep?
154         string   => 'ld: cannot find',
155         message  => 'Build failure: missing library - missing build-dep?',
156         check    => 1,
157         stop     => 1,
158         timeout  => 0, # This is a real error, not a build timeout
159     },
160     {
161         # Build failed - missing build-dep?
162         string   => 'fatal error:.*No such file or directory',
163         message  => 'Build failure: missing header - missing build-dep?',
164         check    => 1,
165         stop     => 1,
166         timeout  => 0, # This is a real error, not a build timeout
167     },
168     {
169         # Build failed - missing build-dep?
170         string   => 'SEVERE: Cannot resolve dependencies',
171         message  => 'Build failure - missing build-dep?',
172         check    => 1,
173         stop     => 1,
174         timeout  => 0, # This is a real error, not a build timeout
175     },
176     {
177         # Build failed - can't exec something...
178         string   => 'error trying to exec.*execvp: No',
179         message  => 'Build failure (missing binary)',
180         check    => 1,
181         stop     => 1,
182         timeout  => 0, # This is a real error, not a build timeout
183     },
184     {
185         # Build failed
186         string   => 'BUILD FAILED',
187         message  => 'Build failure (java/javadoc))',
188         check    => 1,
189         stop     => 1,
190         timeout  => 0, # This is a real error, not a build timeout
191     },
192     {
193         # Build failed
194         string   => 'make.*returned exit code',
195         message  => 'Build failure (other)',
196         check    => 1,
197         stop     => 0,
198         timeout  => 0, # This is a real error, not a build timeout
199     },
200     {
201         # Build failed
202         string   => '^make.*\*\*\*.* \[debian/rules.*Error \d+$',
203         message  => 'Build failure (other)',
204         check    => 1,
205         stop     => 0,
206         timeout  => 0, # This is a real error, not a build timeout
207     },
208     {
209         # Build failed
210         string   => 'dpkg-source: error: unrepresentable changes to source',
211         message  => 'dpkg-source failure',
212         check    => 1,
213         stop     => 1,
214         timeout  => 0, # This is a real error, not a build timeout
215     },
216     {
217         # Build failed
218         string   => 'fakeroot debian/rules binary',
219         message  => 'Build failure (other)',
220         check    => 0,
221         stop     => 1,
222     },
223     {
224         # Test failure
225         string   => 'OSError: \[Errno 13\] Permission denied',
226         message  => 'Python EPERM test failure',
227         check    => 1,
228         stop     => 1,
229     },
230     {
231         # Test failure
232         string   => 'dh_auto_test:.*returned exit code \d+',
233         message  => 'Test failure',
234         check    => 1,
235         stop     => 1,
236     },
237     {
238         # Timeout. pbuilder is too dumb to do this properly :-(
239         string   => 'I: Terminating build process due to timeout',
240         message  => 'Pbuilder build timeout',
241         check    => 1,
242         stop     => 1,
243         timeout  => 1, # This is a build timeout. If this happened
244                        # before other errors, then we should retry
245     },
246     {
247         # Timeout from sbuild
248         string   => 'Build killed with signal TERM after \d+ minutes of inactivity',
249         message  => 'Sbuild build timeout',
250         check    => 1,
251         stop     => 1,
252         timeout  => 1, # This is a build timeout. If this happened
253                        # before other errors, then we should retry
254     },
255 );
256
257 my %log_results;
258
259 #foreach my $checktmp (@logcheck) {
260 #    my %check = %$checktmp;
261 #    print "looking for \"$check{string}\"\n";
262 #    print "  with log message \"$check{message}\"\n";
263 #    print "  check this regexp: $check{check}\n";
264 #    print "  stop if found: $check{stop}\n";
265 #}
266
267 print "<html>\n";
268 print "<head>\n";
269 print "<title>Build log analysis</title>\n";
270 print "</head>\n";
271 print "<body>\n";
272 print "<h1>Build log analysis</h1>\n";
273 print "<p><a href=\"#summary\">Summary</a></p>\n";
274 print "<h2>Packages</h2>\n";
275 print "<ol>\n";
276
277 foreach my $input (@ARGV) {
278     open (IN, "< $input") or die "Can't read $input: $!\n";
279     $num_fail++;
280     my $stop = 0;
281     my $lineno = 0;
282     my $errors = 0;
283     my $oldline = "";
284     my %file_results;
285     print "<li>Looking at <a href=\"$input\">$input</a>:\n";
286     print "<ul>\n";
287     while (defined (my $line = <IN>) and !$stop) {
288         $lineno++;
289         foreach my $checktmp (@logcheck) {
290             my %check = %$checktmp;
291             if ($check{check}) {
292                 if (!$stop
293                     and ($line =~ m/$check{string}/)
294                     and (!$check{pstring} or $oldline =~ m/$check{pstring}/)) {
295 #                   print "  Line $lineno: found \"$check{string}\"\n";
296                     my $match = $1;
297                     my $message = $check{message};
298                     $message =~ s,RESULT,$match,g;
299                     $file_results{$message} = 1;
300                     if ($check{timeout} and $errors == 0) {
301                         print "  <li>Line $lineno: $message\n";
302                         print "  <li>Build killed by timeout before any errors at line $lineno\n";
303                     } else {
304                         print "  <li>Line $lineno: $message\n";
305                         $errors++;
306                     }
307                     if ($check{stop}) {
308 #                       print "  stopping processing\n";
309                         $stop = 1;
310                     }
311                 }
312             }
313         }
314         $oldline = $line;
315     }
316     close IN;
317     # End of checking this package
318     print "  <li><strong>Found errors: $errors</strong>\n";
319     if (!$errors) {
320         print " (maybe just timed out during build?)\n";
321     }
322
323     # Look for a note for manually-added logfile analysis
324     my $note = $input;
325     $note =~ s,\.log$,.note,;
326     if (-f $note) {
327         open (IN, "< $note") or die "Can't open $note for reading: $!\n";
328         while (defined (my $line = <IN>)) {
329             chomp $line;
330             if ($line =~ m,#(\d+),) {
331                 my $bugno = $1;
332                 $existing_bugs++;
333                 $line =~ s,#(\d+),<a href="https://bugs.debian.org/$1">#$1</a>,g;
334             }
335             print "  <li>$line\n";
336         }
337         close IN;
338     }
339
340     print "</ul>\n";
341     foreach my $key (keys %file_results) {
342         $log_results{$key} += 1;
343 #       print "now have $log_results{$key} for \"$key\"\n";
344     }
345 }
346 print "</ol>\n";
347
348 print "<a name=\"summary\"</a>\n";
349 print "<h2>Summary of results from $num_fail failed builds:</h2>\n";
350 print "<ul>\n";
351 print "<li>Found $existing_bugs existing bugs</li>\n";
352 foreach my $key (sort { $log_results{$b} <=> $log_results{$a} } keys %log_results) {
353     print "  <li>Found $log_results{$key} logs showing $key\n";
354 }
355 print "</ul>\n";
356 print "</body>\n";
357 print "</html>\n";