You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
9.8 KiB
263 lines
9.8 KiB
#!/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()
|
|
|