blob: 71a05cfd332388bb5dd9e1010a3334aaf76afb32 [file] [log] [blame]
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the cc_toolchain_config rule."""
load(
"//cc:cc_toolchain_config_lib.bzl",
legacy_action_config = "action_config",
legacy_feature = "feature",
legacy_flag_group = "flag_group",
legacy_flag_set = "flag_set",
legacy_tool = "tool",
)
load("//cc/toolchains:cc_toolchain_info.bzl", "ActionTypeInfo", "ToolchainConfigInfo")
load("//cc/toolchains/impl:legacy_converter.bzl", "convert_toolchain")
load("//cc/toolchains/impl:toolchain_config_info.bzl", _toolchain_config_info = "toolchain_config_info")
load("//tests/rule_based_toolchain:subjects.bzl", "result_fn_wrapper", "subjects")
visibility("private")
toolchain_config_info = result_fn_wrapper(_toolchain_config_info)
_COLLECTED_CPP_COMPILE_FILES = [
# From :compile_config's tool
"tests/rule_based_toolchain/testdata/bin",
"tests/rule_based_toolchain/testdata/bin_wrapper",
# From :compile_feature's args
"tests/rule_based_toolchain/testdata/file2",
# From :compile_feature's args' allowlist_include_directories
"tests/rule_based_toolchain/testdata/subdir2/file_bar",
]
_COLLECTED_C_COMPILE_FILES = _COLLECTED_CPP_COMPILE_FILES + [
# From :c_compile_args
"tests/rule_based_toolchain/testdata/file1",
# From :c_compile_args's allowlist_include_directories
"tests/rule_based_toolchain/testdata/subdir1/file_foo",
# From :c_compile_tool's allowlist_include_directories
"tests/rule_based_toolchain/testdata/subdir3/file_baz",
]
def _expect_that_toolchain(env, expr = None, **kwargs):
return env.expect.that_value(
value = toolchain_config_info(label = Label("//:toolchain"), **kwargs),
expr = expr,
factory = subjects.result(subjects.ToolchainConfigInfo),
)
def _missing_tool_map_invalid_test(env, _targets):
_expect_that_toolchain(
env,
tool_map = None,
expr = "missing_tool_map",
).err().contains(
"tool_map is required",
)
def _empty_toolchain_valid_test(env, targets):
_expect_that_toolchain(
env,
tool_map = targets.empty_tool_map, # tool_map is always required.
).ok()
def _duplicate_feature_names_invalid_test(env, targets):
_expect_that_toolchain(
env,
known_features = [targets.simple_feature, targets.same_feature_name],
tool_map = targets.empty_tool_map,
expr = "duplicate_feature_name",
).err().contains_all_of([
"The feature name simple_feature was defined by",
targets.same_feature_name.label,
targets.simple_feature.label,
])
# Overriding a feature gives it the same name. Ensure this isn't blocked.
_expect_that_toolchain(
env,
known_features = [targets.builtin_feature, targets.overrides_feature],
tool_map = targets.empty_tool_map,
expr = "override_feature",
).ok()
def _feature_config_implies_missing_feature_invalid_test(env, targets):
_expect_that_toolchain(
env,
expr = "feature_with_implies",
known_features = [targets.simple_feature, targets.implies_simple_feature],
tool_map = targets.empty_tool_map,
).ok()
_expect_that_toolchain(
env,
known_features = [targets.implies_simple_feature],
tool_map = targets.empty_tool_map,
expr = "feature_missing_implies",
).err().contains(
"%s implies the feature %s" % (targets.implies_simple_feature.label, targets.simple_feature.label),
)
def _feature_missing_requirements_invalid_test(env, targets):
_expect_that_toolchain(
env,
known_features = [targets.requires_any_simple_feature, targets.simple_feature],
tool_map = targets.empty_tool_map,
expr = "requires_any_simple_has_simple",
).ok()
_expect_that_toolchain(
env,
known_features = [targets.requires_any_simple_feature, targets.simple_feature2],
tool_map = targets.empty_tool_map,
expr = "requires_any_simple_has_simple2",
).ok()
_expect_that_toolchain(
env,
known_features = [targets.requires_any_simple_feature],
tool_map = targets.empty_tool_map,
expr = "requires_any_simple_has_none",
).err().contains(
"It is impossible to enable %s" % targets.requires_any_simple_feature.label,
)
_expect_that_toolchain(
env,
known_features = [targets.requires_all_simple_feature, targets.simple_feature, targets.simple_feature2],
tool_map = targets.empty_tool_map,
expr = "requires_all_simple_has_both",
).ok()
_expect_that_toolchain(
env,
known_features = [targets.requires_all_simple_feature, targets.simple_feature],
tool_map = targets.empty_tool_map,
expr = "requires_all_simple_has_simple",
).err().contains(
"It is impossible to enable %s" % targets.requires_all_simple_feature.label,
)
_expect_that_toolchain(
env,
known_features = [targets.requires_all_simple_feature, targets.simple_feature2],
tool_map = targets.empty_tool_map,
expr = "requires_all_simple_has_simple2",
).err().contains(
"It is impossible to enable %s" % targets.requires_all_simple_feature.label,
)
def _args_missing_requirements_invalid_test(env, targets):
_expect_that_toolchain(
env,
args = [targets.requires_all_simple_args],
known_features = [targets.simple_feature, targets.simple_feature2],
tool_map = targets.empty_tool_map,
expr = "has_both",
).ok()
_expect_that_toolchain(
env,
args = [targets.requires_all_simple_args],
known_features = [targets.simple_feature],
tool_map = targets.empty_tool_map,
expr = "has_only_one",
).err().contains(
"It is impossible to enable %s" % targets.requires_all_simple_args.label,
)
def _toolchain_collects_files_test(env, targets):
tc = env.expect.that_target(
targets.collects_files_toolchain_config,
).provider(ToolchainConfigInfo)
tc.files().get(targets.c_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_C_COMPILE_FILES)
tc.files().get(targets.cpp_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_CPP_COMPILE_FILES)
env.expect.that_target(
targets.collects_files_c_compile,
).default_outputs().contains_exactly(_COLLECTED_C_COMPILE_FILES)
env.expect.that_target(
targets.collects_files_cpp_compile,
).default_outputs().contains_exactly(_COLLECTED_CPP_COMPILE_FILES)
legacy = convert_toolchain(tc.actual)
env.expect.that_collection(legacy.features).contains_exactly([
legacy_feature(
name = "simple_feature",
enabled = True,
flag_sets = [legacy_flag_set(
actions = ["c_compile"],
flag_groups = [
legacy_flag_group(flags = ["c_compile_args"]),
],
)],
),
legacy_feature(
name = "compile_feature",
enabled = False,
flag_sets = [legacy_flag_set(
actions = ["c_compile", "cpp_compile"],
flag_groups = [
legacy_flag_group(flags = ["compile_args"]),
],
)],
),
legacy_feature(
name = "implied_by_always_enabled",
enabled = True,
flag_sets = [
legacy_flag_set(
actions = [
"c++-compile",
"c++-header-parsing",
"c++-link-dynamic-library",
"c++-link-executable",
"c++-link-nodeps-dynamic-library",
"c++-module-codegen",
"c++-module-compile",
"c-compile",
"clif-match",
"linkstamp-compile",
"lto-backend",
"lto-index-for-dynamic-library",
"lto-index-for-executable",
"lto-index-for-nodeps-dynamic-library",
],
flag_groups = [
legacy_flag_group(flags = [
"--sysroot=tests/rule_based_toolchain/testdata",
]),
],
),
legacy_flag_set(
actions = ["c_compile"],
flag_groups = [
legacy_flag_group(flags = ["c_compile_args"]),
],
),
],
),
]).in_order()
exe = tc.tool_map().some().configs().get(
targets.c_compile[ActionTypeInfo],
).actual.exe
env.expect.that_collection(legacy.action_configs).contains_exactly([
legacy_action_config(
action_name = "c_compile",
enabled = True,
tools = [legacy_tool(tool = exe)],
),
legacy_action_config(
action_name = "cpp_compile",
enabled = True,
tools = [legacy_tool(tool = exe)],
implies = [],
),
]).in_order()
TARGETS = [
"//tests/rule_based_toolchain/actions:c_compile",
"//tests/rule_based_toolchain/actions:cpp_compile",
":builtin_feature",
":compile_tool_map",
":collects_files_c_compile",
":collects_files_cpp_compile",
":collects_files_toolchain_config",
":compile_feature",
":c_compile_args",
":c_compile_tool_map",
":empty_tool_map",
":implies_simple_feature",
":overrides_feature",
":requires_any_simple_feature",
":requires_all_simple_feature",
":requires_all_simple_args",
":simple_feature",
":simple_feature2",
":same_feature_name",
]
# @unsorted-dict-items
TESTS = {
"empty_toolchain_valid_test": _empty_toolchain_valid_test,
"missing_tool_map_invalid_test": _missing_tool_map_invalid_test,
"duplicate_feature_names_fail_validation_test": _duplicate_feature_names_invalid_test,
"feature_config_implies_missing_feature_invalid_test": _feature_config_implies_missing_feature_invalid_test,
"feature_missing_requirements_invalid_test": _feature_missing_requirements_invalid_test,
"args_missing_requirements_invalid_test": _args_missing_requirements_invalid_test,
"toolchain_collects_files_test": _toolchain_collects_files_test,
}