| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2013 The Chromium Authors. All rights reserved. | 3 # Copyright 2013 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 types of tests from one unified interface. | 7 """Runs all types of tests from one unified interface. |
| 8 | 8 |
| 9 TODO(gkanwar): | 9 TODO(gkanwar): |
| 10 * Add options to run Monkey tests. | 10 * Add options to run Monkey tests. |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import collections | 13 import collections |
| 14 import optparse | 14 import optparse |
| 15 import os | 15 import os |
| 16 import shutil | 16 import shutil |
| 17 import sys | 17 import sys |
| 18 | 18 |
| 19 from pylib import constants | 19 from pylib import constants |
| 20 from pylib import ports | 20 from pylib import ports |
| 21 from pylib.base import base_test_result | 21 from pylib.base import base_test_result |
| 22 from pylib.base import test_dispatcher | 22 from pylib.base import test_dispatcher |
| 23 from pylib.gtest import gtest_config | 23 from pylib.gtest import gtest_config |
| 24 from pylib.gtest import setup as gtest_setup | 24 from pylib.gtest import setup as gtest_setup |
| 25 from pylib.gtest import test_options as gtest_test_options | 25 from pylib.gtest import test_options as gtest_test_options |
| 26 from pylib.host_driven import setup as host_driven_setup | 26 from pylib.host_driven import setup as host_driven_setup |
| 27 from pylib.instrumentation import setup as instrumentation_setup | 27 from pylib.instrumentation import setup as instrumentation_setup |
| 28 from pylib.instrumentation import test_options as instrumentation_test_options | 28 from pylib.instrumentation import test_options as instrumentation_test_options |
| 29 from pylib.monkey import setup as monkey_setup |
| 30 from pylib.monkey import test_options as monkey_test_options |
| 29 from pylib.uiautomator import setup as uiautomator_setup | 31 from pylib.uiautomator import setup as uiautomator_setup |
| 30 from pylib.uiautomator import test_options as uiautomator_test_options | 32 from pylib.uiautomator import test_options as uiautomator_test_options |
| 31 from pylib.utils import report_results | 33 from pylib.utils import report_results |
| 32 from pylib.utils import run_tests_helper | 34 from pylib.utils import run_tests_helper |
| 33 | 35 |
| 34 | 36 |
| 35 _SDK_OUT_DIR = os.path.join(constants.DIR_SOURCE_ROOT, 'out') | 37 _SDK_OUT_DIR = os.path.join(constants.DIR_SOURCE_ROOT, 'out') |
| 36 | 38 |
| 37 | 39 |
| 38 def AddBuildTypeOption(option_parser): | 40 def AddBuildTypeOption(option_parser): |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 325 |
| 324 def ProcessUIAutomatorOptions(options, error_func): | 326 def ProcessUIAutomatorOptions(options, error_func): |
| 325 """Processes UIAutomator options/arguments. | 327 """Processes UIAutomator options/arguments. |
| 326 | 328 |
| 327 Args: | 329 Args: |
| 328 options: optparse.Options object. | 330 options: optparse.Options object. |
| 329 error_func: Function to call with the error message in case of an error. | 331 error_func: Function to call with the error message in case of an error. |
| 330 | 332 |
| 331 Returns: | 333 Returns: |
| 332 A UIAutomatorOptions named tuple which contains all options relevant to | 334 A UIAutomatorOptions named tuple which contains all options relevant to |
| 333 instrumentation tests. | 335 uiautomator tests. |
| 334 """ | 336 """ |
| 335 | 337 |
| 336 ProcessJavaTestOptions(options, error_func) | 338 ProcessJavaTestOptions(options, error_func) |
| 337 | 339 |
| 338 if not options.package_name: | 340 if not options.package_name: |
| 339 error_func('--package-name must be specified.') | 341 error_func('--package-name must be specified.') |
| 340 | 342 |
| 341 if not options.test_jar: | 343 if not options.test_jar: |
| 342 error_func('--test-jar must be specified.') | 344 error_func('--test-jar must be specified.') |
| 343 | 345 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 362 options.test_filter, | 364 options.test_filter, |
| 363 options.test_data, | 365 options.test_data, |
| 364 options.save_perf_json, | 366 options.save_perf_json, |
| 365 options.screenshot_failures, | 367 options.screenshot_failures, |
| 366 options.disable_assertions, | 368 options.disable_assertions, |
| 367 options.uiautomator_jar, | 369 options.uiautomator_jar, |
| 368 options.uiautomator_info_jar, | 370 options.uiautomator_info_jar, |
| 369 options.package_name) | 371 options.package_name) |
| 370 | 372 |
| 371 | 373 |
| 374 def AddMonkeyTestOptions(option_parser): |
| 375 """Adds monkey test options to |option_parser|.""" |
| 376 option_parser.add_option('--package-name', help='Allowed package.') |
| 377 option_parser.add_option( |
| 378 '--activity-name', default='com.google.android.apps.chrome.Main', |
| 379 help='Name of the activity to start [default: %default].') |
| 380 option_parser.add_option( |
| 381 '--event-count', default=10000, type='int', |
| 382 help='Number of events to generate [default: %default].') |
| 383 option_parser.add_option( |
| 384 '--category', default='', |
| 385 help='A list of allowed categories [default: %default].') |
| 386 option_parser.add_option( |
| 387 '--throttle', default=100, type='int', |
| 388 help='Delay between events (ms) [default: %default]. ') |
| 389 option_parser.add_option( |
| 390 '--seed', type='int', |
| 391 help=('Seed value for pseudo-random generator. Same seed value generates ' |
| 392 'the same sequence of events. Seed is randomized by default.')) |
| 393 option_parser.add_option( |
| 394 '--extra-args', default='', |
| 395 help=('String of other args to pass to the command verbatim ' |
| 396 '[default: "%default"].')) |
| 397 |
| 398 AddCommonOptions(option_parser) |
| 399 |
| 400 |
| 401 def ProcessMonkeyTestOptions(options, error_func): |
| 402 """Processes all monkey test options. |
| 403 |
| 404 Args: |
| 405 options: optparse.Options object. |
| 406 error_func: Function to call with the error message in case of an error. |
| 407 |
| 408 Returns: |
| 409 A MonkeyOptions named tuple which contains all options relevant to |
| 410 monkey tests. |
| 411 """ |
| 412 if not options.package_name: |
| 413 error_func('Package name is required.') |
| 414 |
| 415 category = options.category |
| 416 if category: |
| 417 category = options.category.split(',') |
| 418 |
| 419 return monkey_test_options.MonkeyOptions( |
| 420 options.build_type, |
| 421 options.verbose_count, |
| 422 options.package_name, |
| 423 options.activity_name, |
| 424 options.event_count, |
| 425 category, |
| 426 options.throttle, |
| 427 options.seed, |
| 428 options.extra_args) |
| 429 |
| 430 |
| 372 def _RunGTests(options, error_func): | 431 def _RunGTests(options, error_func): |
| 373 """Subcommand of RunTestsCommands which runs gtests.""" | 432 """Subcommand of RunTestsCommands which runs gtests.""" |
| 374 ProcessGTestOptions(options) | 433 ProcessGTestOptions(options) |
| 375 | 434 |
| 376 exit_code = 0 | 435 exit_code = 0 |
| 377 for suite_name in options.suite_name: | 436 for suite_name in options.suite_name: |
| 378 # TODO(gkanwar): Move this into ProcessGTestOptions once we require -s for | 437 # TODO(gkanwar): Move this into ProcessGTestOptions once we require -s for |
| 379 # the gtest command. | 438 # the gtest command. |
| 380 gtest_options = gtest_test_options.GTestOptions( | 439 gtest_options = gtest_test_options.GTestOptions( |
| 381 options.build_type, | 440 options.build_type, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 build_type=options.build_type, | 518 build_type=options.build_type, |
| 460 flakiness_server=options.flakiness_dashboard_server) | 519 flakiness_server=options.flakiness_dashboard_server) |
| 461 | 520 |
| 462 return exit_code | 521 return exit_code |
| 463 | 522 |
| 464 | 523 |
| 465 def _RunUIAutomatorTests(options, error_func): | 524 def _RunUIAutomatorTests(options, error_func): |
| 466 """Subcommand of RunTestsCommands which runs uiautomator tests.""" | 525 """Subcommand of RunTestsCommands which runs uiautomator tests.""" |
| 467 uiautomator_options = ProcessUIAutomatorOptions(options, error_func) | 526 uiautomator_options = ProcessUIAutomatorOptions(options, error_func) |
| 468 | 527 |
| 469 results = base_test_result.TestRunResults() | |
| 470 exit_code = 0 | |
| 471 | |
| 472 runner_factory, tests = uiautomator_setup.Setup(uiautomator_options) | 528 runner_factory, tests = uiautomator_setup.Setup(uiautomator_options) |
| 473 | 529 |
| 474 results, exit_code = test_dispatcher.RunTests( | 530 results, exit_code = test_dispatcher.RunTests( |
| 475 tests, runner_factory, False, options.test_device, | 531 tests, runner_factory, False, options.test_device, |
| 476 shard=True, | 532 shard=True, |
| 477 build_type=options.build_type, | 533 build_type=options.build_type, |
| 478 test_timeout=None, | 534 test_timeout=None, |
| 479 num_retries=options.num_retries) | 535 num_retries=options.num_retries) |
| 480 | 536 |
| 481 report_results.LogFull( | 537 report_results.LogFull( |
| 482 results=results, | 538 results=results, |
| 483 test_type='UIAutomator', | 539 test_type='UIAutomator', |
| 484 test_package=os.path.basename(options.test_jar), | 540 test_package=os.path.basename(options.test_jar), |
| 485 annotation=options.annotations, | 541 annotation=options.annotations, |
| 486 build_type=options.build_type, | 542 build_type=options.build_type, |
| 487 flakiness_server=options.flakiness_dashboard_server) | 543 flakiness_server=options.flakiness_dashboard_server) |
| 488 | 544 |
| 489 return exit_code | 545 return exit_code |
| 490 | 546 |
| 491 | 547 |
| 548 def _RunMonkeyTests(options, error_func): |
| 549 """Subcommand of RunTestsCommands which runs monkey tests.""" |
| 550 monkey_options = ProcessMonkeyTestOptions(options, error_func) |
| 551 |
| 552 runner_factory, tests = monkey_setup.Setup(monkey_options) |
| 553 |
| 554 results, exit_code = test_dispatcher.RunTests( |
| 555 tests, runner_factory, False, None, shard=False) |
| 556 |
| 557 report_results.LogFull( |
| 558 results=results, |
| 559 test_type='Monkey', |
| 560 test_package='Monkey', |
| 561 build_type=options.build_type) |
| 562 |
| 563 return exit_code |
| 564 |
| 565 |
| 566 |
| 492 def RunTestsCommand(command, options, args, option_parser): | 567 def RunTestsCommand(command, options, args, option_parser): |
| 493 """Checks test type and dispatches to the appropriate function. | 568 """Checks test type and dispatches to the appropriate function. |
| 494 | 569 |
| 495 Args: | 570 Args: |
| 496 command: String indicating the command that was received to trigger | 571 command: String indicating the command that was received to trigger |
| 497 this function. | 572 this function. |
| 498 options: optparse options dictionary. | 573 options: optparse options dictionary. |
| 499 args: List of extra args from optparse. | 574 args: List of extra args from optparse. |
| 500 option_parser: optparse.OptionParser object. | 575 option_parser: optparse.OptionParser object. |
| 501 | 576 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 513 return constants.ERROR_EXIT_CODE | 588 return constants.ERROR_EXIT_CODE |
| 514 | 589 |
| 515 ProcessCommonOptions(options) | 590 ProcessCommonOptions(options) |
| 516 | 591 |
| 517 if command == 'gtest': | 592 if command == 'gtest': |
| 518 return _RunGTests(options, option_parser.error) | 593 return _RunGTests(options, option_parser.error) |
| 519 elif command == 'instrumentation': | 594 elif command == 'instrumentation': |
| 520 return _RunInstrumentationTests(options, option_parser.error) | 595 return _RunInstrumentationTests(options, option_parser.error) |
| 521 elif command == 'uiautomator': | 596 elif command == 'uiautomator': |
| 522 return _RunUIAutomatorTests(options, option_parser.error) | 597 return _RunUIAutomatorTests(options, option_parser.error) |
| 598 elif command == 'monkey': |
| 599 return _RunMonkeyTests(options, option_parser.error) |
| 523 else: | 600 else: |
| 524 raise Exception('Unknown test type.') | 601 raise Exception('Unknown test type.') |
| 525 | 602 |
| 526 | 603 |
| 527 def HelpCommand(command, options, args, option_parser): | 604 def HelpCommand(command, options, args, option_parser): |
| 528 """Display help for a certain command, or overall help. | 605 """Display help for a certain command, or overall help. |
| 529 | 606 |
| 530 Args: | 607 Args: |
| 531 command: String indicating the command that was received to trigger | 608 command: String indicating the command that was received to trigger |
| 532 this function. | 609 this function. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 # syntax is a bit prettier. The tuple is two functions: (add options, run | 646 # syntax is a bit prettier. The tuple is two functions: (add options, run |
| 570 # command). | 647 # command). |
| 571 CommandFunctionTuple = collections.namedtuple( | 648 CommandFunctionTuple = collections.namedtuple( |
| 572 'CommandFunctionTuple', ['add_options_func', 'run_command_func']) | 649 'CommandFunctionTuple', ['add_options_func', 'run_command_func']) |
| 573 VALID_COMMANDS = { | 650 VALID_COMMANDS = { |
| 574 'gtest': CommandFunctionTuple(AddGTestOptions, RunTestsCommand), | 651 'gtest': CommandFunctionTuple(AddGTestOptions, RunTestsCommand), |
| 575 'instrumentation': CommandFunctionTuple( | 652 'instrumentation': CommandFunctionTuple( |
| 576 AddInstrumentationTestOptions, RunTestsCommand), | 653 AddInstrumentationTestOptions, RunTestsCommand), |
| 577 'uiautomator': CommandFunctionTuple( | 654 'uiautomator': CommandFunctionTuple( |
| 578 AddUIAutomatorTestOptions, RunTestsCommand), | 655 AddUIAutomatorTestOptions, RunTestsCommand), |
| 656 'monkey': CommandFunctionTuple( |
| 657 AddMonkeyTestOptions, RunTestsCommand), |
| 579 'help': CommandFunctionTuple(lambda option_parser: None, HelpCommand) | 658 'help': CommandFunctionTuple(lambda option_parser: None, HelpCommand) |
| 580 } | 659 } |
| 581 | 660 |
| 582 | 661 |
| 583 class CommandOptionParser(optparse.OptionParser): | 662 class CommandOptionParser(optparse.OptionParser): |
| 584 """Wrapper class for OptionParser to help with listing commands.""" | 663 """Wrapper class for OptionParser to help with listing commands.""" |
| 585 | 664 |
| 586 def __init__(self, *args, **kwargs): | 665 def __init__(self, *args, **kwargs): |
| 587 self.command_list = kwargs.pop('command_list', []) | 666 self.command_list = kwargs.pop('command_list', []) |
| 588 self.example = kwargs.pop('example', '') | 667 self.example = kwargs.pop('example', '') |
| (...skipping 28 matching lines...) Expand all Loading... |
| 617 return 0 | 696 return 0 |
| 618 command = argv[1] | 697 command = argv[1] |
| 619 VALID_COMMANDS[command].add_options_func(option_parser) | 698 VALID_COMMANDS[command].add_options_func(option_parser) |
| 620 options, args = option_parser.parse_args(argv) | 699 options, args = option_parser.parse_args(argv) |
| 621 return VALID_COMMANDS[command].run_command_func( | 700 return VALID_COMMANDS[command].run_command_func( |
| 622 command, options, args, option_parser) | 701 command, options, args, option_parser) |
| 623 | 702 |
| 624 | 703 |
| 625 if __name__ == '__main__': | 704 if __name__ == '__main__': |
| 626 sys.exit(main(sys.argv)) | 705 sys.exit(main(sys.argv)) |
| OLD | NEW |