xref: /aosp_15_r20/external/bazel-skylib/tests/selects_tests.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1# Copyright 2017 The Bazel Authors. All rights reserved.
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
15"""Unit tests for selects.bzl."""
16
17load("//lib:selects.bzl", "selects")
18load("//lib:unittest.bzl", "analysistest", "asserts", "unittest")
19
20###################################################
21# with_or_test
22###################################################
23def _with_or_test(ctx):
24    """Unit tests for with_or."""
25    env = unittest.begin(ctx)
26
27    # We actually test on with_or_dict because Starlark can't get the
28    # dictionary from a select().
29
30    # Test select()-compatible input syntax.
31    input_dict = {":foo": ":d1", "//conditions:default": ":d1"}
32    asserts.equals(env, input_dict, selects.with_or_dict(input_dict))
33
34    # Test OR syntax.
35    or_dict = {(":foo", ":bar"): ":d1"}
36    asserts.equals(
37        env,
38        {":bar": ":d1", ":foo": ":d1"},
39        selects.with_or_dict(or_dict),
40    )
41
42    # Test mixed syntax.
43    mixed_dict = {
44        ":foo": ":d1",
45        (":bar", ":baz"): ":d2",
46        "//conditions:default": ":d3",
47    }
48    asserts.equals(
49        env,
50        {
51            ":bar": ":d2",
52            ":baz": ":d2",
53            ":foo": ":d1",
54            "//conditions:default": ":d3",
55        },
56        selects.with_or_dict(mixed_dict),
57    )
58
59    return unittest.end(env)
60
61with_or_test = unittest.make(_with_or_test)
62
63###################################################
64# BUILD declarations for config_setting_group tests
65###################################################
66
67# TODO: redefine these config_settings with Starlark build flags when
68# they're available non-experimentally.
69def _create_config_settings():
70    native.config_setting(
71        name = "condition1",
72        values = {"cpu": "ppc"},
73    )
74    native.config_setting(
75        name = "condition2",
76        values = {"compilation_mode": "opt"},
77    )
78    native.config_setting(
79        name = "condition3",
80        values = {"features": "myfeature"},
81    )
82
83def _create_config_setting_groups():
84    selects.config_setting_group(
85        name = "1_and_2_and_3",
86        match_all = [":condition1", ":condition2", ":condition3"],
87    )
88    selects.config_setting_group(
89        name = "1_and_nothing_else",
90        match_all = [":condition1"],
91    )
92    selects.config_setting_group(
93        name = "1_or_2_or_3",
94        match_any = [":condition1", ":condition2", ":condition3"],
95    )
96    selects.config_setting_group(
97        name = "1_or_nothing_else",
98        match_any = [":condition1"],
99    )
100
101###################################################
102# Support code for config_setting_group tests
103###################################################
104
105def _set_conditions(condition_list):
106    """Returns an argument for config_settings that sets specific options.
107
108    Args:
109      condition_list: a list of three booleans
110
111    Returns:
112      a dictionary parameter for config_settings such that ":conditionN" is True
113          iff condition_list[N + 1] is True
114    """
115    if len(condition_list) != 3:
116        fail("condition_list must be a list of 3 booleans")
117    ans = {}
118    if condition_list[0]:
119        ans["//command_line_option:cpu"] = "ppc"
120    else:
121        ans["//command_line_option:cpu"] = "k8"
122    if condition_list[1]:
123        ans["//command_line_option:compilation_mode"] = "opt"
124    else:
125        ans["//command_line_option:compilation_mode"] = "dbg"
126    if condition_list[2]:
127        ans["//command_line_option:features"] = ["myfeature"]
128    else:
129        ans["//command_line_option:features"] = ["notmyfeature"]
130    return ans
131
132_BooleanInfo = provider(
133    doc = "value for boolean tests",
134    fields = ["value"],
135)
136
137def _boolean_attr_impl(ctx):
138    return [_BooleanInfo(value = ctx.attr.myboolean)]
139
140boolean_attr_rule = rule(
141    implementation = _boolean_attr_impl,
142    attrs = {"myboolean": attr.bool()},
143)
144
145def _expect_matches(ctx):
146    """Generic test implementation expecting myboolean == True."""
147    env = analysistest.begin(ctx)
148    attrval = analysistest.target_under_test(env)[_BooleanInfo].value
149    asserts.equals(env, True, attrval)
150    return analysistest.end(env)
151
152def _expect_doesnt_match(ctx):
153    """Generic test implementation expecting myboolean == False."""
154    env = analysistest.begin(ctx)
155    attrval = analysistest.target_under_test(env)[_BooleanInfo].value
156    asserts.equals(env, False, attrval)
157    return analysistest.end(env)
158
159###################################################
160# and_config_setting_group_matches_test
161###################################################
162and_config_setting_group_matches_test = analysistest.make(
163    _expect_matches,
164    config_settings = _set_conditions([True, True, True]),
165)
166
167def _and_config_setting_group_matches_test():
168    """Test verifying match on an ANDing config_setting_group."""
169    boolean_attr_rule(
170        name = "and_config_setting_group_matches_rule",
171        myboolean = select(
172            {
173                ":1_and_2_and_3": True,
174                "//conditions:default": False,
175            },
176        ),
177    )
178    and_config_setting_group_matches_test(
179        name = "and_config_setting_group_matches_test",
180        target_under_test = ":and_config_setting_group_matches_rule",
181    )
182
183###################################################
184# and_config_setting_group_first_match_fails_test
185###################################################
186and_config_setting_group_first_match_fails_test = analysistest.make(
187    _expect_doesnt_match,
188    config_settings = _set_conditions([False, True, True]),
189)
190
191def _and_config_setting_group_first_match_fails_test():
192    """Test verifying first condition mismatch on an ANDing config_setting_group."""
193    boolean_attr_rule(
194        name = "and_config_setting_group_first_match_fails_rule",
195        myboolean = select(
196            {
197                ":1_and_2_and_3": True,
198                "//conditions:default": False,
199            },
200        ),
201    )
202    and_config_setting_group_first_match_fails_test(
203        name = "and_config_setting_group_first_match_fails_test",
204        target_under_test = ":and_config_setting_group_first_match_fails_rule",
205    )
206
207###################################################
208# and_config_setting_group_middle_match_fails_test
209###################################################
210and_config_setting_group_middle_match_fails_test = analysistest.make(
211    _expect_doesnt_match,
212    config_settings = _set_conditions([True, False, True]),
213)
214
215def _and_config_setting_group_middle_match_fails_test():
216    """Test verifying middle condition mismatch on an ANDing config_setting_group."""
217    boolean_attr_rule(
218        name = "and_config_setting_group_middle_match_fails_rule",
219        myboolean = select(
220            {
221                ":1_and_2_and_3": True,
222                "//conditions:default": False,
223            },
224        ),
225    )
226    and_config_setting_group_middle_match_fails_test(
227        name = "and_config_setting_group_middle_match_fails_test",
228        target_under_test = ":and_config_setting_group_middle_match_fails_rule",
229    )
230
231###################################################
232# and_config_setting_group_last_match_fails_test
233###################################################
234and_config_setting_group_last_match_fails_test = analysistest.make(
235    _expect_doesnt_match,
236    config_settings = _set_conditions([True, True, False]),
237)
238
239def _and_config_setting_group_last_match_fails_test():
240    """Test verifying last condition mismatch on an ANDing config_setting_group."""
241    boolean_attr_rule(
242        name = "and_config_setting_group_last_match_fails_rule",
243        myboolean = select(
244            {
245                ":1_and_2_and_3": True,
246                "//conditions:default": False,
247            },
248        ),
249    )
250    and_config_setting_group_last_match_fails_test(
251        name = "and_config_setting_group_last_match_fails_test",
252        target_under_test = ":and_config_setting_group_last_match_fails_rule",
253    )
254
255###################################################
256# and_config_setting_group_multiple_matches_fail_test
257###################################################
258and_config_setting_group_multiple_matches_fail_test = analysistest.make(
259    _expect_doesnt_match,
260    config_settings = _set_conditions([True, False, False]),
261)
262
263def _and_config_setting_group_multiple_matches_fail_test():
264    """Test verifying multiple conditions mismatch on an ANDing config_setting_group."""
265    boolean_attr_rule(
266        name = "and_config_setting_group_multiple_matches_fail_rule",
267        myboolean = select(
268            {
269                ":1_and_2_and_3": True,
270                "//conditions:default": False,
271            },
272        ),
273    )
274    and_config_setting_group_multiple_matches_fail_test(
275        name = "and_config_setting_group_multiple_matches_fail_test",
276        target_under_test = ":and_config_setting_group_multiple_matches_fail_rule",
277    )
278
279###################################################
280# and_config_setting_group_all_matches_fail_test
281###################################################
282and_config_setting_group_all_matches_fail_test = analysistest.make(
283    _expect_doesnt_match,
284    config_settings = _set_conditions([False, False, False]),
285)
286
287def _and_config_setting_group_all_matches_fail_test():
288    """Test verifying all conditions mismatch on an ANDing config_setting_group."""
289    boolean_attr_rule(
290        name = "and_config_setting_group_all_matches_fail_rule",
291        myboolean = select(
292            {
293                ":1_and_2_and_3": True,
294                "//conditions:default": False,
295            },
296        ),
297    )
298    and_config_setting_group_all_matches_fail_test(
299        name = "and_config_setting_group_all_matches_fail_test",
300        target_under_test = ":and_config_setting_group_all_matches_fail_rule",
301    )
302
303###################################################
304# and_config_setting_group_single_setting_matches_test
305###################################################
306and_config_setting_group_single_setting_matches_test = analysistest.make(
307    _expect_matches,
308    config_settings = {"//command_line_option:cpu": "ppc"},
309)
310
311def _and_config_setting_group_single_setting_matches_test():
312    """Test verifying match on single-entry ANDing config_setting_group."""
313    boolean_attr_rule(
314        name = "and_config_setting_group_single_setting_matches_rule",
315        myboolean = select(
316            {
317                ":1_and_nothing_else": True,
318                "//conditions:default": False,
319            },
320        ),
321    )
322    and_config_setting_group_single_setting_matches_test(
323        name = "and_config_setting_group_single_setting_matches_test",
324        target_under_test = ":and_config_setting_group_single_setting_matches_rule",
325    )
326
327###################################################
328# and_config_setting_group_single_setting_fails_test
329###################################################
330and_config_setting_group_single_setting_fails_test = analysistest.make(
331    _expect_doesnt_match,
332    config_settings = {"//command_line_option:cpu": "x86"},
333)
334
335def _and_config_setting_group_single_setting_fails_test():
336    """Test verifying no match on single-entry ANDing config_setting_group."""
337    boolean_attr_rule(
338        name = "and_config_setting_group_single_setting_fails_rule",
339        myboolean = select(
340            {
341                ":1_and_nothing_else": True,
342                "//conditions:default": False,
343            },
344        ),
345    )
346    and_config_setting_group_single_setting_fails_test(
347        name = "and_config_setting_group_single_setting_fails_test",
348        target_under_test = ":and_config_setting_group_single_setting_fails_rule",
349    )
350
351###################################################
352# or_config_setting_group_no_match_test
353###################################################
354or_config_setting_group_no_matches_test = analysistest.make(
355    _expect_doesnt_match,
356    config_settings = _set_conditions([False, False, False]),
357)
358
359def _or_config_setting_group_no_matches_test():
360    """Test verifying no matches on an ORing config_setting_group."""
361    boolean_attr_rule(
362        name = "or_config_setting_group_no_matches_rule",
363        myboolean = select(
364            {
365                ":1_or_2_or_3": True,
366                "//conditions:default": False,
367            },
368        ),
369    )
370    or_config_setting_group_no_matches_test(
371        name = "or_config_setting_group_no_matches_test",
372        target_under_test = ":or_config_setting_group_no_matches_rule",
373    )
374
375###################################################
376# or_config_setting_group_first_cond_matches_test
377###################################################
378or_config_setting_group_first_cond_matches_test = analysistest.make(
379    _expect_matches,
380    config_settings = _set_conditions([True, False, False]),
381)
382
383def _or_config_setting_group_first_cond_matches_test():
384    """Test verifying first condition matching on an ORing config_setting_group."""
385    boolean_attr_rule(
386        name = "or_config_setting_group_first_cond_matches_rule",
387        myboolean = select(
388            {
389                ":1_or_2_or_3": True,
390                "//conditions:default": False,
391            },
392        ),
393    )
394    or_config_setting_group_first_cond_matches_test(
395        name = "or_config_setting_group_first_cond_matches_test",
396        target_under_test = ":or_config_setting_group_first_cond_matches_rule",
397    )
398
399###################################################
400# or_config_setting_group_middle_cond_matches_test
401###################################################
402or_config_setting_group_middle_cond_matches_test = analysistest.make(
403    _expect_matches,
404    config_settings = _set_conditions([False, True, False]),
405)
406
407def _or_config_setting_group_middle_cond_matches_test():
408    """Test verifying middle condition matching on an ORing config_setting_group."""
409    boolean_attr_rule(
410        name = "or_config_setting_group_middle_cond_matches_rule",
411        myboolean = select(
412            {
413                ":1_or_2_or_3": True,
414                "//conditions:default": False,
415            },
416        ),
417    )
418    or_config_setting_group_middle_cond_matches_test(
419        name = "or_config_setting_group_middle_cond_matches_test",
420        target_under_test = ":or_config_setting_group_middle_cond_matches_rule",
421    )
422
423###################################################
424# or_config_setting_group_last_cond_matches_test
425###################################################
426or_config_setting_group_last_cond_matches_test = analysistest.make(
427    _expect_matches,
428    config_settings = _set_conditions([False, False, True]),
429)
430
431def _or_config_setting_group_last_cond_matches_test():
432    """Test verifying last condition matching on an ORing config_setting_group."""
433    boolean_attr_rule(
434        name = "or_config_setting_group_last_cond_matches_rule",
435        myboolean = select(
436            {
437                ":1_or_2_or_3": True,
438                "//conditions:default": False,
439            },
440        ),
441    )
442    or_config_setting_group_last_cond_matches_test(
443        name = "or_config_setting_group_last_cond_matches_test",
444        target_under_test = ":or_config_setting_group_last_cond_matches_rule",
445    )
446
447###################################################
448# or_config_setting_group_multiple_conds_match_test
449###################################################
450or_config_setting_group_multiple_conds_match_test = analysistest.make(
451    _expect_matches,
452    config_settings = _set_conditions([False, True, True]),
453)
454
455def _or_config_setting_group_multiple_conds_match_test():
456    """Test verifying multiple conditions matching on an ORing config_setting_group."""
457    boolean_attr_rule(
458        name = "or_config_setting_group_multiple_conds_match_rule",
459        myboolean = select(
460            {
461                ":1_or_2_or_3": True,
462                "//conditions:default": False,
463            },
464        ),
465    )
466    or_config_setting_group_multiple_conds_match_test(
467        name = "or_config_setting_group_multiple_conds_match_test",
468        target_under_test = ":or_config_setting_group_multiple_conds_match_rule",
469    )
470
471###################################################
472# or_config_setting_group_all_conds_match_test
473###################################################
474or_config_setting_group_all_conds_match_test = analysistest.make(
475    _expect_matches,
476    config_settings = _set_conditions([False, True, True]),
477)
478
479def _or_config_setting_group_all_conds_match_test():
480    """Test verifying all conditions matching on an ORing config_setting_group."""
481    boolean_attr_rule(
482        name = "or_config_setting_group_all_conds_match_rule",
483        myboolean = select(
484            {
485                ":1_or_2_or_3": True,
486                "//conditions:default": False,
487            },
488        ),
489    )
490    or_config_setting_group_all_conds_match_test(
491        name = "or_config_setting_group_all_conds_match_test",
492        target_under_test = ":or_config_setting_group_all_conds_match_rule",
493    )
494
495###################################################
496# or_config_setting_group_single_setting_matches_test
497###################################################
498or_config_setting_group_single_setting_matches_test = analysistest.make(
499    _expect_matches,
500    config_settings = {"//command_line_option:cpu": "ppc"},
501)
502
503def _or_config_setting_group_single_setting_matches_test():
504    """Test verifying match on single-entry ORing config_setting_group."""
505    boolean_attr_rule(
506        name = "or_config_setting_group_single_setting_matches_rule",
507        myboolean = select(
508            {
509                ":1_or_nothing_else": True,
510                "//conditions:default": False,
511            },
512        ),
513    )
514    or_config_setting_group_single_setting_matches_test(
515        name = "or_config_setting_group_single_setting_matches_test",
516        target_under_test = ":or_config_setting_group_single_setting_matches_rule",
517    )
518
519###################################################
520# or_config_setting_group_single_setting_fails_test
521###################################################
522or_config_setting_group_single_setting_fails_test = analysistest.make(
523    _expect_doesnt_match,
524    config_settings = {"//command_line_option:cpu": "x86"},
525)
526
527def _or_config_setting_group_single_setting_fails_test():
528    """Test verifying no match on single-entry ORing config_setting_group."""
529    boolean_attr_rule(
530        name = "or_config_setting_group_single_setting_fails_rule",
531        myboolean = select(
532            {
533                ":1_or_nothing_else": True,
534                "//conditions:default": False,
535            },
536        ),
537    )
538    or_config_setting_group_single_setting_fails_test(
539        name = "or_config_setting_group_single_setting_fails_test",
540        target_under_test = ":or_config_setting_group_single_setting_fails_rule",
541    )
542
543###################################################
544# always_true_match_all_test
545###################################################
546always_true_match_all_test = analysistest.make(_expect_matches)
547
548def _always_true_match_all_test():
549    """Tests that "match_all=['//conditions:default']" always matches."""
550    selects.config_setting_group(
551        name = "all_always_match",
552        match_all = ["//conditions:default"],
553    )
554    boolean_attr_rule(
555        name = "match_always_true_rule",
556        myboolean = select(
557            {
558                ":all_always_match": True,
559            },
560        ),
561    )
562    always_true_match_all_test(
563        name = "always_true_match_all_test",
564        target_under_test = ":match_always_true_rule",
565    )
566
567###################################################
568# always_true_match_any_test
569###################################################
570always_true_match_any_test = analysistest.make(_expect_matches)
571
572def _always_true_match_any_test():
573    """Tests that "match_any=['//conditions:default']" always matches."""
574    selects.config_setting_group(
575        name = "any_always_match",
576        match_any = ["//conditions:default"],
577    )
578    boolean_attr_rule(
579        name = "match_any_always_true_rule",
580        myboolean = select(
581            {
582                ":any_always_match": True,
583            },
584        ),
585    )
586    always_true_match_any_test(
587        name = "always_true_match_any_test",
588        target_under_test = ":match_any_always_true_rule",
589    )
590
591###################################################
592# empty_config_setting_group_not_allowed_test
593###################################################
594
595# config_setting_group with no parameters triggers a failure.
596# TODO: how do we test this? This requires catching macro
597# evaluation failure.
598
599###################################################
600# and_and_or_not_allowed_together_test
601###################################################
602
603# config_setting_group: setting both match_any and match_or
604# triggers a failure.
605# TODO: how do we test this? This requires catching macro
606# evaluation failure.
607
608###################################################
609
610# buildifier: disable=unnamed-macro
611def selects_test_suite():
612    """Creates the test targets and test suite for selects.bzl tests."""
613    unittest.suite(
614        "selects_tests",
615        with_or_test,
616    )
617
618    _create_config_settings()
619    _create_config_setting_groups()
620
621    _and_config_setting_group_matches_test()
622    _and_config_setting_group_first_match_fails_test()
623    _and_config_setting_group_middle_match_fails_test()
624    _and_config_setting_group_last_match_fails_test()
625    _and_config_setting_group_multiple_matches_fail_test()
626    _and_config_setting_group_all_matches_fail_test()
627    _and_config_setting_group_single_setting_matches_test()
628    _and_config_setting_group_single_setting_fails_test()
629
630    _or_config_setting_group_no_matches_test()
631    _or_config_setting_group_first_cond_matches_test()
632    _or_config_setting_group_middle_cond_matches_test()
633    _or_config_setting_group_last_cond_matches_test()
634    _or_config_setting_group_multiple_conds_match_test()
635    _or_config_setting_group_all_conds_match_test()
636    _or_config_setting_group_single_setting_matches_test()
637    _or_config_setting_group_single_setting_fails_test()
638
639    _always_true_match_all_test()
640    _always_true_match_any_test()
641
642    # _empty_config_setting_group_not_allowed_test()
643    # _and_and_or_not_allowed_together_test()
644