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

Side by Side Diff: scripts/slave/runtest.py

Issue 2330133002: Updating the SwarmingIsolatedScriptTest to upload chartjson results to the (Closed)
Patch Set: Fixing presubmit issues Created 4 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """A tool used to run a Chrome test executable and process the output. 6 """A tool used to run a Chrome test executable and process the output.
7 7
8 This script is used by the buildbot slaves. It must be run from the outer 8 This script is used by the buildbot slaves. It must be run from the outer
9 build directory, e.g. chrome-release/build/. 9 build directory, e.g. chrome-release/build/.
10 10
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 63
64 # Directory to write JSON for test results into. 64 # Directory to write JSON for test results into.
65 DEST_DIR = 'gtest_results' 65 DEST_DIR = 'gtest_results'
66 66
67 # Names of httpd configuration file under different platforms. 67 # Names of httpd configuration file under different platforms.
68 HTTPD_CONF = { 68 HTTPD_CONF = {
69 'linux': 'httpd2_linux.conf', 69 'linux': 'httpd2_linux.conf',
70 'mac': 'httpd2_mac.conf', 70 'mac': 'httpd2_mac.conf',
71 'win': 'httpd.conf' 71 'win': 'httpd.conf'
72 } 72 }
73 # Regex matching git comment lines containing svn revision info.
74 GIT_SVN_ID_RE = re.compile(r'^git-svn-id: .*@([0-9]+) .*$')
75 # Regex for the master branch commit position.
76 GIT_CR_POS_RE = re.compile(r'^Cr-Commit-Position: refs/heads/master@{#(\d+)}$')
77 73
78 # The directory that this script is in. 74 # The directory that this script is in.
79 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 75 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
80 76
81 LOG_PROCESSOR_CLASSES = { 77 LOG_PROCESSOR_CLASSES = {
82 'gtest': gtest_utils.GTestLogParser, 78 'gtest': gtest_utils.GTestLogParser,
83 'graphing': performance_log_processor.GraphingLogProcessor, 79 'graphing': performance_log_processor.GraphingLogProcessor,
84 } 80 }
85 81
86 82
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 def _GetMaster(): 197 def _GetMaster():
202 """Return the master name for the current host.""" 198 """Return the master name for the current host."""
203 return chromium_utils.GetActiveMaster() 199 return chromium_utils.GetActiveMaster()
204 200
205 201
206 def _GetMasterString(master): 202 def _GetMasterString(master):
207 """Returns a message describing what the master is.""" 203 """Returns a message describing what the master is."""
208 return '[Running for master: "%s"]' % master 204 return '[Running for master: "%s"]' % master
209 205
210 206
211 def _GetGitCommitPositionFromLog(log):
212 """Returns either the commit position or svn rev from a git log."""
213 # Parse from the bottom up, in case the commit message embeds the message
214 # from a different commit (e.g., for a revert).
215 for r in [GIT_CR_POS_RE, GIT_SVN_ID_RE]:
216 for line in reversed(log.splitlines()):
217 m = r.match(line.strip())
218 if m:
219 return m.group(1)
220 return None
221
222
223 def _GetGitCommitPosition(dir_path):
224 """Extracts the commit position or svn revision number of the HEAD commit."""
225 git_exe = 'git.bat' if sys.platform.startswith('win') else 'git'
226 p = subprocess.Popen(
227 [git_exe, 'log', '-n', '1', '--pretty=format:%B', 'HEAD'],
228 cwd=dir_path, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
229 (log, _) = p.communicate()
230 if p.returncode != 0:
231 return None
232 return _GetGitCommitPositionFromLog(log)
233
234
235 def _IsGitDirectory(dir_path):
236 """Checks whether the given directory is in a git repository.
237
238 Args:
239 dir_path: The directory path to be tested.
240
241 Returns:
242 True if given directory is in a git repository, False otherwise.
243 """
244 git_exe = 'git.bat' if sys.platform.startswith('win') else 'git'
245 with open(os.devnull, 'w') as devnull:
246 p = subprocess.Popen([git_exe, 'rev-parse', '--git-dir'],
247 cwd=dir_path, stdout=devnull, stderr=devnull)
248 return p.wait() == 0
249
250
251 def _GetRevision(in_directory):
252 """Returns the SVN revision, git commit position, or git hash.
253
254 Args:
255 in_directory: A directory in the repository to be checked.
256
257 Returns:
258 An SVN revision as a string if the given directory is in a SVN repository,
259 or a git commit position number, or if that's not available, a git hash.
260 If all of that fails, an empty string is returned.
261 """
262 import xml.dom.minidom
263 if not os.path.exists(os.path.join(in_directory, '.svn')):
264 if _IsGitDirectory(in_directory):
265 svn_rev = _GetGitCommitPosition(in_directory)
266 if svn_rev:
267 return svn_rev
268 return _GetGitRevision(in_directory)
269 else:
270 return ''
271
272 # Note: Not thread safe: http://bugs.python.org/issue2320
273 output = subprocess.Popen(['svn', 'info', '--xml'],
274 cwd=in_directory,
275 shell=(sys.platform == 'win32'),
276 stdout=subprocess.PIPE).communicate()[0]
277 try:
278 dom = xml.dom.minidom.parseString(output)
279 return dom.getElementsByTagName('entry')[0].getAttribute('revision')
280 except xml.parsers.expat.ExpatError:
281 return ''
282 return ''
283
284
285 def _GetGitRevision(in_directory):
286 """Returns the git hash tag for the given directory.
287
288 Args:
289 in_directory: The directory where git is to be run.
290
291 Returns:
292 The git SHA1 hash string.
293 """
294 git_exe = 'git.bat' if sys.platform.startswith('win') else 'git'
295 p = subprocess.Popen(
296 [git_exe, 'rev-parse', 'HEAD'],
297 cwd=in_directory, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
298 (stdout, _) = p.communicate()
299 return stdout.strip()
300
301
302 def _GenerateJSONForTestResults(options, log_processor): 207 def _GenerateJSONForTestResults(options, log_processor):
303 """Generates or updates a JSON file from the gtest results XML and upload the 208 """Generates or updates a JSON file from the gtest results XML and upload the
304 file to the archive server. 209 file to the archive server.
305 210
306 The archived JSON file will be placed at: 211 The archived JSON file will be placed at:
307 www-dir/DEST_DIR/buildname/testname/results.json 212 www-dir/DEST_DIR/buildname/testname/results.json
308 on the archive server. NOTE: This will be deprecated. 213 on the archive server. NOTE: This will be deprecated.
309 214
310 Args: 215 Args:
311 options: command-line options that are supposed to have build_dir, 216 options: command-line options that are supposed to have build_dir,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 258
354 print _GetMasterString(generate_json_options.master_name) 259 print _GetMasterString(generate_json_options.master_name)
355 260
356 generator = None 261 generator = None
357 262
358 try: 263 try:
359 if options.revision: 264 if options.revision:
360 generate_json_options.chrome_revision = options.revision 265 generate_json_options.chrome_revision = options.revision
361 else: 266 else:
362 chrome_dir = chromium_utils.FindUpwardParent(build_dir, 'third_party') 267 chrome_dir = chromium_utils.FindUpwardParent(build_dir, 'third_party')
363 generate_json_options.chrome_revision = _GetRevision(chrome_dir) 268 generate_json_options.chrome_revision = \
269 slave_utils.GetRevision(chrome_dir)
364 270
365 if options.webkit_revision: 271 if options.webkit_revision:
366 generate_json_options.webkit_revision = options.webkit_revision 272 generate_json_options.webkit_revision = options.webkit_revision
367 else: 273 else:
368 webkit_dir = chromium_utils.FindUpward( 274 webkit_dir = chromium_utils.FindUpward(
369 build_dir, 'third_party', 'WebKit', 'Source') 275 build_dir, 'third_party', 'WebKit', 'Source')
370 generate_json_options.webkit_revision = _GetRevision(webkit_dir) 276 generate_json_options.webkit_revision = \
277 slave_utils.GetRevision(webkit_dir)
371 278
372 # Generate results JSON file and upload it to the appspot server. 279 # Generate results JSON file and upload it to the appspot server.
373 generator = gtest_slave_utils.GenerateJSONResults( 280 generator = gtest_slave_utils.GenerateJSONResults(
374 results_map, generate_json_options) 281 results_map, generate_json_options)
375 282
376 except Exception as e: 283 except Exception as e:
377 print 'Unexpected error while generating JSON: %s' % e 284 print 'Unexpected error while generating JSON: %s' % e
378 sys.excepthook(*sys.exc_info()) 285 sys.excepthook(*sys.exc_info())
379 return False 286 return False
380 287
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 else: 377 else:
471 return LOG_PROCESSOR_CLASSES[options.annotate] 378 return LOG_PROCESSOR_CLASSES[options.annotate]
472 else: 379 else:
473 raise KeyError('"%s" is not a valid GTest parser!' % options.annotate) 380 raise KeyError('"%s" is not a valid GTest parser!' % options.annotate)
474 elif options.generate_json_file: 381 elif options.generate_json_file:
475 return LOG_PROCESSOR_CLASSES['gtest'] 382 return LOG_PROCESSOR_CLASSES['gtest']
476 383
477 return None 384 return None
478 385
479 386
480 def _GetCommitPos(build_properties):
481 """Extracts the commit position from the build properties, if its there."""
482 if 'got_revision_cp' not in build_properties:
483 return None
484 commit_pos = build_properties['got_revision_cp']
485 return int(re.search(r'{#(\d+)}', commit_pos).group(1))
486
487
488 def _GetMainRevision(options): 387 def _GetMainRevision(options):
489 """Return revision to use as the numerical x-value in the perf dashboard. 388 slave_utils.GetMainRevision(
490 389 options.build_properties, options.build_dir, options.revision)
491 This will be used as the value of "rev" in the data passed to
492 results_dashboard.SendResults.
493
494 In order or priority, this function could return:
495 1. The value of the --revision flag (IF it can be parsed as an int).
496 2. The value of "got_revision_cp" in build properties.
497 3. An SVN number, git commit position, or git commit hash.
498 """
499 if options.revision and options.revision.isdigit():
500 return options.revision
501 commit_pos_num = _GetCommitPos(options.build_properties)
502 if commit_pos_num is not None:
503 return commit_pos_num
504 # TODO(sullivan,qyearsley): Don't fall back to _GetRevision if it returns
505 # a git commit, since this should be a numerical revision. Instead, abort
506 # and fail.
507 return _GetRevision(os.path.dirname(os.path.abspath(options.build_dir)))
508 390
509 391
510 def _GetBlinkRevision(options): 392 def _GetBlinkRevision(options):
511 if options.webkit_revision: 393 slave_utils.GetBlinkRevision(options.build_dir, options.webkit_revision)
512 webkit_revision = options.webkit_revision
513 else:
514 try:
515 webkit_dir = chromium_utils.FindUpward(
516 os.path.abspath(options.build_dir), 'third_party', 'WebKit', 'Source')
517 webkit_revision = _GetRevision(webkit_dir)
518 except Exception:
519 webkit_revision = None
520 return webkit_revision
521 394
522 395
523 def _GetTelemetryRevisions(options): 396 def _GetPerfDashboardRevisions(options):
524 """Fills in the same revisions fields that process_log_utils does.""" 397 return slave_utils.GetPerfDashboardRevisions(
525 398 options.build_properties,
526 versions = {} 399 _GetMainRevision(options),
527 versions['rev'] = _GetMainRevision(options) 400 _GetBlinkRevision(options),
528 versions['webkit_rev'] = _GetBlinkRevision(options) 401 options.point_id)
529 versions['webrtc_rev'] = options.build_properties.get('got_webrtc_revision')
530 versions['v8_rev'] = options.build_properties.get('got_v8_revision')
531 versions['ver'] = options.build_properties.get('version')
532 versions['git_revision'] = options.build_properties.get('git_revision')
533 versions['point_id'] = options.point_id
534 # There are a lot of "bad" revisions to check for, so clean them all up here.
535 for key in versions.keys():
536 if not versions[key] or versions[key] == 'undefined':
537 del versions[key]
538 return versions
539 402
540 403
541 def _CreateLogProcessor(log_processor_class, options, telemetry_info): 404 def _CreateLogProcessor(log_processor_class, options, telemetry_info):
542 """Creates a log processor instance. 405 """Creates a log processor instance.
543 406
544 Args: 407 Args:
545 log_processor_class: A subclass of PerformanceLogProcessor or similar class. 408 log_processor_class: A subclass of PerformanceLogProcessor or similar class.
546 options: Command-line options (from OptionParser). 409 options: Command-line options (from OptionParser).
547 telemetry_info: dict of info for run_benchmark runs. 410 telemetry_info: dict of info for run_benchmark runs.
548 411
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 supplemental_columns.update(extra_columns) 479 supplemental_columns.update(extra_columns)
617 fields = { 480 fields = {
618 'system': _GetPerfID(options), 481 'system': _GetPerfID(options),
619 'test': options.test_type, 482 'test': options.test_type,
620 'url': options.results_url, 483 'url': options.results_url,
621 'mastername': options.build_properties.get('mastername'), 484 'mastername': options.build_properties.get('mastername'),
622 'buildername': options.build_properties.get('buildername'), 485 'buildername': options.build_properties.get('buildername'),
623 'buildnumber': options.build_properties.get('buildnumber'), 486 'buildnumber': options.build_properties.get('buildnumber'),
624 'build_dir': build_dir, 487 'build_dir': build_dir,
625 'supplemental_columns': supplemental_columns, 488 'supplemental_columns': supplemental_columns,
626 'revisions': _GetTelemetryRevisions(options), 489 'revisions': _GetPerfDashboardRevisions(options),
627 } 490 }
628 return fields 491 return fields
629 492
630 493
631 def _GenerateDashboardJson(log_processor, args): 494 def _GenerateDashboardJson(log_processor, args):
632 """Generates chartjson to send to the dashboard. 495 """Generates chartjson to send to the dashboard.
633 496
634 Args: 497 Args:
635 log_processor: An instance of a log processor class, which has been used to 498 log_processor: An instance of a log processor class, which has been used to
636 process the test output, so it contains the test results. 499 process the test output, so it contains the test results.
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 finally: 1772 finally:
1910 if did_launch_dbus: 1773 if did_launch_dbus:
1911 # It looks like the command line argument --exit-with-session 1774 # It looks like the command line argument --exit-with-session
1912 # isn't working to clean up the spawned dbus-daemon. Kill it 1775 # isn't working to clean up the spawned dbus-daemon. Kill it
1913 # manually. 1776 # manually.
1914 _ShutdownDBus() 1777 _ShutdownDBus()
1915 1778
1916 1779
1917 if '__main__' == __name__: 1780 if '__main__' == __name__:
1918 sys.exit(main()) 1781 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698