• 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 the cc_toolchain_config rule."""
15
16load(
17    "//cc:cc_toolchain_config_lib.bzl",
18    legacy_action_config = "action_config",
19    legacy_feature = "feature",
20    legacy_flag_group = "flag_group",
21    legacy_flag_set = "flag_set",
22    legacy_tool = "tool",
23)
24load("//cc/toolchains:cc_toolchain_info.bzl", "ActionTypeInfo", "ToolchainConfigInfo")
25load("//cc/toolchains/impl:legacy_converter.bzl", "convert_toolchain")
26load("//cc/toolchains/impl:toolchain_config_info.bzl", _toolchain_config_info = "toolchain_config_info")
27load("//tests/rule_based_toolchain:subjects.bzl", "result_fn_wrapper", "subjects")
28
29visibility("private")
30
31toolchain_config_info = result_fn_wrapper(_toolchain_config_info)
32
33_COLLECTED_CPP_COMPILE_FILES = [
34    # From :compile_config's tool
35    "tests/rule_based_toolchain/testdata/bin",
36    "tests/rule_based_toolchain/testdata/bin_wrapper",
37    # From :compile_feature's args
38    "tests/rule_based_toolchain/testdata/file2",
39    # From :compile_feature's args' allowlist_include_directories
40    "tests/rule_based_toolchain/testdata/subdir2/file_bar",
41]
42
43_COLLECTED_C_COMPILE_FILES = _COLLECTED_CPP_COMPILE_FILES + [
44    # From :c_compile_args
45    "tests/rule_based_toolchain/testdata/file1",
46    # From :c_compile_args's allowlist_include_directories
47    "tests/rule_based_toolchain/testdata/subdir1/file_foo",
48    # From :c_compile_tool's allowlist_include_directories
49    "tests/rule_based_toolchain/testdata/subdir3/file_baz",
50]
51
52def _expect_that_toolchain(env, expr = None, **kwargs):
53    return env.expect.that_value(
54        value = toolchain_config_info(label = Label("//:toolchain"), **kwargs),
55        expr = expr,
56        factory = subjects.result(subjects.ToolchainConfigInfo),
57    )
58
59def _missing_tool_map_invalid_test(env, _targets):
60    _expect_that_toolchain(
61        env,
62        tool_map = None,
63        expr = "missing_tool_map",
64    ).err().contains(
65        "tool_map is required",
66    )
67
68def _empty_toolchain_valid_test(env, targets):
69    _expect_that_toolchain(
70        env,
71        tool_map = targets.empty_tool_map,  # tool_map is always required.
72    ).ok()
73
74def _duplicate_feature_names_invalid_test(env, targets):
75    _expect_that_toolchain(
76        env,
77        known_features = [targets.simple_feature, targets.same_feature_name],
78        tool_map = targets.empty_tool_map,
79        expr = "duplicate_feature_name",
80    ).err().contains_all_of([
81        "The feature name simple_feature was defined by",
82        targets.same_feature_name.label,
83        targets.simple_feature.label,
84    ])
85
86    # Overriding a feature gives it the same name. Ensure this isn't blocked.
87    _expect_that_toolchain(
88        env,
89        known_features = [targets.builtin_feature, targets.overrides_feature],
90        tool_map = targets.empty_tool_map,
91        expr = "override_feature",
92    ).ok()
93
94def _feature_config_implies_missing_feature_invalid_test(env, targets):
95    _expect_that_toolchain(
96        env,
97        expr = "feature_with_implies",
98        known_features = [targets.simple_feature, targets.implies_simple_feature],
99        tool_map = targets.empty_tool_map,
100    ).ok()
101
102    _expect_that_toolchain(
103        env,
104        known_features = [targets.implies_simple_feature],
105        tool_map = targets.empty_tool_map,
106        expr = "feature_missing_implies",
107    ).err().contains(
108        "%s implies the feature %s" % (targets.implies_simple_feature.label, targets.simple_feature.label),
109    )
110
111def _feature_missing_requirements_invalid_test(env, targets):
112    _expect_that_toolchain(
113        env,
114        known_features = [targets.requires_any_simple_feature, targets.simple_feature],
115        tool_map = targets.empty_tool_map,
116        expr = "requires_any_simple_has_simple",
117    ).ok()
118    _expect_that_toolchain(
119        env,
120        known_features = [targets.requires_any_simple_feature, targets.simple_feature2],
121        tool_map = targets.empty_tool_map,
122        expr = "requires_any_simple_has_simple2",
123    ).ok()
124    _expect_that_toolchain(
125        env,
126        known_features = [targets.requires_any_simple_feature],
127        tool_map = targets.empty_tool_map,
128        expr = "requires_any_simple_has_none",
129    ).err().contains(
130        "It is impossible to enable %s" % targets.requires_any_simple_feature.label,
131    )
132
133    _expect_that_toolchain(
134        env,
135        known_features = [targets.requires_all_simple_feature, targets.simple_feature, targets.simple_feature2],
136        tool_map = targets.empty_tool_map,
137        expr = "requires_all_simple_has_both",
138    ).ok()
139    _expect_that_toolchain(
140        env,
141        known_features = [targets.requires_all_simple_feature, targets.simple_feature],
142        tool_map = targets.empty_tool_map,
143        expr = "requires_all_simple_has_simple",
144    ).err().contains(
145        "It is impossible to enable %s" % targets.requires_all_simple_feature.label,
146    )
147    _expect_that_toolchain(
148        env,
149        known_features = [targets.requires_all_simple_feature, targets.simple_feature2],
150        tool_map = targets.empty_tool_map,
151        expr = "requires_all_simple_has_simple2",
152    ).err().contains(
153        "It is impossible to enable %s" % targets.requires_all_simple_feature.label,
154    )
155
156def _args_missing_requirements_invalid_test(env, targets):
157    _expect_that_toolchain(
158        env,
159        args = [targets.requires_all_simple_args],
160        known_features = [targets.simple_feature, targets.simple_feature2],
161        tool_map = targets.empty_tool_map,
162        expr = "has_both",
163    ).ok()
164    _expect_that_toolchain(
165        env,
166        args = [targets.requires_all_simple_args],
167        known_features = [targets.simple_feature],
168        tool_map = targets.empty_tool_map,
169        expr = "has_only_one",
170    ).err().contains(
171        "It is impossible to enable %s" % targets.requires_all_simple_args.label,
172    )
173
174def _toolchain_collects_files_test(env, targets):
175    tc = env.expect.that_target(
176        targets.collects_files_toolchain_config,
177    ).provider(ToolchainConfigInfo)
178    tc.files().get(targets.c_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_C_COMPILE_FILES)
179    tc.files().get(targets.cpp_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_CPP_COMPILE_FILES)
180
181    env.expect.that_target(
182        targets.collects_files_c_compile,
183    ).default_outputs().contains_exactly(_COLLECTED_C_COMPILE_FILES)
184    env.expect.that_target(
185        targets.collects_files_cpp_compile,
186    ).default_outputs().contains_exactly(_COLLECTED_CPP_COMPILE_FILES)
187
188    legacy = convert_toolchain(tc.actual)
189    env.expect.that_collection(legacy.features).contains_exactly([
190        legacy_feature(
191            name = "simple_feature",
192            enabled = True,
193            flag_sets = [legacy_flag_set(
194                actions = ["c_compile"],
195                flag_groups = [
196                    legacy_flag_group(flags = ["c_compile_args"]),
197                ],
198            )],
199        ),
200        legacy_feature(
201            name = "compile_feature",
202            enabled = False,
203            flag_sets = [legacy_flag_set(
204                actions = ["c_compile", "cpp_compile"],
205                flag_groups = [
206                    legacy_flag_group(flags = ["compile_args"]),
207                ],
208            )],
209        ),
210        legacy_feature(
211            name = "supports_pic",
212            enabled = False,
213        ),
214        legacy_feature(
215            name = "implied_by_always_enabled_env_sets",
216            enabled = True,
217        ),
218    ]).in_order()
219
220    exe = tc.tool_map().some().configs().get(
221        targets.c_compile[ActionTypeInfo],
222    ).actual.exe
223    env.expect.that_collection(legacy.action_configs).contains_exactly([
224        legacy_action_config(
225            action_name = "c_compile",
226            enabled = True,
227            tools = [legacy_tool(tool = exe)],
228            implies = ["supports_pic"],
229            flag_sets = [
230                legacy_flag_set(
231                    flag_groups = [
232                        legacy_flag_group(flags = [
233                            "--sysroot=tests/rule_based_toolchain/testdata",
234                        ]),
235                    ],
236                ),
237                legacy_flag_set(
238                    flag_groups = [
239                        legacy_flag_group(flags = ["c_compile_args"]),
240                    ],
241                ),
242            ],
243        ),
244        legacy_action_config(
245            action_name = "cpp_compile",
246            enabled = True,
247            tools = [legacy_tool(tool = exe)],
248            implies = [],
249            flag_sets = [
250                legacy_flag_set(
251                    flag_groups = [
252                        legacy_flag_group(flags = [
253                            "--sysroot=tests/rule_based_toolchain/testdata",
254                        ]),
255                    ],
256                ),
257            ],
258        ),
259    ]).in_order()
260
261TARGETS = [
262    "//tests/rule_based_toolchain/actions:c_compile",
263    "//tests/rule_based_toolchain/actions:cpp_compile",
264    ":builtin_feature",
265    ":compile_tool_map",
266    ":collects_files_c_compile",
267    ":collects_files_cpp_compile",
268    ":collects_files_toolchain_config",
269    ":compile_feature",
270    ":c_compile_args",
271    ":c_compile_tool_map",
272    ":empty_tool_map",
273    ":implies_simple_feature",
274    ":overrides_feature",
275    ":requires_any_simple_feature",
276    ":requires_all_simple_feature",
277    ":requires_all_simple_args",
278    ":simple_feature",
279    ":simple_feature2",
280    ":same_feature_name",
281]
282
283# @unsorted-dict-items
284TESTS = {
285    "empty_toolchain_valid_test": _empty_toolchain_valid_test,
286    "missing_tool_map_invalid_test": _missing_tool_map_invalid_test,
287    "duplicate_feature_names_fail_validation_test": _duplicate_feature_names_invalid_test,
288    "feature_config_implies_missing_feature_invalid_test": _feature_config_implies_missing_feature_invalid_test,
289    "feature_missing_requirements_invalid_test": _feature_missing_requirements_invalid_test,
290    "args_missing_requirements_invalid_test": _args_missing_requirements_invalid_test,
291    "toolchain_collects_files_test": _toolchain_collects_files_test,
292}
293