| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """Runs all the native unit tests. | 7 """Runs all the native unit tests. |
| 8 | 8 |
| 9 1. Copy over test binary to /data/local on device. | 9 1. Copy over test binary to /data/local on device. |
| 10 2. Resources: chrome/unit_tests requires resources (chrome.pak and en-US.pak) | 10 2. Resources: chrome/unit_tests requires resources (chrome.pak and en-US.pak) |
| 11 to be deployed to the device. We use the device's $EXTERNAL_STORAGE as the | 11 to be deployed to the device. We use the device's $EXTERNAL_STORAGE as the |
| 12 base dir (which maps to Context.getExternalFilesDir()). | 12 base dir (which maps to Context.getExternalFilesDir()). |
| 13 3. Environment: | 13 3. Environment: |
| 14 3.1. chrome/unit_tests requires (via chrome_paths.cc) a directory named: | 14 3.1. chrome/unit_tests requires (via chrome_paths.cc) a directory named: |
| 15 $EXTERNAL_STORAGE + /chrome/test/data | 15 $EXTERNAL_STORAGE + /chrome/test/data |
| 16 3.2. page_cycler_tests have following requirements, | |
| 17 3.2.1 the following data on host: | |
| 18 <chrome_src_dir>/tools/page_cycler | |
| 19 <chrome_src_dir>/data/page_cycler | |
| 20 3.2.2. two data directories to store above test data on device named: | |
| 21 $EXTERNAL_STORAGE + /tools/ (for database perf test) | |
| 22 $EXTERNAL_STORAGE + /data/ (for other perf tests) | |
| 23 3.2.3. a http server to serve http perf tests. | |
| 24 The http root is host's <chrome_src_dir>/data/page_cycler/, port 8000. | |
| 25 3.2.4 a tool named forwarder is also required to run on device to | |
| 26 forward the http request/response between host and device. | |
| 27 3.2.5 Chrome is installed on device. | |
| 28 4. Run the binary in the device and stream the log to the host. | 16 4. Run the binary in the device and stream the log to the host. |
| 29 4.1. Optionally, filter specific tests. | 17 4.1. Optionally, filter specific tests. |
| 30 4.2. If we're running a single test suite and we have multiple devices | 18 4.2. If we're running a single test suite and we have multiple devices |
| 31 connected, we'll shard the tests. | 19 connected, we'll shard the tests. |
| 32 5. Clean up the device. | 20 5. Clean up the device. |
| 33 | 21 |
| 34 Suppressions: | 22 Suppressions: |
| 35 | 23 |
| 36 Individual tests in a test binary can be suppressed by listing it in | 24 Individual tests in a test binary can be suppressed by listing it in |
| 37 the gtest_filter directory in a file of the same name as the test binary, | 25 the gtest_filter directory in a file of the same name as the test binary, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 except: | 166 except: |
| 179 pass | 167 pass |
| 180 del os.environ['DISPLAY'] | 168 del os.environ['DISPLAY'] |
| 181 self._pid = 0 | 169 self._pid = 0 |
| 182 | 170 |
| 183 | 171 |
| 184 class TestSharder(BaseTestSharder): | 172 class TestSharder(BaseTestSharder): |
| 185 """Responsible for sharding the tests on the connected devices.""" | 173 """Responsible for sharding the tests on the connected devices.""" |
| 186 | 174 |
| 187 def __init__(self, attached_devices, test_suite, gtest_filter, | 175 def __init__(self, attached_devices, test_suite, gtest_filter, |
| 188 test_arguments, timeout, performance_test, | 176 test_arguments, timeout, cleanup_test_files, tool, |
| 189 cleanup_test_files, tool, log_dump_name, fast_and_loose, | 177 log_dump_name, fast_and_loose, build_type, in_webkit_checkout): |
| 190 build_type, in_webkit_checkout): | |
| 191 BaseTestSharder.__init__(self, attached_devices, build_type) | 178 BaseTestSharder.__init__(self, attached_devices, build_type) |
| 192 self.test_suite = test_suite | 179 self.test_suite = test_suite |
| 193 self.test_suite_basename = os.path.basename(test_suite) | 180 self.test_suite_basename = os.path.basename(test_suite) |
| 194 self.gtest_filter = gtest_filter or '' | 181 self.gtest_filter = gtest_filter or '' |
| 195 self.test_arguments = test_arguments | 182 self.test_arguments = test_arguments |
| 196 self.timeout = timeout | 183 self.timeout = timeout |
| 197 self.performance_test = performance_test | |
| 198 self.cleanup_test_files = cleanup_test_files | 184 self.cleanup_test_files = cleanup_test_files |
| 199 self.tool = tool | 185 self.tool = tool |
| 200 self.log_dump_name = log_dump_name | 186 self.log_dump_name = log_dump_name |
| 201 self.fast_and_loose = fast_and_loose | 187 self.fast_and_loose = fast_and_loose |
| 202 self.in_webkit_checkout = in_webkit_checkout | 188 self.in_webkit_checkout = in_webkit_checkout |
| 203 self.all_tests = [] | 189 self.all_tests = [] |
| 204 if not self.gtest_filter: | 190 if not self.gtest_filter: |
| 205 # No filter has been specified, let's add all tests then. | 191 # No filter has been specified, let's add all tests then. |
| 206 self.all_tests = self._GetAllEnabledTests() | 192 self.all_tests = self._GetAllEnabledTests() |
| 207 self.tests = self.all_tests | 193 self.tests = self.all_tests |
| (...skipping 18 matching lines...) Expand all Loading... |
| 226 raise Exception('No device available to get the list of tests.') | 212 raise Exception('No device available to get the list of tests.') |
| 227 | 213 |
| 228 def _GetTestsFromDevice(self, device): | 214 def _GetTestsFromDevice(self, device): |
| 229 logging.info('Obtaining tests from %s', device) | 215 logging.info('Obtaining tests from %s', device) |
| 230 test_runner = SingleTestRunner( | 216 test_runner = SingleTestRunner( |
| 231 device, | 217 device, |
| 232 self.test_suite, | 218 self.test_suite, |
| 233 self.gtest_filter, | 219 self.gtest_filter, |
| 234 self.test_arguments, | 220 self.test_arguments, |
| 235 self.timeout, | 221 self.timeout, |
| 236 self.performance_test, | |
| 237 self.cleanup_test_files, | 222 self.cleanup_test_files, |
| 238 self.tool, | 223 self.tool, |
| 239 0, | 224 0, |
| 240 not not self.log_dump_name, | 225 not not self.log_dump_name, |
| 241 self.fast_and_loose, | 226 self.fast_and_loose, |
| 242 self.build_type, | 227 self.build_type, |
| 243 self.in_webkit_checkout) | 228 self.in_webkit_checkout) |
| 244 # The executable/apk needs to be copied before we can call GetAllTests. | 229 # The executable/apk needs to be copied before we can call GetAllTests. |
| 245 test_runner.test_package.StripAndCopyExecutable() | 230 test_runner.test_package.StripAndCopyExecutable() |
| 246 all_tests = test_runner.test_package.GetAllTests() | 231 all_tests = test_runner.test_package.GetAllTests() |
| (...skipping 18 matching lines...) Expand all Loading... |
| 265 device_num = len(self.attached_devices) | 250 device_num = len(self.attached_devices) |
| 266 shard_size = (len(self.tests) + device_num - 1) / device_num | 251 shard_size = (len(self.tests) + device_num - 1) / device_num |
| 267 shard_test_list = self.tests[index * shard_size : (index + 1) * shard_size] | 252 shard_test_list = self.tests[index * shard_size : (index + 1) * shard_size] |
| 268 test_filter = ':'.join(shard_test_list) + self.gtest_filter | 253 test_filter = ':'.join(shard_test_list) + self.gtest_filter |
| 269 return SingleTestRunner( | 254 return SingleTestRunner( |
| 270 device, | 255 device, |
| 271 self.test_suite, | 256 self.test_suite, |
| 272 test_filter, | 257 test_filter, |
| 273 self.test_arguments, | 258 self.test_arguments, |
| 274 self.timeout, | 259 self.timeout, |
| 275 self.performance_test, | |
| 276 self.cleanup_test_files, self.tool, index, | 260 self.cleanup_test_files, self.tool, index, |
| 277 not not self.log_dump_name, | 261 not not self.log_dump_name, |
| 278 self.fast_and_loose, | 262 self.fast_and_loose, |
| 279 self.build_type, | 263 self.build_type, |
| 280 self.in_webkit_checkout) | 264 self.in_webkit_checkout) |
| 281 | 265 |
| 282 def OnTestsCompleted(self, test_runners, test_results): | 266 def OnTestsCompleted(self, test_runners, test_results): |
| 283 """Notifies that we completed the tests.""" | 267 """Notifies that we completed the tests.""" |
| 284 test_results.LogFull('Unit test', os.path.basename(self.test_suite), | 268 test_results.LogFull('Unit test', os.path.basename(self.test_suite), |
| 285 self.build_type, self.all_tests) | 269 self.build_type, self.all_tests) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 if not attached_devices: | 318 if not attached_devices: |
| 335 logging.critical('A device must be attached and online.') | 319 logging.critical('A device must be attached and online.') |
| 336 buildbot_report.PrintError() | 320 buildbot_report.PrintError() |
| 337 return 1 | 321 return 1 |
| 338 | 322 |
| 339 # Reset the test port allocation. It's important to do it before starting | 323 # Reset the test port allocation. It's important to do it before starting |
| 340 # to dispatch any tests. | 324 # to dispatch any tests. |
| 341 if not ports.ResetTestServerPortAllocation(): | 325 if not ports.ResetTestServerPortAllocation(): |
| 342 raise Exception('Failed to reset test server port.') | 326 raise Exception('Failed to reset test server port.') |
| 343 | 327 |
| 344 if options.performance_test or options.gtest_filter: | 328 if options.gtest_filter: |
| 345 logging.warning('Sharding is not possible with these configurations.') | 329 logging.warning('Sharding is not possible with these configurations.') |
| 346 attached_devices = [attached_devices[0]] | 330 attached_devices = [attached_devices[0]] |
| 347 | 331 |
| 348 sharder = TestSharder( | 332 sharder = TestSharder( |
| 349 attached_devices, | 333 attached_devices, |
| 350 options.test_suite, | 334 options.test_suite, |
| 351 options.gtest_filter, | 335 options.gtest_filter, |
| 352 options.test_arguments, | 336 options.test_arguments, |
| 353 options.timeout, | 337 options.timeout, |
| 354 options.performance_test, | |
| 355 options.cleanup_test_files, | 338 options.cleanup_test_files, |
| 356 options.tool, | 339 options.tool, |
| 357 options.log_dump, | 340 options.log_dump, |
| 358 options.fast_and_loose, | 341 options.fast_and_loose, |
| 359 options.build_type, | 342 options.build_type, |
| 360 options.webkit) | 343 options.webkit) |
| 361 test_results = sharder.RunShardedTests() | 344 test_results = sharder.RunShardedTests() |
| 362 | 345 |
| 363 for buildbot_emulator in buildbot_emulators: | 346 for buildbot_emulator in buildbot_emulators: |
| 364 buildbot_emulator.Shutdown() | 347 buildbot_emulator.Shutdown() |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 '(use -s help to list them)') | 398 '(use -s help to list them)') |
| 416 option_parser.add_option('--out-directory', dest='out_directory', | 399 option_parser.add_option('--out-directory', dest='out_directory', |
| 417 help='Path to the out/ directory, irrespective of ' | 400 help='Path to the out/ directory, irrespective of ' |
| 418 'the build type. Only for non-Chromium uses.') | 401 'the build type. Only for non-Chromium uses.') |
| 419 option_parser.add_option('-d', '--device', dest='test_device', | 402 option_parser.add_option('-d', '--device', dest='test_device', |
| 420 help='Target device the test suite to run ') | 403 help='Target device the test suite to run ') |
| 421 option_parser.add_option('-f', '--gtest_filter', dest='gtest_filter', | 404 option_parser.add_option('-f', '--gtest_filter', dest='gtest_filter', |
| 422 help='gtest filter') | 405 help='gtest filter') |
| 423 option_parser.add_option('-a', '--test_arguments', dest='test_arguments', | 406 option_parser.add_option('-a', '--test_arguments', dest='test_arguments', |
| 424 help='Additional arguments to pass to the test') | 407 help='Additional arguments to pass to the test') |
| 425 option_parser.add_option('-p', dest='performance_test', | |
| 426 help='Indicator of performance test', | |
| 427 action='store_true') | |
| 428 option_parser.add_option('-L', dest='log_dump', | 408 option_parser.add_option('-L', dest='log_dump', |
| 429 help='file name of log dump, which will be put in ' | 409 help='file name of log dump, which will be put in ' |
| 430 'subfolder debug_info_dumps under the same ' | 410 'subfolder debug_info_dumps under the same ' |
| 431 'directory in where the test_suite exists.') | 411 'directory in where the test_suite exists.') |
| 432 option_parser.add_option('-e', '--emulator', dest='use_emulator', | 412 option_parser.add_option('-e', '--emulator', dest='use_emulator', |
| 433 action='store_true', | 413 action='store_true', |
| 434 help='Run tests in a new instance of emulator') | 414 help='Run tests in a new instance of emulator') |
| 435 option_parser.add_option('-n', '--emulator_count', | 415 option_parser.add_option('-n', '--emulator_count', |
| 436 type='int', default=1, | 416 type='int', default=1, |
| 437 help='Number of emulators to launch for running the ' | 417 help='Number of emulators to launch for running the ' |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 # the batch (this happens because the exit status is a sum of all failures | 463 # the batch (this happens because the exit status is a sum of all failures |
| 484 # from all suites, but the buildbot associates the exit status only with the | 464 # from all suites, but the buildbot associates the exit status only with the |
| 485 # most recent step). | 465 # most recent step). |
| 486 if options.exit_code: | 466 if options.exit_code: |
| 487 return failed_tests_count | 467 return failed_tests_count |
| 488 return 0 | 468 return 0 |
| 489 | 469 |
| 490 | 470 |
| 491 if __name__ == '__main__': | 471 if __name__ == '__main__': |
| 492 sys.exit(main(sys.argv)) | 472 sys.exit(main(sys.argv)) |
| OLD | NEW |