• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""
6Unit tests for functions in `build_data`.
7"""
8
9
10import json
11import mock
12import os
13import sys
14import unittest
15
16import common
17from autotest_lib.site_utils.stable_images import build_data
18
19
20# _OMAHA_TEST_DATA - File with JSON data to be used as test input to
21#   `_make_omaha_versions()`.  In the file, the various items in the
22#   `omaha_data` list are selected to capture various specific test
23#   cases:
24#     + Board with no "beta" channel.
25#     + Board with "beta" and another channel.
26#     + Board with only a "beta" channel.
27#     + Board with no "chrome_version" entry.
28#     + Obsolete board with "is_active" set to false.
29# The JSON content of the file is a subset of an actual
30# `omaha_status.json` file copied when the unit test was last
31# updated.
32#
33# _EXPECTED_OMAHA_VERSIONS - The expected output produced by the
34#   contents of _OMAHA_TEST_DATA.
35
36_OMAHA_TEST_DATA = 'test_omaha_status.json'
37_EXPECTED_OMAHA_VERSIONS = {
38    'auron-paine': 'R55-8872.54.0',
39    'gale': 'R55-8872.40.9',
40    'kevin': 'R55-8872.64.0',
41    'zako-freon': 'R41-6680.52.0'
42}
43
44
45class OmahaDataTests(unittest.TestCase):
46    """Tests for the `get_omaha_version_map()` function."""
47
48    @mock.patch.object(build_data, '_read_gs_json_data')
49    def test_make_omaha_versions(self, mock_read_gs):
50        """Test `get_omaha_version_map()` against one simple input.
51
52        This is a trivial sanity test that asserts that a single
53        hard-coded input returns a correct hard-coded output.
54
55        @param mock_read_gs  Mock created for `_read_gs_json_data()`.
56        """
57        module_dir = os.path.dirname(sys.modules[__name__].__file__)
58        data_file_path = os.path.join(module_dir, _OMAHA_TEST_DATA)
59        mock_read_gs.return_value = json.load(open(data_file_path, 'r'))
60        omaha_versions = build_data.get_omaha_version_map()
61        self.assertEqual(omaha_versions, _EXPECTED_OMAHA_VERSIONS)
62
63
64class KeyPathTests(unittest.TestCase):
65    """Tests for the `_get_by_key_path()` function."""
66
67    DICTDICT = {'level0': 'OK', 'level1_a': {'level1_b': 'OK'}}
68
69    def _get_by_key_path(self, keypath):
70        get_by_key_path = build_data._get_by_key_path
71        return get_by_key_path(self.DICTDICT, keypath)
72
73    def _check_path_valid(self, keypath):
74        self.assertEqual(self._get_by_key_path(keypath), 'OK')
75
76    def _check_path_invalid(self, keypath):
77        self.assertIsNone(self._get_by_key_path(keypath))
78
79    def test_one_element(self):
80        """Test a single-element key path with a valid key."""
81        self._check_path_valid(['level0'])
82
83    def test_two_element(self):
84        """Test a two-element key path with a valid key."""
85        self._check_path_valid(['level1_a', 'level1_b'])
86
87    def test_one_element_invalid(self):
88        """Test a single-element key path with an invalid key."""
89        self._check_path_invalid(['absent'])
90
91    def test_two_element_invalid(self):
92        """Test a two-element key path with an invalid key."""
93        self._check_path_invalid(['level1_a', 'absent'])
94
95
96class GetOmahaUpgradeTests(unittest.TestCase):
97    """Tests for `get_omaha_upgrade()`."""
98
99    V0 = 'R66-10452.27.0'
100    V1 = 'R66-10452.30.0'
101    V2 = 'R67-10494.0.0'
102
103    def test_choose_cros_version(self):
104        """Test that the CrOS version is chosen when it is later."""
105        new_version = build_data.get_omaha_upgrade(
106            {'board': self.V0}, 'board', self.V1)
107        self.assertEquals(new_version, self.V1)
108
109    def test_choose_omaha_version(self):
110        """Test that the Omaha version is chosen when it is later."""
111        new_version = build_data.get_omaha_upgrade(
112            {'board': self.V1}, 'board', self.V0)
113        self.assertEquals(new_version, self.V1)
114
115    def test_branch_version_comparison(self):
116        """Test that versions on different branches compare properly."""
117        new_version = build_data.get_omaha_upgrade(
118            {'board': self.V1}, 'board', self.V2)
119        self.assertEquals(new_version, self.V2)
120
121    def test_identical_versions(self):
122        """Test handling when both the versions are the same."""
123        new_version = build_data.get_omaha_upgrade(
124            {'board': self.V1}, 'board', self.V1)
125        self.assertEquals(new_version, self.V1)
126
127    def test_board_name_mapping(self):
128        """Test that AFE board names are mapped to Omaha board names."""
129        board_equivalents = [
130            ('a-b', 'a-b'), ('c_d', 'c-d'),
131            ('e_f-g', 'e-f-g'), ('hi', 'hi')
132        ]
133        for afe_board, omaha_board in board_equivalents:
134            new_version = build_data.get_omaha_upgrade(
135                {omaha_board: self.V1}, afe_board, self.V0)
136            self.assertEquals(new_version, self.V1)
137
138    def test_no_omaha_version(self):
139        """Test handling when there's no Omaha version."""
140        new_version = build_data.get_omaha_upgrade(
141            {}, 'board', self.V1)
142        self.assertEquals(new_version, self.V1)
143
144    def test_no_afe_version(self):
145        """Test handling when there's no CrOS version."""
146        new_version = build_data.get_omaha_upgrade(
147            {'board': self.V1}, 'board', None)
148        self.assertEquals(new_version, self.V1)
149
150    def test_no_version_whatsoever(self):
151        """Test handling when both versions are `None`."""
152        new_version = build_data.get_omaha_upgrade(
153            {}, 'board', None)
154        self.assertIsNone(new_version)
155
156
157class GetFirmwareVersionsTests(unittest.TestCase):
158    """Tests for get_firmware_versions."""
159
160    def setUp(self):
161        self.cros_version = 'R64-10176.65.0'
162
163    @mock.patch.object(build_data, '_read_gs_json_data')
164    def test_get_firmware_versions_on_normal_build(self, mock_read_gs):
165        """Test get_firmware_versions on normal build."""
166        metadata_json = """
167{
168    "unibuild": false,
169    "board-metadata":{
170        "auron_paine":{
171             "main-firmware-version":"Google_Auron_paine.6301.58.98"
172        }
173   }
174}
175        """
176        mock_read_gs.return_value = json.loads(metadata_json)
177        board = 'auron_paine'
178
179        fw_version = build_data.get_firmware_versions(
180                board, self.cros_version)
181        expected_version = {board: "Google_Auron_paine.6301.58.98"}
182        self.assertEqual(fw_version, expected_version)
183
184    @mock.patch.object(build_data, '_read_gs_json_data',
185                       side_effect = Exception('GS ERROR'))
186    def test_get_firmware_versions_with_exceptions(self, mock_read_gs):
187        """Test get_firmware_versions on normal build with exceptions."""
188        afe_mock = mock.Mock()
189        fw_version = build_data.get_firmware_versions(
190                'auron_paine', self.cros_version)
191        self.assertEqual(fw_version, {'auron_paine': None})
192
193    @mock.patch.object(build_data, '_read_gs_json_data')
194    def test_get_firmware_versions_on_unibuild(self, mock_read_gs):
195        """Test get_firmware_version on uni-build."""
196        metadata_json = """
197{
198    "unibuild": true,
199    "board-metadata":{
200        "coral":{
201            "kernel-version":"4.4.114-r1354",
202            "models":{
203                "blue":{
204                    "main-readonly-firmware-version":"Google_Coral.10068.37.0",
205                    "main-readwrite-firmware-version":"Google_Coral.10068.39.0"
206                },
207                "robo360":{
208                    "main-readonly-firmware-version":"Google_Coral.10068.34.0",
209                    "main-readwrite-firmware-version":null
210                },
211                "porbeagle":{
212                    "main-readonly-firmware-version":null,
213                    "main-readwrite-firmware-version":null
214                }
215            }
216        }
217    }
218}
219"""
220        mock_read_gs.return_value = json.loads(metadata_json)
221        fw_version = build_data.get_firmware_versions(
222            'coral', self.cros_version)
223        expected_version = {
224            'blue': 'Google_Coral.10068.39.0',
225            'robo360': 'Google_Coral.10068.34.0',
226            'porbeagle': None
227        }
228        self.assertEqual(fw_version, expected_version)
229
230    @mock.patch.object(build_data, '_read_gs_json_data')
231    def test_get_firmware_versions_on_unibuild_no_models(self, mock_read_gs):
232        """Test get_firmware_versions on uni-build without models dict."""
233        metadata_json = """
234{
235    "unibuild": true,
236    "board-metadata":{
237        "coral":{
238            "kernel-version":"4.4.114-r1354"
239        }
240    }
241}
242"""
243        mock_read_gs.return_value = json.loads(metadata_json)
244        fw_version = build_data.get_firmware_versions(
245                'coral', self.cros_version)
246        self.assertEqual(fw_version, {'coral': None})
247
248
249if __name__ == '__main__':
250    unittest.main()
251