177 lines
6.9 KiB
Python
177 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2021 - The Android Open Source Project
|
|
#
|
|
# 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.
|
|
|
|
"""Unit tests for RemoteEmulatorConsole."""
|
|
|
|
import unittest
|
|
import subprocess
|
|
|
|
from unittest import mock
|
|
|
|
from acloud import errors
|
|
from acloud.internal.lib import driver_test_lib
|
|
from acloud.internal.lib import emulator_console
|
|
|
|
|
|
class EmulatorConsoleTest(driver_test_lib.BaseDriverTest):
|
|
"""Unit tests for RemoteEmulatorConsole."""
|
|
|
|
_LOCAL_PORT = 56789
|
|
_TIMEOUT_SECS = 100
|
|
|
|
def setUp(self):
|
|
"""Create mock objects."""
|
|
super().setUp()
|
|
self._mock_pick_free_port = self.Patch(
|
|
emulator_console.utils, "PickFreePort",
|
|
return_value=self._LOCAL_PORT)
|
|
self._mock_establish_ssh_tunnel = self.Patch(
|
|
emulator_console.utils,
|
|
"EstablishSshTunnel")
|
|
self._mock_release_port = self.Patch(
|
|
emulator_console.utils,
|
|
"ReleasePort")
|
|
self._mock_connection = mock.Mock()
|
|
self._mock_create_connection = self.Patch(
|
|
emulator_console.socket,
|
|
"create_connection",
|
|
return_value=self._mock_connection)
|
|
|
|
def _CreateRemoteEmulatorConsole(self):
|
|
"""_Create a RemoteEmulatorConsole."""
|
|
console = emulator_console.RemoteEmulatorConsole(
|
|
"192.0.2.1", 5444, "user", "key_path", "extra args",
|
|
self._TIMEOUT_SECS)
|
|
self._mock_pick_free_port.assert_called_once()
|
|
self._mock_establish_ssh_tunnel.assert_called_once_with(
|
|
"192.0.2.1", "key_path", "user",
|
|
[(self._LOCAL_PORT, 5444)], "extra args")
|
|
self._mock_create_connection.assert_called_once_with(
|
|
("127.0.0.1", self._LOCAL_PORT), self._TIMEOUT_SECS)
|
|
self._mock_connection.settimeout.assert_called_once_with(
|
|
self._TIMEOUT_SECS)
|
|
self._mock_release_port.assert_not_called()
|
|
self._mock_connection.close.assert_not_called()
|
|
|
|
self._mock_pick_free_port.reset_mock()
|
|
self._mock_establish_ssh_tunnel.reset_mock()
|
|
self._mock_create_connection.reset_mock()
|
|
self._mock_connection.settimeout.reset_mock()
|
|
return console
|
|
|
|
def testInitSshTunnelError(self):
|
|
"""Test not releasing port if SSH tunnel fails."""
|
|
self._mock_establish_ssh_tunnel.side_effect = (
|
|
subprocess.CalledProcessError(returncode=1, cmd="ssh"))
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
emulator_console.RemoteEmulatorConsole(
|
|
"192.0.2.1", 5444, "user", "key_path", "extra args",
|
|
self._TIMEOUT_SECS)
|
|
self._mock_connection.settimeout.assert_not_called()
|
|
self._mock_connection.close.assert_not_called()
|
|
self._mock_release_port.assert_not_called()
|
|
|
|
def testInitConnectionError(self):
|
|
"""Test releasing port when create_connection fails."""
|
|
self._mock_create_connection.side_effect = OSError()
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
emulator_console.RemoteEmulatorConsole(
|
|
"192.0.2.1", 5444, "user", "key_path", "extra args",
|
|
self._TIMEOUT_SECS)
|
|
self._mock_connection.settimeout.assert_not_called()
|
|
self._mock_connection.close.assert_not_called()
|
|
self._mock_release_port.assert_called_once()
|
|
|
|
def testInitSocketError(self):
|
|
"""Test closing socket when settimeout fails."""
|
|
self._mock_connection.settimeout.side_effect = OSError()
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
emulator_console.RemoteEmulatorConsole(
|
|
"192.0.2.1", 5444, "user", "key_path", "extra args",
|
|
self._TIMEOUT_SECS)
|
|
self._mock_connection.settimeout.assert_called_once()
|
|
self._mock_connection.close.assert_called_once()
|
|
self._mock_release_port.assert_called_once()
|
|
|
|
def testContext(self):
|
|
"""Test RemoteEmulatorConsole as a context manager."""
|
|
with self._CreateRemoteEmulatorConsole():
|
|
pass
|
|
self._mock_connection.close.assert_called_once()
|
|
self._mock_release_port.assert_called_once()
|
|
|
|
def testReconnect(self):
|
|
"""Test RemoteEmulatorConsole.Reconnect."""
|
|
console = self._CreateRemoteEmulatorConsole()
|
|
console.Reconnect()
|
|
self._mock_pick_free_port.assert_not_called()
|
|
self._mock_establish_ssh_tunnel.assert_not_called()
|
|
self._mock_release_port.assert_not_called()
|
|
self._mock_connection.close.assert_called_once()
|
|
self._mock_create_connection.assert_called_once_with(
|
|
("127.0.0.1", self._LOCAL_PORT), self._TIMEOUT_SECS)
|
|
self._mock_connection.settimeout.assert_called_once_with(
|
|
self._TIMEOUT_SECS)
|
|
|
|
def testSend(self):
|
|
"""Test RemoteEmulatorConsole.Send."""
|
|
console = self._CreateRemoteEmulatorConsole()
|
|
console.Send("ping")
|
|
self._mock_connection.send.assert_called_with(b"ping\n")
|
|
|
|
self._mock_connection.send.side_effect = OSError()
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
console.Send("ping")
|
|
|
|
def testRecv(self):
|
|
"""Test RemoteEmulatorConsole.Recv."""
|
|
console = self._CreateRemoteEmulatorConsole()
|
|
|
|
self._mock_connection.recv.side_effect = [b"1", b"1"]
|
|
self.assertEqual("11", console.Recv("11", buffer_size=1))
|
|
self._mock_connection.recv.side_effect = [b"12"]
|
|
self.assertEqual("12", console.Recv("2"))
|
|
|
|
self._mock_connection.recv.side_effect = [b"1", b""]
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
console.Recv("2")
|
|
self._mock_connection.recv.side_effect = OSError()
|
|
with self.assertRaises(errors.DeviceConnectionError):
|
|
console.Recv("1")
|
|
|
|
def testPing(self):
|
|
"""Test RemoteEmulatorConsole.Ping."""
|
|
console = self._CreateRemoteEmulatorConsole()
|
|
|
|
self._mock_connection.recv.side_effect = [b"I am alive!\r\nOK\r\n"]
|
|
self.assertTrue(console.Ping())
|
|
|
|
self._mock_connection.recv.side_effect = [b""]
|
|
self.assertFalse(console.Ping())
|
|
|
|
self._mock_connection.recv.side_effect = OSError()
|
|
self.assertFalse(console.Ping())
|
|
|
|
def testKill(self):
|
|
"""Test RemoteEmulatorConsole.Kill."""
|
|
console = self._CreateRemoteEmulatorConsole()
|
|
self._mock_connection.recv.side_effect = [b"bye bye\r\n"]
|
|
console.Kill()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|