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