| 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 """Defines TestPackageApk to help run APK-based native tests.""" | 5 """Defines TestPackageApk to help run APK-based native tests.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import shlex | 9 import shlex |
| 10 import sys | 10 import sys |
| 11 import tempfile | 11 import tempfile |
| 12 import time | 12 import time |
| 13 | 13 |
| 14 from pylib import android_commands | 14 from pylib import android_commands |
| 15 from pylib import cmd_helper |
| 15 from pylib import constants | 16 from pylib import constants |
| 16 from pylib import pexpect | 17 from pylib import pexpect |
| 17 from pylib.android_commands import errors | 18 from pylib.android_commands import errors |
| 18 | 19 |
| 19 from test_package import TestPackage | 20 from test_package import TestPackage |
| 20 | 21 |
| 21 | 22 |
| 22 class TestPackageApk(TestPackage): | 23 class TestPackageApk(TestPackage): |
| 23 """A helper class for running APK-based native tests.""" | 24 """A helper class for running APK-based native tests.""" |
| 24 | 25 |
| 25 def __init__(self, adb, device, suite_path_full, tool, test_apk_package_name, | 26 def __init__(self, suite_name, build_type): |
| 26 test_activity_name, command_line_file): | |
| 27 """ | 27 """ |
| 28 Args: | 28 Args: |
| 29 adb: ADB interface the tests are using. | 29 suite_name: Name of the test suite (e.g. base_unittests). |
| 30 device: Device to run the tests. | 30 build_type: 'Release' or 'Debug'. |
| 31 suite_path_full: Absolute path to a specific test suite to run, | |
| 32 empty to run all. | |
| 33 Ex: '/foo/bar/base_unittests-debug.apk', for which | |
| 34 self.suite_path_full = '/foo/bar/base_unittests-debug.apk' | |
| 35 self.suite_path = '/foo/bar/base_unittests-debug' | |
| 36 self.suite_basename = 'base_unittests' | |
| 37 self.suite_dirname = '/foo/bar' | |
| 38 tool: Name of the Valgrind tool. | |
| 39 test_apk_package_name: Apk package name for tests running in APKs. | |
| 40 test_activity_name: Test activity to invoke for APK tests. | |
| 41 command_line_file: Filename to use to pass arguments to tests. | |
| 42 """ | 31 """ |
| 43 TestPackage.__init__(self, adb, device, suite_path_full, tool) | 32 TestPackage.__init__(self, suite_name) |
| 44 self._test_apk_package_name = test_apk_package_name | 33 product_dir = os.path.join(cmd_helper.OutDirectory.get(), build_type) |
| 45 self._test_activity_name = test_activity_name | 34 if suite_name == 'content_browsertests': |
| 46 self._command_line_file = command_line_file | 35 self.suite_path = os.path.join( |
| 36 product_dir, 'apks', '%s.apk' % suite_name) |
| 37 self._test_apk_package_name = constants.BROWSERTEST_TEST_PACKAGE_NAME |
| 38 self._test_activity_name = constants.BROWSERTEST_TEST_ACTIVITY_NAME |
| 39 self._command_line_file = constants.BROWSERTEST_COMMAND_LINE_FILE |
| 40 else: |
| 41 self.suite_path = os.path.join( |
| 42 product_dir, '%s_apk' % suite_name, '%s-debug.apk' % suite_name) |
| 43 self._test_apk_package_name = constants.GTEST_TEST_PACKAGE_NAME |
| 44 self._test_activity_name = constants.GTEST_TEST_ACTIVITY_NAME |
| 45 self._command_line_file = constants.GTEST_COMMAND_LINE_FILE |
| 47 | 46 |
| 48 def _CreateCommandLineFileOnDevice(self, options): | 47 def _CreateCommandLineFileOnDevice(self, adb, options): |
| 49 command_line_file = tempfile.NamedTemporaryFile() | 48 command_line_file = tempfile.NamedTemporaryFile() |
| 50 # GTest expects argv[0] to be the executable path. | 49 # GTest expects argv[0] to be the executable path. |
| 51 command_line_file.write(self.suite_basename + ' ' + options) | 50 command_line_file.write(self.suite_name + ' ' + options) |
| 52 command_line_file.flush() | 51 command_line_file.flush() |
| 53 self.adb.PushIfNeeded(command_line_file.name, | 52 adb.PushIfNeeded(command_line_file.name, |
| 54 constants.TEST_EXECUTABLE_DIR + '/' + | 53 constants.TEST_EXECUTABLE_DIR + '/' + |
| 55 self._command_line_file) | 54 self._command_line_file) |
| 56 | 55 |
| 57 def _GetGTestReturnCode(self): | |
| 58 return None | |
| 59 | |
| 60 def _GetFifo(self): | 56 def _GetFifo(self): |
| 61 # The test.fifo path is determined by: | 57 # The test.fifo path is determined by: |
| 62 # testing/android/java/src/org/chromium/native_test/ | 58 # testing/android/java/src/org/chromium/native_test/ |
| 63 # ChromeNativeTestActivity.java and | 59 # ChromeNativeTestActivity.java and |
| 64 # testing/android/native_test_launcher.cc | 60 # testing/android/native_test_launcher.cc |
| 65 return '/data/data/' + self._test_apk_package_name + '/files/test.fifo' | 61 return '/data/data/' + self._test_apk_package_name + '/files/test.fifo' |
| 66 | 62 |
| 67 def _ClearFifo(self): | 63 def _ClearFifo(self, adb): |
| 68 self.adb.RunShellCommand('rm -f ' + self._GetFifo()) | 64 adb.RunShellCommand('rm -f ' + self._GetFifo()) |
| 69 | 65 |
| 70 def _WatchFifo(self, timeout, logfile=None): | 66 def _WatchFifo(self, adb, timeout, logfile=None): |
| 71 for i in range(10): | 67 for i in range(10): |
| 72 if self.adb.FileExistsOnDevice(self._GetFifo()): | 68 if adb.FileExistsOnDevice(self._GetFifo()): |
| 73 logging.info('Fifo created.') | 69 logging.info('Fifo created.') |
| 74 break | 70 break |
| 75 time.sleep(i) | 71 time.sleep(i) |
| 76 else: | 72 else: |
| 77 raise errors.DeviceUnresponsiveError( | 73 raise errors.DeviceUnresponsiveError( |
| 78 'Unable to find fifo on device %s ' % self._GetFifo()) | 74 'Unable to find fifo on device %s ' % self._GetFifo()) |
| 79 args = shlex.split(self.adb.Adb()._target_arg) | 75 args = shlex.split(adb.Adb()._target_arg) |
| 80 args += ['shell', 'cat', self._GetFifo()] | 76 args += ['shell', 'cat', self._GetFifo()] |
| 81 return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile) | 77 return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile) |
| 82 | 78 |
| 83 def _StartActivity(self): | 79 def _StartActivity(self, adb): |
| 84 self.adb.StartActivity( | 80 adb.StartActivity( |
| 85 self._test_apk_package_name, | 81 self._test_apk_package_name, |
| 86 self._test_activity_name, | 82 self._test_activity_name, |
| 87 wait_for_completion=True, | 83 wait_for_completion=True, |
| 88 action='android.intent.action.MAIN', | 84 action='android.intent.action.MAIN', |
| 89 force_stop=True) | 85 force_stop=True) |
| 90 | 86 |
| 91 def _GetTestSuiteBaseName(self): | 87 #override |
| 92 """Returns the base name of the test suite.""" | 88 def ClearApplicationState(self, adb): |
| 93 # APK test suite names end with '-debug.apk' | 89 adb.ClearApplicationState(self._test_apk_package_name) |
| 94 return os.path.basename(self.suite_path).rsplit('-debug', 1)[0] | |
| 95 | 90 |
| 96 #override | 91 #override |
| 97 def ClearApplicationState(self): | 92 def CreateCommandLineFileOnDevice(self, adb, test_filter, test_arguments): |
| 98 self.adb.ClearApplicationState(self._test_apk_package_name) | 93 self._CreateCommandLineFileOnDevice( |
| 94 adb, '--gtest_filter=%s %s' % (test_filter, test_arguments)) |
| 99 | 95 |
| 100 #override | 96 #override |
| 101 def CreateCommandLineFileOnDevice(self, test_filter, test_arguments): | 97 def GetAllTests(self, adb): |
| 102 self._CreateCommandLineFileOnDevice( | 98 self._CreateCommandLineFileOnDevice(adb, '--gtest_list_tests') |
| 103 '--gtest_filter=%s %s' % (test_filter, test_arguments)) | |
| 104 | |
| 105 #override | |
| 106 def GetAllTests(self): | |
| 107 self._CreateCommandLineFileOnDevice('--gtest_list_tests') | |
| 108 try: | 99 try: |
| 109 self.tool.SetupEnvironment() | 100 self.tool.SetupEnvironment() |
| 110 # Clear and start monitoring logcat. | 101 # Clear and start monitoring logcat. |
| 111 self._ClearFifo() | 102 self._ClearFifo(adb) |
| 112 self._StartActivity() | 103 self._StartActivity(adb) |
| 113 # Wait for native test to complete. | 104 # Wait for native test to complete. |
| 114 p = self._WatchFifo(timeout=30 * self.tool.GetTimeoutScale()) | 105 p = self._WatchFifo(adb, timeout=30 * self.tool.GetTimeoutScale()) |
| 115 p.expect('<<ScopedMainEntryLogger') | 106 p.expect('<<ScopedMainEntryLogger') |
| 116 p.close() | 107 p.close() |
| 117 finally: | 108 finally: |
| 118 self.tool.CleanUpEnvironment() | 109 self.tool.CleanUpEnvironment() |
| 119 # We need to strip the trailing newline. | 110 # We need to strip the trailing newline. |
| 120 content = [line.rstrip() for line in p.before.splitlines()] | 111 content = [line.rstrip() for line in p.before.splitlines()] |
| 121 return self._ParseGTestListTests(content) | 112 return self._ParseGTestListTests(content) |
| 122 | 113 |
| 123 #override | 114 #override |
| 124 def SpawnTestProcess(self): | 115 def SpawnTestProcess(self, adb): |
| 125 try: | 116 try: |
| 126 self.tool.SetupEnvironment() | 117 self.tool.SetupEnvironment() |
| 127 self._ClearFifo() | 118 self._ClearFifo(adb) |
| 128 self._StartActivity() | 119 self._StartActivity(adb) |
| 129 finally: | 120 finally: |
| 130 self.tool.CleanUpEnvironment() | 121 self.tool.CleanUpEnvironment() |
| 131 logfile = android_commands.NewLineNormalizer(sys.stdout) | 122 logfile = android_commands.NewLineNormalizer(sys.stdout) |
| 132 return self._WatchFifo(timeout=10, logfile=logfile) | 123 return self._WatchFifo(adb, timeout=10, logfile=logfile) |
| 133 | 124 |
| 134 #override | 125 #override |
| 135 def Install(self): | 126 def Install(self, adb): |
| 136 self.tool.CopyFiles() | 127 self.tool.CopyFiles() |
| 137 self.adb.ManagedInstall(self.suite_path_full, False, | 128 adb.ManagedInstall(self.suite_path, False, |
| 138 package_name=self._test_apk_package_name) | 129 package_name=self._test_apk_package_name) |
| 139 | |
| OLD | NEW |