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
18import 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(object):
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        instance_alive = [alive_instance1, alive_instance2, alive_local_instance]
48        self.Patch(list_instance, "GetInstances", return_value=instance_alive)
49        instances_list = list_instance.GetInstancesFromInstanceNames(cfg, instance_names)
50        instances_name_in_list = [instance_object.name for instance_object in instances_list]
51        self.assertEqual(instances_name_in_list.sort(), instance_names.sort())
52
53        instance_names = ["alive_instance1", "alive_local_instance", "alive_local_instance"]
54        instances_list = list_instance.GetInstancesFromInstanceNames(cfg, instance_names)
55        instances_name_in_list = [instance_object.name for instance_object in instances_list]
56        self.assertEqual(instances_name_in_list.sort(), instance_names.sort())
57
58        # test get instance from instance name error with invalid input.
59        instance_names = ["miss2_local_instance", "alive_instance1"]
60        miss_instance_names = ["miss2_local_instance"]
61        self.assertRaisesRegexp(
62            errors.NoInstancesFound,
63            "Did not find the following instances: %s" % ' '.join(miss_instance_names),
64            list_instance.GetInstancesFromInstanceNames,
65            cfg=cfg,
66            instance_names=instance_names)
67
68    def testChooseOneRemoteInstance(self):
69        """test choose one remote instance from instance names."""
70        cfg = mock.MagicMock()
71
72        # Test only one instance case
73        instance_names = ["cf_instance1"]
74        self.Patch(list_instance, "GetCFRemoteInstances", return_value=instance_names)
75        expected_instance = "cf_instance1"
76        self.assertEqual(list_instance.ChooseOneRemoteInstance(cfg), expected_instance)
77
78        # Test no instance case
79        self.Patch(list_instance, "GetCFRemoteInstances", return_value=[])
80        with self.assertRaises(errors.NoInstancesFound):
81            list_instance.ChooseOneRemoteInstance(cfg)
82
83        # Test two instances case.
84        instance_names = ["cf_instance1", "cf_instance2"]
85        choose_instance = ["cf_instance2"]
86        self.Patch(list_instance, "GetCFRemoteInstances", return_value=instance_names)
87        self.Patch(utils, "GetAnswerFromList", return_value=choose_instance)
88        expected_instance = "cf_instance2"
89        self.assertEqual(list_instance.ChooseOneRemoteInstance(cfg), expected_instance)
90
91    # pylint: disable=attribute-defined-outside-init
92    def testFilterInstancesByAdbPort(self):
93        """test FilterInstancesByAdbPort."""
94        alive_instance1 = InstanceObject("alive_instance1")
95        alive_instance1.adb_port = 1111
96        alive_instance1.fullname = "device serial: 127.0.0.1:1111 alive_instance1"
97        expected_instance = [alive_instance1]
98        # Test to find instance by adb port number.
99        self.assertEqual(
100            expected_instance,
101            list_instance.FilterInstancesByAdbPort(expected_instance, 1111))
102        # Test for instance can't be found by adb port number.
103        with self.assertRaises(errors.NoInstancesFound):
104            list_instance.FilterInstancesByAdbPort(expected_instance, 2222)
105
106    # pylint: disable=protected-access
107    def testGetLocalCuttlefishInstances(self):
108        """test _GetLocalCuttlefishInstances."""
109        # Test getting two instance case
110        self.Patch(instance, "GetAllLocalInstanceConfigs",
111                   return_value=["fake_path1", "fake_path2"])
112        self.Patch(instance, "GetLocalInstanceRuntimeDir")
113
114        local_ins = mock.MagicMock()
115        local_ins.CvdStatus.return_value = True
116        self.Patch(instance, "LocalInstance", return_value=local_ins)
117
118        ins_list = list_instance._GetLocalCuttlefishInstances()
119        self.assertEqual(2, len(ins_list))
120
121        local_ins = mock.MagicMock()
122        local_ins.CvdStatus.return_value = False
123        self.Patch(instance, "LocalInstance", return_value=local_ins)
124        ins_list = list_instance._GetLocalCuttlefishInstances()
125        self.assertEqual(0, len(ins_list))
126
127    # pylint: disable=no-member
128    def testPrintInstancesDetails(self):
129        """test PrintInstancesDetails."""
130        # Test instance Summary should be called if verbose
131        self.Patch(instance.Instance, "Summary")
132        cf_config = mock.MagicMock(
133            x_res=728,
134            y_res=728,
135            dpi=240,
136            instance_dir="fake_dir",
137            adb_ip_port="127.0.0.1:6520"
138        )
139        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
140                   return_value=cf_config)
141
142        ins = instance.LocalInstance("fake_cf_path")
143        list_instance.PrintInstancesDetails([ins], verbose=True)
144        instance.Instance.Summary.assert_called_once()
145
146        # Test Summary shouldn't be called if not verbose
147        self.Patch(instance.Instance, "Summary")
148        list_instance.PrintInstancesDetails([ins], verbose=False)
149        instance.Instance.Summary.assert_not_called()
150
151        # Test Summary shouldn't be called if no instance found.
152        list_instance.PrintInstancesDetails([], verbose=True)
153        instance.Instance.Summary.assert_not_called()
154
155
156if __name__ == "__main__":
157    unittest.main()
158