264 lines
9.8 KiB
Python
264 lines
9.8 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2017 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.
|
|
#
|
|
|
|
import os
|
|
import unittest
|
|
|
|
try:
|
|
from unittest import mock
|
|
except ImportError:
|
|
import mock
|
|
|
|
try:
|
|
import StringIO as string_io_module
|
|
except ImportError:
|
|
import io as string_io_module
|
|
|
|
from host_controller.build import build_flasher
|
|
from host_controller.tfc import command_task
|
|
from host_controller.tfc import device_info
|
|
from host_controller import common
|
|
from host_controller import console
|
|
|
|
|
|
class ConsoleTest(unittest.TestCase):
|
|
"""A test for console.Console.
|
|
|
|
Attribute:
|
|
_out_file: The console output buffer.
|
|
_host_controller: A mock tfc_host_controller.HostController.
|
|
_build_provider_pab: A mock build_provider_pab.BuildProviderPAB.
|
|
_tfc_client: A mock tfc_client.TfcClient.
|
|
_vti_client A mock vti_endpoint_client.VtiEndpointClient.
|
|
_console: The console being tested.
|
|
"""
|
|
_DEVICES = [
|
|
device_info.DeviceInfo(
|
|
device_serial="ABC001",
|
|
run_target="sailfish",
|
|
state="Available",
|
|
build_id="111111",
|
|
sdk_version="27")
|
|
]
|
|
_TASKS = [
|
|
command_task.CommandTask(
|
|
request_id="1",
|
|
task_id="1-0",
|
|
command_id="2",
|
|
command_line="vts -m SampleShellTest",
|
|
device_serials=["ABC001"])
|
|
]
|
|
|
|
def setUp(self):
|
|
"""Creates the console."""
|
|
self._out_file = string_io_module.StringIO()
|
|
self._host_controller = mock.Mock()
|
|
self._build_provider_pab = mock.Mock()
|
|
self._tfc_client = mock.Mock()
|
|
self._vti_client = mock.Mock()
|
|
self._console = console.Console(
|
|
self._vti_client,
|
|
self._tfc_client,
|
|
self._build_provider_pab, [self._host_controller],
|
|
None,
|
|
out_file=self._out_file)
|
|
self._console.device_image_info = {}
|
|
|
|
def tearDown(self):
|
|
"""Closes the output file."""
|
|
self._out_file.close()
|
|
|
|
def _IssueCommand(self, command_line):
|
|
"""Issues a command in the console.
|
|
|
|
Args:
|
|
command_line: A string, the input to the console.
|
|
|
|
Returns:
|
|
A string, the output of the console.
|
|
"""
|
|
out_position = self._out_file.tell()
|
|
self._console.onecmd(command_line)
|
|
self._out_file.seek(out_position)
|
|
return self._out_file.read()
|
|
|
|
def testLease(self):
|
|
"""Tests the lease command."""
|
|
self._host_controller.LeaseCommandTasks.return_value = self._TASKS
|
|
output = self._IssueCommand("lease")
|
|
expected = (
|
|
"request_id command_id task_id device_serials command_line \n"
|
|
"1 2 1-0 ABC001 vts -m SampleShellTest\n"
|
|
)
|
|
self.assertEqual(expected, output)
|
|
output = self._IssueCommand("lease --host 0")
|
|
self.assertEqual(expected, output)
|
|
|
|
def testRequest(self):
|
|
"""Tests the request command."""
|
|
user = "user0"
|
|
cluster = "cluster0"
|
|
run_target = "sailfish"
|
|
command_line = "vts -m SampleShellTest"
|
|
self._IssueCommand("request --user %s --cluster %s --run-target %s "
|
|
"-- %s" % (user, cluster, run_target, command_line))
|
|
req = self._tfc_client.NewRequest.call_args[0][0]
|
|
self.assertEqual(user, req.user)
|
|
self.assertEqual(cluster, req.cluster)
|
|
self.assertEqual(run_target, req.run_target)
|
|
self.assertEqual(command_line, req.command_line)
|
|
|
|
def testListHosts(self):
|
|
"""Tests the list command."""
|
|
self._host_controller.hostname = "host0"
|
|
output = self._IssueCommand("list hosts")
|
|
self.assertEqual("index name\n" "[ 0] host0\n", output)
|
|
|
|
def testListDevices(self):
|
|
"""Tests the list command."""
|
|
self._host_controller.ListDevices.return_value = self._DEVICES
|
|
self._host_controller.hostname = "host0"
|
|
output = self._IssueCommand("list devices")
|
|
expected = (
|
|
"[ 0] host0\n"
|
|
"device_serial state run_target build_id sdk_version stub\n"
|
|
"ABC001 Available sailfish 111111 27 \n"
|
|
)
|
|
self.assertEqual(expected, output)
|
|
output = self._IssueCommand("list devices --host 0")
|
|
self.assertEqual(expected, output)
|
|
|
|
def testWrongHostIndex(self):
|
|
"""Tests host index out of range."""
|
|
output = self._IssueCommand("list devices --host 1")
|
|
expected = "IndexError: "
|
|
self.assertTrue(output.startswith(expected))
|
|
output = self._IssueCommand("lease --host 1")
|
|
self.assertTrue(output.startswith(expected))
|
|
|
|
@mock.patch('host_controller.build.build_flasher.BuildFlasher')
|
|
def testFetchPOSTAndFlash(self, mock_class):
|
|
"""Tests fetching from pab and flashing."""
|
|
self._build_provider_pab.GetArtifact.return_value = ({
|
|
"system.img":
|
|
"/mock/system.img",
|
|
"odm.img":
|
|
"/mock/odm.img"
|
|
}, {}, {
|
|
"build_id":
|
|
"build_id"
|
|
}, {})
|
|
self._build_provider_pab.GetFetchedArtifactType.return_value = common._ARTIFACT_TYPE_DEVICE
|
|
self._IssueCommand(
|
|
"fetch --branch=aosp-master-ndk --target=darwin_mac "
|
|
"--account_id=100621237 "
|
|
"--artifact_name=foo-{build_id}.tar.bz2 --method=POST")
|
|
self._build_provider_pab.GetArtifact.assert_called_with(
|
|
account_id='100621237',
|
|
branch='aosp-master-ndk',
|
|
target='darwin_mac',
|
|
artifact_name='foo-{build_id}.tar.bz2',
|
|
build_id='latest',
|
|
method='POST',
|
|
full_device_images=False)
|
|
self.assertEqual(self._console.device_image_info, {
|
|
"system.img": "/mock/system.img",
|
|
"odm.img": "/mock/odm.img"
|
|
})
|
|
|
|
flasher = mock.Mock()
|
|
mock_class.return_value = flasher
|
|
self._IssueCommand("flash --current system=system.img odm=odm.img")
|
|
flasher.Flash.assert_called_with({
|
|
"system": "/mock/system.img",
|
|
"odm": "/mock/odm.img"
|
|
}, False)
|
|
|
|
def testFetchAndEnvironment(self):
|
|
"""Tests fetching from pab and check stored os environment"""
|
|
build_id_return = "4328532"
|
|
target_return = "darwin_mac"
|
|
expected_fetch_info = {"build_id": build_id_return}
|
|
|
|
self._build_provider_pab.GetArtifact.return_value = ({
|
|
"system.img":
|
|
"/mock/system.img",
|
|
"odm.img":
|
|
"/mock/odm.img"
|
|
}, {}, expected_fetch_info, {})
|
|
self._IssueCommand(
|
|
"fetch --branch=aosp-master-ndk --target=%s "
|
|
"--account_id=100621237 "
|
|
"--artifact_name=foo-{id}.tar.bz2 --method=POST" % target_return)
|
|
self._build_provider_pab.GetArtifact.assert_called_with(
|
|
account_id='100621237',
|
|
branch='aosp-master-ndk',
|
|
target='darwin_mac',
|
|
artifact_name='foo-{id}.tar.bz2',
|
|
build_id='latest',
|
|
full_device_images=False,
|
|
method='POST')
|
|
|
|
expected = expected_fetch_info["build_id"]
|
|
self.assertEqual(build_id_return, expected)
|
|
|
|
@mock.patch('host_controller.build.build_flasher.BuildFlasher')
|
|
def testFlashGSI(self, mock_class):
|
|
flasher = mock.Mock()
|
|
mock_class.return_value = flasher
|
|
self._IssueCommand("flash --gsi=system.img")
|
|
flasher.FlashGSI.assert_called_with(
|
|
'system.img', None, skip_vbmeta=False)
|
|
|
|
@mock.patch('host_controller.build.build_flasher.BuildFlasher')
|
|
def testFlashGSIWithVbmeta(self, mock_class):
|
|
flasher = mock.Mock()
|
|
mock_class.return_value = flasher
|
|
self._IssueCommand("flash --gsi=system.img --vbmeta=vbmeta.img")
|
|
flasher.FlashGSI.assert_called_with(
|
|
'system.img', 'vbmeta.img', skip_vbmeta=False)
|
|
|
|
@mock.patch('host_controller.build.build_flasher.BuildFlasher')
|
|
def testFlashall(self, mock_class):
|
|
flasher = mock.Mock()
|
|
mock_class.return_value = flasher
|
|
self._IssueCommand("flash --build_dir=path/to/dir/")
|
|
flasher.Flashall.assert_called_with('path/to/dir/')
|
|
|
|
@mock.patch('host_controller.command_processor.command_flash.importlib')
|
|
@mock.patch('host_controller.command_processor.command_flash.issubclass')
|
|
def testImportFlasher(self, mock_issubclass, mock_importlib):
|
|
mock_issubclass.return_value = True
|
|
flasher_module = mock.Mock()
|
|
flasher = mock.Mock()
|
|
mock_importlib.import_module.return_value = flasher_module
|
|
flasher_module.Flasher.return_value = flasher
|
|
self._IssueCommand("flash --serial ABC001 "
|
|
"--flasher_type test.flasher.Flasher "
|
|
"--flasher_path /test/flasher "
|
|
"-- --unit test")
|
|
mock_issubclass.assert_called_once_with(flasher_module.Flasher,
|
|
build_flasher.BuildFlasher)
|
|
mock_importlib.import_module.assert_called_with("test.flasher")
|
|
flasher_module.Flasher.assert_called_with("ABC001", "/test/flasher")
|
|
flasher.Flash.assert_called_with({}, {}, "--unit", "test")
|
|
flasher.WaitForDevice.assert_called_with()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|