OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Takes care of sharding the python-drive tests in multiple devices.""" | 5 """Takes care of sharding the python-drive tests in multiple devices.""" |
6 | 6 |
| 7 import copy |
7 import logging | 8 import logging |
8 import multiprocessing | 9 import multiprocessing |
9 | 10 |
10 from python_test_caller import CallPythonTest | 11 from python_test_caller import CallPythonTest |
11 from run_java_tests import FatalTestException | 12 from run_java_tests import FatalTestException |
12 import sharded_tests_queue | 13 import sharded_tests_queue |
13 from test_result import TestResults | 14 from test_result import TestResults |
14 | 15 |
15 | 16 |
16 def SetTestsContainer(tests_container): | 17 def SetTestsContainer(tests_container): |
(...skipping 26 matching lines...) Expand all Loading... |
43 class PythonTestRunner(object): | 44 class PythonTestRunner(object): |
44 """Thin wrapper around a list of PythonTestBase instances. | 45 """Thin wrapper around a list of PythonTestBase instances. |
45 | 46 |
46 This is meant to be a long-lived object which can run multiple Python tests | 47 This is meant to be a long-lived object which can run multiple Python tests |
47 within its lifetime. Tests will receive the device_id and shard_index. | 48 within its lifetime. Tests will receive the device_id and shard_index. |
48 | 49 |
49 The shard index affords the ability to create unique port numbers (e.g. | 50 The shard index affords the ability to create unique port numbers (e.g. |
50 DEFAULT_PORT + shard_index) if the test so wishes. | 51 DEFAULT_PORT + shard_index) if the test so wishes. |
51 """ | 52 """ |
52 | 53 |
53 def __init__(self, device_id, shard_index): | 54 def __init__(self, options): |
54 """Constructor. | 55 """Constructor. |
55 | 56 |
56 Args: | 57 Args: |
57 device_id: ID of the device which this test will talk to. | 58 options: Options to use for setting up tests. |
58 shard_index: shard index, used to create such as unique port numbers. | |
59 """ | 59 """ |
60 self.device_id = device_id | 60 self.options = options |
61 self.shard_index = shard_index | |
62 | 61 |
63 def RunTests(self): | 62 def RunTests(self): |
64 """Runs tests from the shared pool of tests, aggregating results. | 63 """Runs tests from the shared pool of tests, aggregating results. |
65 | 64 |
66 Returns: | 65 Returns: |
67 A list of test results for all of the tests which this runner executed. | 66 A list of test results for all of the tests which this runner executed. |
68 """ | 67 """ |
69 tests = PythonTestSharder.tests_container | 68 tests = PythonTestSharder.tests_container |
70 | 69 |
71 results = [] | 70 results = [] |
72 for t in tests: | 71 for t in tests: |
73 res = CallPythonTest(t, self.device_id, self.shard_index) | 72 res = CallPythonTest(t, self.options) |
74 results.append(res) | 73 results.append(res) |
75 | 74 |
76 return TestResults.FromTestResults(results) | 75 return TestResults.FromTestResults(results) |
77 | 76 |
78 | 77 |
79 class PythonTestSharder(object): | 78 class PythonTestSharder(object): |
80 """Runs Python tests in parallel on multiple devices. | 79 """Runs Python tests in parallel on multiple devices. |
81 | 80 |
82 This is lifted more or less wholesale from BaseTestRunner. | 81 This is lifted more or less wholesale from BaseTestRunner. |
83 | 82 |
84 Under the covers, it creates a pool of long-lived PythonTestRunners, which | 83 Under the covers, it creates a pool of long-lived PythonTestRunners, which |
85 execute tests from the pool of tests. | 84 execute tests from the pool of tests. |
86 | 85 |
87 Args: | 86 Args: |
88 attached_devices: a list of device IDs attached to the host. | 87 attached_devices: a list of device IDs attached to the host. |
89 shard_retries: number of retries for any given test. | |
90 available_tests: a list of tests to run which subclass PythonTestBase. | 88 available_tests: a list of tests to run which subclass PythonTestBase. |
| 89 options: Options to use for setting up tests. |
91 | 90 |
92 Returns: | 91 Returns: |
93 An aggregated list of test results. | 92 An aggregated list of test results. |
94 """ | 93 """ |
95 tests_container = None | 94 tests_container = None |
96 | 95 |
97 def __init__(self, attached_devices, shard_retries, available_tests): | 96 def __init__(self, attached_devices, available_tests, options): |
| 97 self.options = options |
98 self.attached_devices = attached_devices | 98 self.attached_devices = attached_devices |
99 self.retries = shard_retries | 99 self.retries = options.shard_retries |
100 self.tests = available_tests | 100 self.tests = available_tests |
101 | 101 |
102 def _SetupSharding(self, tests): | 102 def _SetupSharding(self, tests): |
103 """Creates the shared pool of tests and makes it available to test runners. | 103 """Creates the shared pool of tests and makes it available to test runners. |
104 | 104 |
105 Args: | 105 Args: |
106 tests: the list of tests which will be consumed by workers. | 106 tests: the list of tests which will be consumed by workers. |
107 """ | 107 """ |
108 SetTestsContainer(sharded_tests_queue.ShardedTestsQueue( | 108 SetTestsContainer(sharded_tests_queue.ShardedTestsQueue( |
109 len(self.attached_devices), tests)) | 109 len(self.attached_devices), tests)) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 Returns: | 171 Returns: |
172 A list of PythonTestRunners, one for each device. | 172 A list of PythonTestRunners, one for each device. |
173 """ | 173 """ |
174 test_runners = [] | 174 test_runners = [] |
175 for index, device in enumerate(attached_devices): | 175 for index, device in enumerate(attached_devices): |
176 logging.warning('*' * 80) | 176 logging.warning('*' * 80) |
177 logging.warning('Creating shard %d for %s', index, device) | 177 logging.warning('Creating shard %d for %s', index, device) |
178 logging.warning('*' * 80) | 178 logging.warning('*' * 80) |
179 # Bind the PythonTestRunner to a device & shard index. Give it the | 179 # Bind the PythonTestRunner to a device & shard index. Give it the |
180 # runnable which it will use to actually execute the tests. | 180 # runnable which it will use to actually execute the tests. |
181 test_runner = PythonTestRunner(device, index) | 181 test_options = copy.deepcopy(self.options) |
| 182 test_options.ensure_value('device_id', device) |
| 183 test_options.ensure_value('shard_index', index) |
| 184 test_runner = PythonTestRunner(test_options) |
182 test_runners.append(test_runner) | 185 test_runners.append(test_runner) |
183 | 186 |
184 return test_runners | 187 return test_runners |
185 | 188 |
186 def _GetTestsToRetry(self, available_tests, failed_tests): | 189 def _GetTestsToRetry(self, available_tests, failed_tests): |
187 """Infers a list of tests to retry from failed tests and available tests. | 190 """Infers a list of tests to retry from failed tests and available tests. |
188 | 191 |
189 Args: | 192 Args: |
190 available_tests: a list of tests which subclass PythonTestBase. | 193 available_tests: a list of tests which subclass PythonTestBase. |
191 failed_tests: a list of SingleTestResults representing failed tests. | 194 failed_tests: a list of SingleTestResults representing failed tests. |
192 | 195 |
193 Returns: | 196 Returns: |
194 A list of test objects which correspond to test names found in | 197 A list of test objects which correspond to test names found in |
195 failed_tests, or an empty list if there is no correspondence. | 198 failed_tests, or an empty list if there is no correspondence. |
196 """ | 199 """ |
197 failed_test_names = map(lambda t: t.test_name, failed_tests) | 200 failed_test_names = map(lambda t: t.test_name, failed_tests) |
198 tests_to_retry = [t for t in available_tests | 201 tests_to_retry = [t for t in available_tests |
199 if t.qualified_name in failed_test_names] | 202 if t.qualified_name in failed_test_names] |
200 return tests_to_retry | 203 return tests_to_retry |
OLD | NEW |