Chromium Code Reviews| 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 """Run specific test on specific environment.""" | 5 """Run specific test on specific environment.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import tempfile | 9 import tempfile |
| 10 | 10 |
| 11 from devil.utils import reraiser_thread | |
| 12 from devil.utils import tempdir | |
| 11 from pylib.base import base_test_result | 13 from pylib.base import base_test_result |
| 12 from pylib.remote.device import remote_device_test_run | 14 from pylib.remote.device import remote_device_test_run |
| 13 | 15 |
| 14 | 16 |
| 15 class RemoteDeviceInstrumentationTestRun( | 17 class RemoteDeviceInstrumentationTestRun( |
| 16 remote_device_test_run.RemoteDeviceTestRun): | 18 remote_device_test_run.RemoteDeviceTestRun): |
| 17 """Run instrumentation tests on a remote device.""" | 19 """Run instrumentation tests on a remote device.""" |
| 18 | 20 |
| 19 #override | 21 #override |
| 20 def TestPackage(self): | 22 def TestPackage(self): |
| 21 return self._test_instance.test_package | 23 return self._test_instance.test_package |
| 22 | 24 |
| 23 #override | 25 #override |
| 24 def _TriggerSetUp(self): | 26 def _GetAppPath(self): |
| 25 """Set up the triggering of a test run.""" | 27 return self._test_instance.apk_under_test |
| 26 logging.info('Triggering test run.') | |
| 27 | |
| 28 # pylint: disable=protected-access | |
| 29 with tempfile.NamedTemporaryFile(suffix='.txt') as test_list_file: | |
| 30 tests = self._test_instance.GetTests() | |
| 31 logging.debug('preparing to run %d instrumentation tests remotely:', | |
| 32 len(tests)) | |
| 33 for t in tests: | |
| 34 test_name = '%s#%s' % (t['class'], t['method']) | |
| 35 logging.debug(' %s', test_name) | |
| 36 test_list_file.write('%s\n' % test_name) | |
| 37 test_list_file.flush() | |
| 38 self._test_instance._data_deps.append( | |
| 39 (os.path.abspath(test_list_file.name), None)) | |
| 40 | |
| 41 env_vars = self._test_instance.GetDriverEnvironmentVars( | |
| 42 test_list_file_path=test_list_file.name) | |
| 43 env_vars.update(self._test_instance.GetHttpServerEnvironmentVars()) | |
| 44 | |
| 45 logging.debug('extras:') | |
| 46 for k, v in env_vars.iteritems(): | |
| 47 logging.debug(' %s: %s', k, v) | |
| 48 | |
| 49 self._AmInstrumentTestSetup( | |
| 50 self._test_instance.apk_under_test, | |
| 51 self._test_instance.driver_apk, | |
| 52 self._test_instance.driver_name, | |
| 53 environment_variables=env_vars, | |
| 54 extra_apks=([self._test_instance.test_apk] + | |
| 55 self._test_instance.additional_apks)) | |
| 56 | 28 |
| 57 #override | 29 #override |
| 58 def _ParseTestResults(self): | 30 def _GetTestFramework(self): |
| 31 if self._env.test_framework: | |
| 32 logging.warning('Ignoring configured test_framework "%s"', | |
| 33 self._env.test_framework) | |
| 34 return 'robotium' | |
| 35 | |
| 36 #override | |
| 37 def _ParseTestResults(self, test_output, results_zip): | |
| 59 logging.info('Parsing results from stdout.') | 38 logging.info('Parsing results from stdout.') |
| 60 r = base_test_result.TestRunResults() | 39 results = base_test_result.TestRunResults() |
| 61 result_code, result_bundle, statuses = ( | 40 result_code, result_bundle, statuses = ( |
| 62 self._test_instance.ParseAmInstrumentRawOutput( | 41 self._test_instance.ParseAmInstrumentRawOutput( |
| 63 self._results['results']['output'].splitlines())) | 42 test_output['results']['output'].splitlines())) |
| 64 result = self._test_instance.GenerateTestResults( | 43 result = self._test_instance.GenerateTestResults( |
| 65 result_code, result_bundle, statuses, 0, 0) | 44 result_code, result_bundle, statuses, 0, 0) |
| 66 | 45 |
| 67 if isinstance(result, base_test_result.BaseTestResult): | 46 if isinstance(result, base_test_result.BaseTestResult): |
| 68 r.AddResult(result) | 47 results.AddResult(result) |
| 69 elif isinstance(result, list): | 48 elif isinstance(result, list): |
| 70 r.AddResults(result) | 49 results.AddResults(result) |
| 71 else: | 50 else: |
| 72 raise Exception('Unexpected result type: %s' % type(result).__name__) | 51 raise Exception('Unexpected result type: %s' % type(result).__name__) |
| 73 | 52 |
| 74 self._DetectPlatformErrors(r) | 53 remote_device_test_run.DetectPlatformErrors( |
| 75 return r | 54 results, test_output, results_zip) |
| 55 return results | |
| 56 | |
| 57 #override | |
| 58 def _ShouldShard(self): | |
| 59 return True | |
| 60 | |
| 61 #override | |
| 62 def _SetupTestShards(self, num_shards): | |
|
jbudorick
2015/12/01 04:07:13
This function is also doing too much. It shouldn't
| |
| 63 test_ids = [] | |
| 64 | |
| 65 all_tests = self._test_instance.GetTests() | |
| 66 test_shards = [all_tests[i::num_shards] for i in range(num_shards)] | |
| 67 | |
| 68 test_list_files = [] | |
| 69 with tempdir.TempDir() as test_list_dir: | |
| 70 for i, tests in enumerate(test_shards): | |
| 71 test_list_file = tempfile.NamedTemporaryFile( | |
| 72 suffix='.txt', dir=test_list_dir, delete=False) | |
| 73 test_list_files.append(test_list_file) | |
| 74 for t in tests: | |
| 75 test_name = '%s#%s' % (t['class'], t['method']) | |
| 76 logging.debug('shard %s: %s', i, test_name) | |
| 77 test_list_file.write('%s\n' % test_name) | |
| 78 test_list_file.flush() | |
| 79 | |
| 80 with tempfile.NamedTemporaryFile(suffix='.zip') as test_package: | |
| 81 extra_apks = ([self._test_instance.test_apk] + | |
| 82 self._test_instance.additional_apks) | |
| 83 data_deps = (self._test_instance.GetDataDependencies() + | |
| 84 [(os.path.abspath(f.name), None) for f in test_list_files]) | |
| 85 package_configs = self._PackageTest( | |
| 86 test_package.name, self._test_instance.driver_apk, data_deps, | |
| 87 extra_apks=extra_apks) | |
| 88 | |
| 89 framework_configs = { | |
| 90 'runner': self._test_instance.driver_name, | |
| 91 } | |
| 92 framework_configs.update(package_configs) | |
| 93 | |
| 94 def upload_test_shards(test_list_file): | |
| 95 shard_framework_config = dict(framework_configs) | |
| 96 env_vars = self._test_instance.GetDriverEnvironmentVars( | |
| 97 test_list_file_path=test_list_file.name) | |
| 98 env_vars.update(self._test_instance.GetHttpServerEnvironmentVars()) | |
| 99 shard_framework_config['environment_vars'] = ','.join( | |
| 100 '%s=%s' % (k, v) for k, v in env_vars.iteritems()) | |
| 101 | |
| 102 test_id = self._UploadTestToDevice(test_package.name) | |
| 103 self._UploadTestConfigToDevice( | |
| 104 test_id, shard_framework_config, self._appurify_configs) | |
| 105 test_ids.append(test_id) | |
| 106 | |
| 107 reraiser_thread.RunAsync( | |
| 108 funcs=[upload_test_shards]*num_shards, | |
|
jbudorick
2015/12/01 04:07:13
I'd prefer you not add args, kwargs, or names to R
| |
| 109 args=[[test_list_file] for test_list_file in test_list_files], | |
| 110 names=['upload test shard %d' % i for i in range(num_shards)]) | |
| 111 | |
| 112 return test_ids | |
| OLD | NEW |