OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Functions for adding results to perf dashboard.""" |
| 7 |
| 8 import httplib |
| 9 import json |
| 10 import os |
| 11 import urllib |
| 12 import urllib2 |
| 13 |
| 14 from slave import slave_utils |
| 15 |
| 16 # The paths in the results dashboard URLs for sending and viewing results. |
| 17 SEND_RESULTS_PATH = "/add_point" |
| 18 RESULTS_LINK_PATH = "/report?masters=%s&bots=%s&tests=%s&rev=%s" |
| 19 # CACHE_DIR/CACHE_FILENAME will be created in options.build_dir to cache |
| 20 # results which need to be retried. |
| 21 CACHE_DIR = "results_dashboard" |
| 22 CACHE_FILENAME = "results_to_retry" |
| 23 |
| 24 |
| 25 def SendResults(logname, lines, system, test, url, build_dir): |
| 26 if not logname.endswith("-summary.dat"): |
| 27 return |
| 28 |
| 29 new_results_line = _GetResultsJson(logname, lines, system, test, url) |
| 30 # Write the new request line to the cache, in case of errors. |
| 31 cache_filename = _GetCacheFileName(build_dir) |
| 32 cache = open(cache_filename, "ab") |
| 33 cache.write("\n" + new_results_line) |
| 34 cache.close() |
| 35 |
| 36 # Send all the results from this run and the previous cache to the dashboard. |
| 37 cache = open(cache_filename, "rb") |
| 38 cache_lines = cache.readlines() |
| 39 cache.close() |
| 40 errors = [] |
| 41 lines_to_retry = [] |
| 42 fatal_error = False |
| 43 for index, line in enumerate(cache_lines): |
| 44 line = line.strip() |
| 45 if not line: |
| 46 continue |
| 47 error = _SendResultsJson(url, line) |
| 48 if error: |
| 49 if index != len(cache_lines) -1: |
| 50 # This request has already been tried before, now it's fatal. |
| 51 fatal_error = True |
| 52 lines_to_retry.append(line) |
| 53 errors.append(error) |
| 54 |
| 55 # Write any failing requests to the cache. |
| 56 cache = open(cache_filename, "wb") |
| 57 cache.write("\n".join(set(lines_to_retry))) |
| 58 cache.close() |
| 59 |
| 60 # Print any errors, and if there was a fatal error, it should be an exception. |
| 61 for error in errors: |
| 62 print error |
| 63 if fatal_error: |
| 64 print "Multiple failures uploading to dashboard." |
| 65 print "@@@STEP_EXCEPTION@@@" |
| 66 |
| 67 def _GetCacheFileName(build_dir): |
| 68 """Gets the cache filename, creating the file if it does not exist.""" |
| 69 cache_dir = os.path.join(os.path.abspath(build_dir), CACHE_DIR) |
| 70 if not os.path.exists(cache_dir): |
| 71 os.makedirs(cache_dir) |
| 72 cache_filename = os.path.join(cache_dir, CACHE_FILENAME) |
| 73 if not os.path.exists(cache_filename): |
| 74 # Create the file. |
| 75 open(cache_filename, "wb").close() |
| 76 return cache_filename |
| 77 |
| 78 def _GetResultsJson(logname, lines, system, test, url): |
| 79 results_to_add = [] |
| 80 master = slave_utils.GetActiveMaster(default="ChromiumPerf") |
| 81 bot = system |
| 82 graph = logname.replace("-summary.dat", "") |
| 83 for line in lines: |
| 84 data = json.loads(line) |
| 85 revision = data["rev"] |
| 86 for (trace, values) in data["traces"].iteritems(): |
| 87 if trace == graph + "_ref": |
| 88 trace = "ref" |
| 89 graph = graph.replace("_by_url", "") |
| 90 trace = trace.replace("/", "_") |
| 91 test_path = "%s/%s/%s" % (test, graph, trace) |
| 92 if graph == trace: |
| 93 test_path = "%s/%s" % (test, graph) |
| 94 result = { |
| 95 "master": master, |
| 96 "bot": system, |
| 97 "test": test_path, |
| 98 "revision": revision, |
| 99 "value": values[0], |
| 100 "error": values[1], |
| 101 } |
| 102 if "webkit_rev" in data and data["webkit_rev"] != "undefined": |
| 103 result.setdefault( |
| 104 "supplemental_columns", {})["r_webkit_rev"] = data["webkit_rev"] |
| 105 results_to_add.append(result) |
| 106 _PrintLinkStep(url, master, bot, test_path, revision) |
| 107 return json.dumps(results_to_add) |
| 108 |
| 109 def _SendResultsJson(url, results_json): |
| 110 data = urllib.urlencode({"data": results_json}) |
| 111 req = urllib2.Request(url + SEND_RESULTS_PATH, data) |
| 112 try: |
| 113 urllib2.urlopen(req) |
| 114 except urllib2.HTTPError, e: |
| 115 return "HTTPError: %d for JSON %s\n" % (e.code, results_json) |
| 116 except urllib2.URLError, e: |
| 117 return "URLError: %s for JSON %s\n" % (str(e.reason), results_json) |
| 118 except httplib.HTTPException, e: |
| 119 return "HTTPException for JSON %s\n" % results_json |
| 120 return None |
| 121 |
| 122 def _PrintLinkStep(url, master, bot, test_path, revision): |
| 123 results_link = url + RESULTS_LINK_PATH % ( |
| 124 urllib.quote(master), |
| 125 urllib.quote(bot), |
| 126 urllib.quote(test_path), |
| 127 revision) |
| 128 print "@@@STEP_LINK@%s@%s@@@" % ("Results Dashboard", results_link) |
OLD | NEW |