• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 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"""Tests for features for the rule based toolchain."""
15
16load(
17    "//cc:cc_toolchain_config_lib.bzl",
18    legacy_feature_set = "feature_set",
19    legacy_flag_group = "flag_group",
20    legacy_flag_set = "flag_set",
21)
22load(
23    "//cc/toolchains:cc_toolchain_info.bzl",
24    "ActionTypeInfo",
25    "ArgsInfo",
26    "FeatureConstraintInfo",
27    "FeatureInfo",
28    "FeatureSetInfo",
29    "MutuallyExclusiveCategoryInfo",
30)
31load(
32    "//cc/toolchains/impl:legacy_converter.bzl",
33    "convert_feature",
34    "convert_feature_constraint",
35)
36
37visibility("private")
38
39_C_COMPILE_FILE = "tests/rule_based_toolchain/testdata/file1"
40_SUBDIR1 = "tests/rule_based_toolchain/testdata/subdir1"
41_SUBDIR1_FILES = ["tests/rule_based_toolchain/testdata/subdir1/file_foo"]
42
43def _sentinel_feature_test(env, targets):
44    sentinel_feature = env.expect.that_target(targets.sentinel_feature).provider(FeatureInfo)
45    sentinel_feature.name().equals("sentinel_feature_name")
46    sentinel_feature.args().args().contains_exactly([])
47
48def _simple_feature_test(env, targets):
49    simple = env.expect.that_target(targets.simple).provider(FeatureInfo)
50    simple.name().equals("feature_name")
51    simple.args().args().contains_exactly([targets.c_compile_args.label])
52    simple.enabled().equals(False)
53    simple.overrides().is_none()
54    simple.overridable().equals(False)
55
56    simple.args().files().contains_exactly([_C_COMPILE_FILE])
57    c_compile_action = simple.args().by_action().get(
58        targets.c_compile_args[ArgsInfo].actions.to_list()[0],
59    )
60    c_compile_action.files().contains_exactly([_C_COMPILE_FILE])
61    c_compile_action.args().contains_exactly([targets.c_compile_args[ArgsInfo]])
62
63    legacy = convert_feature(simple.actual)
64    env.expect.that_str(legacy.name).equals("feature_name")
65    env.expect.that_bool(legacy.enabled).equals(False)
66    env.expect.that_collection(legacy.flag_sets).contains_exactly([
67        legacy_flag_set(
68            actions = ["c_compile"],
69            with_features = [],
70            flag_groups = [legacy_flag_group(flags = ["c"])],
71        ),
72    ])
73
74def _feature_collects_requirements_test(env, targets):
75    ft = env.expect.that_target(targets.requires).provider(FeatureInfo)
76    ft.requires_any_of().contains_exactly([
77        targets.feature_set.label,
78    ])
79
80    legacy = convert_feature(ft.actual)
81    env.expect.that_collection(legacy.requires).contains_exactly([
82        legacy_feature_set(features = ["feature_name", "simple2"]),
83    ])
84
85def _feature_collects_implies_test(env, targets):
86    env.expect.that_target(targets.implies).provider(
87        FeatureInfo,
88    ).implies().contains_exactly([
89        targets.simple.label,
90    ])
91
92def _feature_collects_mutual_exclusion_test(env, targets):
93    env.expect.that_target(targets.simple).provider(
94        MutuallyExclusiveCategoryInfo,
95    ).name().equals("feature_name")
96    env.expect.that_target(targets.mutual_exclusion_feature).provider(
97        FeatureInfo,
98    ).mutually_exclusive().contains_exactly([
99        targets.simple.label,
100        targets.category.label,
101    ])
102
103def _feature_set_collects_features_test(env, targets):
104    env.expect.that_target(targets.feature_set).provider(
105        FeatureSetInfo,
106    ).features().contains_exactly([
107        targets.simple.label,
108        targets.simple2.label,
109    ])
110
111def _feature_constraint_collects_direct_features_test(env, targets):
112    constraint = env.expect.that_target(targets.direct_constraint).provider(
113        FeatureConstraintInfo,
114    )
115    constraint.all_of().contains_exactly([targets.simple.label])
116    constraint.none_of().contains_exactly([targets.simple2.label])
117
118def _feature_constraint_collects_transitive_features_test(env, targets):
119    constraint = env.expect.that_target(targets.transitive_constraint).provider(
120        FeatureConstraintInfo,
121    )
122    constraint.all_of().contains_exactly([
123        targets.simple.label,
124        targets.requires.label,
125    ])
126    constraint.none_of().contains_exactly([
127        targets.simple2.label,
128        targets.implies.label,
129    ])
130
131    legacy = convert_feature_constraint(constraint.actual)
132    env.expect.that_collection(legacy.features).contains_exactly([
133        "feature_name",
134        "requires",
135    ])
136    env.expect.that_collection(legacy.not_features).contains_exactly([
137        "simple2",
138        "implies",
139    ])
140
141def _external_feature_is_a_feature_test(env, targets):
142    external_feature = env.expect.that_target(targets.builtin_feature).provider(
143        FeatureInfo,
144    )
145    external_feature.name().equals("builtin_feature")
146
147    # It's not a string, but we don't have a factory for the type.
148    env.expect.that_str(convert_feature(external_feature.actual)).equals(None)
149
150def _feature_can_be_overridden_test(env, targets):
151    overrides = env.expect.that_target(targets.overrides).provider(FeatureInfo)
152    overrides.name().equals("builtin_feature")
153    overrides.overrides().some().label().equals(targets.builtin_feature.label)
154
155def _feature_with_directory_test(env, targets):
156    with_dir = env.expect.that_target(targets.feature_with_dir).provider(FeatureInfo)
157    with_dir.allowlist_include_directories().contains_exactly([_SUBDIR1])
158
159    c_compile = env.expect.that_target(targets.feature_with_dir).provider(FeatureInfo).args().by_action().get(
160        targets.c_compile[ActionTypeInfo],
161    )
162    c_compile.files().contains_at_least(_SUBDIR1_FILES)
163
164TARGETS = [
165    ":args_with_dir",
166    ":builtin_feature",
167    ":c_compile_args",
168    ":category",
169    ":direct_constraint",
170    ":feature_set",
171    ":feature_with_dir",
172    ":implies",
173    ":mutual_exclusion_feature",
174    ":overrides",
175    ":requires",
176    ":sentinel_feature",
177    ":simple",
178    ":simple2",
179    ":transitive_constraint",
180    "//tests/rule_based_toolchain/actions:c_compile",
181]
182
183# @unsorted-dict-items
184TESTS = {
185    "sentinel_feature_test": _sentinel_feature_test,
186    "simple_feature_test": _simple_feature_test,
187    "feature_collects_requirements_test": _feature_collects_requirements_test,
188    "feature_collects_implies_test": _feature_collects_implies_test,
189    "feature_collects_mutual_exclusion_test": _feature_collects_mutual_exclusion_test,
190    "feature_set_collects_features_test": _feature_set_collects_features_test,
191    "feature_constraint_collects_direct_features_test": _feature_constraint_collects_direct_features_test,
192    "feature_constraint_collects_transitive_features_test": _feature_constraint_collects_transitive_features_test,
193    "external_feature_is_a_feature_test": _external_feature_is_a_feature_test,
194    "feature_can_be_overridden_test": _feature_can_be_overridden_test,
195    "feature_with_directory_test": _feature_with_directory_test,
196}
197