• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Tests for list."""
15
16import unittest
17
18from unittest import mock
19
20from acloud import errors
21from acloud.internal.lib import cvd_runtime_config
22from acloud.internal.lib import driver_test_lib
23from acloud.internal.lib import utils
24from acloud.list import list as list_instance
25from acloud.list import instance
26
27
28class InstanceObject:
29    """Mock to store data of instance."""
30
31    def __init__(self, name):
32        self.name = name
33
34
35class ListTest(driver_test_lib.BaseDriverTest):
36    """Test list."""
37
38    def testGetInstancesFromInstanceNames(self):
39        """test get instances from instance names."""
40        cfg = mock.MagicMock()
41        instance_names = ["alive_instance1", "alive_local_instance"]
42
43        alive_instance1 = InstanceObject("alive_instance1")
44        alive_instance2 = InstanceObject("alive_instance2")
45        alive_local_instance = InstanceObject("alive_local_instance")
46
47        self.Patch(list_instance, "GetLocalInstancesByNames",
48                   return_value=[alive_local_instance])
49        self.Patch(list_instance, "GetRemoteInstances",
50                   return_value=[alive_instance1, alive_instance2])
51        instances_list = list_instance.GetInstancesFromInstanceNames(cfg, instance_names)
52        instances_name_in_list = [instance_object.name for instance_object in instances_list]
53        self.assertEqual(instances_name_in_list.sort(), instance_names.sort())
54
55        instance_names = ["alive_instance1", "alive_local_instance", "alive_local_instance"]
56        instances_list = list_instance.GetInstancesFromInstanceNames(cfg, instance_names)
57        instances_name_in_list = [instance_object.name for instance_object in instances_list]
58        self.assertEqual(instances_name_in_list.sort(), instance_names.sort())
59
60        # test get instance from instance name error with invalid input.
61        instance_names = ["miss2_local_instance", "alive_instance1"]
62        miss_instance_names = ["miss2_local_instance"]
63        self.assertRaisesRegex(
64            errors.NoInstancesFound,
65            "Did not find the following instances: %s" % ' '.join(miss_instance_names),
66            list_instance.GetInstancesFromInstanceNames,
67            cfg=cfg,
68            instance_names=instance_names)
69
70    def testChooseOneRemoteInstance(self):
71        """test choose one remote instance from instance names."""
72        cfg = mock.MagicMock()
73
74        # Test only one instance case
75        instance_names = ["cf_instance1"]
76        self.Patch(list_instance, "GetCFRemoteInstances", return_value=instance_names)
77        expected_instance = "cf_instance1"
78        self.assertEqual(list_instance.ChooseOneRemoteInstance(cfg), expected_instance)
79
80        # Test no instance case
81        self.Patch(list_instance, "GetCFRemoteInstances", return_value=[])
82        with self.assertRaises(errors.NoInstancesFound):
83            list_instance.ChooseOneRemoteInstance(cfg)
84
85        # Test two instances case.
86        instance_names = ["cf_instance1", "cf_instance2"]
87        choose_instance = ["cf_instance2"]
88        self.Patch(list_instance, "GetCFRemoteInstances", return_value=instance_names)
89        self.Patch(utils, "GetAnswerFromList", return_value=choose_instance)
90        expected_instance = "cf_instance2"
91        self.assertEqual(list_instance.ChooseOneRemoteInstance(cfg), expected_instance)
92
93    def testGetLocalInstancesByNames(self):
94        """test GetLocalInstancesByNames."""
95        self.Patch(
96            instance, "GetLocalInstanceIdByName",
97            side_effect=lambda name: 1 if name == "local-instance-1" else None)
98        self.Patch(instance, "GetLocalInstanceConfig",
99                   return_value="path1")
100        self.Patch(instance, "GetDefaultCuttlefishConfig",
101                   return_value="path2")
102        mock_cf_ins = mock.Mock()
103        mock_cf_ins.name = "local-instance-1"
104        mock_get_cf = self.Patch(list_instance,
105                                 "_GetLocalCuttlefishInstances",
106                                 return_value=[mock_cf_ins])
107        mock_gf_ins = mock.Mock()
108        mock_gf_ins.name = "local-goldfish-instance-1"
109        self.Patch(instance.LocalGoldfishInstance, "GetExistingInstances",
110                   return_value=[mock_gf_ins])
111
112        ins_list = list_instance.GetLocalInstancesByNames([
113            mock_cf_ins.name, "local-instance-6", mock_gf_ins.name])
114        self.assertEqual([mock_cf_ins, mock_gf_ins], ins_list)
115        mock_get_cf.assert_called_with([(1, "path1"), (1, "path2")])
116
117    # pylint: disable=attribute-defined-outside-init
118    def testFilterInstancesByAdbPort(self):
119        """test FilterInstancesByAdbPort."""
120        alive_instance1 = InstanceObject("alive_instance1")
121        alive_instance1.adb_port = 1111
122        alive_instance1.fullname = "device serial: 127.0.0.1:1111 alive_instance1"
123        expected_instance = [alive_instance1]
124        # Test to find instance by adb port number.
125        self.assertEqual(
126            expected_instance,
127            list_instance.FilterInstancesByAdbPort(expected_instance, 1111))
128        # Test for instance can't be found by adb port number.
129        with self.assertRaises(errors.NoInstancesFound):
130            list_instance.FilterInstancesByAdbPort(expected_instance, 2222)
131
132    # pylint: disable=protected-access
133    def testGetLocalCuttlefishInstances(self):
134        """test _GetLocalCuttlefishInstances."""
135        # Test getting two instance case
136        id_cfg_pairs = [(1, "fake_path1"), (2, "fake_path2")]
137        mock_isfile = self.Patch(list_instance.os.path, "isfile",
138                                 return_value=True)
139
140        mock_lock = mock.Mock()
141        mock_lock.Lock.return_value = True
142        self.Patch(instance, "GetLocalInstanceLock", return_value=mock_lock)
143
144        local_ins = mock.MagicMock()
145        local_ins.CvdStatus.return_value = True
146        self.Patch(instance, "LocalInstance", return_value=local_ins)
147
148        ins_list = list_instance._GetLocalCuttlefishInstances(id_cfg_pairs)
149        self.assertEqual(2, len(ins_list))
150        mock_isfile.assert_called()
151        local_ins.CvdStatus.assert_called()
152        self.assertEqual(2, mock_lock.Lock.call_count)
153        self.assertEqual(2, mock_lock.Unlock.call_count)
154
155        local_ins.CvdStatus.reset_mock()
156        mock_lock.Lock.reset_mock()
157        mock_lock.Lock.return_value = False
158        mock_lock.Unlock.reset_mock()
159        ins_list = list_instance._GetLocalCuttlefishInstances(id_cfg_pairs)
160        self.assertEqual(0, len(ins_list))
161        local_ins.CvdStatus.assert_not_called()
162        self.assertEqual(2, mock_lock.Lock.call_count)
163        mock_lock.Unlock.assert_not_called()
164
165        mock_lock.Lock.reset_mock()
166        mock_lock.Lock.return_value = True
167        local_ins.CvdStatus.return_value = False
168        ins_list = list_instance._GetLocalCuttlefishInstances(id_cfg_pairs)
169        self.assertEqual(0, len(ins_list))
170        self.assertEqual(2, mock_lock.Lock.call_count)
171        self.assertEqual(2, mock_lock.Unlock.call_count)
172
173    # pylint: disable=no-member
174    def testPrintInstancesDetails(self):
175        """test PrintInstancesDetails."""
176        # Test instance Summary should be called if verbose
177        self.Patch(instance.Instance, "Summary")
178        cf_config = mock.MagicMock(
179            x_res=728,
180            y_res=728,
181            dpi=240,
182            instance_dir="fake_dir",
183            adb_ip_port="127.0.0.1:6520"
184        )
185        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
186                   return_value=cf_config)
187
188        ins = instance.LocalInstance("fake_cf_path")
189        list_instance.PrintInstancesDetails([ins], verbose=True)
190        instance.Instance.Summary.assert_called_once()
191
192        # Test Summary shouldn't be called if not verbose
193        self.Patch(instance.Instance, "Summary")
194        list_instance.PrintInstancesDetails([ins], verbose=False)
195        instance.Instance.Summary.assert_not_called()
196
197        # Test Summary shouldn't be called if no instance found.
198        list_instance.PrintInstancesDetails([], verbose=True)
199        instance.Instance.Summary.assert_not_called()
200
201
202if __name__ == "__main__":
203    unittest.main()
204