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