OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import json | 5 import json |
6 import os | 6 import os |
7 | 7 |
8 from slave import recipe_api | 8 from slave import recipe_api |
9 from . import perf_test | 9 from . import perf_test |
10 | 10 |
11 BUCKET = 'chrome-perf' | 11 BUCKET = 'chrome-perf' |
12 RESULTS_GS_DIR = 'bisect-results' | 12 RESULTS_GS_DIR = 'bisect-results' |
13 | 13 |
| 14 |
14 class BisectTesterApi(recipe_api.RecipeApi): | 15 class BisectTesterApi(recipe_api.RecipeApi): |
15 """A module for the bisect tester bot using the chromium recipe.""" | 16 """A module for the bisect tester bot using the chromium recipe.""" |
16 | 17 |
17 def __init__(self, **kwargs): | 18 def __init__(self, **kwargs): |
18 super(BisectTesterApi, self).__init__(**kwargs) | 19 super(BisectTesterApi, self).__init__(**kwargs) |
19 | 20 |
20 def load_config_from_dict(self, bisect_config): | 21 def load_config_from_dict(self, bisect_config): |
21 """Copies the required configuration keys to a new dict.""" | 22 """Copies the required configuration keys to a new dict.""" |
22 if bisect_config['test_type'] == 'perf': | 23 if bisect_config['test_type'] == 'perf': |
23 return { | 24 return { |
24 'test_type': 'perf', | 25 'test_type': 'perf', |
25 'command': bisect_config['command'], | 26 'command': bisect_config['command'], |
26 'metric': bisect_config['metric'], | 27 'metric': bisect_config['metric'], |
27 'repeat_count': int(bisect_config['repeat_count']), | 28 'repeat_count': int(bisect_config['repeat_count']), |
28 'timeout_seconds': float(bisect_config['max_time_minutes']) * 60, | 29 'timeout_seconds': float(bisect_config['max_time_minutes']) * 60, |
29 'truncate_percent': float(bisect_config['truncate_percent']), | 30 'truncate_percent': float(bisect_config['truncate_percent']), |
30 } | 31 } |
31 else: #pragma: no cover | 32 else: # pragma: no cover |
32 # TODO(robertocn): Add test to remove this pragma | 33 # TODO(robertocn): Add test to remove this pragma |
33 raise NotImplementedError('Test type %s not supported.' % | 34 raise NotImplementedError('Test type %s not supported.' % |
34 bisect_config['test_type']) | 35 bisect_config['test_type']) |
35 | 36 |
36 def run_test(self, test_config): | 37 def run_test(self, test_config): |
37 """Call the appropriate test function depending on the type of bisect.""" | 38 """Call the appropriate test function depending on the type of bisect.""" |
38 if test_config['test_type'] == 'perf': | 39 if test_config['test_type'] == 'perf': |
39 return perf_test.run_perf_test(self, test_config) | 40 return perf_test.run_perf_test(self, test_config) |
40 else: #pragma: no cover | 41 else: # pragma: no cover |
41 # TODO(robertocn): Add test to remove this pragma | 42 # TODO(robertocn): Add test to remove this pragma |
42 raise NotImplementedError('Test type %s not supported.' % | 43 raise NotImplementedError('Test type %s not supported.' % |
43 test_config['test_type']) | 44 test_config['test_type']) |
44 | 45 |
45 def digest_run_results(self, results, test_config): | 46 def digest_run_results(self, results, test_config): |
46 """Calculates relevant statistical functions from the results.""" | 47 """Calculates relevant statistical functions from the results.""" |
47 if test_config['test_type'] == 'perf': | 48 if test_config['test_type'] == 'perf': |
48 return perf_test.truncate_and_aggregate(self, results, | 49 return perf_test.truncate_and_aggregate(self, results, |
49 test_config['truncate_percent']) | 50 test_config['truncate_percent']) |
50 else: #pragma: no cover | 51 else: # pragma: no cover |
51 # TODO(robertocn): Add test to remove this pragma | 52 # TODO(robertocn): Add test to remove this pragma |
52 raise NotImplementedError('Test type %s not supported.' % | 53 raise NotImplementedError('Test type %s not supported.' % |
53 test_config['test_type']) | 54 test_config['test_type']) |
54 | 55 |
55 def upload_results(self, output, results): | 56 def upload_results(self, output, results): |
56 """Puts the results as a json file in a GS bucket.""" | 57 """Puts the results as a JSON file in a GS bucket.""" |
57 gs_filename = RESULTS_GS_DIR + '/' + self.m.properties['job_name'] + '.resul
ts' | 58 gs_filename = (RESULTS_GS_DIR + '/' + |
| 59 self.m.properties['job_name'] + '.results') |
58 contents = {'results': results, 'output': output} | 60 contents = {'results': results, 'output': output} |
59 contents_json = json.dumps(contents) | 61 contents_json = json.dumps(contents) |
60 local_save_results = self.m.python('saving json to temp file', | 62 local_save_results = self.m.python('saving json to temp file', |
61 self.resource('put_temp.py'), | 63 self.resource('put_temp.py'), |
62 stdout=self.m.raw_io.output(), | 64 stdout=self.m.raw_io.output(), |
63 stdin=self.m.raw_io.input( | 65 stdin=self.m.raw_io.input( |
64 contents_json)) | 66 contents_json)) |
65 local_file = local_save_results.stdout.splitlines()[0].strip() | 67 local_file = local_save_results.stdout.splitlines()[0].strip() |
66 # TODO(robertocn): Look into using self.m.json.input(contents) instead of | 68 # TODO(robertocn): Look into using self.m.json.input(contents) instead of |
67 # local_file. | 69 # local_file. |
68 self.m.gsutil.upload(local_file, BUCKET, gs_filename) | 70 self.m.gsutil.upload(local_file, BUCKET, gs_filename) |
69 | 71 |
70 def upload_job_url(self): | 72 def upload_job_url(self): |
71 """Puts the URL to the job's status on a GS file.""" | 73 """Puts the URL to the job's status on a GS file.""" |
72 gs_filename = RESULTS_GS_DIR + '/' + self.m.properties['job_name'] | 74 gs_filename = RESULTS_GS_DIR + '/' + self.m.properties['job_name'] |
73 if 'TESTING_MASTER_HOST' in os.environ: #pragma: no cover | 75 if 'TESTING_MASTER_HOST' in os.environ: # pragma: no cover |
74 url = "http://%s:8041/json/builders/%s/builds/%s" % ( | 76 url = "http://%s:8041/json/builders/%s/builds/%s" % ( |
75 os.environ['TESTING_MASTER_HOST'], | 77 os.environ['TESTING_MASTER_HOST'], |
76 self.m.properties['buildername'], | 78 self.m.properties['buildername'], |
77 self.m.properties['buildnumber']) | 79 self.m.properties['buildnumber']) |
78 else: | 80 else: |
79 url = "http://build.chromium.org/p/%s/json/builders/%s/builds/%s" % ( | 81 url = "http://build.chromium.org/p/%s/json/builders/%s/builds/%s" % ( |
80 self.m.properties['mastername'], | 82 self.m.properties['mastername'], |
81 self.m.properties['buildername'], | 83 self.m.properties['buildername'], |
82 self.m.properties['buildnumber']) | 84 self.m.properties['buildnumber']) |
83 local_save_results = self.m.python('saving url to temp file', | 85 local_save_results = self.m.python('saving url to temp file', |
84 self.resource('put_temp.py'), | 86 self.resource('put_temp.py'), |
85 stdout=self.m.raw_io.output(), | 87 stdout=self.m.raw_io.output(), |
86 stdin=self.m.raw_io.input(url)) | 88 stdin=self.m.raw_io.input(url)) |
87 local_file = local_save_results.stdout.splitlines()[0].strip() | 89 local_file = local_save_results.stdout.splitlines()[0].strip() |
88 self.m.gsutil.upload(local_file, BUCKET, gs_filename, name=str(gs_filename)) | 90 self.m.gsutil.upload(local_file, BUCKET, gs_filename, name=str(gs_filename)) |
89 | |
OLD | NEW |