Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: Tools/Scripts/bisect-builds

Issue 25892005: Remove some unused scripts from Tools/Scripts/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Tools/Scripts/check-for-inappropriate-files-in-framework » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 #
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 # its contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 # This script attempts to find the point at which a regression (or progression)
30 # of behavior occurred by searching WebKit nightly builds.
31
32 # To override the location where the nightly builds are downloaded or the path
33 # to the Safari web browser, create a ~/.bisect-buildsrc file with one or more o f
34 # the following lines (use "~/" to specify a path from your home directory):
35 #
36 # $branch = "branch-name";
37 # $nightlyDownloadDirectory = "~/path/to/nightly/downloads";
38 # $safariPath = "/path/to/Safari.app";
39
40 use strict;
41
42 use File::Basename;
43 use File::Path;
44 use File::Spec;
45 use File::Temp qw(tempfile);
46 use FindBin;
47 use Getopt::Long;
48 use Time::HiRes qw(usleep);
49
50 use lib $FindBin::Bin;
51 use webkitdirs qw(safariPathFromSafariBundle);
52
53 sub createTempFile($);
54 sub downloadNightly($$$);
55 sub findMacOSXVersion();
56 sub findNearestNightlyIndex(\@$$);
57 sub findSafariVersion($);
58 sub loadSettings();
59 sub makeNightlyList($$$$);
60 sub max($$) { return $_[0] > $_[1] ? $_[0] : $_[1]; }
61 sub mountAndRunNightly($$$$);
62 sub parseRevisions($$;$);
63 sub printStatus($$$);
64 sub printTracLink($$);
65 sub promptForTest($);
66
67 loadSettings();
68
69 my %validBranches = map { $_ => 1 } qw(feature-branch trunk);
70 my $branch = $Settings::branch;
71 my $nightlyDownloadDirectory = $Settings::nightlyDownloadDirectory;
72 my $safariPath = $Settings::safariPath;
73
74 my @nightlies;
75
76 my $isProgression;
77 my $localOnly;
78 my @revisions;
79 my $sanityCheck;
80 my $showHelp;
81 my $testURL;
82
83 # Fix up -r switches in @ARGV
84 @ARGV = map { /^(-r)(.+)$/ ? ($1, $2) : $_ } @ARGV;
85
86 my $result = GetOptions(
87 "b|branch=s" => \$branch,
88 "d|download-directory=s" => \$nightlyDownloadDirectory,
89 "h|help" => \$showHelp,
90 "l|local!" => \$localOnly,
91 "p|progression!" => \$isProgression,
92 "r|revisions=s" => \&parseRevisions,
93 "safari-path=s" => \$safariPath,
94 "s|sanity-check!" => \$sanityCheck,
95 );
96 $testURL = shift @ARGV;
97
98 $branch = "feature-branch" if $branch eq "feature";
99 if (!exists $validBranches{$branch}) {
100 print STDERR "ERROR: Invalid branch '$branch'\n";
101 $showHelp = 1;
102 }
103
104 if (!$result || $showHelp || scalar(@ARGV) > 0) {
105 print STDERR "Search WebKit nightly builds for changes in behavior.\n";
106 print STDERR "Usage: " . basename($0) . " [options] [url]\n";
107 print STDERR <<END;
108 [-b|--branch name] name of the nightly build branch (default: trun k)
109 [-d|--download-directory dir] nightly build download directory (default: ~/Li brary/Caches/WebKit-Nightlies)
110 [-h|--help] show this help message
111 [-l|--local] only use local (already downloaded) nightlies
112 [-p|--progression] searching for a progression, not a regression
113 [-r|--revision M[:N]] specify starting (and optional ending) revision s to search
114 [--safari-path path] path to Safari application bundle (default: /Ap plications/Safari.app)
115 [-s|--sanity-check] verify both starting and ending revisions befor e bisecting
116 END
117 exit 1;
118 }
119
120 my $nightlyWebSite = "http://nightly.webkit.org";
121 my $nightlyBuildsURLBase = $nightlyWebSite . File::Spec->catdir("/builds", $bran ch, "mac");
122 my $nightlyFilesURLBase = $nightlyWebSite . File::Spec->catdir("/files", $branch , "mac");
123
124 $nightlyDownloadDirectory = glob($nightlyDownloadDirectory) if $nightlyDownloadD irectory =~ /^~/;
125 $safariPath = glob($safariPath) if $safariPath =~ /^~/;
126 $safariPath = safariPathFromSafariBundle($safariPath) if $safariPath =~ m#\.app/ *#;
127
128 $nightlyDownloadDirectory = File::Spec->catdir($nightlyDownloadDirectory, $branc h);
129 if (! -d $nightlyDownloadDirectory) {
130 mkpath($nightlyDownloadDirectory, 0, 0755) || die "Could not create $nightly DownloadDirectory: $!";
131 }
132
133 @nightlies = makeNightlyList($localOnly, $nightlyDownloadDirectory, findMacOSXVe rsion(), findSafariVersion($safariPath));
134
135 my $startIndex = $revisions[0] ? findNearestNightlyIndex(@nightlies, $revisions[ 0], 'ceil') : 0;
136 my $endIndex = $revisions[1] ? findNearestNightlyIndex(@nightlies, $revisions[1] , 'floor') : $#nightlies;
137
138 my $tempFile = createTempFile($testURL);
139
140 if ($sanityCheck) {
141 my $didReproduceBug;
142
143 do {
144 printf "\nChecking starting revision r%s...\n",
145 $nightlies[$startIndex]->{rev};
146 downloadNightly($nightlies[$startIndex]->{file}, $nightlyFilesURLBase, $ nightlyDownloadDirectory);
147 mountAndRunNightly($nightlies[$startIndex]->{file}, $nightlyDownloadDire ctory, $safariPath, $tempFile);
148 $didReproduceBug = promptForTest($nightlies[$startIndex]->{rev});
149 $startIndex-- if $didReproduceBug < 0;
150 } while ($didReproduceBug < 0);
151 die "ERROR: Bug reproduced in starting revision! Do you need to test an ear lier revision or for a progression?"
152 if $didReproduceBug && !$isProgression;
153 die "ERROR: Bug not reproduced in starting revision! Do you need to test an earlier revision or for a regression?"
154 if !$didReproduceBug && $isProgression;
155
156 do {
157 printf "\nChecking ending revision r%s...\n",
158 $nightlies[$endIndex]->{rev};
159 downloadNightly($nightlies[$endIndex]->{file}, $nightlyFilesURLBase, $ni ghtlyDownloadDirectory);
160 mountAndRunNightly($nightlies[$endIndex]->{file}, $nightlyDownloadDirect ory, $safariPath, $tempFile);
161 $didReproduceBug = promptForTest($nightlies[$endIndex]->{rev});
162 $endIndex++ if $didReproduceBug < 0;
163 } while ($didReproduceBug < 0);
164 die "ERROR: Bug NOT reproduced in ending revision! Do you need to test a la ter revision or for a progression?"
165 if !$didReproduceBug && !$isProgression;
166 die "ERROR: Bug reproduced in ending revision! Do you need to test a later revision or for a regression?"
167 if $didReproduceBug && $isProgression;
168 }
169
170 printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $isPro gression);
171
172 my %brokenRevisions = ();
173 while (abs($endIndex - $startIndex) > 1) {
174 my $index = $startIndex + int(($endIndex - $startIndex) / 2);
175
176 my $didReproduceBug;
177 do {
178 if (exists $nightlies[$index]) {
179 my $buildsLeft = max(max(0, $endIndex - $index - 1), max(0, $index - $startIndex - 1));
180 my $plural = $buildsLeft == 1 ? "" : "s";
181 printf "\nChecking revision r%s (%d build%s left to test after this) ...\n", $nightlies[$index]->{rev}, $buildsLeft, $plural;
182 downloadNightly($nightlies[$index]->{file}, $nightlyFilesURLBase, $n ightlyDownloadDirectory);
183 mountAndRunNightly($nightlies[$index]->{file}, $nightlyDownloadDirec tory, $safariPath, $tempFile);
184 $didReproduceBug = promptForTest($nightlies[$index]->{rev});
185 }
186 if ($didReproduceBug < 0) {
187 $brokenRevisions{$nightlies[$index]->{rev}} = $nightlies[$index]->{f ile};
188 delete $nightlies[$index];
189 $endIndex--;
190 $index = $startIndex + int(($endIndex - $startIndex) / 2);
191 }
192 } while ($didReproduceBug < 0);
193
194 if ($didReproduceBug && !$isProgression || !$didReproduceBug && $isProgressi on) {
195 $endIndex = $index;
196 } else {
197 $startIndex = $index;
198 }
199
200 print "\nBroken revisions skipped: r" . join(", r", keys %brokenRevisions) . "\n"
201 if scalar keys %brokenRevisions > 0;
202 printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $i sProgression);
203 }
204
205 printTracLink($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev});
206
207 unlink $tempFile if $tempFile;
208
209 exit 0;
210
211 sub createTempFile($)
212 {
213 my ($url) = @_;
214
215 return undef if !$url;
216
217 my ($fh, $tempFile) = tempfile(
218 basename($0) . "-XXXXXXXX",
219 DIR => File::Spec->tmpdir(),
220 SUFFIX => ".html",
221 UNLINK => 0,
222 );
223 print $fh "<meta http-equiv=\"refresh\" content=\"0; $url\">\n";
224 close($fh);
225
226 return $tempFile;
227 }
228
229 sub downloadNightly($$$)
230 {
231 my ($filename, $urlBase, $directory) = @_;
232 my $path = File::Spec->catfile($directory, $filename);
233 if (! -f $path) {
234 print "Downloading $filename to $directory...\n";
235 `curl -# -o '$path' '$urlBase/$filename'`;
236 }
237 }
238
239 sub findMacOSXVersion()
240 {
241 my $version;
242 open(SW_VERS, "-|", "/usr/bin/sw_vers") || die;
243 while (<SW_VERS>) {
244 $version = $1 if /^ProductVersion:\s+([^\s]+)/;
245 }
246 close(SW_VERS);
247 return $version;
248 }
249
250 sub findNearestNightlyIndex(\@$$)
251 {
252 my ($nightlies, $revision, $round) = @_;
253
254 my $lowIndex = 0;
255 my $highIndex = $#{$nightlies};
256
257 return $highIndex if uc($revision) eq 'HEAD' || $revision >= $nightlies->[$h ighIndex]->{rev};
258 return $lowIndex if $revision <= $nightlies->[$lowIndex]->{rev};
259
260 while (abs($highIndex - $lowIndex) > 1) {
261 my $index = $lowIndex + int(($highIndex - $lowIndex) / 2);
262 if ($revision < $nightlies->[$index]->{rev}) {
263 $highIndex = $index;
264 } elsif ($revision > $nightlies->[$index]->{rev}) {
265 $lowIndex = $index;
266 } else {
267 return $index;
268 }
269 }
270
271 return ($round eq "floor") ? $lowIndex : $highIndex;
272 }
273
274 sub findSafariVersion($)
275 {
276 my ($path) = @_;
277 my $versionPlist = File::Spec->catdir(dirname(dirname($path)), "version.plis t");
278 my $version;
279 open(PLIST, "< $versionPlist") || die;
280 while (<PLIST>) {
281 if (m#^\s*<key>CFBundleShortVersionString</key>#) {
282 $version = <PLIST>;
283 $version =~ s#^\s*<string>([0-9.]+)[^<]*</string>\s*[\r\n]*#$1#;
284 }
285 }
286 close(PLIST);
287 return $version;
288 }
289
290 sub loadSettings()
291 {
292 package Settings;
293
294 our $branch = "trunk";
295 our $nightlyDownloadDirectory = File::Spec->catdir($ENV{HOME}, "Library/Cach es/WebKit-Nightlies");
296 our $safariPath = "/Applications/Safari.app";
297
298 my $rcfile = File::Spec->catdir($ENV{HOME}, ".bisect-buildsrc");
299 return if !-f $rcfile;
300
301 my $result = do $rcfile;
302 die "Could not parse $rcfile: $@" if $@;
303 }
304
305 sub makeNightlyList($$$$)
306 {
307 my ($useLocalFiles, $localDirectory, $macOSXVersion, $safariVersion) = @_;
308 my @files;
309
310 if ($useLocalFiles) {
311 opendir(DIR, $localDirectory) || die "$!";
312 foreach my $file (readdir(DIR)) {
313 if ($file =~ /^WebKit-SVN-r([0-9]+)\.dmg$/) {
314 push(@files, +{ rev => $1, file => $file });
315 }
316 }
317 closedir(DIR);
318 } else {
319 open(NIGHTLIES, "curl -s $nightlyBuildsURLBase/all |") || die;
320
321 while (my $line = <NIGHTLIES>) {
322 chomp $line;
323 my ($revision, $timestamp, $url) = split(/,/, $line);
324 my $nightly = basename($url);
325 push(@files, +{ rev => $revision, file => $nightly });
326 }
327 close(NIGHTLIES);
328 }
329
330 if (eval "v$macOSXVersion" ge v10.5) {
331 if ($safariVersion eq "4 Public Beta") {
332 @files = grep { $_->{rev} >= 39682 } @files;
333 } elsif (eval "v$safariVersion" ge v3.2) {
334 @files = grep { $_->{rev} >= 37348 } @files;
335 } elsif (eval "v$safariVersion" ge v3.1) {
336 @files = grep { $_->{rev} >= 29711 } @files;
337 } elsif (eval "v$safariVersion" ge v3.0) {
338 @files = grep { $_->{rev} >= 25124 } @files;
339 } elsif (eval "v$safariVersion" ge v2.0) {
340 @files = grep { $_->{rev} >= 19594 } @files;
341 } else {
342 die "Requires Safari 2.0 or newer";
343 }
344 } elsif (eval "v$macOSXVersion" ge v10.4) {
345 if ($safariVersion eq "4 Public Beta") {
346 @files = grep { $_->{rev} >= 39682 } @files;
347 } elsif (eval "v$safariVersion" ge v3.2) {
348 @files = grep { $_->{rev} >= 37348 } @files;
349 } elsif (eval "v$safariVersion" ge v3.1) {
350 @files = grep { $_->{rev} >= 29711 } @files;
351 } elsif (eval "v$safariVersion" ge v3.0) {
352 @files = grep { $_->{rev} >= 19992 } @files;
353 } elsif (eval "v$safariVersion" ge v2.0) {
354 @files = grep { $_->{rev} >= 11976 } @files;
355 } else {
356 die "Requires Safari 2.0 or newer";
357 }
358 } else {
359 die "Requires Mac OS X 10.4 (Tiger) or 10.5 (Leopard)";
360 }
361
362 my $nightlycmp = sub { return $a->{rev} <=> $b->{rev}; };
363
364 return sort $nightlycmp @files;
365 }
366
367 sub mountAndRunNightly($$$$)
368 {
369 my ($filename, $directory, $safari, $tempFile) = @_;
370 my $mountPath = "/Volumes/WebKit";
371 my $webkitApp = File::Spec->catfile($mountPath, "WebKit.app");
372 my $diskImage = File::Spec->catfile($directory, $filename);
373 my $devNull = File::Spec->devnull();
374
375 my $i = 0;
376 while (-e $mountPath) {
377 $i++;
378 usleep 100 if $i > 1;
379 `hdiutil detach '$mountPath' 2> $devNull`;
380 die "Could not unmount $diskImage at $mountPath" if $i > 100;
381 }
382 die "Can't mount $diskImage: $mountPath already exists!" if -e $mountPath;
383
384 print "Mounting disk image and running WebKit...\n";
385 `hdiutil attach '$diskImage'`;
386 $i = 0;
387 while (! -e $webkitApp) {
388 usleep 100;
389 $i++;
390 die "Could not mount $diskImage at $mountPath" if $i > 100;
391 }
392
393 my $frameworkPath;
394 if (-d "/Volumes/WebKit/WebKit.app/Contents/Frameworks") {
395 my $osXVersion = join('.', (split(/\./, findMacOSXVersion()))[0..1]);
396 $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Frameworks/$osXVer sion";
397 } else {
398 $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Resources";
399 }
400
401 $tempFile ||= "";
402 `DYLD_FRAMEWORK_PATH=$frameworkPath WEBKIT_UNSET_DYLD_FRAMEWORK_PATH=YES $sa fari $tempFile`;
403
404 `hdiutil detach '$mountPath' 2> $devNull`;
405 }
406
407 sub parseRevisions($$;$)
408 {
409 my ($optionName, $value, $ignored) = @_;
410
411 if ($value =~ /^r?([0-9]+|HEAD):?$/i) {
412 push(@revisions, $1);
413 die "Too many revision arguments specified" if scalar @revisions > 2;
414 } elsif ($value =~ /^r?([0-9]+):?r?([0-9]+|HEAD)$/i) {
415 $revisions[0] = $1;
416 $revisions[1] = $2;
417 } else {
418 die "Unknown revision '$value': expected 'M' or 'M:N'";
419 }
420 }
421
422 sub printStatus($$$)
423 {
424 my ($startRevision, $endRevision, $isProgression) = @_;
425 printf "\n%s: r%s %s: r%s\n",
426 $isProgression ? "Fails" : "Works", $startRevision,
427 $isProgression ? "Works" : "Fails", $endRevision;
428 }
429
430 sub printTracLink($$)
431 {
432 my ($startRevision, $endRevision) = @_;
433 printf("http://trac.webkit.org/log/trunk/?rev=%s&stop_rev=%s\n", $endRevisio n, $startRevision + 1);
434 }
435
436 sub promptForTest($)
437 {
438 my ($revision) = @_;
439 print "Did the bug reproduce in r$revision (yes/no/broken)? ";
440 my $answer = <STDIN>;
441 return 1 if $answer =~ /^(1|y.*)$/i;
442 return -1 if $answer =~ /^(-1|b.*)$/i; # Broken
443 return 0;
444 }
445
OLDNEW
« no previous file with comments | « no previous file | Tools/Scripts/check-for-inappropriate-files-in-framework » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698