| OLD | NEW |
| (Empty) |
| 1 # Copyright (C) 2012 Google Inc. All rights reserved. | |
| 2 # | |
| 3 # Redistribution and use in source and binary forms, with or without | |
| 4 # modification, are permitted provided that the following conditions are | |
| 5 # met: | |
| 6 # | |
| 7 # * Redistributions of source code must retain the above copyright | |
| 8 # notice, this list of conditions and the following disclaimer. | |
| 9 # * Redistributions in binary form must reproduce the above | |
| 10 # copyright notice, this list of conditions and the following disclaimer | |
| 11 # in the documentation and/or other materials provided with the | |
| 12 # distribution. | |
| 13 # * Neither the name of Google Inc. nor the names of its | |
| 14 # contributors may be used to endorse or promote products derived from | |
| 15 # this software without specific prior written permission. | |
| 16 # | |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 28 | |
| 29 import optparse | |
| 30 import StringIO | |
| 31 import time | |
| 32 import unittest2 as unittest | |
| 33 import sys | |
| 34 | |
| 35 from webkitpy.common.system import executive_mock | |
| 36 from webkitpy.common.system.executive_mock import MockExecutive2 | |
| 37 from webkitpy.common.system.systemhost_mock import MockSystemHost | |
| 38 | |
| 39 from webkitpy.layout_tests.port import chromium_android | |
| 40 from webkitpy.layout_tests.port import chromium_port_testcase | |
| 41 from webkitpy.layout_tests.port import driver | |
| 42 from webkitpy.layout_tests.port import driver_unittest | |
| 43 from webkitpy.tool.mocktool import MockOptions | |
| 44 | |
| 45 | |
| 46 # Any "adb" commands will be interpret by this class instead of executing actual | |
| 47 # commansd on the file system, which we don't want to do. | |
| 48 class MockAndroidDebugBridge: | |
| 49 def __init__(self, device_count): | |
| 50 self._device_count = device_count | |
| 51 self._last_command = None | |
| 52 | |
| 53 # Local public methods. | |
| 54 | |
| 55 def run_command(self, args): | |
| 56 self._last_command = ' '.join(args) | |
| 57 if args[0].startswith('path'): | |
| 58 if args[0] == 'path1': | |
| 59 return '' | |
| 60 if args[0] == 'path2': | |
| 61 return 'version 1.1' | |
| 62 | |
| 63 return 'version 1.0' | |
| 64 | |
| 65 if args[0] == 'adb': | |
| 66 if len(args) > 1 and args[1] == 'version': | |
| 67 return 'version 1.0' | |
| 68 if len(args) > 1 and args[1] == 'devices': | |
| 69 return self._get_device_output() | |
| 70 if len(args) > 3 and args[3] == 'command': | |
| 71 return 'mockoutput' | |
| 72 if len(args) > 5 and args[5] == 'battery': | |
| 73 return 'level: 99' | |
| 74 | |
| 75 return '' | |
| 76 | |
| 77 def last_command(self): | |
| 78 return self._last_command | |
| 79 | |
| 80 # Local private methods. | |
| 81 | |
| 82 def _get_device_output(self): | |
| 83 serials = ['123456789ABCDEF0', '123456789ABCDEF1', '123456789ABCDEF2', | |
| 84 '123456789ABCDEF3', '123456789ABCDEF4', '123456789ABCDEF5'] | |
| 85 output = 'List of devices attached\n' | |
| 86 for serial in serials[:self._device_count]: | |
| 87 output += '%s\tdevice\n' % serial | |
| 88 return output | |
| 89 | |
| 90 | |
| 91 class AndroidCommandsTest(unittest.TestCase): | |
| 92 def setUp(self): | |
| 93 chromium_android.AndroidCommands._adb_command_path = None | |
| 94 chromium_android.AndroidCommands._adb_command_path_options = ['adb'] | |
| 95 | |
| 96 def make_executive(self, device_count): | |
| 97 self._mock_executive = MockAndroidDebugBridge(device_count) | |
| 98 return MockExecutive2(run_command_fn=self._mock_executive.run_command) | |
| 99 | |
| 100 def make_android_commands(self, device_count, serial): | |
| 101 return chromium_android.AndroidCommands(self.make_executive(device_count
), serial) | |
| 102 | |
| 103 # The "adb" binary with the latest version should be used. | |
| 104 def serial_test_adb_command_path(self): | |
| 105 executive = self.make_executive(0) | |
| 106 | |
| 107 chromium_android.AndroidCommands.set_adb_command_path_options(['path1',
'path2', 'path3']) | |
| 108 self.assertEqual('path2', chromium_android.AndroidCommands.adb_command_p
ath(executive)) | |
| 109 | |
| 110 # The used adb command should include the device's serial number, and get_se
rial() should reflect this. | |
| 111 def test_adb_command_and_get_serial(self): | |
| 112 android_commands = self.make_android_commands(1, '123456789ABCDEF0') | |
| 113 self.assertEquals(['adb', '-s', '123456789ABCDEF0'], android_commands.ad
b_command()) | |
| 114 self.assertEquals('123456789ABCDEF0', android_commands.get_serial()) | |
| 115 | |
| 116 # Running an adb command should return the command's output. | |
| 117 def test_run_command(self): | |
| 118 android_commands = self.make_android_commands(1, '123456789ABCDEF0') | |
| 119 | |
| 120 output = android_commands.run(['command']) | |
| 121 self.assertEquals('adb -s 123456789ABCDEF0 command', self._mock_executiv
e.last_command()) | |
| 122 self.assertEquals('mockoutput', output) | |
| 123 | |
| 124 # Test that the convenience methods create the expected commands. | |
| 125 def test_convenience_methods(self): | |
| 126 android_commands = self.make_android_commands(1, '123456789ABCDEF0') | |
| 127 | |
| 128 android_commands.file_exists('/tombstones') | |
| 129 self.assertEquals('adb -s 123456789ABCDEF0 shell ls /tombstones', self._
mock_executive.last_command()) | |
| 130 | |
| 131 android_commands.push('foo', 'bar') | |
| 132 self.assertEquals('adb -s 123456789ABCDEF0 push foo bar', self._mock_exe
cutive.last_command()) | |
| 133 | |
| 134 android_commands.pull('bar', 'foo') | |
| 135 self.assertEquals('adb -s 123456789ABCDEF0 pull bar foo', self._mock_exe
cutive.last_command()) | |
| 136 | |
| 137 | |
| 138 class ChromiumAndroidPortTest(chromium_port_testcase.ChromiumPortTestCase): | |
| 139 port_name = 'chromium-android' | |
| 140 port_maker = chromium_android.ChromiumAndroidPort | |
| 141 | |
| 142 def make_port(self, **kwargs): | |
| 143 port = super(ChromiumAndroidPortTest, self).make_port(**kwargs) | |
| 144 port._mock_adb = MockAndroidDebugBridge(kwargs.get('device_count', 1)) | |
| 145 port._executive = MockExecutive2(run_command_fn=port._mock_adb.run_comma
nd) | |
| 146 return port | |
| 147 | |
| 148 # Test that content_shell currently is the only supported driver. | |
| 149 def test_non_content_shell_driver(self): | |
| 150 self.assertRaises(self.make_port, options=optparse.Values({'driver_name'
: 'foobar'})) | |
| 151 | |
| 152 # Test that the number of child processes to create depends on the devices. | |
| 153 def test_default_child_processes(self): | |
| 154 port_default = self.make_port(device_count=5) | |
| 155 port_fixed_device = self.make_port(device_count=5, options=optparse.Valu
es({'adb_device': '123456789ABCDEF9'})) | |
| 156 | |
| 157 self.assertEquals(5, port_default.default_child_processes()) | |
| 158 self.assertEquals(1, port_fixed_device.default_child_processes()) | |
| 159 | |
| 160 # Test that an HTTP server indeed is required by Android (as we serve all te
sts over them) | |
| 161 def test_requires_http_server(self): | |
| 162 self.assertTrue(self.make_port(device_count=1).requires_http_server()) | |
| 163 | |
| 164 # Tests the default timeouts for Android, which are different than the rest
of Chromium. | |
| 165 def test_default_timeout_ms(self): | |
| 166 self.assertEqual(self.make_port(options=optparse.Values({'configuration'
: 'Release'})).default_timeout_ms(), 10000) | |
| 167 self.assertEqual(self.make_port(options=optparse.Values({'configuration'
: 'Debug'})).default_timeout_ms(), 10000) | |
| 168 | |
| 169 | |
| 170 class ChromiumAndroidDriverTest(unittest.TestCase): | |
| 171 def setUp(self): | |
| 172 self._mock_adb = MockAndroidDebugBridge(1) | |
| 173 self._mock_executive = MockExecutive2(run_command_fn=self._mock_adb.run_
command) | |
| 174 | |
| 175 android_commands = chromium_android.AndroidCommands(self._mock_executive
, '123456789ABCDEF0') | |
| 176 self._port = chromium_android.ChromiumAndroidPort(MockSystemHost(executi
ve=self._mock_executive), 'chromium-android') | |
| 177 self._driver = chromium_android.ChromiumAndroidDriver(self._port, worker
_number=0, | |
| 178 pixel_tests=True, driver_details=chromium_android.ContentShellDriver
Details(), android_devices=self._port._devices) | |
| 179 | |
| 180 # The cmd_line() method in the Android port is used for starting a shell, no
t the test runner. | |
| 181 def test_cmd_line(self): | |
| 182 self.assertEquals(['adb', '-s', '123456789ABCDEF0', 'shell'], self._driv
er.cmd_line(False, [])) | |
| 183 | |
| 184 # Test that the Chromium Android port can interpret Android's shell output. | |
| 185 def test_read_prompt(self): | |
| 186 self._driver._server_process = driver_unittest.MockServerProcess(lines=[
'root@android:/ # ']) | |
| 187 self.assertIsNone(self._driver._read_prompt(time.time() + 1)) | |
| 188 self._driver._server_process = driver_unittest.MockServerProcess(lines=[
'$ ']) | |
| 189 self.assertIsNone(self._driver._read_prompt(time.time() + 1)) | |
| 190 | |
| 191 | |
| 192 class ChromiumAndroidDriverTwoDriversTest(unittest.TestCase): | |
| 193 # Test two drivers getting the right serial numbers, and that we disregard p
er-test arguments. | |
| 194 def test_two_drivers(self): | |
| 195 mock_adb = MockAndroidDebugBridge(2) | |
| 196 mock_executive = MockExecutive2(run_command_fn=mock_adb.run_command) | |
| 197 | |
| 198 port = chromium_android.ChromiumAndroidPort(MockSystemHost(executive=moc
k_executive), 'chromium-android') | |
| 199 driver0 = chromium_android.ChromiumAndroidDriver(port, worker_number=0,
pixel_tests=True, | |
| 200 driver_details=chromium_android.ContentShellDriverDetails(), android
_devices=port._devices) | |
| 201 driver1 = chromium_android.ChromiumAndroidDriver(port, worker_number=1,
pixel_tests=True, | |
| 202 driver_details=chromium_android.ContentShellDriverDetails(), android
_devices=port._devices) | |
| 203 | |
| 204 self.assertEqual(['adb', '-s', '123456789ABCDEF0', 'shell'], driver0.cmd
_line(True, [])) | |
| 205 self.assertEqual(['adb', '-s', '123456789ABCDEF1', 'shell'], driver1.cmd
_line(True, ['anything'])) | |
| 206 | |
| 207 | |
| 208 class ChromiumAndroidTwoPortsTest(unittest.TestCase): | |
| 209 # Test that the driver's command line indeed goes through to the driver. | |
| 210 def test_options_with_two_ports(self): | |
| 211 mock_adb = MockAndroidDebugBridge(2) | |
| 212 mock_executive = MockExecutive2(run_command_fn=mock_adb.run_command) | |
| 213 | |
| 214 port0 = chromium_android.ChromiumAndroidPort(MockSystemHost(executive=mo
ck_executive), | |
| 215 'chromium-android', options=MockOptions(additional_drt_flag=['--foo=
bar'])) | |
| 216 port1 = chromium_android.ChromiumAndroidPort(MockSystemHost(executive=mo
ck_executive), | |
| 217 'chromium-android', options=MockOptions(driver_name='content_shell')
) | |
| 218 | |
| 219 self.assertEqual(1, port0.driver_cmd_line().count('--foo=bar')) | |
| 220 self.assertEqual(0, port1.driver_cmd_line().count('--create-stdin-fifo')
) | |
| OLD | NEW |