blob: 6d42989c0f91af4029e684f5e22d0b4187563426 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import mock
from antlion.controllers.sl4a_lib import rpc_client, sl4a_manager
class Sl4aManagerFactoryTest(unittest.TestCase):
"""Tests the sl4a_manager module-level functions."""
def setUp(self):
"""Clears the Sl4aManager cache."""
sl4a_manager._all_sl4a_managers = {}
def test_create_manager(self):
"""Tests sl4a_manager.create_sl4a_manager().
Tests that a new Sl4aManager is returned without an error.
"""
adb = mock.Mock()
adb.serial = "SERIAL"
sl4a_man = sl4a_manager.create_sl4a_manager(adb)
self.assertEqual(sl4a_man.adb, adb)
def test_create_sl4a_manager_return_already_created_manager(self):
"""Tests sl4a_manager.create_sl4a_manager().
Tests that a second call to create_sl4a_manager() does not create a
new Sl4aManager, and returns the first created Sl4aManager instead.
"""
adb = mock.Mock()
adb.serial = "SERIAL"
first_manager = sl4a_manager.create_sl4a_manager(adb)
adb_same_serial = mock.Mock()
adb_same_serial.serial = "SERIAL"
second_manager = sl4a_manager.create_sl4a_manager(adb)
self.assertEqual(first_manager, second_manager)
def test_create_sl4a_manager_multiple_devices_with_one_manager_each(self):
"""Tests sl4a_manager.create_sl4a_manager().
Tests that when create_s4l4a_manager() is called for different devices,
each device gets its own Sl4aManager object.
"""
adb_1 = mock.Mock()
adb_1.serial = "SERIAL"
first_manager = sl4a_manager.create_sl4a_manager(adb_1)
adb_2 = mock.Mock()
adb_2.serial = "DIFFERENT_SERIAL_NUMBER"
second_manager = sl4a_manager.create_sl4a_manager(adb_2)
self.assertNotEqual(first_manager, second_manager)
class Sl4aManagerTest(unittest.TestCase):
"""Tests the sl4a_manager.Sl4aManager class."""
ATTEMPT_INTERVAL = 0.25
MAX_WAIT_ON_SERVER_SECONDS = 1
_SL4A_LAUNCH_SERVER_CMD = ""
_SL4A_CLOSE_SERVER_CMD = ""
_SL4A_ROOT_FIND_PORT_CMD = ""
_SL4A_USER_FIND_PORT_CMD = ""
_SL4A_START_SERVICE_CMD = ""
@classmethod
def setUpClass(cls):
# Copy all module constants before testing begins.
Sl4aManagerTest.ATTEMPT_INTERVAL = sl4a_manager.ATTEMPT_INTERVAL
Sl4aManagerTest.MAX_WAIT_ON_SERVER_SECONDS = (
sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS
)
Sl4aManagerTest._SL4A_LAUNCH_SERVER_CMD = sl4a_manager._SL4A_LAUNCH_SERVER_CMD
Sl4aManagerTest._SL4A_CLOSE_SERVER_CMD = sl4a_manager._SL4A_CLOSE_SERVER_CMD
Sl4aManagerTest._SL4A_ROOT_FIND_PORT_CMD = sl4a_manager._SL4A_ROOT_FIND_PORT_CMD
Sl4aManagerTest._SL4A_USER_FIND_PORT_CMD = sl4a_manager._SL4A_USER_FIND_PORT_CMD
Sl4aManagerTest._SL4A_START_SERVICE_CMD = sl4a_manager._SL4A_START_SERVICE_CMD
def setUp(self):
# Restore all module constants at the beginning of each test case.
sl4a_manager.ATTEMPT_INTERVAL = Sl4aManagerTest.ATTEMPT_INTERVAL
sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS = (
Sl4aManagerTest.MAX_WAIT_ON_SERVER_SECONDS
)
sl4a_manager._SL4A_LAUNCH_SERVER_CMD = Sl4aManagerTest._SL4A_LAUNCH_SERVER_CMD
sl4a_manager._SL4A_CLOSE_SERVER_CMD = Sl4aManagerTest._SL4A_CLOSE_SERVER_CMD
sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = Sl4aManagerTest._SL4A_ROOT_FIND_PORT_CMD
sl4a_manager._SL4A_USER_FIND_PORT_CMD = Sl4aManagerTest._SL4A_USER_FIND_PORT_CMD
sl4a_manager._SL4A_START_SERVICE_CMD = Sl4aManagerTest._SL4A_START_SERVICE_CMD
# Reset module data at the beginning of each test.
sl4a_manager._all_sl4a_managers = {}
def test_sl4a_ports_in_use(self):
"""Tests sl4a_manager.Sl4aManager.sl4a_ports_in_use
Tests to make sure all server ports are returned with no duplicates.
"""
adb = mock.Mock()
manager = sl4a_manager.Sl4aManager(adb)
session_1 = mock.Mock()
session_1.server_port = 12345
manager.sessions[1] = session_1
session_2 = mock.Mock()
session_2.server_port = 15973
manager.sessions[2] = session_2
session_3 = mock.Mock()
session_3.server_port = 12345
manager.sessions[3] = session_3
session_4 = mock.Mock()
session_4.server_port = 67890
manager.sessions[4] = session_4
session_5 = mock.Mock()
session_5.server_port = 75638
manager.sessions[5] = session_5
returned_ports = manager.sl4a_ports_in_use
# No duplicated ports.
self.assertEqual(len(returned_ports), len(set(returned_ports)))
# One call for each session
self.assertSetEqual(set(returned_ports), {12345, 15973, 67890, 75638})
@mock.patch("time.sleep", return_value=None)
def test_start_sl4a_server_uses_all_retries(self, _):
"""Tests sl4a_manager.Sl4aManager.start_sl4a_server().
Tests to ensure that _start_sl4a_server retries and successfully returns
a port.
"""
adb = mock.Mock()
adb.shell = lambda _, **kwargs: ""
side_effects = []
expected_port = 12345
for _ in range(
int(sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS / sl4a_manager.ATTEMPT_INTERVAL)
- 1
):
side_effects.append(None)
side_effects.append(expected_port)
manager = sl4a_manager.create_sl4a_manager(adb)
manager._get_open_listening_port = mock.Mock(side_effect=side_effects)
try:
found_port = manager.start_sl4a_server(0)
self.assertTrue(found_port)
except rpc_client.Sl4aConnectionError:
self.fail("start_sl4a_server failed to respect FIND_PORT_RETRIES.")
@mock.patch("time.sleep", return_value=None)
def test_start_sl4a_server_fails_all_retries(self, _):
"""Tests sl4a_manager.Sl4aManager.start_sl4a_server().
Tests to ensure that start_sl4a_server throws an error if all retries
fail.
"""
adb = mock.Mock()
adb.shell = lambda _, **kwargs: ""
side_effects = []
for _ in range(
int(sl4a_manager.MAX_WAIT_ON_SERVER_SECONDS / sl4a_manager.ATTEMPT_INTERVAL)
):
side_effects.append(None)
manager = sl4a_manager.create_sl4a_manager(adb)
manager._get_open_listening_port = mock.Mock(side_effect=side_effects)
try:
manager.start_sl4a_server(0)
self.fail("Sl4aConnectionError was not thrown.")
except rpc_client.Sl4aConnectionError:
pass
def test_get_all_ports_command_uses_root_cmd(self):
"""Tests sl4a_manager.Sl4aManager._get_all_ports_command().
Tests that _get_all_ports_command calls the root command when root is
available.
"""
adb = mock.Mock()
adb.is_root = lambda: True
command = "ngo45hke3b4vie3mv5ni93,vfu3j"
sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = command
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertEqual(manager._get_all_ports_command(), command)
def test_get_all_ports_command_escalates_to_root(self):
"""Tests sl4a_manager.Sl4aManager._call_get_ports_command().
Tests that _call_get_ports_command calls the root command when adb is
user but can escalate to root.
"""
adb = mock.Mock()
adb.is_root = lambda: False
adb.ensure_root = lambda: True
command = "ngo45hke3b4vie3mv5ni93,vfu3j"
sl4a_manager._SL4A_ROOT_FIND_PORT_CMD = command
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertEqual(manager._get_all_ports_command(), command)
def test_get_all_ports_command_uses_user_cmd(self):
"""Tests sl4a_manager.Sl4aManager._call_get_ports_command().
Tests that _call_get_ports_command calls the user command when root is
unavailable.
"""
adb = mock.Mock()
adb.is_root = lambda: False
adb.ensure_root = lambda: False
command = "ngo45hke3b4vie3mv5ni93,vfu3j"
sl4a_manager._SL4A_USER_FIND_PORT_CMD = command
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertEqual(manager._get_all_ports_command(), command)
def test_get_open_listening_port_no_port_found(self):
"""Tests sl4a_manager.Sl4aManager._get_open_listening_port().
Tests to ensure None is returned if no open port is found.
"""
adb = mock.Mock()
adb.shell = lambda _: ""
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertIsNone(manager._get_open_listening_port())
def test_get_open_listening_port_no_new_port_found(self):
"""Tests sl4a_manager.Sl4aManager._get_open_listening_port().
Tests to ensure None is returned if the ports returned have all been
marked as in used.
"""
adb = mock.Mock()
adb.shell = lambda _: "12345 67890"
manager = sl4a_manager.create_sl4a_manager(adb)
manager._sl4a_ports = {"12345", "67890"}
self.assertIsNone(manager._get_open_listening_port())
def test_get_open_listening_port_port_is_avaiable(self):
"""Tests sl4a_manager.Sl4aManager._get_open_listening_port().
Tests to ensure a port is returned if a port is found and has not been
marked as used.
"""
adb = mock.Mock()
adb.shell = lambda _: "12345 67890"
manager = sl4a_manager.create_sl4a_manager(adb)
manager._sl4a_ports = {"12345"}
self.assertEqual(manager._get_open_listening_port(), 67890)
def test_is_sl4a_installed_is_true(self):
"""Tests sl4a_manager.Sl4aManager.is_sl4a_installed().
Tests is_sl4a_installed() returns true when pm returns data
"""
adb = mock.Mock()
adb.shell = lambda _, **kwargs: "asdf"
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertTrue(manager.is_sl4a_installed())
def test_is_sl4a_installed_is_false(self):
"""Tests sl4a_manager.Sl4aManager.is_sl4a_installed().
Tests is_sl4a_installed() returns true when pm returns data
"""
adb = mock.Mock()
adb.shell = lambda _, **kwargs: ""
manager = sl4a_manager.create_sl4a_manager(adb)
self.assertFalse(manager.is_sl4a_installed())
def test_start_sl4a_throws_error_on_sl4a_not_installed(self):
"""Tests sl4a_manager.Sl4aManager.start_sl4a_service().
Tests that a MissingSl4aError is thrown when SL4A is not installed.
"""
adb = mock.Mock()
manager = sl4a_manager.create_sl4a_manager(adb)
manager.is_sl4a_installed = lambda: False
try:
manager.start_sl4a_service()
self.fail("An error should have been thrown.")
except rpc_client.Sl4aNotInstalledError:
pass
def test_start_sl4a_starts_sl4a_if_not_running(self):
"""Tests sl4a_manager.Sl4aManager.start_sl4a_service().
Tests that SL4A is started if it was not already running.
"""
adb = mock.Mock()
adb.shell = mock.Mock(side_effect=["", "", ""])
manager = sl4a_manager.create_sl4a_manager(adb)
manager.is_sl4a_installed = lambda: True
try:
manager.start_sl4a_service()
except rpc_client.Sl4aNotInstalledError:
self.fail("An error should not have been thrown.")
adb.shell.assert_called_with(sl4a_manager._SL4A_START_SERVICE_CMD)
def test_create_session_uses_oldest_server_port(self):
"""Tests sl4a_manager.Sl4aManager.create_session().
Tests that when no port is given, the oldest server port opened is used
as the server port for a new session. The oldest server port can be
found by getting the oldest session's server port.
"""
adb = mock.Mock()
manager = sl4a_manager.create_sl4a_manager(adb)
# Ignore starting SL4A.
manager.start_sl4a_service = lambda: None
session_1 = mock.Mock()
session_1.server_port = 12345
session_2 = mock.Mock()
session_2.server_port = 67890
session_3 = mock.Mock()
session_3.server_port = 67890
manager.sessions[3] = session_3
manager.sessions[1] = session_1
manager.sessions[2] = session_2
with mock.patch.object(rpc_client.RpcClient, "__init__", return_value=None):
created_session = manager.create_session()
self.assertEqual(created_session.server_port, session_1.server_port)
def test_create_session_uses_random_port_when_no_session_exists(self):
"""Tests sl4a_manager.Sl4aManager.create_session().
Tests that when no port is given, and no SL4A server exists, the server
port for the session is set to 0.
"""
adb = mock.Mock()
manager = sl4a_manager.create_sl4a_manager(adb)
# Ignore starting SL4A.
manager.start_sl4a_service = lambda: None
with mock.patch.object(rpc_client.RpcClient, "__init__", return_value=None):
created_session = manager.create_session()
self.assertEqual(created_session.server_port, 0)
def test_terminate_all_session_call_terminate_on_all_sessions(self):
"""Tests sl4a_manager.Sl4aManager.terminate_all_sessions().
Tests to see that the manager has called terminate on all sessions.
"""
called_terminate_on = list()
def called_on(session):
called_terminate_on.append(session)
adb = mock.Mock()
manager = sl4a_manager.Sl4aManager(adb)
session_1 = mock.Mock()
session_1.terminate = lambda *args, **kwargs: called_on(session_1)
manager.sessions[1] = session_1
session_4 = mock.Mock()
session_4.terminate = lambda *args, **kwargs: called_on(session_4)
manager.sessions[4] = session_4
session_5 = mock.Mock()
session_5.terminate = lambda *args, **kwargs: called_on(session_5)
manager.sessions[5] = session_5
manager._get_all_ports = lambda: []
manager.terminate_all_sessions()
# No duplicates calls to terminate.
self.assertEqual(len(called_terminate_on), len(set(called_terminate_on)))
# One call for each session
self.assertSetEqual(set(called_terminate_on), {session_1, session_4, session_5})
def test_terminate_all_session_close_each_server(self):
"""Tests sl4a_manager.Sl4aManager.terminate_all_sessions().
Tests to see that the manager has called terminate on all sessions.
"""
closed_ports = list()
def close(command):
if str.isdigit(command):
closed_ports.append(command)
return ""
adb = mock.Mock()
adb.shell = close
sl4a_manager._SL4A_CLOSE_SERVER_CMD = "%s"
ports_to_close = {"12345", "67890", "24680", "13579"}
manager = sl4a_manager.Sl4aManager(adb)
manager._sl4a_ports = set(ports_to_close)
manager._get_all_ports = lambda: []
manager.terminate_all_sessions()
# No duplicate calls to close port
self.assertEqual(len(closed_ports), len(set(closed_ports)))
# One call for each port
self.assertSetEqual(ports_to_close, set(closed_ports))
def test_obtain_sl4a_server_starts_new_server(self):
"""Tests sl4a_manager.Sl4aManager.obtain_sl4a_server().
Tests that a new server can be returned if the server does not exist.
"""
adb = mock.Mock()
manager = sl4a_manager.Sl4aManager(adb)
manager.start_sl4a_server = mock.Mock()
manager.obtain_sl4a_server(0)
self.assertTrue(manager.start_sl4a_server.called)
@mock.patch(
"antlion.controllers.sl4a_lib.sl4a_manager.Sl4aManager.sl4a_ports_in_use",
new_callable=mock.PropertyMock,
)
def test_obtain_sl4a_server_returns_existing_server(self, sl4a_ports_in_use):
"""Tests sl4a_manager.Sl4aManager.obtain_sl4a_server().
Tests that an existing server is returned if it is already opened.
"""
adb = mock.Mock()
manager = sl4a_manager.Sl4aManager(adb)
manager.start_sl4a_server = mock.Mock()
sl4a_ports_in_use.return_value = [12345]
ret = manager.obtain_sl4a_server(12345)
self.assertFalse(manager.start_sl4a_server.called)
self.assertEqual(12345, ret)
if __name__ == "__main__":
unittest.main()