• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 The ChromiumOS Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Tests for check_firmware_configuration."""
5
6import unittest
7
8from checker.common_checks.check_firmware_configuration import (
9    FirmwareConfigurationConstraintSuite)
10
11from chromiumos.config.payload.config_bundle_pb2 import ConfigBundle
12from chromiumos.config.api.design_pb2 import Design
13from chromiumos.config.api.program_pb2 import (Program,
14                                               FirmwareConfigurationSegment)
15from chromiumos.config.api.hardware_topology_pb2 import HardwareTopology
16from chromiumos.config.api.topology_pb2 import HardwareFeatures, Topology
17
18# Alias a few nested classes to make creating test objects less verbose
19# pylint: disable=invalid-name
20FirmwareConfiguration = HardwareFeatures.FirmwareConfiguration
21Config = Design.Config
22# pylint: enable=invalid-name
23
24# Some tests just check no exceptions were raised, and will not call self.assert
25# methods
26# pylint: disable=no-self-use
27
28
29class CheckFirmwareConfigurationTest(unittest.TestCase):
30  """Tests for check_firmware_configuration."""
31
32  def test_check_firmware_configuration_masks(self):
33    """Tests check_firmware_configuration_masks with valid configs."""
34    program_config = ConfigBundle(program_list=[
35        Program(firmware_configuration_segments=[
36            FirmwareConfigurationSegment(name='screen', mask=0b0001),
37            FirmwareConfigurationSegment(name='form_factor', mask=0b0110),
38        ])
39    ])
40
41    project_config = ConfigBundle(design_list=[
42        Design(configs=[
43            Config(
44                hardware_topology=HardwareTopology(
45                    screen=Topology(
46                        type=Topology.SCREEN,
47                        hardware_feature=HardwareFeatures(
48                            fw_config=FirmwareConfiguration(
49                                value=0b0000,
50                                mask=0b0001,
51                            ))),
52                    form_factor=Topology(
53                        type=Topology.FORM_FACTOR,
54                        hardware_feature=HardwareFeatures(
55                            fw_config=FirmwareConfiguration(
56                                value=0b0010,
57                                mask=0b0110,
58                            ))),
59                ))
60        ]),
61    ])
62
63    FirmwareConfigurationConstraintSuite().check_firmware_configuration_masks(
64        program_config=program_config,
65        project_config=project_config,
66        factory_dir=None,
67    )
68
69  def test_check_firmware_configuration_masks_overlap(self):
70    """Tests check_firmware_configuration_masks with overlapping segments."""
71    program_config = ConfigBundle(program_list=[
72        Program(firmware_configuration_segments=[
73            FirmwareConfigurationSegment(name='screen', mask=0b0011),
74            FirmwareConfigurationSegment(name='form_factor', mask=0b0110),
75        ])
76    ])
77
78    with self.assertRaisesRegex(
79        AssertionError,
80        'Overlap in masks screen and form_factor: 11 & 110 = 10'):
81      FirmwareConfigurationConstraintSuite().check_firmware_configuration_masks(
82          program_config=program_config, project_config=None, factory_dir=None)
83
84  def test_check_firmware_configuration_multiple_masks_in_use(self):
85    """Tests check_firmware_configuration_masks with a topology using
86    multiple fw_config fields.
87    """
88    program_config = ConfigBundle(program_list=[
89        Program(firmware_configuration_segments=[
90            FirmwareConfigurationSegment(name='screen_a', mask=0b0001),
91            FirmwareConfigurationSegment(name='screen_b', mask=0b1110),
92        ])
93    ])
94
95    project_config = ConfigBundle(design_list=[
96        Design(configs=[
97            Config(
98                hardware_topology=HardwareTopology(
99                    screen=Topology(
100                        id="DEFAULT",
101                        type=Topology.SCREEN,
102                        hardware_feature=HardwareFeatures(
103                            fw_config=FirmwareConfiguration(
104                                value=0b0001,
105                                mask=0b1111,
106                            ))),))
107        ]),
108    ])
109
110    FirmwareConfigurationConstraintSuite().check_firmware_configuration_masks(
111        program_config=program_config,
112        project_config=project_config,
113        factory_dir=None,
114    )
115
116  def test_check_firmware_configuration_incomplete_mask(self):
117    """Tests check_firmware_configuration_masks with an incomplete mask."""
118    program_config = ConfigBundle(program_list=[
119        Program(firmware_configuration_segments=[
120            FirmwareConfigurationSegment(name='screen_a', mask=0b0001),
121            FirmwareConfigurationSegment(name='screen_b', mask=0b1110),
122        ])
123    ])
124
125    project_config = ConfigBundle(design_list=[
126        Design(configs=[
127            Config(
128                hardware_topology=HardwareTopology(
129                    screen=Topology(
130                        id="DEFAULT",
131                        type=Topology.SCREEN,
132                        hardware_feature=HardwareFeatures(
133                            fw_config=FirmwareConfiguration(
134                                value=0b0001,
135                                mask=0b0111,
136                            ))),))
137        ]),
138    ])
139
140    with self.assertRaisesRegex(
141        AssertionError, 'Topology SCREEN:DEFAULT with fw_config mask '
142        '0x00000007 did not specify the complete '
143        'fw_config field "screen_b" with mask '
144        '0x0000000E'):
145      FirmwareConfigurationConstraintSuite().check_firmware_configuration_masks(
146          program_config=program_config,
147          project_config=project_config,
148          factory_dir=None,
149      )
150
151  def test_check_firmware_configuration_extra_mask(self):
152    """Tests check_firmware_configuration_masks with an extra mask."""
153    program_config = ConfigBundle(program_list=[
154        Program(firmware_configuration_segments=[
155            FirmwareConfigurationSegment(name='screen', mask=0b0001),
156        ])
157    ])
158
159    project_config = ConfigBundle(design_list=[
160        Design(configs=[
161            Config(
162                hardware_topology=HardwareTopology(
163                    screen=Topology(
164                        id="DEFAULT",
165                        type=Topology.SCREEN,
166                        hardware_feature=HardwareFeatures(
167                            fw_config=FirmwareConfiguration(
168                                value=0b0001,
169                                mask=0b0111,
170                            ))),))
171        ]),
172    ])
173
174    with self.assertRaisesRegex(
175        AssertionError, 'Topology SCREEN:DEFAULT specifies fw_mask '
176        'that is not known 0x00000006'):
177      FirmwareConfigurationConstraintSuite().check_firmware_configuration_masks(
178          program_config=program_config,
179          project_config=project_config,
180          factory_dir=None,
181      )
182
183  def test_check_firmware_value_collision(self):
184    """Tests check_firmware_value_collision on a valid config."""
185    project_config = ConfigBundle(design_list=[
186        Design(configs=[
187            Config(
188                hardware_topology=HardwareTopology(
189                    # ('screen1', SCREEN) topology uses fw value 0b0001.
190                    screen=Topology(
191                        id='screen1',
192                        type=Topology.SCREEN,
193                        description={'EN': 'First description'},
194                        hardware_feature=HardwareFeatures(
195                            fw_config=FirmwareConfiguration(value=0b0001))),
196                    # ('ff1', FORM_FACTOR) topology doesn't specify a fw
197                    # value.
198                    form_factor=Topology(
199                        id='ff1',
200                        type=Topology.FORM_FACTOR,
201                    ),
202                )),
203            Config(
204                hardware_topology=HardwareTopology(
205                    # ('screen2', SCREEN) topology is used in a different
206                    # design, again using fw value 0b0001. This is valid,
207                    # because the topology has the same type.
208                    screen=Topology(
209                        id='screen2',
210                        type=Topology.SCREEN,
211                        description={'EN': 'Slightly different description'},
212                        hardware_feature=HardwareFeatures(
213                            fw_config=FirmwareConfiguration(value=0b0001))),),),
214        ]),
215    ])
216
217    FirmwareConfigurationConstraintSuite(
218    ).check_firmware_configuration_value_collision(
219        program_config=None,
220        project_config=project_config,
221        factory_dir=None,
222    )
223
224  def test_check_firmware_value_collision_invalid_config(self):
225    """Tests check_firmware_value_collision on an invalid config."""
226    project_config = ConfigBundle(design_list=[
227        Design(configs=[
228            Config(
229                hardware_topology=HardwareTopology(
230                    # Both ('screen1', SCREEN) and ('thermal1', THERMAL) use
231                    # fw value 0b0001.
232                    screen=Topology(
233                        id='screen1',
234                        type=Topology.SCREEN,
235                        hardware_feature=HardwareFeatures(
236                            fw_config=FirmwareConfiguration(value=0b0001))),
237                    thermal=Topology(
238                        id='thermal1',
239                        type=Topology.THERMAL,
240                        hardware_feature=HardwareFeatures(
241                            fw_config=FirmwareConfiguration(value=0b0001))),
242                )),
243        ]),
244    ])
245
246    with self.assertRaisesRegex(
247        AssertionError,
248        (r'Topologies \(thermal1, THERMAL\) and \(screen1, SCREEN\) both use '
249         r'firmware value 1 but have different types')):
250      FirmwareConfigurationConstraintSuite(
251      ).check_firmware_configuration_value_collision(
252          program_config=None,
253          project_config=project_config,
254          factory_dir=None,
255      )
256