• 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_ids."""
5
6import unittest
7
8from checker.common_checks.check_ids import IdConstraintSuite
9
10from chromiumos.config.payload.config_bundle_pb2 import ConfigBundle
11from chromiumos.config.api.design_pb2 import Design
12from chromiumos.config.api.design_id_pb2 import DesignId
13from chromiumos.config.api.design_config_id_pb2 import DesignConfigId
14from chromiumos.config.api.program_pb2 import (DesignConfigIdSegment, Program)
15from chromiumos.config.api.program_id_pb2 import ProgramId
16
17# Alias a few nested classes to make creating test objects less verbose
18# pylint: disable=invalid-name
19Config = Design.Config
20# pylint: enable=invalid-name
21
22# Some tests just check no exceptions were raised, and will not call self.assert
23# methods
24# pylint: disable=no-self-use
25
26
27class CheckIdsTest(unittest.TestCase):
28  """Tests for check_ids."""
29
30  def test_check_ids_consistent(self):
31    """Tests check_ids_consistent with valid configs."""
32    program_config = ConfigBundle(
33        program_list=[Program(id=ProgramId(value='testprogram1'))])
34
35    project_config = ConfigBundle(design_list=[
36        Design(program_id=ProgramId(value='testprogram1')),
37        Design(program_id=ProgramId(value='testprogram1')),
38    ])
39
40    IdConstraintSuite().check_ids_consistent(
41        program_config=program_config,
42        project_config=project_config,
43        factory_dir=None,
44    )
45
46  def test_check_ids_consistent_violated(self):
47    """Tests check_ids_consistent with invalid configs."""
48    program_config = ConfigBundle(
49        program_list=[Program(id=ProgramId(value='testprogram1'))])
50
51    project_config = ConfigBundle(design_list=[
52        Design(program_id=ProgramId(value='testprogram1')),
53        Design(program_id=ProgramId(value='testprogram2')),
54    ])
55
56    with self.assertRaises(AssertionError):
57      IdConstraintSuite().check_ids_consistent(
58          program_config=program_config,
59          project_config=project_config,
60          factory_dir=None,
61      )
62
63  def test_check_design_config_id_segments(self):
64    """Test check_design_config_id_segments with valid configs."""
65    program_config = ConfigBundle(program_list=[
66        Program(design_config_id_segments=[
67            DesignConfigIdSegment(
68                design_id=DesignId(value='a'),
69                min_id=11,
70                max_id=20,
71            ),
72            DesignConfigIdSegment(
73                design_id=DesignId(value='b'),
74                min_id=21,
75                max_id=30,
76            ),
77        ])
78    ])
79
80    project_config = ConfigBundle(design_list=[
81        Design(
82            id=DesignId(value='a'),
83            configs=[
84                Config(id=DesignConfigId(value='a:11')),
85                Config(id=DesignConfigId(value='a:15')),
86                Config(id=DesignConfigId(value='a:20')),
87            ]),
88        Design(
89            id=DesignId(value='b'),
90            configs=[
91                Config(id=DesignConfigId(value='b:25')),
92                # Unprovisioned ids are exempt from the check.
93                Config(id=DesignConfigId(value='b:2147483647')),
94            ]),
95        # Design 'c' doesn't have a segment.
96        Design(
97            id=DesignId(value='c'),
98            configs=[
99                Config(id=DesignConfigId(value='c:40')),
100            ]),
101    ])
102
103    IdConstraintSuite().check_design_config_id_segments(
104        program_config=program_config,
105        project_config=project_config,
106        factory_dir=None,
107    )
108
109  def test_check_design_config_id_segments_violated(self):
110    """Test check_design_config_id_segments with ids out of range."""
111    program_config = ConfigBundle(program_list=[
112        Program(design_config_id_segments=[
113            DesignConfigIdSegment(
114                design_id=DesignId(value='a'),
115                min_id=11,
116                max_id=20,
117            ),
118        ])
119    ])
120
121    # Test ids on the lower boundary.
122    for id_num in (9, 10):
123      project_config = ConfigBundle(design_list=[
124          Design(
125              id=DesignId(value='a'),
126              configs=[
127                  Config(id=DesignConfigId(value='a:{}'.format(id_num))),
128              ]),
129      ])
130
131      with self.assertRaisesRegex(
132          AssertionError,
133          'DesignConfigId must be >= 11, got {}'.format(id_num)):
134        IdConstraintSuite().check_design_config_id_segments(
135            program_config=program_config,
136            project_config=project_config,
137            factory_dir=None,
138        )
139
140    # Test ids on the upper boundary.
141    for id_num in (21, 22):
142      project_config = ConfigBundle(design_list=[
143          Design(
144              id=DesignId(value='a'),
145              configs=[
146                  Config(id=DesignConfigId(value='a:{}'.format(id_num))),
147              ]),
148      ])
149
150      with self.assertRaisesRegex(
151          AssertionError,
152          'DesignConfigId must be <= 20, got {}'.format(id_num)):
153        IdConstraintSuite().check_design_config_id_segments(
154            program_config=program_config,
155            project_config=project_config,
156            factory_dir=None,
157        )
158
159  def test_check_design_config_id_segments_overlap(self):
160    """Test check_design_config_id_segments_overlap with valid configs."""
161    program_config = ConfigBundle(program_list=[
162        Program(design_config_id_segments=[
163            DesignConfigIdSegment(
164                design_id=DesignId(value='a'),
165                min_id=11,
166                max_id=20,
167            ),
168            DesignConfigIdSegment(
169                design_id=DesignId(value='b'),
170                min_id=21,
171                max_id=30,
172            ),
173            DesignConfigIdSegment(
174                design_id=DesignId(value='c'),
175                min_id=41,
176                max_id=50,
177            ),
178        ])
179    ])
180
181    IdConstraintSuite().check_design_config_id_segments_overlap(
182        program_config=program_config, project_config=None, factory_dir=None)
183
184  def test_check_design_config_id_segments_overlap_violated(self):
185    """Test check_design_config_id_segments_overlap with overlapping segments."""
186    program_config = ConfigBundle(program_list=[
187        Program(design_config_id_segments=[
188            DesignConfigIdSegment(
189                design_id=DesignId(value='a'),
190                min_id=11,
191                max_id=20,
192            ),
193            DesignConfigIdSegment(
194                design_id=DesignId(value='b'),
195                min_id=20,
196                max_id=30,
197            ),
198            DesignConfigIdSegment(
199                design_id=DesignId(value='c'),
200                min_id=31,
201                max_id=40,
202            ),
203        ])
204    ])
205
206    with self.assertRaisesRegex(
207        AssertionError, 'Segments {} and {} overlap'.format(
208            program_config.program_list[0].design_config_id_segments[0],
209            program_config.program_list[0].design_config_id_segments[1],
210        )):
211      IdConstraintSuite().check_design_config_id_segments_overlap(
212          program_config=program_config, project_config=None, factory_dir=None)
213
214    # Segments are declared in a different order.
215    program_config = ConfigBundle(program_list=[
216        Program(design_config_id_segments=[
217            DesignConfigIdSegment(
218                design_id=DesignId(value='a'),
219                min_id=31,
220                max_id=40,
221            ),
222            DesignConfigIdSegment(
223                design_id=DesignId(value='b'),
224                min_id=20,
225                max_id=30,
226            ),
227            DesignConfigIdSegment(
228                design_id=DesignId(value='c'),
229                min_id=11,
230                max_id=20,
231            ),
232        ])
233    ])
234
235    with self.assertRaisesRegex(
236        AssertionError, 'Segments {} and {} overlap'.format(
237            program_config.program_list[0].design_config_id_segments[2],
238            program_config.program_list[0].design_config_id_segments[1],
239        )):
240      IdConstraintSuite().check_design_config_id_segments_overlap(
241          program_config=program_config, project_config=None, factory_dir=None)
242
243    # Two segments have the same min_id.
244    program_config = ConfigBundle(program_list=[
245        Program(design_config_id_segments=[
246            DesignConfigIdSegment(
247                design_id=DesignId(value='b'),
248                min_id=20,
249                max_id=30,
250            ),
251            DesignConfigIdSegment(
252                design_id=DesignId(value='a'),
253                min_id=20,
254                max_id=25,
255            ),
256        ])
257    ])
258
259    with self.assertRaisesRegex(
260        AssertionError, 'Segments {} and {} overlap'.format(
261            program_config.program_list[0].design_config_id_segments[0],
262            program_config.program_list[0].design_config_id_segments[1],
263        )):
264      IdConstraintSuite().check_design_config_id_segments_overlap(
265          program_config=program_config, project_config=None, factory_dir=None)
266
267  def test_check_design_config_ids_unique(self):
268    """Tests check_design_config_ids_unique with valid configs."""
269    project_config = ConfigBundle(design_list=[
270        Design(configs=[
271            Config(id=DesignConfigId(value='a')),
272            Config(id=DesignConfigId(value='b')),
273        ]),
274        Design(configs=[Config(id=DesignConfigId(value='c'))]),
275    ])
276
277    IdConstraintSuite().check_design_config_ids_unique(
278        program_config=None,
279        project_config=project_config,
280        factory_dir=None,
281    )
282
283  def test_check_design_config_ids_unique_violated(self):
284    """Tests check_design_config_ids_unique with valid configs."""
285    project_config = ConfigBundle(design_list=[
286        Design(configs=[
287            Config(id=DesignConfigId(value='a')),
288            Config(id=DesignConfigId(value='b')),
289        ]),
290        Design(configs=[Config(id=DesignConfigId(value='a'))]),
291    ])
292
293    with self.assertRaisesRegex(AssertionError,
294                                "Found multiple configs with id 'a'"):
295      IdConstraintSuite().check_design_config_ids_unique(
296          program_config=None,
297          project_config=project_config,
298          factory_dir=None,
299      )
300