adb_compatibility_devicetest.py revision 33259e44c8229f70ffe0cf3bb5ca9375c4feb2f9
1#!/usr/bin/env python 2# Copyright 2016 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import contextlib 7import os 8import posixpath 9import random 10import signal 11import sys 12import unittest 13 14_CATAPULT_BASE_DIR = os.path.abspath(os.path.join( 15 os.path.dirname(__file__), '..', '..', '..', '..')) 16 17sys.path.append(os.path.join(_CATAPULT_BASE_DIR, 'devil')) 18from devil import devil_env 19from devil.android import device_errors 20from devil.android import device_test_case 21from devil.android.sdk import adb_wrapper 22from devil.utils import cmd_helper 23from devil.utils import timeout_retry 24 25 26_TEST_DATA_DIR = os.path.abspath(os.path.join( 27 os.path.dirname(__file__), 'test', 'data')) 28 29 30def _hostAdbPids(): 31 ps_status, ps_output = cmd_helper.GetCmdStatusAndOutput( 32 ['pgrep', '-l', 'adb']) 33 if ps_status != 0: 34 return [] 35 36 pids_and_names = (line.split() for line in ps_output.splitlines()) 37 return [int(pid) for pid, name in pids_and_names 38 if name == 'adb'] 39 40 41class AdbCompatibilityTest(device_test_case.DeviceTestCase): 42 43 @classmethod 44 def setUpClass(cls): 45 custom_adb_path = os.environ.get('ADB_PATH') 46 custom_deps = { 47 'config_type': 'BaseConfig', 48 'dependencies': {}, 49 } 50 if custom_adb_path: 51 custom_deps['dependencies']['adb'] = { 52 'file_info': { 53 devil_env.GetPlatform(): { 54 'local_paths': [custom_adb_path], 55 }, 56 }, 57 } 58 devil_env.config.Initialize(configs=[custom_deps]) 59 60 def testStartServer(self): 61 # Manually kill off any instances of adb. 62 adb_pids = _hostAdbPids() 63 for p in adb_pids: 64 os.kill(p, signal.SIGKILL) 65 66 self.assertIsNotNone( 67 timeout_retry.WaitFor( 68 lambda: not _hostAdbPids(), wait_period=0.1, max_tries=10)) 69 70 # start the adb server 71 start_server_status, _ = cmd_helper.GetCmdStatusAndOutput( 72 [adb_wrapper.AdbWrapper.GetAdbPath(), 'start-server']) 73 74 # verify that the server is now online 75 self.assertEquals(0, start_server_status) 76 self.assertIsNotNone( 77 timeout_retry.WaitFor( 78 lambda: bool(_hostAdbPids()), wait_period=0.1, max_tries=10)) 79 80 def testKillServer(self): 81 adb_pids = _hostAdbPids() 82 if not adb_pids: 83 adb_wrapper.AdbWrapper.StartServer() 84 85 adb_pids = _hostAdbPids() 86 self.assertGreaterEqual(len(adb_pids), 1) 87 88 kill_server_status, _ = cmd_helper.GetCmdStatusAndOutput( 89 [adb_wrapper.AdbWrapper.GetAdbPath(), 'kill-server']) 90 self.assertEqual(0, kill_server_status) 91 92 adb_pids = _hostAdbPids() 93 self.assertEqual(0, len(adb_pids)) 94 95 def testDevices(self): 96 devices = adb_wrapper.AdbWrapper.Devices() 97 self.assertNotEqual(0, len(devices), 'No devices found.') 98 99 def getTestInstance(self): 100 """Creates a real AdbWrapper instance for testing.""" 101 return adb_wrapper.AdbWrapper(self.serial) 102 103 def testShell(self): 104 under_test = self.getTestInstance() 105 shell_ls_result = under_test.Shell('ls') 106 self.assertIsInstance(shell_ls_result, str) 107 self.assertTrue(bool(shell_ls_result)) 108 109 def testShell_failed(self): 110 under_test = self.getTestInstance() 111 with self.assertRaises(device_errors.AdbShellCommandFailedError): 112 under_test.Shell('ls /foo/bar/baz') 113 114 def testShell_externalStorageDefined(self): 115 under_test = self.getTestInstance() 116 external_storage = under_test.Shell('echo $EXTERNAL_STORAGE') 117 self.assertIsInstance(external_storage, str) 118 self.assertTrue(posixpath.isabs(external_storage)) 119 120 @contextlib.contextmanager 121 def getTestPushDestination(self, under_test): 122 """Creates a temporary directory suitable for pushing to.""" 123 external_storage = under_test.Shell('echo $EXTERNAL_STORAGE').strip() 124 if not external_storage: 125 self.skipTest('External storage not available.') 126 while True: 127 random_hex = hex(random.randint(0, 2 ** 52))[2:] 128 name = 'tmp_push_test%s' % random_hex 129 path = posixpath.join(external_storage, name) 130 try: 131 under_test.Shell('ls %s' % path) 132 except device_errors.AdbShellCommandFailedError: 133 break 134 under_test.Shell('mkdir %s' % path) 135 try: 136 yield path 137 finally: 138 under_test.Shell('rm -rf %s' % path) 139 140 def testPush_fileToFile(self): 141 under_test = self.getTestInstance() 142 with self.getTestPushDestination(under_test) as push_target_directory: 143 src = os.path.join(_TEST_DATA_DIR, 'push_file.txt') 144 dest = posixpath.join(push_target_directory, 'push_file.txt') 145 with self.assertRaises(device_errors.AdbShellCommandFailedError): 146 under_test.Shell('ls %s' % dest) 147 under_test.Push(src, dest) 148 self.assertEquals(dest, under_test.Shell('ls %s' % dest).strip()) 149 150 def testPush_fileToDirectory(self): 151 under_test = self.getTestInstance() 152 with self.getTestPushDestination(under_test) as push_target_directory: 153 src = os.path.join(_TEST_DATA_DIR, 'push_file.txt') 154 dest = push_target_directory 155 resulting_file = posixpath.join(dest, 'push_file.txt') 156 with self.assertRaises(device_errors.AdbShellCommandFailedError): 157 under_test.Shell('ls %s' % resulting_file) 158 under_test.Push(src, dest) 159 self.assertEquals( 160 resulting_file, 161 under_test.Shell('ls %s' % resulting_file).strip()) 162 163 def testPush_directoryToDirectory(self): 164 under_test = self.getTestInstance() 165 with self.getTestPushDestination(under_test) as push_target_directory: 166 src = os.path.join(_TEST_DATA_DIR, 'push_directory') 167 dest = posixpath.join(push_target_directory, 'push_directory') 168 with self.assertRaises(device_errors.AdbShellCommandFailedError): 169 under_test.Shell('ls %s' % dest) 170 under_test.Push(src, dest) 171 self.assertEquals( 172 sorted(os.listdir(src)), 173 sorted(under_test.Shell('ls %s' % dest).strip().split())) 174 175 def testPush_directoryToExistingDirectory(self): 176 under_test = self.getTestInstance() 177 with self.getTestPushDestination(under_test) as push_target_directory: 178 src = os.path.join(_TEST_DATA_DIR, 'push_directory') 179 dest = push_target_directory 180 resulting_directory = posixpath.join(dest, 'push_directory') 181 with self.assertRaises(device_errors.AdbShellCommandFailedError): 182 under_test.Shell('ls %s' % resulting_directory) 183 under_test.Shell('mkdir %s' % resulting_directory) 184 under_test.Push(src, dest) 185 self.assertEquals( 186 sorted(os.listdir(src)), 187 sorted(under_test.Shell('ls %s' % resulting_directory).split())) 188 189 # TODO(jbudorick): Implement tests for the following: 190 # taskset -c 191 # devices [-l] 192 # pull 193 # shell 194 # ls 195 # logcat [-c] [-d] [-v] [-b] 196 # forward [--remove] [--list] 197 # jdwp 198 # install [-l] [-r] [-s] [-d] 199 # install-multiple [-l] [-r] [-s] [-d] [-p] 200 # uninstall [-k] 201 # backup -f [-apk] [-shared] [-nosystem] [-all] 202 # restore 203 # wait-for-device 204 # get-state (BROKEN IN THE M SDK) 205 # get-devpath 206 # remount 207 # reboot 208 # reboot-bootloader 209 # root 210 # emu 211 212 @classmethod 213 def tearDownClass(cls): 214 print 215 print 216 print 'tested %s' % adb_wrapper.AdbWrapper.GetAdbPath() 217 print ' %s' % adb_wrapper.AdbWrapper.Version() 218 print 'connected devices:' 219 try: 220 for d in adb_wrapper.AdbWrapper.Devices(): 221 print ' %s' % d 222 except device_errors.AdbCommandFailedError: 223 print ' <failed to list devices>' 224 raise 225 finally: 226 print 227 228 229if __name__ == '__main__': 230 sys.exit(unittest.main()) 231