1# Copyright 2024 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://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, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Tests for pw_cc_feature and pw_cc_feature_set.""" 15 16load( 17 "@rules_cc//cc:cc_toolchain_config_lib.bzl", 18 rules_cc_feature = "feature", 19) 20load( 21 "//cc_toolchain/tests:utils.bzl", 22 "assert_eq", 23 "assert_fail", 24 "assert_labels_eq", 25 "generate_test_rule", 26) 27 28visibility("private") 29 30def _test_features_impl(_ctx, features, feature_sets, flag_sets, to_untyped_config, feature_constraints, **_): 31 # Verify that we the builtin features don't generate any configs. 32 assert_eq(to_untyped_config(features = []).features, []) 33 34 assert_eq(features.foo.name, "foo") 35 assert_eq(features.foo.flag_sets.to_list(), [flag_sets.foo]) 36 37 # Verify that we can't have two features with the same feature name. 38 assert_eq(len(to_untyped_config(features = [features.foo]).features), 1) 39 assert_fail(to_untyped_config, features = [features.foo, features.conflict]) 40 41 assert_labels_eq( 42 feature_sets.foobar.features, 43 [features.foo, features.bar], 44 ) 45 46 assert_labels_eq( 47 features.implies.implies_features, 48 [features.foo, features.bar], 49 ) 50 51 assert_eq(list(features.requires.requires_any_of), [feature_sets.foobar, feature_sets.baz]) 52 53 # Implies requires both foo and bar to be listed. 54 assert_fail( 55 to_untyped_config, 56 features = [features.implies, features.foo], 57 ) 58 to_untyped_config( 59 features = [features.implies, features.foo, features.bar], 60 ) 61 62 # Requires requires either baz OR (foo AND bar) to be listed. 63 to_untyped_config( 64 features = [features.requires, features.baz], 65 ) 66 67 to_untyped_config( 68 features = [features.requires, features.foo, features.bar], 69 ) 70 assert_fail( 71 to_untyped_config, 72 features = [features.requires, features.foo], 73 ) 74 75 # Verify that we fail iff the duplicate was not an override. 76 assert_eq( 77 to_untyped_config( 78 features = [features.supports_pic], 79 ).features, 80 [rules_cc_feature(name = "supports_pic", enabled = True)], 81 ) 82 assert_fail( 83 to_untyped_config, 84 features = [features.supports_pic_no_override], 85 ) 86 87 # Verify that you can imply a "known" feature. 88 to_untyped_config( 89 features = [features.implies_supports_pic], 90 ) 91 92 assert_labels_eq( 93 feature_constraints.foo_not_baz.all_of, 94 [features.foo], 95 ) 96 assert_labels_eq( 97 feature_constraints.foo_not_baz.none_of, 98 [features.baz], 99 ) 100 101 assert_labels_eq( 102 feature_constraints.foo_only.all_of, 103 [features.foo], 104 ) 105 assert_labels_eq( 106 feature_constraints.foo_only.none_of, 107 [features.baz, features.bar], 108 ) 109 110 # Constrained requires either (foo AND not baz) OR bar. 111 to_untyped_config(features = [features.constrained, features.bar]) 112 113 # Validate that we don't require baz to exist. 114 to_untyped_config(features = [features.constrained, features.foo]) 115 assert_fail(to_untyped_config, features = [features.constrained]) 116 117 # You should be able to do mutual exclusion without all the features being 118 # defined 119 assert_eq( 120 to_untyped_config(features = [features.primary_feature]).features[0].provides, 121 ["@@//cc_toolchain/tests/features:category"], 122 ) 123 assert_eq( 124 to_untyped_config(features = [features.mutex_provider]).features[0].provides, 125 ["@@//cc_toolchain/tests/features:category"], 126 ) 127 assert_eq( 128 to_untyped_config(features = [features.mutex_label]).features[0].provides, 129 ["primary_feature"], 130 ) 131 132 ft = to_untyped_config(features = [features.bar]).features[0] 133 assert_eq(len(ft.flag_sets), 1) 134 assert_eq(ft.flag_sets[0].flag_groups[0].flags, ["--bar"]) 135 assert_eq(ft.env_sets[0].env_entries[0].key, "foo") 136 assert_eq(ft.env_sets[0].env_entries[0].value, "%{bar}") 137 assert_eq(ft.env_sets[0].env_entries[0].expand_if_available, "bar") 138 139test_features = generate_test_rule(_test_features_impl) 140