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