1 #!/usr/bin/env python3 2 # 3 # Copyright 2018 - The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 import mock 17 import unittest 18 19 from acts.controllers.sl4a_lib import sl4a_manager 20 from acts.controllers.sl4a_lib import rpc_client 21 22 23 class Sl4aManagerFactoryTest(unittest.TestCase): 24 """Tests the sl4a_manager module-level functions.""" 25 26 def setUp(self): 27 """Clears the Sl4aManager cache.""" 28 sl4a_manager._all_sl4a_managers = {} 29 30 def test_create_manager(self): 31 """Tests sl4a_manager.create_sl4a_manager(). 32 33 Tests that a new Sl4aManager is returned without an error. 34 """ 35 adb = mock.Mock() 36 adb.serial = 'SERIAL' 37 sl4a_man = sl4a_manager.create_sl4a_manager(adb) 38 self.assertEqual(sl4a_man.adb, adb) 39 40 def test_create_sl4a_manager_return_already_created_manager(self): 41 """Tests sl4a_manager.create_sl4a_manager(). 42 43 Tests that a second call to create_sl4a_manager() does not create a 44 new Sl4aManager, and returns the first created Sl4aManager instead. 45 """ 46 adb = mock.Mock() 47 adb.serial = 'SERIAL' 48 first_manager = sl4a_manager.create_sl4a_manager(adb) 49 50 adb_same_serial = mock.Mock() 51 adb_same_serial.serial = 'SERIAL' 52 second_manager = sl4a_manager.create_sl4a_manager(adb) 53 54 self.assertEqual(first_manager, second_manager) 55 56 def test_create_sl4a_manager_multiple_devices_with_one_manager_each(self): 57 """Tests sl4a_manager.create_sl4a_manager(). 58 59 Tests that when create_s4l4a_manager() is called for different devices, 60 each device gets its own Sl4aManager object. 61 """ 62 adb_1 = mock.Mock() 63 adb_1.serial = 'SERIAL' 64 first_manager = sl4a_manager.create_sl4a_manager(adb_1) 65 66 adb_2 = mock.Mock() 67 adb_2.serial = 'DIFFERENT_SERIAL_NUMBER' 68 second_manager = sl4a_manager.create_sl4a_manager(adb_2) 69 70 self.assertNotEqual(first_manager, second_manager) 71 72 73 class Sl4aManagerTest(unittest.TestCase): 74 """Tests the sl4a_manager.Sl4aManager class.""" 75 ATTEMPT_INTERVAL = .25 76 MAX_WAIT_ON_SERVER_SECONDS = 1 77 _SL4A_LAUNCH_SERVER_CMD = '' 78 _SL4A_CLOSE_SERVER_CMD = '' 79 _SL4A_ROOT_FIND_PORT_CMD = '' 80 _SL4A_USER_FIND_PORT_CMD = '' 81 _SL4A_START_SERVICE_CMD = '' 82 83 @classmethod 84 def setUpClass(cls): 85 # Copy all module constants before testing begins. 86 Sl4aManagerTest.ATTEMPT_INTERVAL = \ 87 sl4a_manager.ATTEMPT_INTERVAL 88 Sl4aManagerTest.MAX_WAIT_ON_SERVER_SECONDS = \ 89 sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS 90 Sl4aManagerTest._SL4A_LAUNCH_SERVER_CMD = \ 91 sl4a_manager._SL4A_LAUNCH_SERVER_CMD 92 Sl4aManagerTest._SL4A_CLOSE_SERVER_CMD = \ 93 sl4a_manager._SL4A_CLOSE_SERVER_CMD 94 Sl4aManagerTest._SL4A_ROOT_FIND_PORT_CMD = \ 95 sl4a_manager._SL4A_ROOT_FIND_PORT_CMD 96 Sl4aManagerTest._SL4A_USER_FIND_PORT_CMD = \ 97 sl4a_manager._SL4A_USER_FIND_PORT_CMD 98 Sl4aManagerTest._SL4A_START_SERVICE_CMD = \ 99 sl4a_manager._SL4A_START_SERVICE_CMD 100 101 def setUp(self): 102 # Restore all module constants at the beginning of each test case. 103 sl4a_manager.ATTEMPT_INTERVAL = \ 104 Sl4aManagerTest.ATTEMPT_INTERVAL 105 sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS = \ 106 Sl4aManagerTest.MAX_WAIT_ON_SERVER_SECONDS 107 sl4a_manager._SL4A_LAUNCH_SERVER_CMD = \ 108 Sl4aManagerTest._SL4A_LAUNCH_SERVER_CMD 109 sl4a_manager._SL4A_CLOSE_SERVER_CMD = \ 110 Sl4aManagerTest._SL4A_CLOSE_SERVER_CMD 111 sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = \ 112 Sl4aManagerTest._SL4A_ROOT_FIND_PORT_CMD 113 sl4a_manager._SL4A_USER_FIND_PORT_CMD = \ 114 Sl4aManagerTest._SL4A_USER_FIND_PORT_CMD 115 sl4a_manager._SL4A_START_SERVICE_CMD = \ 116 Sl4aManagerTest._SL4A_START_SERVICE_CMD 117 118 # Reset module data at the beginning of each test. 119 sl4a_manager._all_sl4a_managers = {} 120 121 def test_sl4a_ports_in_use(self): 122 """Tests sl4a_manager.Sl4aManager.sl4a_ports_in_use 123 124 Tests to make sure all server ports are returned with no duplicates. 125 """ 126 adb = mock.Mock() 127 manager = sl4a_manager.Sl4aManager(adb) 128 session_1 = mock.Mock() 129 session_1.server_port = 12345 130 manager.sessions[1] = session_1 131 session_2 = mock.Mock() 132 session_2.server_port = 15973 133 manager.sessions[2] = session_2 134 session_3 = mock.Mock() 135 session_3.server_port = 12345 136 manager.sessions[3] = session_3 137 session_4 = mock.Mock() 138 session_4.server_port = 67890 139 manager.sessions[4] = session_4 140 session_5 = mock.Mock() 141 session_5.server_port = 75638 142 manager.sessions[5] = session_5 143 144 returned_ports = manager.sl4a_ports_in_use 145 146 # No duplicated ports. 147 self.assertEqual(len(returned_ports), len(set(returned_ports))) 148 # One call for each session 149 self.assertSetEqual(set(returned_ports), {12345, 15973, 67890, 75638}) 150 151 @mock.patch('time.sleep', return_value=None) 152 def test_start_sl4a_server_uses_all_retries(self, _): 153 """Tests sl4a_manager.Sl4aManager.start_sl4a_server(). 154 155 Tests to ensure that _start_sl4a_server retries and successfully returns 156 a port. 157 """ 158 adb = mock.Mock() 159 adb.shell = lambda _, **kwargs: '' 160 161 side_effects = [] 162 expected_port = 12345 163 for _ in range(int(sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS / 164 sl4a_manager.ATTEMPT_INTERVAL) - 1): 165 side_effects.append(None) 166 side_effects.append(expected_port) 167 168 manager = sl4a_manager.create_sl4a_manager(adb) 169 manager._get_open_listening_port = mock.Mock(side_effect=side_effects) 170 try: 171 found_port = manager.start_sl4a_server(0) 172 self.assertTrue(found_port) 173 except rpc_client.Sl4aConnectionError: 174 self.fail('start_sl4a_server failed to respect FIND_PORT_RETRIES.') 175 176 @mock.patch('time.sleep', return_value=None) 177 def test_start_sl4a_server_fails_all_retries(self, _): 178 """Tests sl4a_manager.Sl4aManager.start_sl4a_server(). 179 180 Tests to ensure that start_sl4a_server throws an error if all retries 181 fail. 182 """ 183 adb = mock.Mock() 184 adb.shell = lambda _, **kwargs: '' 185 186 side_effects = [] 187 for _ in range(int(sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS / 188 sl4a_manager.ATTEMPT_INTERVAL)): 189 side_effects.append(None) 190 191 manager = sl4a_manager.create_sl4a_manager(adb) 192 manager._get_open_listening_port = mock.Mock(side_effect=side_effects) 193 try: 194 manager.start_sl4a_server(0) 195 self.fail('Sl4aConnectionError was not thrown.') 196 except rpc_client.Sl4aConnectionError: 197 pass 198 199 def test_get_all_ports_command_uses_root_cmd(self): 200 """Tests sl4a_manager.Sl4aManager._get_all_ports_command(). 201 202 Tests that _get_all_ports_command calls the root command when root is 203 available. 204 """ 205 adb = mock.Mock() 206 adb.is_root = lambda: True 207 command = 'ngo45hke3b4vie3mv5ni93,vfu3j' 208 sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = command 209 210 manager = sl4a_manager.create_sl4a_manager(adb) 211 self.assertEqual(manager._get_all_ports_command(), command) 212 213 def test_get_all_ports_command_escalates_to_root(self): 214 """Tests sl4a_manager.Sl4aManager._call_get_ports_command(). 215 216 Tests that _call_get_ports_command calls the root command when adb is 217 user but can escalate to root. 218 """ 219 adb = mock.Mock() 220 adb.is_root = lambda: False 221 adb.ensure_root = lambda: True 222 command = 'ngo45hke3b4vie3mv5ni93,vfu3j' 223 sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = command 224 225 manager = sl4a_manager.create_sl4a_manager(adb) 226 self.assertEqual(manager._get_all_ports_command(), command) 227 228 def test_get_all_ports_command_uses_user_cmd(self): 229 """Tests sl4a_manager.Sl4aManager._call_get_ports_command(). 230 231 Tests that _call_get_ports_command calls the user command when root is 232 unavailable. 233 """ 234 adb = mock.Mock() 235 adb.is_root = lambda: False 236 adb.ensure_root = lambda: False 237 command = 'ngo45hke3b4vie3mv5ni93,vfu3j' 238 sl4a_manager._SL4A_USER_FIND_PORT_CMD = command 239 240 manager = sl4a_manager.create_sl4a_manager(adb) 241 self.assertEqual(manager._get_all_ports_command(), command) 242 243 def test_get_open_listening_port_no_port_found(self): 244 """Tests sl4a_manager.Sl4aManager._get_open_listening_port(). 245 246 Tests to ensure None is returned if no open port is found. 247 """ 248 adb = mock.Mock() 249 adb.shell = lambda _: '' 250 251 manager = sl4a_manager.create_sl4a_manager(adb) 252 self.assertIsNone(manager._get_open_listening_port()) 253 254 def test_get_open_listening_port_no_new_port_found(self): 255 """Tests sl4a_manager.Sl4aManager._get_open_listening_port(). 256 257 Tests to ensure None is returned if the ports returned have all been 258 marked as in used. 259 """ 260 adb = mock.Mock() 261 adb.shell = lambda _: '12345 67890' 262 263 manager = sl4a_manager.create_sl4a_manager(adb) 264 manager._sl4a_ports = {'12345', '67890'} 265 self.assertIsNone(manager._get_open_listening_port()) 266 267 def test_get_open_listening_port_port_is_avaiable(self): 268 """Tests sl4a_manager.Sl4aManager._get_open_listening_port(). 269 270 Tests to ensure a port is returned if a port is found and has not been 271 marked as used. 272 """ 273 adb = mock.Mock() 274 adb.shell = lambda _: '12345 67890' 275 276 manager = sl4a_manager.create_sl4a_manager(adb) 277 manager._sl4a_ports = {'12345'} 278 self.assertEqual(manager._get_open_listening_port(), 67890) 279 280 def test_is_sl4a_installed_is_true(self): 281 """Tests sl4a_manager.Sl4aManager.is_sl4a_installed(). 282 283 Tests is_sl4a_installed() returns true when pm returns data 284 """ 285 adb = mock.Mock() 286 adb.shell = lambda _, **kwargs: 'asdf' 287 manager = sl4a_manager.create_sl4a_manager(adb) 288 self.assertTrue(manager.is_sl4a_installed()) 289 290 def test_is_sl4a_installed_is_false(self): 291 """Tests sl4a_manager.Sl4aManager.is_sl4a_installed(). 292 293 Tests is_sl4a_installed() returns true when pm returns data 294 """ 295 adb = mock.Mock() 296 adb.shell = lambda _, **kwargs: '' 297 manager = sl4a_manager.create_sl4a_manager(adb) 298 self.assertFalse(manager.is_sl4a_installed()) 299 300 def test_start_sl4a_throws_error_on_sl4a_not_installed(self): 301 """Tests sl4a_manager.Sl4aManager.start_sl4a_service(). 302 303 Tests that a MissingSl4aError is thrown when SL4A is not installed. 304 """ 305 adb = mock.Mock() 306 307 manager = sl4a_manager.create_sl4a_manager(adb) 308 manager.is_sl4a_installed = lambda: False 309 try: 310 manager.start_sl4a_service() 311 self.fail('An error should have been thrown.') 312 except rpc_client.MissingSl4AError: 313 pass 314 315 def test_start_sl4a_starts_sl4a_if_not_running(self): 316 """Tests sl4a_manager.Sl4aManager.start_sl4a_service(). 317 318 Tests that SL4A is started if it was not already running. 319 """ 320 adb = mock.Mock() 321 adb.shell = mock.Mock(side_effect=['', '', '']) 322 323 manager = sl4a_manager.create_sl4a_manager(adb) 324 manager.is_sl4a_installed = lambda: True 325 try: 326 manager.start_sl4a_service() 327 except rpc_client.MissingSl4AError: 328 self.fail('An error should not have been thrown.') 329 adb.shell.assert_called_with(sl4a_manager._SL4A_START_SERVICE_CMD) 330 331 def test_create_session_uses_oldest_server_port(self): 332 """Tests sl4a_manager.Sl4aManager.create_session(). 333 334 Tests that when no port is given, the oldest server port opened is used 335 as the server port for a new session. The oldest server port can be 336 found by getting the oldest session's server port. 337 """ 338 adb = mock.Mock() 339 340 manager = sl4a_manager.create_sl4a_manager(adb) 341 # Ignore starting SL4A. 342 manager.start_sl4a_service = lambda: None 343 344 session_1 = mock.Mock() 345 session_1.server_port = 12345 346 session_2 = mock.Mock() 347 session_2.server_port = 67890 348 session_3 = mock.Mock() 349 session_3.server_port = 67890 350 351 manager.sessions[3] = session_3 352 manager.sessions[1] = session_1 353 manager.sessions[2] = session_2 354 355 with mock.patch.object( 356 rpc_client.RpcClient, '__init__', return_value=None): 357 created_session = manager.create_session() 358 359 self.assertEqual(created_session.server_port, session_1.server_port) 360 361 def test_create_session_uses_random_port_when_no_session_exists(self): 362 """Tests sl4a_manager.Sl4aManager.create_session(). 363 364 Tests that when no port is given, and no SL4A server exists, the server 365 port for the session is set to 0. 366 """ 367 adb = mock.Mock() 368 369 manager = sl4a_manager.create_sl4a_manager(adb) 370 # Ignore starting SL4A. 371 manager.start_sl4a_service = lambda: None 372 373 with mock.patch.object( 374 rpc_client.RpcClient, '__init__', return_value=None): 375 created_session = manager.create_session() 376 377 self.assertEqual(created_session.server_port, 0) 378 379 def test_terminate_all_session_call_terminate_on_all_sessions(self): 380 """Tests sl4a_manager.Sl4aManager.terminate_all_sessions(). 381 382 Tests to see that the manager has called terminate on all sessions. 383 """ 384 called_terminate_on = list() 385 386 def called_on(session): 387 called_terminate_on.append(session) 388 389 adb = mock.Mock() 390 manager = sl4a_manager.Sl4aManager(adb) 391 392 session_1 = mock.Mock() 393 session_1.terminate = lambda *args, **kwargs: called_on(session_1) 394 manager.sessions[1] = session_1 395 session_4 = mock.Mock() 396 session_4.terminate = lambda *args, **kwargs: called_on(session_4) 397 manager.sessions[4] = session_4 398 session_5 = mock.Mock() 399 session_5.terminate = lambda *args, **kwargs: called_on(session_5) 400 manager.sessions[5] = session_5 401 402 manager._get_all_ports = lambda: [] 403 manager.terminate_all_sessions() 404 # No duplicates calls to terminate. 405 self.assertEqual( 406 len(called_terminate_on), len(set(called_terminate_on))) 407 # One call for each session 408 self.assertSetEqual( 409 set(called_terminate_on), {session_1, session_4, session_5}) 410 411 def test_terminate_all_session_close_each_server(self): 412 """Tests sl4a_manager.Sl4aManager.terminate_all_sessions(). 413 414 Tests to see that the manager has called terminate on all sessions. 415 """ 416 closed_ports = list() 417 418 def close(command): 419 if str.isdigit(command): 420 closed_ports.append(command) 421 return '' 422 423 adb = mock.Mock() 424 adb.shell = close 425 sl4a_manager._SL4A_CLOSE_SERVER_CMD = '%s' 426 ports_to_close = {'12345', '67890', '24680', '13579'} 427 428 manager = sl4a_manager.Sl4aManager(adb) 429 manager._sl4a_ports = set(ports_to_close) 430 manager._get_all_ports = lambda: [] 431 manager.terminate_all_sessions() 432 433 # No duplicate calls to close port 434 self.assertEqual(len(closed_ports), len(set(closed_ports))) 435 # One call for each port 436 self.assertSetEqual(ports_to_close, set(closed_ports)) 437 438 def test_obtain_sl4a_server_starts_new_server(self): 439 """Tests sl4a_manager.Sl4aManager.obtain_sl4a_server(). 440 441 Tests that a new server can be returned if the server does not exist. 442 """ 443 adb = mock.Mock() 444 manager = sl4a_manager.Sl4aManager(adb) 445 manager.start_sl4a_server = mock.Mock() 446 447 manager.obtain_sl4a_server(0) 448 449 self.assertTrue(manager.start_sl4a_server.called) 450 451 @mock.patch( 452 'acts.controllers.sl4a_lib.sl4a_manager.Sl4aManager.sl4a_ports_in_use', 453 new_callable=mock.PropertyMock) 454 def test_obtain_sl4a_server_returns_existing_server( 455 self, sl4a_ports_in_use): 456 """Tests sl4a_manager.Sl4aManager.obtain_sl4a_server(). 457 458 Tests that an existing server is returned if it is already opened. 459 """ 460 adb = mock.Mock() 461 manager = sl4a_manager.Sl4aManager(adb) 462 manager.start_sl4a_server = mock.Mock() 463 sl4a_ports_in_use.return_value = [12345] 464 465 ret = manager.obtain_sl4a_server(12345) 466 467 self.assertFalse(manager.start_sl4a_server.called) 468 self.assertEqual(12345, ret) 469 470 471 if __name__ == '__main__': 472 unittest.main() 473