| 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 |