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