• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Tests for pw_cc_feature and pw_cc_feature_set."""
15
16load(
17    "@rules_cc//cc:cc_toolchain_config_lib.bzl",
18    rules_cc_feature = "feature",
19)
20load(
21    "//cc_toolchain/tests:utils.bzl",
22    "assert_eq",
23    "assert_fail",
24    "assert_labels_eq",
25    "generate_test_rule",
26)
27
28visibility("private")
29
30def _test_features_impl(_ctx, features, feature_sets, flag_sets, to_untyped_config, feature_constraints, **_):
31    # Verify that we the builtin features don't generate any configs.
32    assert_eq(to_untyped_config(features = []).features, [])
33
34    assert_eq(features.foo.name, "foo")
35    assert_eq(features.foo.flag_sets.to_list(), [flag_sets.foo])
36
37    # Verify that we can't have two features with the same feature name.
38    assert_eq(len(to_untyped_config(features = [features.foo]).features), 1)
39    assert_fail(to_untyped_config, features = [features.foo, features.conflict])
40
41    assert_labels_eq(
42        feature_sets.foobar.features,
43        [features.foo, features.bar],
44    )
45
46    assert_labels_eq(
47        features.implies.implies_features,
48        [features.foo, features.bar],
49    )
50
51    assert_eq(list(features.requires.requires_any_of), [feature_sets.foobar, feature_sets.baz])
52
53    # Implies requires both foo and bar to be listed.
54    assert_fail(
55        to_untyped_config,
56        features = [features.implies, features.foo],
57    )
58    to_untyped_config(
59        features = [features.implies, features.foo, features.bar],
60    )
61
62    # Requires requires either baz OR (foo AND bar) to be listed.
63    to_untyped_config(
64        features = [features.requires, features.baz],
65    )
66
67    to_untyped_config(
68        features = [features.requires, features.foo, features.bar],
69    )
70    assert_fail(
71        to_untyped_config,
72        features = [features.requires, features.foo],
73    )
74
75    # Verify that we fail iff the duplicate was not an override.
76    assert_eq(
77        to_untyped_config(
78            features = [features.supports_pic],
79        ).features,
80        [rules_cc_feature(name = "supports_pic", enabled = True)],
81    )
82    assert_fail(
83        to_untyped_config,
84        features = [features.supports_pic_no_override],
85    )
86
87    # Verify that you can imply a "known" feature.
88    to_untyped_config(
89        features = [features.implies_supports_pic],
90    )
91
92    assert_labels_eq(
93        feature_constraints.foo_not_baz.all_of,
94        [features.foo],
95    )
96    assert_labels_eq(
97        feature_constraints.foo_not_baz.none_of,
98        [features.baz],
99    )
100
101    assert_labels_eq(
102        feature_constraints.foo_only.all_of,
103        [features.foo],
104    )
105    assert_labels_eq(
106        feature_constraints.foo_only.none_of,
107        [features.baz, features.bar],
108    )
109
110    # Constrained requires either (foo AND not baz) OR bar.
111    to_untyped_config(features = [features.constrained, features.bar])
112
113    # Validate that we don't require baz to exist.
114    to_untyped_config(features = [features.constrained, features.foo])
115    assert_fail(to_untyped_config, features = [features.constrained])
116
117    # You should be able to do mutual exclusion without all the features being
118    # defined
119    assert_eq(
120        to_untyped_config(features = [features.primary_feature]).features[0].provides,
121        ["@@//cc_toolchain/tests/features:category"],
122    )
123    assert_eq(
124        to_untyped_config(features = [features.mutex_provider]).features[0].provides,
125        ["@@//cc_toolchain/tests/features:category"],
126    )
127    assert_eq(
128        to_untyped_config(features = [features.mutex_label]).features[0].provides,
129        ["primary_feature"],
130    )
131
132    ft = to_untyped_config(features = [features.bar]).features[0]
133    assert_eq(len(ft.flag_sets), 1)
134    assert_eq(ft.flag_sets[0].flag_groups[0].flags, ["--bar"])
135    assert_eq(ft.env_sets[0].env_entries[0].key, "foo")
136    assert_eq(ft.env_sets[0].env_entries[0].value, "%{bar}")
137    assert_eq(ft.env_sets[0].env_entries[0].expand_if_available, "bar")
138
139test_features = generate_test_rule(_test_features_impl)
140