| Index: build/android/run_tests.py
|
| diff --git a/build/android/run_tests.py b/build/android/run_tests.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..1425240f32c979f259afb3867bfa7f452cf9798a
|
| --- /dev/null
|
| +++ b/build/android/run_tests.py
|
| @@ -0,0 +1,208 @@
|
| +#!/usr/bin/python
|
| +# Copyright (c) 2011 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.
|
| +
|
| +"""Runs all the native unit tests.
|
| +
|
| +1. Copy over test binary to /data/local on device.
|
| +2. Resources: chrome/unit_tests requires resources (chrome.pak and en-US.pak)
|
| + to be deployed to the device (in /data/local/tmp).
|
| +3. Environment:
|
| +3.1. chrome/unit_tests requires (via chrome_paths.cc) a directory named:
|
| + /data/local/tmp/chrome/test/data
|
| +3.2. page_cycler_tests have following requirements,
|
| +3.2.1 the following data on host:
|
| + <chrome_src_dir>/tools/page_cycler
|
| + <chrome_src_dir>/data/page_cycler
|
| +3.2.2. two data directories to store above test data on device named:
|
| + /data/local/tmp/tools/ (for database perf test)
|
| + /data/local/tmp/data/ (for other perf tests)
|
| +3.2.3. a http server to serve http perf tests.
|
| + The http root is host's <chrome_src_dir>/data/page_cycler/, port 8000.
|
| +3.2.4 a tool named forwarder is also required to run on device to
|
| + forward the http request/response between host and device.
|
| +3.2.5 Chrome is installed on device.
|
| +4. Run the binary in the device and stream the log to the host.
|
| +4.1. Optionally, filter specific tests.
|
| +4.2. Optionally, rebaseline: run the available tests and update the
|
| + suppressions file for failures.
|
| +4.3. If we're running a single test suite and we have multiple devices
|
| + connected, we'll shard the tests.
|
| +5. Clean up the device.
|
| +
|
| +Suppressions:
|
| +
|
| +Individual tests in a test binary can be suppressed by listing it in
|
| +the gtest_filter directory in a file of the same name as the test binary,
|
| +one test per line. Here is an example:
|
| +
|
| + $ cat gtest_filter/base_unittests_disabled
|
| + DataPackTest.Load
|
| + ReadOnlyFileUtilTest.ContentsEqual
|
| +
|
| +This file is generated by the tests running on devices. If running on emulator,
|
| +additonal filter file which lists the tests only failed in emulator will be
|
| +loaded. We don't care about the rare testcases which succeeded on emuatlor, but
|
| +failed on device.
|
| +"""
|
| +
|
| +import logging
|
| +import os
|
| +import re
|
| +import sys
|
| +
|
| +import android_commands
|
| +import cmd_helper
|
| +import debug_info
|
| +import emulator
|
| +import run_tests_helper
|
| +from single_test_runner import SingleTestRunner
|
| +from test_package_executable import TestPackageExecutable
|
| +from test_result import BaseTestResult, TestResults
|
| +
|
| +_TEST_SUITES = ['base_unittests',]
|
| +
|
| +def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline,
|
| + timeout, performance_test, cleanup_test_files, tool,
|
| + log_dump_name):
|
| + """Runs the tests.
|
| +
|
| + Args:
|
| + device: Device to run the tests.
|
| + test_suite: A specific test suite to run, empty to run all.
|
| + gtest_filter: A gtest_filter flag.
|
| + test_arguments: Additional arguments to pass to the test binary.
|
| + rebaseline: Whether or not to run tests in isolation and update the filter.
|
| + timeout: Timeout for each test.
|
| + performance_test: Whether or not performance test(s).
|
| + cleanup_test_files: Whether or not to cleanup test files on device.
|
| + tool: Name of the Valgrind tool.
|
| + log_dump_name: Name of log dump file.
|
| +
|
| + Returns:
|
| + A TestResults object.
|
| + """
|
| + results = []
|
| +
|
| + if test_suite:
|
| + global _TEST_SUITES
|
| + if not os.path.exists(test_suite):
|
| + logging.critical('Unrecognized test suite, supported: %s' %
|
| + _TEST_SUITES)
|
| + if test_suite in _TEST_SUITES:
|
| + logging.critical('(Remember to include the path: out/Release/%s)',
|
| + test_suite)
|
| + return TestResults.FromOkAndFailed([], [BaseTestResult(test_suite, '')])
|
| + _TEST_SUITES = [test_suite]
|
| + else:
|
| + # If not specified, assume the test suites are in out/Release
|
| + test_suite_dir = os.path.abspath(os.path.join(run_tests_helper.CHROME_DIR,
|
| + 'out', 'Release'))
|
| + _TEST_SUITES = [os.path.join(test_suite_dir, t) for t in _TEST_SUITES]
|
| + debug_info_list = []
|
| + for t in _TEST_SUITES:
|
| + test = SingleTestRunner(device, t, gtest_filter, test_arguments,
|
| + timeout, rebaseline, performance_test,
|
| + cleanup_test_files, tool, not not log_dump_name)
|
| + test.RunTests()
|
| + results += [test.test_results]
|
| + # Collect debug info.
|
| + debug_info_list += [test.dump_debug_info]
|
| + if rebaseline:
|
| + test.UpdateFilter(test.test_results.failed)
|
| + elif test.test_results.failed:
|
| + # Stop running test if encountering failed test.
|
| + test.test_results.LogFull()
|
| + break
|
| + # Zip all debug info outputs into a file named by log_dump_name.
|
| + debug_info.GTestDebugInfo.ZipAndCleanResults(
|
| + os.path.join(run_tests_helper.CHROME_DIR, 'out', 'Release',
|
| + 'debug_info_dumps'),
|
| + log_dump_name, [d for d in debug_info_list if d])
|
| + return TestResults.FromTestResults(results)
|
| +
|
| +def Dispatch(options):
|
| + """Dispatches the tests, sharding if possible.
|
| +
|
| + If options.use_emulator is True, all tests will be run in a new emulator
|
| + instance.
|
| +
|
| + Args:
|
| + options: options for running the tests.
|
| +
|
| + Returns:
|
| + 0 if successful, number of failing tests otherwise.
|
| + """
|
| + if options.test_suite == 'help':
|
| + ListTestSuites()
|
| + return 0
|
| + buildbot_emulator = None
|
| + attached_devices = []
|
| +
|
| + if options.use_emulator:
|
| + buildbot_emulator = emulator.Emulator()
|
| + buildbot_emulator.Launch()
|
| + attached_devices.append(buildbot_emulator.device)
|
| + else:
|
| + attached_devices = android_commands.GetAttachedDevices()
|
| +
|
| + if not attached_devices:
|
| + logging.critical('A device must be attached and online.')
|
| + return 1
|
| +
|
| + test_results = RunTests(attached_devices[0], options.test_suite,
|
| + options.gtest_filter, options.test_arguments,
|
| + options.rebaseline, options.timeout,
|
| + options.performance_test,
|
| + options.cleanup_test_files, options.tool,
|
| + options.log_dump)
|
| + if buildbot_emulator:
|
| + buildbot_emulator.Shutdown()
|
| + return len(test_results.failed)
|
| +
|
| +def ListTestSuites():
|
| + """Display a list of available test suites
|
| + """
|
| + print 'Available test suites are:'
|
| + for test_suite in _TEST_SUITES:
|
| + print test_suite
|
| +
|
| +
|
| +def main(argv):
|
| + option_parser = run_tests_helper.CreateTestRunnerOptionParser(None,
|
| + default_timeout=0)
|
| + option_parser.add_option('-s', dest='test_suite',
|
| + help='Executable name of the test suite to run '
|
| + '(use -s help to list them)')
|
| + option_parser.add_option('-r', dest='rebaseline',
|
| + help='Rebaseline and update *testsuite_disabled',
|
| + action='store_true',
|
| + default=False)
|
| + option_parser.add_option('-f', dest='gtest_filter',
|
| + help='gtest filter')
|
| + option_parser.add_option('-a', '--test_arguments', dest='test_arguments',
|
| + help='Additional arguments to pass to the test')
|
| + option_parser.add_option('-p', dest='performance_test',
|
| + help='Indicator of performance test',
|
| + action='store_true',
|
| + default=False)
|
| + option_parser.add_option('-L', dest='log_dump',
|
| + help='file name of log dump, which will be put in'
|
| + 'subfolder debug_info_dumps under the same directory'
|
| + 'in where the test_suite exists.')
|
| + option_parser.add_option('-e', '--emulator', dest='use_emulator',
|
| + help='Run tests in a new instance of emulator',
|
| + action='store_true',
|
| + default=False)
|
| + options, args = option_parser.parse_args(argv)
|
| + if len(args) > 1:
|
| + print 'Unknown argument:', args[1:]
|
| + option_parser.print_usage()
|
| + sys.exit(1)
|
| + run_tests_helper.SetLogLevel(options.verbose_count)
|
| + return Dispatch(options)
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + sys.exit(main(sys.argv))
|
|
|