1#!/usr/bin/python
2# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import unittest
7
8import common
9
10from autotest_lib.server import utils
11from autotest_lib.server.hosts.cros_label import BoardLabel
12from autotest_lib.server.hosts.cros_label import ModelLabel
13from autotest_lib.server.hosts import host_info
14
15# pylint: disable=missing-docstring
16
17NON_UNI_LSB_RELEASE_OUTPUT = """
18CHROMEOS_RELEASE_APPID={63A9F698-C1CA-4A75-95E7-6B90181B3718}
19CHROMEOS_BOARD_APPID={63A9F698-C1CA-4A75-95E7-6B90181B3718}
20CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
21DEVICETYPE=CHROMEBOOK
22CHROMEOS_ARC_VERSION=4234098
23CHROMEOS_ARC_ANDROID_SDK_VERSION=25
24GOOGLE_RELEASE=9798.0.2017_08_02_1022
25CHROMEOS_DEVSERVER=http://shapiroc3.bld.corp.google.com:8080
26CHROMEOS_RELEASE_BOARD=pyro
27CHROMEOS_RELEASE_BUILD_NUMBER=9798
28CHROMEOS_RELEASE_BRANCH_NUMBER=0
29CHROMEOS_RELEASE_CHROME_MILESTONE=62
30CHROMEOS_RELEASE_PATCH_NUMBER=2017_08_02_1022
31CHROMEOS_RELEASE_TRACK=testimage-channel
32CHROMEOS_RELEASE_DESCRIPTION=9798.0.2017_08_02_1022 (Test Build)
33CHROMEOS_RELEASE_BUILD_TYPE=Test Build
34CHROMEOS_RELEASE_NAME=Chromium OS
35CHROMEOS_RELEASE_VERSION=9798.0.2017_08_02_1022
36CHROMEOS_AUSERVER=http://someserver.bld.corp.google.com:8080/update
37"""
38
39UNI_LSB_RELEASE_OUTPUT = """
40CHROMEOS_RELEASE_APPID={5A3AB642-2A67-470A-8F37-37E737A53CFC}
41CHROMEOS_BOARD_APPID={5A3AB642-2A67-470A-8F37-37E737A53CFC}
42CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
43DEVICETYPE=CHROMEBOOK
44CHROMEOS_ARC_VERSION=4340813
45CHROMEOS_ARC_ANDROID_SDK_VERSION=25
46GOOGLE_RELEASE=9953.0.2017_09_18_1334
47CHROMEOS_DEVSERVER=http://server.bld.corp.google.com:8080
48CHROMEOS_RELEASE_BOARD=coral
49CHROMEOS_RELEASE_BUILD_NUMBER=9953
50CHROMEOS_RELEASE_BRANCH_NUMBER=0
51CHROMEOS_RELEASE_CHROME_MILESTONE=63
52CHROMEOS_RELEASE_PATCH_NUMBER=2017_09_18_1334
53CHROMEOS_RELEASE_TRACK=testimage-channel
54CHROMEOS_RELEASE_DESCRIPTION=9953.0.2017_09_18_1334 (Test Build)
55CHROMEOS_RELEASE_BUILD_TYPE=Test Build
56CHROMEOS_RELEASE_NAME=Chromium OS
57CHROMEOS_RELEASE_UNIBUILD=1
58CHROMEOS_RELEASE_VERSION=9953.0.2017_09_18_1334
59CHROMEOS_AUSERVER=http://server.bld.corp.google.com:8080/update
60CHROMEOS_RELEASE_MODELS=coral astronaut blue bruce lava nasher
61"""
62
63
64class MockCmd(object):
65    """Simple mock command with base command and results"""
66
67    def __init__(self, cmd, exit_status, stdout):
68        self.cmd = cmd
69        self.stdout = stdout
70        self.exit_status = exit_status
71
72
73class MockAFEHost(utils.EmptyAFEHost):
74
75    def __init__(self, labels=[], attributes={}):
76        self.labels = labels
77        self.attributes = attributes
78
79
80class MockHost(object):
81    """Simple host for running mock'd host commands"""
82
83    def __init__(self, labels, *args):
84        self._afe_host = MockAFEHost(labels)
85        self.mock_cmds = {c.cmd: c for c in args}
86        info = host_info.HostInfo(labels=labels)
87        self.host_info_store = host_info.InMemoryHostInfoStore(info)
88
89    def run(self, command, **kwargs):
90        """Finds the matching result by command value"""
91        return self.mock_cmds[command]
92
93
94class MockHostWithoutAFE(MockHost):
95
96    def __init__(self, labels, *args):
97        super(MockHostWithoutAFE, self).__init__(labels, *args)
98        self._afe_host = utils.EmptyAFEHost()
99
100
101class ModelLabelTests(unittest.TestCase):
102    """Unit tests for ModelLabel"""
103
104    def test_cros_config_succeeds(self):
105        cat_lsb_release_output = """
106CHROMEOS_RELEASE_BOARD=pyro
107CHROMEOS_RELEASE_UNIBUILD=1
108"""
109        host = MockHost([],
110                        MockCmd('cros_config / test-label', 0, 'coral\n'),
111                        MockCmd('cat /etc/lsb-release', 0,
112                                cat_lsb_release_output))
113        self.assertEqual(ModelLabel().generate_labels(host), ['coral'])
114
115    def test_cros_config_fails_mosys_succeeds(self):
116        cat_lsb_release_output = """
117CHROMEOS_RELEASE_BOARD=pyro
118CHROMEOS_RELEASE_UNIBUILD=1
119"""
120        host = MockHost([],
121                        MockCmd('cros_config / test-label', 1, ''),
122                        MockCmd('mosys platform model', 0, 'coral\n'),
123                        MockCmd('cat /etc/lsb-release', 0,
124                                cat_lsb_release_output))
125        self.assertEqual(ModelLabel().generate_labels(host), ['coral'])
126
127    def test_cros_config_fails_mosys_fails(self):
128        cat_lsb_release_output = """
129CHROMEOS_RELEASE_BOARD=pyro
130CHROMEOS_RELEASE_UNIBUILD=1
131"""
132        host = MockHost([],
133                        MockCmd('cros_config / test-label', 1, ''),
134                        MockCmd('mosys platform model', 1, ''),
135                        MockCmd('cat /etc/lsb-release', 0,
136                                cat_lsb_release_output))
137        self.assertEqual(ModelLabel().generate_labels(host), ['pyro'])
138
139    def test_cros_config_only_used_for_unibuilds(self):
140        cat_lsb_release_output = """
141CHROMEOS_RELEASE_BOARD=pyro
142"""
143        host = MockHost([],
144                        MockCmd('cat /etc/lsb-release', 0,
145                                cat_lsb_release_output))
146        self.assertEqual(ModelLabel().generate_labels(host), ['pyro'])
147
148    def test_existing_label(self):
149        host = MockHost(['model:existing'])
150        self.assertEqual(ModelLabel().generate_labels(host), ['existing'])
151
152    def test_existing_label_in_host_info_store(self):
153        host = MockHostWithoutAFE(['model:existing'])
154        self.assertEqual(ModelLabel().generate_labels(host), ['existing'])
155
156
157class BoardLabelTests(unittest.TestCase):
158    """Unit tests for BoardLabel"""
159
160    def test_new_label(self):
161        cat_cmd = 'cat /etc/lsb-release'
162        host = MockHost([], MockCmd(cat_cmd, 0, NON_UNI_LSB_RELEASE_OUTPUT))
163        self.assertEqual(BoardLabel().generate_labels(host), ['pyro'])
164
165    def test_existing_label(self):
166        host = MockHost(['board:existing'])
167        self.assertEqual(BoardLabel().generate_labels(host), ['existing'])
168
169    def test_existing_label_in_host_info_store(self):
170        host = MockHostWithoutAFE(['board:existing'])
171        self.assertEqual(BoardLabel().generate_labels(host), ['existing'])
172
173
174if __name__ == '__main__':
175    unittest.main()
176