Bug 453883, ensure true/false marcos are available, r=joshmoz, sr=jst
[wine-gecko.git] / js / tests / known-failures.pl
blob45a229f2f9b30c37346913acf4c5492b358c8cf3
1 #!/usr/bin/perl
2 # -*- Mode: Perl; tab-width: 4; indent-tabs-mode: nil; -*-
4 # ***** BEGIN LICENSE BLOCK *****
5 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 # The contents of this file are subject to the Mozilla Public License Version
8 # 1.1 (the "License"); you may not use this file except in compliance with
9 # the License. You may obtain a copy of the License at
10 # http://www.mozilla.org/MPL/
12 # Software distributed under the License is distributed on an "AS IS" basis,
13 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 # for the specific language governing rights and limitations under the
15 # License.
17 # The Original Code is Mozilla JavaScript Testing Utilities
19 # The Initial Developer of the Original Code is
20 # Mozilla Corporation.
21 # Portions created by the Initial Developer are Copyright (C) 2007
22 # the Initial Developer. All Rights Reserved.
24 # Contributor(s): Bob Clary <bclary@bclary.com>
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
38 # ***** END LICENSE BLOCK *****
40 use strict;
41 use Getopt::Mixed "nextOption";
43 # predeclarations
44 sub debug;
45 sub usage;
46 sub parse_options;
47 sub escape_string;
48 sub escape_pattern;
49 sub unescape_pattern;
51 # option arguments
53 my $option_desc = "b=s branch>b T=s buildtype>T R=s repo>R t=s testtype>t o=s os>o K=s kernel>K A=s arch>A M=s memory>M S=s speed>S z=s timezone>z l=s rawlogfile>l f=s failurelogfile>f r=s patterns>r O=s outputprefix>O D debug>D";
55 my $testid;
56 my $branch;
57 my $repo;
58 my $buildtype;
59 my $testtype;
60 my $rawlogfile;
61 my $failurelogfile;
62 my $os;
63 my $patterns;
64 my $timezone;
65 my $outputprefix;
66 my $arch;
67 my $kernel;
68 my $memory;
69 my $cpuspeed;
70 my $debug = $ENV{DEBUG};
72 # pattern variables
74 my $knownfailurebranchpattern;
75 my $failurebranchpattern;
76 my $knownfailureospattern;
77 my $failureospattern;
78 my $knownfailurerepopattern;
79 my $failurerepopattern;
80 my $knownfailurebuildtypepattern;
81 my $failurebuildtypepattern;
82 my $knownfailuretesttypepattern;
83 my $failuretesttypepattern;
84 my $knownfailuretimezonepattern;
85 my $failuretimezonepattern;
86 my $knownfailurearchpattern;
87 my $failurearchpattern;
88 my $knownfailurekernelpattern;
89 my $failurekernelpattern;
90 my $knownfailurememorypattern;
91 my $failurememorypattern;
92 my $knownfailurecpuspeedpattern;
93 my $failurecpuspeedpattern;
95 my @patterns;
96 my $pattern;
97 my @failures;
98 my @fixes;
99 my @excludedtests;
100 my $excludedtest;
101 my $excludedfile;
102 my %includedtests = {};
103 my $includedfile;
104 my @results;
106 my $regchars = '\[\^\-\]\|\{\}\?\*\+\.\<\>\$\(\)';
109 &parse_options;
111 my $jsdir = $ENV{TEST_JSDIR};
113 if (!defined($jsdir)) {
114 $jsdir = "/work/mozilla/mozilla.com/test.mozilla.com/www/tests/mozilla.org/js";
117 my @excludedfiles = ("excluded-$branch-$testtype-$buildtype.tests");
118 my @includedfiles = ("included-$branch-$testtype-$buildtype.tests");
120 # create working patterns file consisting of matches to users selection
121 # and which has the test description patterns escaped
123 # remove the excluded tests from the possible fixes log
126 foreach $excludedfile ( @excludedfiles ) {
127 open EXCLUDED, "<$jsdir/$excludedfile" or die "Unable to open excluded file $jsdir/$excludedfile: $!\n";
128 while (<EXCLUDED>) {
129 chomp;
131 next if ($_ =~ /^\#/);
133 s/\s+$//;
135 push @excludedtests, ($_);
137 close EXCLUDED;
140 @excludedtests = sort @excludedtests;
142 foreach $includedfile ( @includedfiles ) {
143 open INCLUDED, "<$jsdir/$includedfile" or die "Unable to open included file $jsdir/$includedfile: $!\n";
144 while (<INCLUDED>) {
145 chomp;
147 next if ($_ =~ /^\#/);
149 s/\s+$//;
151 $includedtests{$_} = 1;
153 close INCLUDED;
156 debug "loading patterns $patterns";
157 debug "pattern filter: ^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_REPO=$knownfailurerepopattern, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_MEMORY=$knownfailurememorypattern, TEST_CPUSPEED=$knownfailurecpuspeedpattern, TEST_TIMEZONE=$knownfailuretimezonepattern,";
159 open PATTERNS, "<$patterns" or die "Unable to open known failure patterns file $patterns: $!\n";
160 while (<PATTERNS>) {
161 chomp;
163 s/\s+$//;
165 ($testid) = $_ =~ /^TEST_ID=([^,]*),/;
167 if (!$includedtests{$testid})
169 debug "test $testid was not included during this run";
171 elsif ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$knownfailurebranchpattern, TEST_REPO=$knownfailurerepopattern, TEST_BUILDTYPE=$knownfailurebuildtypepattern, TEST_TYPE=$knownfailuretesttypepattern, TEST_OS=$knownfailureospattern, TEST_KERNEL=$knownfailurekernelpattern, TEST_PROCESSORTYPE=$knownfailurearchpattern, TEST_MEMORY=$knownfailurememorypattern, TEST_CPUSPEED=$knownfailurecpuspeedpattern, TEST_TIMEZONE=$knownfailuretimezonepattern,/) {
172 debug "adding pattern : $_";
173 push @patterns, (escape_pattern($_));
175 else {
176 debug "skipping pattern: $_";
180 close PATTERNS;
182 # create a working copy of the current failures which match the users selection
184 debug "failure filter: ^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_REPO=$failurerepopattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/";
186 if (defined($rawlogfile)) {
188 $failurelogfile = "$outputprefix-results-failures.log";
189 my $alllog = "$outputprefix-results-all.log";
191 debug "writing failures $failurelogfile";
193 open INPUTLOG, "$jsdir/post-process-logs.pl $rawlogfile |" or die "Unable to open $rawlogfile $!\n";
194 open ALLLOG, ">$alllog" or die "Unable to open $alllog $!\n";
195 open FAILURELOG, ">$failurelogfile" or die "Unable to open $failurelogfile $!\n";
197 while (<INPUTLOG>) {
198 chomp;
200 print ALLLOG "$_\n";
202 if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_REPO=$failurerepopattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/) {
203 debug "failure: $_";
204 push @failures, ($_);
205 print FAILURELOG "$_\n";
208 close INPUTLOG;
209 my $inputrc = $?;
210 close ALLLOG;
211 close FAILURELOG;
213 die "FATAL ERROR in post-process-logs.pl" if $inputrc != 0;
215 else
217 debug "loading failures $failurelogfile";
219 my $failurelogfilemode;
221 if ($failurelogfile =~ /\.bz2$/)
223 $failurelogfilemode = "bzcat $failurelogfile|";
225 elsif ($failurelogfile =~ /\.gz$/)
227 $failurelogfilemode = "zcat $failurelogfile|";
229 else
231 $failurelogfilemode = "<$failurelogfile";
234 open FAILURES, "$failurelogfilemode" or die "Unable to open current failure log $failurelogfile: $!\n";
235 while (<FAILURES>) {
236 chomp;
238 if ($_ =~ /^TEST_ID=[^,]*, TEST_BRANCH=$failurebranchpattern, TEST_REPO=$failurerepopattern, TEST_BUILDTYPE=$failurebuildtypepattern, TEST_TYPE=$failuretesttypepattern, TEST_OS=$failureospattern, TEST_KERNEL=$failurekernelpattern, TEST_PROCESSORTYPE=$failurearchpattern, TEST_MEMORY=$failurememorypattern, TEST_CPUSPEED=$failurecpuspeedpattern, TEST_TIMEZONE=$failuretimezonepattern, TEST_RESULT=FAIL[^,]*,/) {
239 debug "failure: $_";
240 push @failures, ($_);
243 close FAILURES;
246 debug "finding fixed bugs";
248 unlink "$outputprefix-results-possible-fixes.log";
250 foreach $pattern (@patterns) {
251 # look for known failure patterns that don't have matches in the
252 # the current failures selected by the user.
254 debug "searching for matches to $pattern\n";
256 @results = grep m@^$pattern@, @failures;
258 if ($debug) {
259 my $failure;
260 foreach $failure (@failures) {
261 if ($failure =~ $pattern) {
262 debug "MATCH: $pattern - $failure\n";
264 else {
265 debug "NOMATCH: $pattern - $failure\n";
269 if ($#results == -1) {
270 debug "fix: '$pattern'";
271 push @fixes, ($pattern)
275 foreach $excludedtest ( @excludedtests ) {
276 # remove any potential fixes which are due to the test being excluded
278 if ($debug) {
279 @results = grep m@$excludedtest@, @fixes;
280 if ($#results > -1) {
281 print "excluding: " . (join ', ', @results) . "\n";
285 @results = grep !m@$excludedtest@, @fixes;
287 @fixes = @results;
290 my $fix;
291 open OUTPUT, ">$outputprefix-results-possible-fixes.log" or die "Unable to open $outputprefix-results-possible-fixes.log: $!";
292 foreach $fix (@fixes) {
293 print OUTPUT unescape_pattern($fix) . "\n";
294 if ($debug) {
295 debug "fix: $fix";
298 close OUTPUT;
300 print STDOUT "log: $outputprefix-results-possible-fixes.log\n";
302 debug "finding regressions";
304 my $pass = 0;
305 my $changed = ($#patterns != -1);
307 debug "changed=$changed, \$#patterns=$#patterns, \$#failures=$#failures";
309 while ($changed) {
311 $pass = $pass + 1;
313 $changed = 0;
315 debug "pass $pass";
317 foreach $pattern (@patterns) {
319 debug "Pattern: $pattern";
321 my @nomatches = grep !m@^$pattern@, @failures;
322 my @matches = grep m@^$pattern@, @failures;
324 if ($debug) {
325 my $temp = join ', ', @nomatches;
326 debug "nomatches: $#nomatches $temp";
327 $temp = join ', ', @matches;
328 debug "matches: $#matches $temp";
331 @failures = @nomatches;
333 if ($#matches > -1) {
334 $changed = 1;
337 debug "*****************************************";
342 debug "\$#excludedtests=$#excludedtests, \$#failures=$#failures";
344 foreach $excludedtest ( @excludedtests ) {
346 if ($debug) {
347 @results = grep m@$excludedtest@, @failures;
348 if ($#results > -1) {
349 print "excluding: " . (join ', ', @results) . "\n";
353 @results = grep !m@$excludedtest@, @failures;
355 debug "\$#results=$#results, \$excludedtest=$excludedtest, \$#failures=$#failures";
357 @failures = @results;
360 debug "possible regressions: \$#failures=$#failures";
362 open OUTPUT, ">$outputprefix-results-possible-regressions.log" or die "Unable to open $outputprefix-results-possible-regressions.log: $!";
364 my $failure;
365 foreach $failure (@failures) {
366 print OUTPUT "$failure\n";
367 if ($debug) {
368 debug "regression: $failure";
371 close OUTPUT;
373 print STDOUT "log: $outputprefix-results-possible-regressions.log\n";
376 sub debug {
377 if ($debug) {
378 my $msg = shift;
379 print STDERR "DEBUG: $msg\n";
383 sub usage {
385 my $msg = shift;
387 print STDERR <<EOF;
389 usage: $msg
391 known-failures.pl [-b|--branch] branch
392 [-T|--buildtype] buildtype
393 [-t|--testtype] testtype
394 [-o|--os] os
395 [-K|--kernel] kernel
396 [-A|--arch] arch
397 [-M|--memory] memory
398 [-S|--speed] speed
399 [-z|--timezone] timezone
400 [-r|--patterns] patterns
401 ([-f|--failurelogfile] failurelogfile|[-l|--logfile] rawlogfile])
402 [-O|--outputprefix] outputprefix
403 [-D]
405 variable description
406 =============== ============================================================
407 -b branch branch 1.8.0, 1.8.1, 1.9.0, all
408 -R repository CVS for 1.8.0, 1.8.1, 1.9.0 branches,
409 mercurial repository name for 1.9.1 branches
410 (\`basename http://hg.mozilla.org/repository\`)
411 -T buildtype build type opt, debug, all
412 -t testtype test type browser, shell, all
413 -o os operating system nt, darwin, linux, all
414 -K kernel kernel, all or a specific pattern
415 -A arch architecture, all or a specific pattern
416 -M memory memory in Gigabytes, all or a specific pattern
417 -S speed speed, all or specific pattern
418 -z timezone -0400, -0700, etc. default to user\'s zone
419 -l rawlogfile raw logfile
420 -f failurelogfile failure logfile
421 -r patterns known failure patterns
422 -O outputprefix output files will be generated with this prefix
423 -D turn on debugging output
426 exit(2);
429 sub parse_options {
430 my ($option, $value);
432 Getopt::Mixed::init ($option_desc);
433 $Getopt::Mixed::order = $Getopt::Mixed::RETURN_IN_ORDER;
435 while (($option, $value) = nextOption()) {
437 if ($option eq "b") {
438 $branch = $value;
440 elsif ($option eq "R") {
441 $repo = $value;
443 elsif ($option eq "T") {
444 $buildtype = $value;
446 elsif ($option eq "t") {
447 $testtype = $value;
449 elsif ($option eq "o") {
450 $os = $value;
452 elsif ($option eq "K") {
453 $kernel = $value;
455 elsif ($option eq "A") {
456 $arch = $value;
458 elsif ($option eq "M") {
459 $memory = $value;
461 elsif ($option eq "S") {
462 $cpuspeed = $value;
463 if ($cpuspeed < 4)
465 $cpuspeed = 'slow';
467 elsif ($cpuspeed < 9)
469 $cpuspeed = 'medium';
471 else
473 $cpuspeed = 'fast';
476 elsif ($option eq "z") {
477 $timezone = $value;
479 elsif ($option eq "r") {
480 $patterns = $value;
482 elsif ($option eq "l") {
483 $rawlogfile = $value;
485 elsif ($option eq "f") {
486 $failurelogfile = $value;
488 elsif ($option eq "O") {
489 $outputprefix = $value;
491 elsif ($option eq "D") {
492 $debug = 1;
497 if ($debug) {
498 print "branch=$branch, buildtype=$buildtype, testtype=$testtype, os=$os, kernel=$kernel, arch=$arch, memory=$memory, cpuspeed=$cpuspeed, timezone=$timezone, patterns=$patterns, rawlogfile=$rawlogfile failurelogfile=$failurelogfile, outputprefix=$outputprefix\n";
500 Getopt::Mixed::cleanup();
502 if ( !defined($branch) ) {
503 usage "missing branch";
506 if (!defined($buildtype)) {
507 usage "missing buildtype";
510 if (!defined($testtype)) {
511 usage "missing testtype";
514 if (!defined($os)) {
515 usage "missing os";
518 if (!defined($memory)) {
519 $memory = 'all';
522 if (!defined($cpuspeed)) {
523 $cpuspeed = 'all';
526 if (!defined($timezone)) {
527 usage "missing timezone";
530 if (!defined($patterns)) {
531 usage "missing patterns";
534 if (!defined($rawlogfile) && !defined($failurelogfile)) {
535 usage "missing logfile";
538 if (!defined($outputprefix)) {
539 usage "missing outputprefix";
542 if ($branch eq "1.8.0") {
543 $knownfailurebranchpattern = "(1\\.8\\.0|\\.\\*)";
544 $failurebranchpattern = "1\\.8\\.0";
546 elsif ($branch eq "1.8.1") {
547 $knownfailurebranchpattern = "(1\\.8\\.1|\\.\\*)";
548 $failurebranchpattern = "1\\.8\\.1";
550 elsif ($branch eq "1.9.0") {
551 $knownfailurebranchpattern = "(1\\.9\\.0|\\.\\*)";
552 $failurebranchpattern = "1\\.9\\.0";
554 elsif ($branch eq "1.9.1") {
555 $knownfailurebranchpattern = "(1\\.9\\.1|\\.\\*)";
556 $failurebranchpattern = "1\\.9\\.1";
558 elsif ($branch eq "all") {
559 $knownfailurebranchpattern = "[^,]*";
560 $failurebranchpattern = "[^,]*";
563 if ($repo eq "all" || $repo eq ".*") {
564 $knownfailurerepopattern = "[^,]*";
565 $failurerepopattern = "[^,]*";
567 else {
568 $knownfailurerepopattern = "($repo|\\.\\*)";
569 $failurerepopattern = "$repo";
572 if ($buildtype eq "opt") {
573 $knownfailurebuildtypepattern = "(opt|\\.\\*)";
574 $failurebuildtypepattern = "opt";
576 elsif ($buildtype eq "debug") {
577 $knownfailurebuildtypepattern = "(debug|\\.\\*)";
578 $failurebuildtypepattern = "debug";
580 elsif ($buildtype eq "all") {
581 $knownfailurebuildtypepattern = "[^,]*";
582 $failurebuildtypepattern = "[^,]*";
585 if ($testtype eq "shell") {
586 $knownfailuretesttypepattern = "(shell|\\.\\*)";
587 $failuretesttypepattern = "shell";
589 elsif ($testtype eq "browser") {
590 $knownfailuretesttypepattern = "(browser|\\.\\*)";
591 $failuretesttypepattern = "browser";
593 elsif ($testtype eq "all") {
594 $knownfailuretesttypepattern = "[^,]*";
595 $failuretesttypepattern = "[^,]*";
598 if ($os eq "nt") {
599 $knownfailureospattern = "(nt|\\.\\*)";
600 $failureospattern = "nt";
602 elsif ($os eq "darwin") {
603 $knownfailureospattern = "(darwin|\\.\\*)";
604 $failureospattern = "darwin";
606 elsif ($os eq "linux") {
607 $knownfailureospattern = "(linux|\\.\\*)";
608 $failureospattern = "linux";
610 elsif ($os eq "all") {
611 $knownfailureospattern = "[^,]*";
612 $failureospattern = "[^,]*";
615 if ($kernel ne "all") {
616 $knownfailurekernelpattern = "(" . $kernel . "|\\.\\*)";
617 $failurekernelpattern = "$kernel";
619 else {
620 $knownfailurekernelpattern = "[^,]*";
621 $failurekernelpattern = "[^,]*";
624 if ($arch ne "all") {
625 $knownfailurearchpattern = "(" . $arch . "|\\.\\*)";
626 $failurearchpattern = "$arch";
628 else {
629 $knownfailurearchpattern = "[^,]*";
630 $failurearchpattern = "[^,]*";
633 if ($memory ne "all") {
634 $knownfailurememorypattern = "(" . $memory . "|\\.\\*)";
635 $failurememorypattern = "$memory";
637 else {
638 $knownfailurememorypattern = "[^,]*";
639 $failurememorypattern = "[^,]*";
642 if ($cpuspeed ne "all") {
643 $knownfailurecpuspeedpattern = "(" . $cpuspeed . "|\\.\\*)";
644 $failurecpuspeedpattern = "$cpuspeed";
646 else {
647 $knownfailurecpuspeedpattern = "[^,]*";
648 $failurecpuspeedpattern = "[^,]*";
651 if ($timezone eq "all") {
652 $knownfailuretimezonepattern = "[^,]*";
653 $failuretimezonepattern = "[^,]*";
655 else {
656 $knownfailuretimezonepattern = "(" . escape_string($timezone) . "|\\.\\*)";
657 $failuretimezonepattern = escape_string("$timezone");
663 sub escape_string {
664 my $s = shift;
666 # replace unescaped regular expression characters in the
667 # string so they are not interpreted as regexp chars
668 # when matching descriptions. leave the escaped regexp chars
669 # `regexp` alone so they can be unescaped later and used in
670 # pattern matching.
672 # see perldoc perlre
674 $s =~ s/\\/\\\\/g;
676 # escape non word chars that aren't surrounded by ``
677 $s =~ s/(?<!`)([$regchars])(?!`)/\\$1/g;
678 $s =~ s/(?<!`)([$regchars])(?=`)/\\$1/g;
679 $s =~ s/(?<=`)([$regchars])(?!`)/\\$1/g;
681 # unquote the regchars
682 $s =~ s/\`([^\`])\`/$1/g;
684 debug "escape_string : $s";
686 return "$s";
690 sub escape_pattern {
692 my $line = shift;
694 chomp;
696 my ($leading, $trailing) = $line =~ /(.*TEST_DESCRIPTION=)(.*)/;
698 # debug "escape_pattern: before: $leading$trailing";
700 $trailing = escape_string($trailing);
702 debug "escape_pattern : $leading$trailing";
704 return "$leading$trailing";
708 sub unescape_pattern {
709 my $line = shift;
711 chomp;
713 my ($leading, $trailing) = $line =~ /(.*TEST_DESCRIPTION=)(.*)/;
715 # quote the unescaped non word chars
716 $trailing =~ s/(?<!\\)([$regchars])/`$1`/g;
718 # unescape the escaped non word chars
719 $trailing =~ s/\\([$regchars])/$1/g;
721 $trailing =~ s/\\\\/\\/g;
723 debug "unescape_pattern: after: $leading$trailing";
725 return "$leading$trailing";
728 ####