Chromium Code Reviews| Index: scripts/slave/recipe_modules/chromedriver/api.py |
| diff --git a/scripts/slave/recipe_modules/chromedriver/api.py b/scripts/slave/recipe_modules/chromedriver/api.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..69130c69fd543f405b73bb7057fbb1dbc406799e |
| --- /dev/null |
| +++ b/scripts/slave/recipe_modules/chromedriver/api.py |
| @@ -0,0 +1,227 @@ |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +from recipe_engine import recipe_api |
| + |
| +GS_CHROMEDRIVER_DATA_BUCKET = 'chromedriver-data' |
| +GS_PREBUILTS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/prebuilts' |
| +GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs' |
| + |
| +TEST_LOG_FORMAT = '%s_log.json' |
| +TEST_LOG_MAX_LENGTH = 500 |
| + |
| +class ChromedriverApi(recipe_api.RecipeApi): |
| + |
| + def __init__(self, *args, **kwargs): |
| + super(ChromedriverApi, self).__init__(*args, **kwargs) |
| + self._chromedriver_log_dir = None |
| + |
| + def get_chromedriver_platform(self, is_android): |
|
jbudorick
2016/06/24 13:31:09
This entire function seems unnecessary at the mome
mikecase (-- gone --)
2016/06/24 18:57:50
Yeah, and now that I think about it, maybe we shou
|
| + """Gets the platform name for Chromedriver.""" |
| + if is_android: |
| + return 'android' |
| + else: # pragma: no cover |
| + raise NotImplementedError('Only Android is currently supported for ' |
| + 'Chromedriver recipes.') |
| + |
| + def download_prebuilts(self): |
| + """Downloads the most recent prebuilts from Google storage.""" |
| + with self.m.step.nest('Download Prebuilts'): |
| + prebuilt_dir = self.m.path.mkdtemp('prebuilt') |
| + zipfile = prebuilt_dir.join('build.zip') |
| + unzip_dir = prebuilt_dir.join('unzipped') |
| + try: |
| + self.m.gsutil.download_latest_file(base_url=GS_PREBUILTS_URL, |
| + partial_name=GS_PREBUILTS_URL + '/r', |
| + destination=zipfile, |
| + name='download latest prebuilt') |
| + self.m.zip.unzip(step_name='unzip prebuilt', |
| + zip_file=zipfile, |
| + output=unzip_dir) |
| + self.m.file.move(name='move prebuilt', |
| + source=unzip_dir.join('chromedriver'), |
| + dest=self.m.chromium.output_dir, |
| + infra_step=False) |
| + finally: |
| + self.m.file.rmtree(name='remove temp dir', path=prebuilt_dir) |
| + |
| + def archive_server_logs(self, chromedriver_log_dir): |
| + """Uploads chromedriver server logs to Google storage. |
| + |
| + Args: |
| + chromedriver_log_dir: Directory containing the Chromedriver server logs. |
| + """ |
| + with self.m.step.nest('Upload Chromedriver Server Logs'): |
| + server_logs = self.m.file.glob( |
| + name='glob search for server logs', |
| + pattern=chromedriver_log_dir.join('*'), |
| + test_data=[chromedriver_log_dir.join('chromedriver_123'), |
| + chromedriver_log_dir.join('chromedriver_456'), |
| + chromedriver_log_dir.join('chromedriver_789')]) |
| + for server_log in server_logs: |
| + self.m.gsutil.upload(name='uploading %s' % server_log, |
| + source=server_log, |
| + bucket=GS_SERVER_LOGS_URL, |
| + dest=self.m.path.basename(server_log), |
| + link_name='server log %s' % server_log) |
| + |
| + def download_test_results_log(self, chromedriver_platform): |
| + """Downloads the test results log for the given Chromedriver platform. |
| + |
| + Args: |
| + chromedriver_platform: The platform of the test results log. |
| + |
| + Returns: |
| + A dictionary where the keys are commit positions and the values are |
| + booleans indicating whether the tests passed. |
| + """ |
| + with self.m.step.nest('Download Test Results Log'): |
| + log_name = TEST_LOG_FORMAT % chromedriver_platform |
| + temp_log_dir = self.m.path.mkdtemp('results_log') |
| + temp_log_file = temp_log_dir.join(log_name) |
| + try: |
| + self.m.gsutil.download(name='download results log', |
| + source=log_name, |
| + bucket=GS_CHROMEDRIVER_DATA_BUCKET, |
| + dest=temp_log_file) |
| + json_data = self.m.file.read(name='read results log file', |
| + path=temp_log_file, |
| + test_data='{}') |
| + json_dict = self.m.json.loads(json_data) |
| + except self.m.step.StepFailure: |
| + json_dict = {} |
| + finally: |
| + self.m.file.rmtree(name='remove temp dir', path=temp_log_dir) |
| + return {int(k): v for k, v in json_dict.iteritems()} |
| + |
| + def upload_test_results_log(self, chromedriver_platform, test_results_log): |
| + """Uploads the given test results log to Google storage.""" |
| + with self.m.step.nest('Upload Test Results Log'): |
| + log_name = TEST_LOG_FORMAT % chromedriver_platform |
| + temp_log_dir = self.m.path.mkdtemp('results_log') |
| + temp_log_file = temp_log_dir.join(log_name) |
| + try: |
| + self.m.file.write(name='write results log to file %s' % log_name, |
| + path=temp_log_file, |
| + data=self.m.json.dumps(test_results_log)) |
| + self.m.gsutil.upload(name='upload results log %s' % log_name, |
| + source=temp_log_file, |
| + bucket=GS_CHROMEDRIVER_DATA_BUCKET, |
| + dest=log_name, |
| + link_name='results log') |
| + finally: |
| + self.m.file.rmtree(name='remove temp dir', path=temp_log_dir) |
| + |
| + def update_test_results_log(self, chromedriver_platform, |
| + commit_position, passed): |
| + """Updates the test results log stored in GS for the given platform. |
| + |
| + Args: |
| + chromedriver_platform: The platform name. |
| + commit_position: The commit position number. |
| + passed: Boolean indicating whether the tests passed at this |
| + commit position. |
| + """ |
| + log = self.download_test_results_log(chromedriver_platform) |
| + while len(log) > TEST_LOG_MAX_LENGTH: # pragma: no cover |
| + del log[min(log.keys())] |
| + if commit_position not in log: |
| + log[commit_position] = bool(passed) |
| + self.upload_test_results_log(chromedriver_platform, log) |
| + else: |
| + raise self.m.step.StepFailure( |
| + 'Results already exist for commit position %s' % commit_position) |
| + |
| + def _generate_test_command(self, script, chromedriver, test_log_dir, |
| + ref_chromedriver=None, android_package=None, |
| + build_type=None, verbose=None): |
| + cmd = [ |
| + script, |
| + '--chromedriver', chromedriver, |
| + '--log-dir', str(test_log_dir) |
|
samuong
2016/06/24 16:40:57
run_py_tests.py and run_java_tests.py have a --log
mikecase (-- gone --)
2016/06/24 18:57:50
ahh. Thanks for catching this. I had to make some
|
| + ] |
| + if ref_chromedriver: |
| + cmd.extend(['--reference-chromedriver', ref_chromedriver]) |
| + if build_type: |
| + cmd.extend(['--build-type', build_type]) |
| + if verbose: |
| + cmd.extend(['--verbose']) |
| + if android_package: |
|
samuong
2016/06/24 16:40:56
i think this should say "if self.m.platform.is_lin
mikecase (-- gone --)
2016/06/24 18:57:50
Done. Now I add the xvfb-run command if the platfo
|
| + cmd = ['xvfb-run', '-a'] + cmd |
| + cmd.extend(['--android-package', android_package]) |
| + return cmd |
| + |
| + def run_python_tests(self, chromedriver, test_log_dir, ref_chromedriver, |
| + chrome=None, chrome_version_name=None, |
| + android_package=None, build_type=None, **kwargs): |
| + """Run the Chromedriver Python tests.""" |
| + version_info = '' |
| + if chrome_version_name: |
| + version_info = '(%s)' % chrome_version_name |
| + self.m.step('python_tests%s' % version_info, |
| + self._generate_test_command('run_py_tests.py', chromedriver, |
| + test_log_dir, |
| + ref_chromedriver=ref_chromedriver, |
| + android_package=android_package, |
| + build_type=build_type), |
| + **kwargs) |
| + |
| + def run_java_tests(self, chromedriver, test_log_dir, chrome=None, |
| + chrome_version_name=None, |
| + android_package=None, build_type=None, verbose=False, |
| + **kwargs): |
| + """Run the Chromedriver Java tests.""" |
| + version_info = '' |
| + if chrome_version_name: |
| + version_info = '(%s)' % chrome_version_name |
| + self.m.step('java_tests%s' % version_info, |
| + self._generate_test_command('run_java_tests.py', chromedriver, |
| + test_log_dir, |
| + ref_chromedriver=None, |
| + android_package=android_package, |
| + build_type=build_type, |
| + verbose=verbose), |
| + **kwargs) |
| + |
| + def run_all_tests(self, android_packages=None, archive_server_logs=True): |
| + """Run all Chromedriver tests.""" |
| + server_name = 'chromedriver' |
| + chromedriver = self.m.chromium.output_dir.join(server_name) |
| + build_type = self.m.path.basename(self.m.chromium.output_dir) |
| + |
| + platform_name = self.m.platform.name |
| + if self.m.platform.is_linux and self.m.platform.bits == 64: |
| + platform_name = 'linux64' |
| + ref_chromedriver = self.m.path.join( |
| + self.m.path['checkout'], |
| + 'chrome', 'test', 'chromedriver', 'third_party', 'java_tests', |
| + 'reference_builds', 'chromedriver_%s' % platform_name) |
| + |
| + test_env = {'PATH': '%(PATH)s'} |
| + test_env['PATH'] = self.m.path.pathsep.join([ |
| + test_env['PATH'], |
| + str(self.m.path['checkout'].join( |
| + 'chrome', 'test', 'chromedriver', 'chrome'))]) |
| + try: |
| + temp_log_dir = self.m.path.mkdtemp('results_log') |
| + with self.m.step.defer_results(): |
| + for package in android_packages: |
| + self.run_python_tests(chromedriver, |
| + temp_log_dir, |
| + ref_chromedriver, |
| + chrome_version_name=package, |
| + android_package=package, |
| + build_type=build_type, |
| + env=test_env) |
| + self.run_java_tests(chromedriver, |
| + temp_log_dir, |
| + chrome_version_name=package, |
| + android_package=package, |
| + build_type=build_type, |
| + verbose=True, |
| + env=test_env) |
| + if archive_server_logs: |
| + self.archive_server_logs(temp_log_dir) |
| + finally: |
| + self.m.file.rmtree(name='Remove Temp Log Dir', path=temp_log_dir) |