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

Side by Side Diff: tools/testing/perf_testing/run_perf_tests.py

Issue 15742016: Fix up Performance testing. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « samples/third_party/dromaeo/tests/dom-traverse-html.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 6
7 import datetime 7 import datetime
8 import math 8 import math
9 import optparse 9 import optparse
10 import os 10 import os
11 from os.path import dirname, abspath 11 from os.path import dirname, abspath
12 import pickle 12 import pickle
13 import platform 13 import platform
14 import random 14 import random
15 import re 15 import re
16 import shutil 16 import shutil
17 import stat 17 import stat
18 import subprocess 18 import subprocess
19 import sys 19 import sys
20 import time 20 import time
21 21
22 TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__))))) 22 TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__)))))
23 TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', 23 TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
24 '..')) 24 '..'))
25 DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', 25 DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..',
26 '..', '..', '..', 26 '..', '..', '..',
27 'dart_checkout_for_perf_testing', 27 'dart_checkout_for_perf_testing',
28 'dart')) 28 'dart'))
29 # The earliest stored version of Dartium. Don't try to test earlier than this. 29 # How far back in time we want to test.
30 EARLIEST_REVISION = 4285 30 EARLIEST_REVISION = 6285
31 FIRST_CHROMEDRIVER = 7823 31 FIRST_CHROMEDRIVER = 7823
32 sys.path.append(TOOLS_PATH) 32 sys.path.append(TOOLS_PATH)
33 sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests')) 33 sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests'))
34 import post_results 34 import post_results
35 import utils 35 import utils
36 36
37 """This script runs to track performance and size progress of 37 """This script runs to track performance and size progress of
38 different svn revisions. It tests to see if there a newer version of the code on 38 different svn revisions. It tests to see if there a newer version of the code on
39 the server, and will sync and run the performance tests if so.""" 39 the server, and will sync and run the performance tests if so."""
40 class TestRunner(object): 40 class TestRunner(object):
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 p = subprocess.Popen(cmd_list, stdout = out, stderr=subprocess.PIPE, 73 p = subprocess.Popen(cmd_list, stdout = out, stderr=subprocess.PIPE,
74 stdin=subprocess.PIPE, shell=self.has_shell) 74 stdin=subprocess.PIPE, shell=self.has_shell)
75 output, stderr = p.communicate(std_in) 75 output, stderr = p.communicate(std_in)
76 if output: 76 if output:
77 print output 77 print output
78 if stderr: 78 if stderr:
79 print stderr 79 print stderr
80 return output, stderr 80 return output, stderr
81 81
82 def TimeCmd(self, cmd): 82 def TimeCmd(self, cmd):
83 """Determine the amount of (real) time it takes to execute a given 83 """Determine the amount of (real) time it takes to execute a given
84 command.""" 84 command."""
85 start = time.time() 85 start = time.time()
86 self.RunCmd(cmd) 86 self.RunCmd(cmd)
87 return time.time() - start 87 return time.time() - start
88 88
89 def ClearOutUnversionedFiles(self): 89 def ClearOutUnversionedFiles(self):
90 """Remove all files that are unversioned by svn.""" 90 """Remove all files that are unversioned by svn."""
91 if os.path.exists(DART_REPO_LOC): 91 if os.path.exists(DART_REPO_LOC):
92 os.chdir(DART_REPO_LOC) 92 os.chdir(DART_REPO_LOC)
93 results, _ = self.RunCmd(['svn', 'st']) 93 results, _ = self.RunCmd(['svn', 'st'])
94 for line in results.split('\n'): 94 for line in results.split('\n'):
95 if line.startswith('?'): 95 if line.startswith('?'):
96 to_remove = line.split()[1] 96 to_remove = line.split()[1]
97 if os.path.isdir(to_remove): 97 if os.path.isdir(to_remove):
98 shutil.rmtree(to_remove, ignore_errors=True) 98 shutil.rmtree(to_remove, onerror=TestRunner._OnRmError)
99 else: 99 else:
100 os.remove(to_remove) 100 os.remove(to_remove)
101 elif any(line.startswith(status) for status in ['A', 'M', 'C', 'D']): 101 elif any(line.startswith(status) for status in ['A', 'M', 'C', 'D']):
102 self.RunCmd(['svn', 'revert', line.split()[1]]) 102 self.RunCmd(['svn', 'revert', line.split()[1]])
103 103
104 def GetArchive(self, archive_name): 104 def GetArchive(self, archive_name):
105 """Wrapper around the pulling down a specific archive from Google Storage. 105 """Wrapper around the pulling down a specific archive from Google Storage.
106 Adds a specific revision argument as needed. 106 Adds a specific revision argument as needed.
107 Returns: A tuple of a boolean (True if we successfully downloaded the 107 Returns: A tuple of a boolean (True if we successfully downloaded the
108 binary), and the stdout and stderr from running this command.""" 108 binary), and the stdout and stderr from running this command."""
(...skipping 12 matching lines...) Expand all
121 return (num_fails < 20, stdout, stderr) 121 return (num_fails < 20, stdout, stderr)
122 122
123 def _Sync(self, revision_num=None): 123 def _Sync(self, revision_num=None):
124 """Update the repository to the latest or specified revision.""" 124 """Update the repository to the latest or specified revision."""
125 os.chdir(dirname(DART_REPO_LOC)) 125 os.chdir(dirname(DART_REPO_LOC))
126 self.ClearOutUnversionedFiles() 126 self.ClearOutUnversionedFiles()
127 if not revision_num: 127 if not revision_num:
128 self.RunCmd(['gclient', 'sync']) 128 self.RunCmd(['gclient', 'sync'])
129 else: 129 else:
130 self.RunCmd(['gclient', 'sync', '-r', str(revision_num), '-t']) 130 self.RunCmd(['gclient', 'sync', '-r', str(revision_num), '-t'])
131 131
132 shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'internal'), 132 shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'internal'),
133 os.path.join(DART_REPO_LOC, 'internal')) 133 os.path.join(DART_REPO_LOC, 'internal'))
134 shutil.rmtree(os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'),
135 onerror=TestRunner._OnRmError)
136 shutil.copytree(os.path.join(TOP_LEVEL_DIR, 'third_party', 'gsutil'),
137 os.path.join(DART_REPO_LOC, 'third_party', 'gsutil'))
134 shutil.copy(os.path.join(TOP_LEVEL_DIR, 'tools', 'get_archive.py'), 138 shutil.copy(os.path.join(TOP_LEVEL_DIR, 'tools', 'get_archive.py'),
135 os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py')) 139 os.path.join(DART_REPO_LOC, 'tools', 'get_archive.py'))
136 shutil.copy( 140 shutil.copy(
137 os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'run_selenium.py'), 141 os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'run_selenium.py'),
138 os.path.join(DART_REPO_LOC, 'tools', 'testing', 'run_selenium.py')) 142 os.path.join(DART_REPO_LOC, 'tools', 'testing', 'run_selenium.py'))
139 143
144 @staticmethod
145 def _OnRmError(func, path, exc_info):
146 """On Windows, the output directory is marked as "Read Only," which causes
147 an error to be thrown when we use shutil.rmtree. This helper function
148 changes the permissions so we can still delete the directory."""
149 if os.path.exists(path):
150 os.chmod(path, stat.S_IWRITE)
151 os.unlink(path)
152
140 def SyncAndBuild(self, suites, revision_num=None): 153 def SyncAndBuild(self, suites, revision_num=None):
141 """Make sure we have the latest version of of the repo, and build it. We 154 """Make sure we have the latest version of of the repo, and build it. We
142 begin and end standing in DART_REPO_LOC. 155 begin and end standing in DART_REPO_LOC.
143 156
144 Args: 157 Args:
145 suites: The set of suites that we wish to build. 158 suites: The set of suites that we wish to build.
146 159
147 Returns: 160 Returns:
148 err_code = 1 if there was a problem building.""" 161 err_code = 1 if there was a problem building."""
149 self._Sync(revision_num) 162 self._Sync(revision_num)
150 if not revision_num: 163 if not revision_num:
151 revision_num = SearchForRevision() 164 revision_num = SearchForRevision()
152 165
153 self.current_revision_num = revision_num 166 self.current_revision_num = revision_num
154 success, stdout, stderr = self.GetArchive('sdk') 167 success, stdout, stderr = self.GetArchive('sdk')
155 if (not os.path.exists(os.path.join( 168 if (not os.path.exists(os.path.join(
156 DART_REPO_LOC, 'tools', 'get_archive.py')) or not success 169 DART_REPO_LOC, 'tools', 'get_archive.py')) or not success
157 or 'InvalidUriError' in stderr or "Couldn't download" in stdout): 170 or 'InvalidUriError' in stderr or "Couldn't download" in stdout or
171 'Unable to download' in stdout):
158 # Couldn't find the SDK on Google Storage. Build it locally. 172 # Couldn't find the SDK on Google Storage. Build it locally.
159 173
160 # On Windows, the output directory is marked as "Read Only," which causes 174 # TODO(efortuna): Currently always building ia32 architecture because we
161 # an error to be thrown when we use shutil.rmtree. This helper function 175 # don't have test statistics for what's passing on x64. Eliminate arch
162 # changes the permissions so we can still delete the directory.
163 def on_rm_error(func, path, exc_info):
164 if os.path.exists(path):
165 os.chmod(path, stat.S_IWRITE)
166 os.unlink(path)
167 # TODO(efortuna): Currently always building ia32 architecture because we
168 # don't have test statistics for what's passing on x64. Eliminate arch
169 # specification when we have tests running on x64, too. 176 # specification when we have tests running on x64, too.
170 shutil.rmtree(os.path.join(os.getcwd(), 177 shutil.rmtree(os.path.join(os.getcwd(),
171 utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32')), 178 utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32')),
172 onerror=on_rm_error) 179 onerror=TestRunner._OnRmError)
173 lines = self.RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 180 lines = self.RunCmd([os.path.join('.', 'tools', 'build.py'), '-m',
174 'release', '--arch=ia32', 'create_sdk']) 181 'release', '--arch=ia32', 'create_sdk'])
175 182
176 for line in lines: 183 for line in lines:
177 if 'BUILD FAILED' in line: 184 if 'BUILD FAILED' in line:
178 # Someone checked in a broken build! Stop trying to make it work 185 # Someone checked in a broken build! Stop trying to make it work
179 # and wait to try again. 186 # and wait to try again.
180 print 'Broken Build' 187 print 'Broken Build'
181 return 1 188 return 1
182 return 0 189 return 0
183 190
184 def EnsureOutputDirectory(self, dir_name): 191 def EnsureOutputDirectory(self, dir_name):
185 """Test that the listed directory name exists, and if not, create one for 192 """Test that the listed directory name exists, and if not, create one for
186 our output to be placed. 193 our output to be placed.
187 194
188 Args: 195 Args:
189 dir_name: the directory we will create if it does not exist.""" 196 dir_name: the directory we will create if it does not exist."""
190 dir_path = os.path.join(TOP_LEVEL_DIR, 'tools', 197 dir_path = os.path.join(TOP_LEVEL_DIR, 'tools',
191 'testing', 'perf_testing', dir_name) 198 'testing', 'perf_testing', dir_name)
192 if not os.path.exists(dir_path): 199 if not os.path.exists(dir_path):
193 os.makedirs(dir_path) 200 os.makedirs(dir_path)
194 print 'Creating output directory ', dir_path 201 print 'Creating output directory ', dir_path
195 202
196 def HasInterestingCode(self, revision_num=None): 203 def HasInterestingCode(self, revision_num=None):
197 """Tests if there are any versions of files that might change performance 204 """Tests if there are any versions of files that might change performance
198 results on the server. 205 results on the server.
199 206
200 Returns: 207 Returns:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 else: 284 else:
278 last_done_cl = int(SearchForRevision(DART_REPO_LOC)) + 1 285 last_done_cl = int(SearchForRevision(DART_REPO_LOC)) + 1
279 while last_done_cl <= latest_interesting_server_rev: 286 while last_done_cl <= latest_interesting_server_rev:
280 file_list = GetFileList(last_done_cl) 287 file_list = GetFileList(last_done_cl)
281 if HasPerfAffectingResults(file_list): 288 if HasPerfAffectingResults(file_list):
282 return (True, last_done_cl) 289 return (True, last_done_cl)
283 else: 290 else:
284 UpdateSetOfDoneCls(last_done_cl) 291 UpdateSetOfDoneCls(last_done_cl)
285 last_done_cl += 1 292 last_done_cl += 1
286 return (False, None) 293 return (False, None)
287 294
288 def GetOsDirectory(self): 295 def GetOsDirectory(self):
289 """Specifies the name of the directory for the testing build of dart, which 296 """Specifies the name of the directory for the testing build of dart, which
290 has yet a different naming convention from utils.getBuildRoot(...).""" 297 has yet a different naming convention from utils.getBuildRoot(...)."""
291 if platform.system() == 'Windows': 298 if platform.system() == 'Windows':
292 return 'windows' 299 return 'windows'
293 elif platform.system() == 'Darwin': 300 elif platform.system() == 'Darwin':
294 return 'macos' 301 return 'macos'
295 else: 302 else:
296 return 'linux' 303 return 'linux'
297 304
298 def ParseArgs(self): 305 def ParseArgs(self):
299 parser = optparse.OptionParser() 306 parser = optparse.OptionParser()
300 parser.add_option('--suites', '-s', dest='suites', help='Run the specified ' 307 parser.add_option('--suites', '-s', dest='suites', help='Run the specified '
301 'comma-separated test suites from set: %s' % \ 308 'comma-separated test suites from set: %s' % \
302 ','.join(TestBuilder.AvailableSuiteNames()), 309 ','.join(TestBuilder.AvailableSuiteNames()),
303 action='store', default=None) 310 action='store', default=None)
304 parser.add_option('--forever', '-f', dest='continuous', help='Run this scri' 311 parser.add_option('--forever', '-f', dest='continuous', help='Run this scri'
305 'pt forever, always checking for the next svn checkin', 312 'pt forever, always checking for the next svn checkin',
306 action='store_true', default=False) 313 action='store_true', default=False)
307 parser.add_option('--nobuild', '-n', dest='no_build', action='store_true', 314 parser.add_option('--nobuild', '-n', dest='no_build', action='store_true',
308 help='Do not sync with the repository and do not ' 315 help='Do not sync with the repository and do not '
309 'rebuild.', default=False) 316 'rebuild.', default=False)
310 parser.add_option('--noupload', '-u', dest='no_upload', action='store_true', 317 parser.add_option('--noupload', '-u', dest='no_upload', action='store_true',
311 help='Do not post the results of the run.', default=False) 318 help='Do not post the results of the run.', default=False)
312 parser.add_option('--notest', '-t', dest='no_test', action='store_true', 319 parser.add_option('--notest', '-t', dest='no_test', action='store_true',
313 help='Do not run the tests.', default=False) 320 help='Do not run the tests.', default=False)
314 parser.add_option('--verbose', '-v', dest='verbose', 321 parser.add_option('--verbose', '-v', dest='verbose',
315 help='Print extra debug output', action='store_true', 322 help='Print extra debug output', action='store_true',
316 default=False) 323 default=False)
317 parser.add_option('--backfill', '-b', dest='backfill', 324 parser.add_option('--backfill', '-b', dest='backfill',
318 help='Backfill earlier CLs with additional results when ' 325 help='Backfill earlier CLs with additional results when '
319 'there is idle time.', action='store_true', 326 'there is idle time.', action='store_true',
320 default=False) 327 default=False)
321 328
322 args, ignored = parser.parse_args() 329 args, ignored = parser.parse_args()
323 330
324 if not args.suites: 331 if not args.suites:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 # cur_time is used as a timestamp of when this performance test was run. 402 # cur_time is used as a timestamp of when this performance test was run.
396 self.cur_time = str(time.mktime(datetime.datetime.now().timetuple())) 403 self.cur_time = str(time.mktime(datetime.datetime.now().timetuple()))
397 self.values_list = values_list 404 self.values_list = values_list
398 self.platform_list = platform_list 405 self.platform_list = platform_list
399 self.test_runner = test_runner 406 self.test_runner = test_runner
400 self.tester = tester 407 self.tester = tester
401 self.file_processor = file_processor 408 self.file_processor = file_processor
402 self.revision_dict = dict() 409 self.revision_dict = dict()
403 self.values_dict = dict() 410 self.values_dict = dict()
404 self.extra_metrics = extra_metrics 411 self.extra_metrics = extra_metrics
405 # Initialize our values store.» » 412 # Initialize our values store.
406 for platform in platform_list:» » 413 for platform in platform_list:
407 self.revision_dict[platform] = dict()» » 414 self.revision_dict[platform] = dict()
408 self.values_dict[platform] = dict()» » 415 self.values_dict[platform] = dict()
409 for f in variants:» » 416 for f in variants:
410 self.revision_dict[platform][f] = dict()» » 417 self.revision_dict[platform][f] = dict()
411 self.values_dict[platform][f] = dict()» » 418 self.values_dict[platform][f] = dict()
412 for val in values_list:»» 419 for val in values_list:
413 self.revision_dict[platform][f][val] = []» » 420 self.revision_dict[platform][f][val] = []
414 self.values_dict[platform][f][val] = []» » 421 self.values_dict[platform][f][val] = []
415 for extra_metric in extra_metrics:» » 422 for extra_metric in extra_metrics:
416 self.revision_dict[platform][f][extra_metric] = []» » 423 self.revision_dict[platform][f][extra_metric] = []
417 self.values_dict[platform][f][extra_metric] = [] 424 self.values_dict[platform][f][extra_metric] = []
418 425
419 def IsValidCombination(self, platform, variant): 426 def IsValidCombination(self, platform, variant):
420 """Check whether data should be captured for this platform/variant 427 """Check whether data should be captured for this platform/variant
421 combination. 428 combination.
422 """ 429 """
423 # TODO(vsm): This avoids a bug in 32-bit Chrome (dartium) 430 if platform == 'dartium' and (variant == 'js' or variant == 'dart2js_html'):
424 # running JS dromaeo. 431 # Testing JavaScript performance on Dartium is a waste of time. Should be
425 if platform == 'dartium' and variant == 'js': 432 # same as Chrome.
426 return False 433 return False
427 if (platform == 'safari' and variant == 'dart2js' and 434 if (platform == 'safari' and variant == 'dart2js' and
428 int(self.test_runner.current_revision_num) < 10193): 435 int(self.test_runner.current_revision_num) < 10193):
429 # In revision 10193 we fixed a bug that allows Safari 6 to run dart2js 436 # In revision 10193 we fixed a bug that allows Safari 6 to run dart2js
430 # code. Since we can't change the Safari version on the machine, we're 437 # code. Since we can't change the Safari version on the machine, we're
431 # just not running 438 # just not running
432 # for this case. 439 # for this case.
433 return False 440 return False
434 return True 441 return True
435 442
436 def Run(self): 443 def Run(self):
437 """Run the benchmarks/tests from the command line and plot the 444 """Run the benchmarks/tests from the command line and plot the
438 results. 445 results.
439 """ 446 """
440 for visitor in [self.tester, self.file_processor]: 447 for visitor in [self.tester, self.file_processor]:
441 visitor.Prepare() 448 visitor.Prepare()
442 449
443 os.chdir(TOP_LEVEL_DIR) 450 os.chdir(TOP_LEVEL_DIR)
444 self.test_runner.EnsureOutputDirectory(self.result_folder_name) 451 self.test_runner.EnsureOutputDirectory(self.result_folder_name)
445 self.test_runner.EnsureOutputDirectory(os.path.join( 452 self.test_runner.EnsureOutputDirectory(os.path.join(
446 'old', self.result_folder_name)) 453 'old', self.result_folder_name))
447 os.chdir(DART_REPO_LOC) 454 os.chdir(DART_REPO_LOC)
448 if not self.test_runner.no_test: 455 if not self.test_runner.no_test:
449 self.tester.RunTests() 456 self.tester.RunTests()
450 457
451 os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'perf_testing')) 458 os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 'testing', 'perf_testing'))
452 459
453 files = os.listdir(self.result_folder_name) 460 files = os.listdir(self.result_folder_name)
454 post_success = True 461 post_success = True
455 for afile in files: 462 for afile in files:
456 if not afile.startswith('.'): 463 if not afile.startswith('.'):
457 should_move_file = self.file_processor.ProcessFile(afile, True) 464 should_move_file = self.file_processor.ProcessFile(afile, True)
458 if should_move_file: 465 if should_move_file:
459 shutil.move(os.path.join(self.result_folder_name, afile), 466 shutil.move(os.path.join(self.result_folder_name, afile),
460 os.path.join('old', self.result_folder_name, afile)) 467 os.path.join('old', self.result_folder_name, afile))
461 else: 468 else:
462 post_success = False 469 post_success = False
463 470
464 return post_success 471 return post_success
465 472
466 473
467 class Tester(object): 474 class Tester(object):
468 """The base level visitor class that runs tests. It contains convenience 475 """The base level visitor class that runs tests. It contains convenience
469 methods that many Tester objects use. Any class that would like to be a 476 methods that many Tester objects use. Any class that would like to be a
470 TesterVisitor must implement the RunTests() method.""" 477 TesterVisitor must implement the RunTests() method."""
471 478
472 def __init__(self, test): 479 def __init__(self, test):
473 self.test = test 480 self.test = test
474 481
475 def Prepare(self): 482 def Prepare(self):
476 """Perform any initial setup required before the test is run.""" 483 """Perform any initial setup required before the test is run."""
477 pass 484 pass
478 485
479 def AddSvnRevisionToTrace(self, outfile, browser = None): 486 def AddSvnRevisionToTrace(self, outfile, browser = None):
480 """Add the svn version number to the provided tracefile.""" 487 """Add the svn version number to the provided tracefile."""
481 def get_dartium_revision(): 488 def get_dartium_revision():
482 version_file_name = os.path.join(DART_REPO_LOC, 'client', 'tests', 489 version_file_name = os.path.join(DART_REPO_LOC, 'client', 'tests',
483 'dartium', 'LAST_VERSION') 490 'dartium', 'LAST_VERSION')
484 version_file = open(version_file_name, 'r') 491 try:
485 version = version_file.read().split('.')[-2] 492 version_file = open(version_file_name, 'r')
486 version_file.close() 493 version = version_file.read().split('.')[-3].split('-')[-1]
487 return version 494 version_file.close()
495 return version
496 except IOError as e:
497 dartium_dir = os.path.join(DART_REPO_LOC, 'client', 'tests', 'dartium')
498 if (os.path.exists(os.path.join(dartium_dir, 'Chromium.app', 'Contents',
499 'MacOS', 'Chromium') or os.path.exists(os.path.join(dartium_dir,
500 'chrome.exe'))) or
501 os.path.exists(os.path.join(dartium_dir, 'chrome'))):
502 print "Error: VERSION file wasn't found."
503 return SearchForRevision()
504 else:
505 raise
488 506
489 if browser and browser == 'dartium': 507 if browser and browser == 'dartium':
490 revision = get_dartium_revision() 508 revision = get_dartium_revision()
491 self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile) 509 self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
492 else: 510 else:
493 revision = SearchForRevision() 511 revision = SearchForRevision()
494 self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile) 512 self.test.test_runner.RunCmd(['echo', 'Revision: ' + revision], outfile)
495 513
496 514
497 class Processor(object): 515 class Processor(object):
498 """The base level vistor class that processes tests. It contains convenience 516 """The base level vistor class that processes tests. It contains convenience
499 methods that many File Processor objects use. Any class that would like to be 517 methods that many File Processor objects use. Any class that would like to be
500 a ProcessorVisitor must implement the ProcessFile() method.""" 518 a ProcessorVisitor must implement the ProcessFile() method."""
501 519
502 SCORE = 'Score' 520 SCORE = 'Score'
503 COMPILE_TIME = 'CompileTime' 521 COMPILE_TIME = 'CompileTime'
504 CODE_SIZE = 'CodeSize' 522 CODE_SIZE = 'CodeSize'
505 523
506 def __init__(self, test): 524 def __init__(self, test):
507 self.test = test 525 self.test = test
508 526
509 def Prepare(self): 527 def Prepare(self):
510 """Perform any initial setup required before the test is run.""" 528 """Perform any initial setup required before the test is run."""
511 pass 529 pass
512 530
513 def OpenTraceFile(self, afile, not_yet_uploaded): 531 def OpenTraceFile(self, afile, not_yet_uploaded):
514 """Find the correct location for the trace file, and open it. 532 """Find the correct location for the trace file, and open it.
515 Args: 533 Args:
516 afile: The tracefile name. 534 afile: The tracefile name.
517 not_yet_uploaded: True if this file is to be found in a directory that 535 not_yet_uploaded: True if this file is to be found in a directory that
518 contains un-uploaded data. 536 contains un-uploaded data.
519 Returns: A file object corresponding to the given file name.""" 537 Returns: A file object corresponding to the given file name."""
520 file_path = os.path.join(self.test.result_folder_name, afile) 538 file_path = os.path.join(self.test.result_folder_name, afile)
521 if not not_yet_uploaded: 539 if not not_yet_uploaded:
522 file_path = os.path.join('old', file_path) 540 file_path = os.path.join('old', file_path)
523 return open(file_path) 541 return open(file_path)
524 542
525 def ReportResults(self, benchmark_name, score, platform, variant, 543 def ReportResults(self, benchmark_name, score, platform, variant,
526 revision_number, metric): 544 revision_number, metric):
527 """Store the results of the benchmark run. 545 """Store the results of the benchmark run.
528 Args: 546 Args:
529 benchmark_name: The name of the individual benchmark. 547 benchmark_name: The name of the individual benchmark.
530 score: The numerical value of this benchmark. 548 score: The numerical value of this benchmark.
531 platform: The platform the test was run on (firefox, command line, etc). 549 platform: The platform the test was run on (firefox, command line, etc).
532 variant: Specifies whether the data was about generated Frog, js, a 550 variant: Specifies whether the data was about generated Frog, js, a
533 combination of both, or Dart depending on the test. 551 combination of both, or Dart depending on the test.
534 revision_number: The revision of the code (and sometimes the revision of 552 revision_number: The revision of the code (and sometimes the revision of
535 dartium). 553 dartium).
536 554
537 Returns: True if the post was successful file.""" 555 Returns: True if the post was successful file."""
538 return post_results.report_results(benchmark_name, score, platform, variant, 556 return post_results.report_results(benchmark_name, score, platform, variant,
539 revision_number, metric) 557 revision_number, metric)
540 558
541 def CalculateGeometricMean(self, platform, variant, svn_revision): 559 def CalculateGeometricMean(self, platform, variant, svn_revision):
542 """Calculate the aggregate geometric mean for JS and dart2js benchmark sets, 560 """Calculate the aggregate geometric mean for JS and dart2js benchmark sets,
543 given two benchmark dictionaries.""" 561 given two benchmark dictionaries."""
544 geo_mean = 0» » 562 geo_mean = 0
545 if self.test.IsValidCombination(platform, variant): 563 if self.test.IsValidCombination(platform, variant):
546 for benchmark in self.test.values_list: 564 for benchmark in self.test.values_list:
547 if not self.test.values_dict[platform][variant][benchmark]: 565 if not self.test.values_dict[platform][variant][benchmark]:
548 print 'Error determining mean for %s %s %s' % (platform, variant, 566 print 'Error determining mean for %s %s %s' % (platform, variant,
549 benchmark) 567 benchmark)
550 continue 568 continue
551 geo_mean += math.log( 569 geo_mean += math.log(
552 self.test.values_dict[platform][variant][benchmark][-1]) 570 self.test.values_dict[platform][variant][benchmark][-1])
553 571
554 self.test.values_dict[platform][variant]['Geo-Mean'] += \ 572 self.test.values_dict[platform][variant]['Geo-Mean'] += \
(...skipping 27 matching lines...) Expand all
582 file_processor: The visitor that processes files in the format 600 file_processor: The visitor that processes files in the format
583 appropriate for this test. 601 appropriate for this test.
584 extra_metrics: A list of any additional measurements we wish to keep 602 extra_metrics: A list of any additional measurements we wish to keep
585 track of (such as the geometric mean of a set, the sum, etc).""" 603 track of (such as the geometric mean of a set, the sum, etc)."""
586 super(RuntimePerformanceTest, self).__init__(result_folder_name, 604 super(RuntimePerformanceTest, self).__init__(result_folder_name,
587 platform_list, versions, benchmarks, test_runner, tester, 605 platform_list, versions, benchmarks, test_runner, tester,
588 file_processor) 606 file_processor)
589 self.platform_list = platform_list 607 self.platform_list = platform_list
590 self.platform_type = platform_type 608 self.platform_type = platform_type
591 self.versions = versions 609 self.versions = versions
592 self.benchmarks = benchmarks 610 self.benchmarks = benchmarks
593 611
594 612
595 class BrowserTester(Tester): 613 class BrowserTester(Tester):
596 @staticmethod 614 @staticmethod
597 def GetBrowsers(add_dartium=True): 615 def GetBrowsers(add_dartium=True):
598 browsers = ['ff', 'chrome'] 616 browsers = ['ff', 'chrome']
599 if add_dartium: 617 if add_dartium:
600 browsers += ['dartium'] 618 browsers += ['dartium']
601 has_shell = False 619 has_shell = False
602 if platform.system() == 'Darwin': 620 if platform.system() == 'Darwin':
603 browsers += ['safari'] 621 browsers += ['safari']
604 if platform.system() == 'Windows': 622 if platform.system() == 'Windows':
605 browsers += ['ie'] 623 browsers += ['ie']
606 has_shell = True 624 has_shell = True
607 return browsers 625 return browsers
608 626
609 627
610 class CommonBrowserTest(RuntimePerformanceTest): 628 class CommonBrowserTest(RuntimePerformanceTest):
611 """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the 629 """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the
612 browser.""" 630 browser."""
613 631
614 def __init__(self, test_runner): 632 def __init__(self, test_runner):
615 """Args: 633 """Args:
616 test_runner: Reference to the object that notifies us when to run.""" 634 test_runner: Reference to the object that notifies us when to run."""
617 super(CommonBrowserTest, self).__init__( 635 super(CommonBrowserTest, self).__init__(
618 self.Name(), BrowserTester.GetBrowsers(False), 636 self.Name(), BrowserTester.GetBrowsers(False),
619 'browser', ['js', 'dart2js'], 637 'browser', ['js', 'dart2js'],
620 self.GetStandaloneBenchmarks(), test_runner, 638 self.GetStandaloneBenchmarks(), test_runner,
621 self.CommonBrowserTester(self), 639 self.CommonBrowserTester(self),
622 self.CommonBrowserFileProcessor(self)) 640 self.CommonBrowserFileProcessor(self))
623 641
624 @staticmethod 642 @staticmethod
625 def Name(): 643 def Name():
626 return 'browser-perf' 644 return 'browser-perf'
627 645
628 @staticmethod 646 @staticmethod
629 def GetStandaloneBenchmarks(): 647 def GetStandaloneBenchmarks():
630 return ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 'BinaryTrees', 648 return ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 'BinaryTrees',
631 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 'Loop', 'Permute', 649 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 'Loop', 'Permute',
632 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 'Tak', 'Takl', 'Towers', 650 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 'Tak', 'Takl', 'Towers',
633 'TreeSort'] 651 'TreeSort']
(...skipping 12 matching lines...) Expand all
646 continue 664 continue
647 self.test.trace_file = os.path.join(TOP_LEVEL_DIR, 665 self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
648 'tools', 'testing', 'perf_testing', self.test.result_folder_name, 666 'tools', 'testing', 'perf_testing', self.test.result_folder_name,
649 'perf-%s-%s-%s' % (self.test.cur_time, browser, version)) 667 'perf-%s-%s-%s' % (self.test.cur_time, browser, version))
650 self.AddSvnRevisionToTrace(self.test.trace_file, browser) 668 self.AddSvnRevisionToTrace(self.test.trace_file, browser)
651 file_path = os.path.join( 669 file_path = os.path.join(
652 os.getcwd(), 'internal', 'browserBenchmarks', 'V8vDart', 670 os.getcwd(), 'internal', 'browserBenchmarks', 'V8vDart',
653 'V8vDart_page_%s.html' % version) 671 'V8vDart_page_%s.html' % version)
654 self.test.test_runner.RunCmd( 672 self.test.test_runner.RunCmd(
655 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), 673 ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
656 '--out', file_path, '--browser', browser, 674 '--out', '"file:///%s"' % file_path, '--browser', browser,
657 '--timeout', '600', '--mode', 'perf'], self.test.trace_file, 675 '--timeout', '600', '--mode', 'perf'], self.test.trace_file,
658 append=True) 676 append=True)
659 677
660 class CommonBrowserFileProcessor(Processor): 678 class CommonBrowserFileProcessor(Processor):
661 679
662 def ProcessFile(self, afile, should_post_file): 680 def ProcessFile(self, afile, should_post_file):
663 """Comb through the html to find the performance results. 681 """Comb through the html to find the performance results.
664 Returns: True if we successfully posted our data to storage and/or we can 682 Returns: True if we successfully posted our data to storage and/or we can
665 delete the trace file.""" 683 delete the trace file."""
666 os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', 684 os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools',
667 'testing', 'perf_testing')) 685 'testing', 'perf_testing'))
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 'getElementsByName', 759 'getElementsByName',
742 'getElementsByName (not in document)']), 760 'getElementsByName (not in document)']),
743 'traverse': ('traverse', [ 761 'traverse': ('traverse', [
744 'firstChild', 762 'firstChild',
745 'lastChild', 763 'lastChild',
746 'nextSibling', 764 'nextSibling',
747 'previousSibling', 765 'previousSibling',
748 'childNodes']) 766 'childNodes'])
749 } 767 }
750 768
751 # Use filenames that don't have unusual characters for benchmark names.» 769 # Use filenames that don't have unusual characters for benchmark names.
752 @staticmethod» 770 @staticmethod
753 def LegalizeFilename(str): 771 def LegalizeFilename(str):
754 remap = {» 772 remap = {
755 ' ': '_',» 773 ' ': '_',
756 '(': '_',» 774 '(': '_',
757 ')': '_',» 775 ')': '_',
758 '*': 'ALL',» 776 '*': 'ALL',
759 '=': 'ASSIGN',» 777 '=': 'ASSIGN',
760 }» 778 }
761 for (old, new) in remap.iteritems():» 779 for (old, new) in remap.iteritems():
762 str = str.replace(old, new) 780 str = str.replace(old, new)
763 return str 781 return str
764 782
765 # TODO(vsm): This is a hack to skip breaking tests. Triage this 783 # TODO(vsm): This is a hack to skip breaking tests. Triage this
766 # failure properly. The modify suite fails on 32-bit chrome, which 784 # failure properly. The modify suite fails on 32-bit chrome, which
767 # is the default on mac and win. 785 # is the default on mac and win.
768 @staticmethod 786 @staticmethod
769 def GetValidDromaeoTags(): 787 def GetValidDromaeoTags():
770 tags = [tag for (tag, _) in DromaeoTester.DROMAEO_BENCHMARKS.values()] 788 tags = [tag for (tag, _) in DromaeoTester.DROMAEO_BENCHMARKS.values()]
771 if platform.system() == 'Darwin' or platform.system() == 'Windows': 789 if platform.system() == 'Darwin' or platform.system() == 'Windows':
772 tags.remove('modify') 790 tags.remove('modify')
773 return tags 791 return tags
774 792
775 @staticmethod 793 @staticmethod
776 def GetDromaeoBenchmarks(): 794 def GetDromaeoBenchmarks():
777 valid = DromaeoTester.GetValidDromaeoTags() 795 valid = DromaeoTester.GetValidDromaeoTags()
778 benchmarks = reduce(lambda l1,l2: l1+l2, 796 benchmarks = reduce(lambda l1,l2: l1+l2,
779 [tests for (tag, tests) in 797 [tests for (tag, tests) in
780 DromaeoTester.DROMAEO_BENCHMARKS.values() 798 DromaeoTester.DROMAEO_BENCHMARKS.values()
781 if tag in valid]) 799 if tag in valid])
782 return map(DromaeoTester.LegalizeFilename, benchmarks) 800 return map(DromaeoTester.LegalizeFilename, benchmarks)
783 801
784 @staticmethod 802 @staticmethod
785 def GetDromaeoVersions(): 803 def GetDromaeoVersions():
786 return ['js', 'dart2js_html'] 804 return ['js', 'dart2js_html', 'dart_html']
787 805
788 806
789 class DromaeoTest(RuntimePerformanceTest): 807 class DromaeoTest(RuntimePerformanceTest):
790 """Runs Dromaeo tests, in the browser.""" 808 """Runs Dromaeo tests, in the browser."""
791 def __init__(self, test_runner): 809 def __init__(self, test_runner):
792 super(DromaeoTest, self).__init__( 810 super(DromaeoTest, self).__init__(
793 self.Name(), 811 self.Name(),
794 BrowserTester.GetBrowsers(True), 812 BrowserTester.GetBrowsers(True),
795 'browser', 813 'browser',
796 DromaeoTester.GetDromaeoVersions(), 814 DromaeoTester.GetDromaeoVersions(),
797 DromaeoTester.GetDromaeoBenchmarks(), test_runner, 815 DromaeoTester.GetDromaeoBenchmarks(), test_runner,
798 self.DromaeoPerfTester(self), 816 self.DromaeoPerfTester(self),
799 self.DromaeoFileProcessor(self)) 817 self.DromaeoFileProcessor(self))
800 818
801 @staticmethod 819 @staticmethod
802 def Name(): 820 def Name():
803 return 'dromaeo' 821 return 'dromaeo'
804 822
805 class DromaeoPerfTester(DromaeoTester): 823 class DromaeoPerfTester(DromaeoTester):
806 def MoveChromeDriverIfNeeded(self, browser): 824 def MoveChromeDriverIfNeeded(self, browser):
807 """Move the appropriate version of ChromeDriver onto the path. 825 """Move the appropriate version of ChromeDriver onto the path.
808 TODO(efortuna): This is a total hack because the latest version of Chrome 826 TODO(efortuna): This is a total hack because the latest version of Chrome
809 (Dartium builds) requires a different version of ChromeDriver, that is 827 (Dartium builds) requires a different version of ChromeDriver, that is
810 incompatible with the release or beta Chrome and vice versa. Remove these 828 incompatible with the release or beta Chrome and vice versa. Remove these
811 shenanigans once we're back to both versions of Chrome using the same 829 shenanigans once we're back to both versions of Chrome using the same
812 version of ChromeDriver. IMPORTANT NOTE: This assumes your chromedriver is 830 version of ChromeDriver. IMPORTANT NOTE: This assumes your chromedriver is
813 in the default location (inside depot_tools). 831 in the default location (inside depot_tools).
814 832
815 Returns: True if we were successfully able to download a new version of 833 Returns: True if we were successfully able to download a new version of
816 chromedriver and/or move the correct chromedriver into position. 834 chromedriver and/or move the correct chromedriver into position.
817 """ 835 """
(...skipping 28 matching lines...) Expand all
846 if not os.path.exists(os.path.dirname(from_dir)): 864 if not os.path.exists(os.path.dirname(from_dir)):
847 os.makedirs(os.path.dirname(from_dir)) 865 os.makedirs(os.path.dirname(from_dir))
848 shutil.copyfile(from_dir, to_dir) 866 shutil.copyfile(from_dir, to_dir)
849 867
850 for loc in path: 868 for loc in path:
851 if 'depot_tools' in loc: 869 if 'depot_tools' in loc:
852 if browser == 'chrome': 870 if browser == 'chrome':
853 if os.path.exists(orig_chromedriver_path): 871 if os.path.exists(orig_chromedriver_path):
854 MoveChromedriver(loc) 872 MoveChromedriver(loc)
855 elif browser == 'dartium': 873 elif browser == 'dartium':
856 if (int(self.test.test_runner.current_revision_num) < 874 if (int(self.test.test_runner.current_revision_num) <
857 FIRST_CHROMEDRIVER): 875 FIRST_CHROMEDRIVER):
858 # If we don't have a stashed a different chromedriver just use 876 # If we don't have a stashed different chromedriver just use
859 # the regular chromedriver. 877 # the regular chromedriver.
860 if not os.path.exists(os.path.dirname(orig_chromedriver_path)): 878 if not os.path.exists(os.path.dirname(orig_chromedriver_path)):
861 os.makedirs(os.path.dirname(orig_chromedriver_path)) 879 os.makedirs(os.path.dirname(orig_chromedriver_path))
862 self.test.test_runner.RunCmd([os.path.join( 880 self.test.test_runner.RunCmd([os.path.join(
863 TOP_LEVEL_DIR, 'tools', 'testing', 'webdriver_test_setup.py'), 881 TOP_LEVEL_DIR, 'tools', 'testing', 'webdriver_test_setup.py'),
864 '-f', '-p', '-s']) 882 '-f', '-p', '-s'])
865 elif not os.path.exists(dartium_chromedriver_path): 883 elif not os.path.exists(dartium_chromedriver_path):
866 success, _, _ = self.test.test_runner.GetArchive('chromedriver') 884 success, _, _ = self.test.test_runner.GetArchive('chromedriver')
867 if not success: 885 if not success:
868 return False 886 return False
869 # Move original chromedriver for storage. 887 # Move original chromedriver for storage.
870 if not os.path.exists(orig_chromedriver_path): 888 if not os.path.exists(orig_chromedriver_path):
871 MoveChromedriver(loc, copy_to_depot_tools_dir=False) 889 MoveChromedriver(loc, copy_to_depot_tools_dir=False)
872 if self.test.test_runner.current_revision_num >= FIRST_CHROMEDRIVER: 890 if self.test.test_runner.current_revision_num >= FIRST_CHROMEDRIVER:
873 # Copy Dartium chromedriver into depot_tools 891 # Copy Dartium chromedriver into depot_tools
874 MoveChromedriver(loc, from_path=os.path.join( 892 MoveChromedriver(loc, from_path=os.path.join(
875 dartium_chromedriver_path, 'chromedriver')) 893 dartium_chromedriver_path, 'chromedriver'))
876 os.chdir(current_dir) 894 os.chdir(current_dir)
877 return True 895 return True
878 896
879 def RunTests(self): 897 def RunTests(self):
880 """Run dromaeo in the browser.""" 898 """Run dromaeo in the browser."""
881
882 success, _, _ = self.test.test_runner.GetArchive('dartium') 899 success, _, _ = self.test.test_runner.GetArchive('dartium')
883 if not success: 900 if not success:
884 # Unable to download dartium. Try later. 901 # Unable to download dartium. Try later.
885 return 902 return
886 903
887 # Build tests. 904 # Build tests.
888 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo') 905 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo')
889 current_path = os.getcwd() 906 current_path = os.getcwd()
890 os.chdir(dromaeo_path) 907 os.chdir(dromaeo_path)
891 if os.path.exists('generate_dart2js_tests.py'): 908 if os.path.exists('generate_dart2js_tests.py'):
(...skipping 13 matching lines...) Expand all
905 return 922 return
906 for version_name in versions: 923 for version_name in versions:
907 if not self.test.IsValidCombination(browser, version_name): 924 if not self.test.IsValidCombination(browser, version_name):
908 continue 925 continue
909 version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery( 926 version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery(
910 browser, version_name) 927 browser, version_name)
911 self.test.trace_file = os.path.join(TOP_LEVEL_DIR, 928 self.test.trace_file = os.path.join(TOP_LEVEL_DIR,
912 'tools', 'testing', 'perf_testing', self.test.result_folder_name, 929 'tools', 'testing', 'perf_testing', self.test.result_folder_name,
913 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name)) 930 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name))
914 self.AddSvnRevisionToTrace(self.test.trace_file, browser) 931 self.AddSvnRevisionToTrace(self.test.trace_file, browser)
915 file_path = '"%s"' % os.path.join(os.getcwd(), dromaeo_path, 932 file_path = os.path.join(os.getcwd(), dromaeo_path,
916 'index-js.html?%s' % version) 933 'index%s.html?%s' % (
934 '' if version_name == 'dart_html' else '-js', version))
917 self.test.test_runner.RunCmd( 935 self.test.test_runner.RunCmd(
918 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), 936 ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
919 '--out', file_path, '--browser', browser, 937 '--out', '"file:///%s"' % file_path, '--browser', browser,
920 '--timeout', '900', '--mode', 'dromaeo'], self.test.trace_file, 938 '--timeout', '900', '--mode', 'dromaeo'], self.test.trace_file,
921 append=True) 939 append=True)
922 # Put default Chromedriver back in. 940 # Put default Chromedriver back in.
923 self.MoveChromeDriverIfNeeded('chrome') 941 self.MoveChromeDriverIfNeeded('chrome')
924 942
925 @staticmethod 943 @staticmethod
926 def GetDromaeoUrlQuery(browser, version): 944 def GetDromaeoUrlQuery(browser, version):
927 if browser == 'dartium': 945 if browser == 'dartium':
928 version = version.replace('frog', 'dart') 946 version = version.replace('frog', 'dart')
929 version = version.replace('_','AND') 947 version = version.replace('_','AND')
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 result_set.add(revision_num) 1053 result_set.add(revision_num)
1036 pickle.dump(result_set, f) 1054 pickle.dump(result_set, f)
1037 f.close() 1055 f.close()
1038 return result_set 1056 return result_set
1039 1057
1040 1058
1041 def FillInBackHistory(results_set, runner): 1059 def FillInBackHistory(results_set, runner):
1042 """Fill in back history performance data. This is done one of two ways, with 1060 """Fill in back history performance data. This is done one of two ways, with
1043 equal probability of trying each way (falling back on the sequential version 1061 equal probability of trying each way (falling back on the sequential version
1044 as our data becomes more densely populated).""" 1062 as our data becomes more densely populated)."""
1063 revision_num = int(SearchForRevision(DART_REPO_LOC))
1045 has_run_extra = False 1064 has_run_extra = False
1046 revision_num = int(SearchForRevision(DART_REPO_LOC))
1047 1065
1048 def TryToRunAdditional(revision_number): 1066 def TryToRunAdditional(revision_number):
1049 """Determine the number of results we have stored for a particular revision 1067 """Determine the number of results we have stored for a particular revision
1050 number, and if it is less than 10, run some extra tests. 1068 number, and if it is less than 10, run some extra tests.
1051 Args: 1069 Args:
1052 - revision_number: the revision whose performance we want to potentially 1070 - revision_number: the revision whose performance we want to potentially
1053 test. 1071 test.
1054 Returns: True if we successfully ran some additional tests.""" 1072 Returns: True if we successfully ran some additional tests."""
1055 if not runner.HasInterestingCode(revision_number)[0]: 1073 if not runner.HasInterestingCode(revision_number)[0]:
1056 results_set = UpdateSetOfDoneCls(revision_number) 1074 results_set = UpdateSetOfDoneCls(revision_number)
1057 return False 1075 return False
1058 a_test = TestBuilder.MakeTest(runner.suite_names[0], runner) 1076 a_test = TestBuilder.MakeTest(runner.suite_names[0], runner)
1059 benchmark_name = a_test.values_list[0] 1077 benchmark_name = a_test.values_list[0]
1060 platform_name = a_test.platform_list[0] 1078 platform_name = a_test.platform_list[0]
1061 variant = a_test.values_dict[platform_name].keys()[0] 1079 variant = a_test.values_dict[platform_name].keys()[0]
1062 num_results = post_results.get_num_results(benchmark_name, 1080 num_results = post_results.get_num_results(benchmark_name,
1063 platform_name, variant, revision_number, 1081 platform_name, variant, revision_number,
1064 a_test.file_processor.GetScoreType(benchmark_name)) 1082 a_test.file_processor.GetScoreType(benchmark_name))
1065 if num_results < 10: 1083 if num_results < 10:
1066 # Run at most two more times. 1084 # Run at most two more times.
1067 if num_results > 8: 1085 if num_results > 8:
1068 reruns = 10 - num_results 1086 reruns = 10 - num_results
1069 else: 1087 else:
1070 reruns = 2 1088 reruns = 2
1071 run = runner.RunTestSequence(revision_num=str(revision_number), 1089 run = runner.RunTestSequence(revision_num=str(revision_number),
1072 num_reruns=reruns) 1090 num_reruns=reruns)
1073 if num_results >= 10 or run == 0 and num_results + reruns >= 10: 1091 if num_results >= 10 or run == 0 and num_results + reruns >= 10:
1074 results_set = UpdateSetOfDoneCls(revision_number) 1092 results_set = UpdateSetOfDoneCls(revision_number)
1075 elif run != 0: 1093 elif run != 0:
1076 return False 1094 return False
1077 return True 1095 return True
1078 1096
1079 if random.choice([True, False]): 1097 # Try to get up to 10 runs of each CL, starting with the most recent
1080 # Select a random CL number, with greater likelihood of selecting a CL in 1098 # CL that does not yet have 10 runs. But only perform a set of extra
1081 # the more recent history than the distant past (using a simplified weighted 1099 # runs at most 2 at a time before checking to see if new code has been
1082 # bucket algorithm). If that CL has less than 10 runs, run additional. If it 1100 # checked in.
1083 # already has 10 runs, look for another CL number that is not yet have all 1101 while revision_num > EARLIEST_REVISION and not has_run_extra:
1084 # of its additional runs (do this up to 15 times). 1102 if revision_num not in results_set:
1085 tries = 0 1103 has_run_extra = TryToRunAdditional(revision_num)
1086 # Select which "thousands bucket" we're going to run additional tests for. 1104 revision_num -= 1
1087 bucket_size = 1000
1088 thousands_list = range(EARLIEST_REVISION/bucket_size,
1089 int(revision_num)/bucket_size + 1)
1090 weighted_total = sum(thousands_list)
1091 generated_random_number = random.randint(0, weighted_total - 1)
1092 for i in list(reversed(thousands_list)):
1093 thousands = i
1094 weighted_total -= i
1095 if weighted_total <= generated_random_number:
1096 break
1097 while tries < 15 and not has_run_extra:
1098 # Now select a particular revision in that bucket.
1099 if thousands == int(revision_num)/bucket_size:
1100 max_range = 1 + revision_num % bucket_size
1101 else:
1102 max_range = bucket_size
1103 rev = thousands * bucket_size + random.randrange(0, max_range)
1104 if rev not in results_set:
1105 has_run_extra = TryToRunAdditional(rev)
1106 tries += 1
1107
1108 if not has_run_extra:
1109 # Try to get up to 10 runs of each CL, starting with the most recent
1110 # CL that does not yet have 10 runs. But only perform a set of extra
1111 # runs at most 2 at a time before checking to see if new code has been
1112 # checked in.
1113 while revision_num > EARLIEST_REVISION and not has_run_extra:
1114 if revision_num not in results_set:
1115 has_run_extra = TryToRunAdditional(revision_num)
1116 revision_num -= 1
1117 if not has_run_extra: 1105 if not has_run_extra:
1118 # No more extra back-runs to do (for now). Wait for new code. 1106 # No more extra back-runs to do (for now). Wait for new code.
1119 time.sleep(200) 1107 time.sleep(200)
1120 return results_set 1108 return results_set
1121 1109
1122 1110
1123 def main(): 1111 def main():
1124 runner = TestRunner() 1112 runner = TestRunner()
1125 continuous = runner.ParseArgs() 1113 continuous = runner.ParseArgs()
1126 1114
(...skipping 14 matching lines...) Expand all
1141 else: 1129 else:
1142 if runner.backfill: 1130 if runner.backfill:
1143 results_set = FillInBackHistory(results_set, runner) 1131 results_set = FillInBackHistory(results_set, runner)
1144 else: 1132 else:
1145 time.sleep(200) 1133 time.sleep(200)
1146 else: 1134 else:
1147 runner.RunTestSequence() 1135 runner.RunTestSequence()
1148 1136
1149 if __name__ == '__main__': 1137 if __name__ == '__main__':
1150 main() 1138 main()
OLDNEW
« no previous file with comments | « samples/third_party/dromaeo/tests/dom-traverse-html.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698