blob: 7a980e6a4005e8644df7fd4fc94dc99fa4ac086d [file] [log] [blame]
# Copyright 2017 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.
"""Unit tests for selects.bzl."""
load("//lib:selects.bzl", "selects")
load("//lib:unittest.bzl", "analysistest", "asserts", "unittest")
###################################################
# with_or_test
###################################################
def _with_or_test(ctx):
"""Unit tests for with_or."""
env = unittest.begin(ctx)
# We actually test on with_or_dict because Starlark can't get the
# dictionary from a select().
# Test select()-compatible input syntax.
input_dict = {":foo": ":d1", "//conditions:default": ":d1"}
asserts.equals(env, input_dict, selects.with_or_dict(input_dict))
# Test OR syntax.
or_dict = {(":foo", ":bar"): ":d1"}
asserts.equals(
env,
{":bar": ":d1", ":foo": ":d1"},
selects.with_or_dict(or_dict),
)
# Test mixed syntax.
mixed_dict = {
":foo": ":d1",
(":bar", ":baz"): ":d2",
"//conditions:default": ":d3",
}
asserts.equals(
env,
{
":bar": ":d2",
":baz": ":d2",
":foo": ":d1",
"//conditions:default": ":d3",
},
selects.with_or_dict(mixed_dict),
)
return unittest.end(env)
with_or_test = unittest.make(_with_or_test)
###################################################
# BUILD declarations for config_setting_group tests
###################################################
# TODO: redefine these config_settings with Starlark build flags when
# they're available non-experimentally.
def _create_config_settings():
native.config_setting(
name = "condition1",
values = {"cpu": "ppc"},
)
native.config_setting(
name = "condition2",
values = {"compilation_mode": "opt"},
)
native.config_setting(
name = "condition3",
values = {"features": "myfeature"},
)
def _create_config_setting_groups():
selects.config_setting_group(
name = "1_and_2_and_3",
match_all = [":condition1", ":condition2", ":condition3"],
)
selects.config_setting_group(
name = "1_and_nothing_else",
match_all = [":condition1"],
)
selects.config_setting_group(
name = "1_or_2_or_3",
match_any = [":condition1", ":condition2", ":condition3"],
)
selects.config_setting_group(
name = "1_or_nothing_else",
match_any = [":condition1"],
)
###################################################
# Support code for config_setting_group tests
###################################################
def _set_conditions(condition_list):
"""Returns an argument for config_settings that sets specific options.
Args:
condition_list: a list of three booleans
Returns:
a dictionary parameter for config_settings such that ":conditionN" is True
iff condition_list[N + 1] is True
"""
if len(condition_list) != 3:
fail("condition_list must be a list of 3 booleans")
ans = {}
if condition_list[0]:
ans["//command_line_option:cpu"] = "ppc"
else:
ans["//command_line_option:cpu"] = "k8"
if condition_list[1]:
ans["//command_line_option:compilation_mode"] = "opt"
else:
ans["//command_line_option:compilation_mode"] = "dbg"
if condition_list[2]:
ans["//command_line_option:features"] = ["myfeature"]
else:
ans["//command_line_option:features"] = ["notmyfeature"]
return ans
_BooleanInfo = provider(
doc = "value for boolean tests",
fields = ["value"],
)
def _boolean_attr_impl(ctx):
return [_BooleanInfo(value = ctx.attr.myboolean)]
boolean_attr_rule = rule(
implementation = _boolean_attr_impl,
attrs = {"myboolean": attr.bool()},
)
def _expect_matches(ctx):
"""Generic test implementation expecting myboolean == True."""
env = analysistest.begin(ctx)
attrval = analysistest.target_under_test(env)[_BooleanInfo].value
asserts.equals(env, True, attrval)
return analysistest.end(env)
def _expect_doesnt_match(ctx):
"""Generic test implementation expecting myboolean == False."""
env = analysistest.begin(ctx)
attrval = analysistest.target_under_test(env)[_BooleanInfo].value
asserts.equals(env, False, attrval)
return analysistest.end(env)
def _config_setting_group_test(name, config_settings):
return analysistest.make()
###################################################
# and_config_setting_group_matches_test
###################################################
and_config_setting_group_matches_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([True, True, True]),
)
def _and_config_setting_group_matches_test():
"""Test verifying match on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_matches_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_matches_test(
name = "and_config_setting_group_matches_test",
target_under_test = ":and_config_setting_group_matches_rule",
)
###################################################
# and_config_setting_group_first_match_fails_test
###################################################
and_config_setting_group_first_match_fails_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([False, True, True]),
)
def _and_config_setting_group_first_match_fails_test():
"""Test verifying first condition mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_first_match_fails_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_first_match_fails_test(
name = "and_config_setting_group_first_match_fails_test",
target_under_test = ":and_config_setting_group_first_match_fails_rule",
)
###################################################
# and_config_setting_group_middle_match_fails_test
###################################################
and_config_setting_group_middle_match_fails_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([True, False, True]),
)
def _and_config_setting_group_middle_match_fails_test():
"""Test verifying middle condition mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_middle_match_fails_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_middle_match_fails_test(
name = "and_config_setting_group_middle_match_fails_test",
target_under_test = ":and_config_setting_group_middle_match_fails_rule",
)
###################################################
# and_config_setting_group_last_match_fails_test
###################################################
and_config_setting_group_last_match_fails_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([True, True, False]),
)
def _and_config_setting_group_last_match_fails_test():
"""Test verifying last condition mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_last_match_fails_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_last_match_fails_test(
name = "and_config_setting_group_last_match_fails_test",
target_under_test = ":and_config_setting_group_last_match_fails_rule",
)
###################################################
# and_config_setting_group_multiple_matches_fail_test
###################################################
and_config_setting_group_multiple_matches_fail_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([True, False, False]),
)
def _and_config_setting_group_multiple_matches_fail_test():
"""Test verifying multple conditions mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_multiple_matches_fail_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_multiple_matches_fail_test(
name = "and_config_setting_group_multiple_matches_fail_test",
target_under_test = ":and_config_setting_group_multiple_matches_fail_rule",
)
###################################################
# and_config_setting_group_all_matches_fail_test
###################################################
and_config_setting_group_all_matches_fail_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([False, False, False]),
)
def _and_config_setting_group_all_matches_fail_test():
"""Test verifying all conditions mismatch on an ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_all_matches_fail_rule",
myboolean = select(
{
":1_and_2_and_3": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_all_matches_fail_test(
name = "and_config_setting_group_all_matches_fail_test",
target_under_test = ":and_config_setting_group_all_matches_fail_rule",
)
###################################################
# and_config_setting_group_single_setting_matches_test
###################################################
and_config_setting_group_single_setting_matches_test = analysistest.make(
_expect_matches,
config_settings = {"//command_line_option:cpu": "ppc"},
)
def _and_config_setting_group_single_setting_matches_test():
"""Test verifying match on single-entry ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_single_setting_matches_rule",
myboolean = select(
{
":1_and_nothing_else": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_single_setting_matches_test(
name = "and_config_setting_group_single_setting_matches_test",
target_under_test = ":and_config_setting_group_single_setting_matches_rule",
)
###################################################
# and_config_setting_group_single_setting_fails_test
###################################################
and_config_setting_group_single_setting_fails_test = analysistest.make(
_expect_doesnt_match,
config_settings = {"//command_line_option:cpu": "x86"},
)
def _and_config_setting_group_single_setting_fails_test():
"""Test verifying no match on single-entry ANDing config_setting_group."""
boolean_attr_rule(
name = "and_config_setting_group_single_setting_fails_rule",
myboolean = select(
{
":1_and_nothing_else": True,
"//conditions:default": False,
},
),
)
and_config_setting_group_single_setting_fails_test(
name = "and_config_setting_group_single_setting_fails_test",
target_under_test = ":and_config_setting_group_single_setting_fails_rule",
)
###################################################
# or_config_setting_group_no_match_test
###################################################
or_config_setting_group_no_matches_test = analysistest.make(
_expect_doesnt_match,
config_settings = _set_conditions([False, False, False]),
)
def _or_config_setting_group_no_matches_test():
"""Test verifying no matches on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_no_matches_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_no_matches_test(
name = "or_config_setting_group_no_matches_test",
target_under_test = ":or_config_setting_group_no_matches_rule",
)
###################################################
# or_config_setting_group_first_cond_matches_test
###################################################
or_config_setting_group_first_cond_matches_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([True, False, False]),
)
def _or_config_setting_group_first_cond_matches_test():
"""Test verifying first condition matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_first_cond_matches_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_first_cond_matches_test(
name = "or_config_setting_group_first_cond_matches_test",
target_under_test = ":or_config_setting_group_first_cond_matches_rule",
)
###################################################
# or_config_setting_group_middle_cond_matches_test
###################################################
or_config_setting_group_middle_cond_matches_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([False, True, False]),
)
def _or_config_setting_group_middle_cond_matches_test():
"""Test verifying middle condition matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_middle_cond_matches_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_middle_cond_matches_test(
name = "or_config_setting_group_middle_cond_matches_test",
target_under_test = ":or_config_setting_group_middle_cond_matches_rule",
)
###################################################
# or_config_setting_group_last_cond_matches_test
###################################################
or_config_setting_group_last_cond_matches_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([False, False, True]),
)
def _or_config_setting_group_last_cond_matches_test():
"""Test verifying last condition matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_last_cond_matches_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_last_cond_matches_test(
name = "or_config_setting_group_last_cond_matches_test",
target_under_test = ":or_config_setting_group_last_cond_matches_rule",
)
###################################################
# or_config_setting_group_multiple_conds_match_test
###################################################
or_config_setting_group_multiple_conds_match_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([False, True, True]),
)
def _or_config_setting_group_multiple_conds_match_test():
"""Test verifying multple conditions matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_multiple_conds_match_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_multiple_conds_match_test(
name = "or_config_setting_group_multiple_conds_match_test",
target_under_test = ":or_config_setting_group_multiple_conds_match_rule",
)
###################################################
# or_config_setting_group_all_conds_match_test
###################################################
or_config_setting_group_all_conds_match_test = analysistest.make(
_expect_matches,
config_settings = _set_conditions([False, True, True]),
)
def _or_config_setting_group_all_conds_match_test():
"""Test verifying all conditions matching on an ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_all_conds_match_rule",
myboolean = select(
{
":1_or_2_or_3": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_all_conds_match_test(
name = "or_config_setting_group_all_conds_match_test",
target_under_test = ":or_config_setting_group_all_conds_match_rule",
)
###################################################
# or_config_setting_group_single_setting_matches_test
###################################################
or_config_setting_group_single_setting_matches_test = analysistest.make(
_expect_matches,
config_settings = {"//command_line_option:cpu": "ppc"},
)
def _or_config_setting_group_single_setting_matches_test():
"""Test verifying match on single-entry ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_single_setting_matches_rule",
myboolean = select(
{
":1_or_nothing_else": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_single_setting_matches_test(
name = "or_config_setting_group_single_setting_matches_test",
target_under_test = ":or_config_setting_group_single_setting_matches_rule",
)
###################################################
# or_config_setting_group_single_setting_fails_test
###################################################
or_config_setting_group_single_setting_fails_test = analysistest.make(
_expect_doesnt_match,
config_settings = {"//command_line_option:cpu": "x86"},
)
def _or_config_setting_group_single_setting_fails_test():
"""Test verifying no match on single-entry ORing config_setting_group."""
boolean_attr_rule(
name = "or_config_setting_group_single_setting_fails_rule",
myboolean = select(
{
":1_or_nothing_else": True,
"//conditions:default": False,
},
),
)
or_config_setting_group_single_setting_fails_test(
name = "or_config_setting_group_single_setting_fails_test",
target_under_test = ":or_config_setting_group_single_setting_fails_rule",
)
###################################################
# always_true_match_all_test
###################################################
always_true_match_all_test = analysistest.make(_expect_matches)
def _always_true_match_all_test():
"""Tests that "match_all=['//conditions:default']" always matches."""
selects.config_setting_group(
name = "all_always_match",
match_all = ["//conditions:default"],
)
boolean_attr_rule(
name = "match_always_true_rule",
myboolean = select(
{
":all_always_match": True,
},
),
)
always_true_match_all_test(
name = "always_true_match_all_test",
target_under_test = ":match_always_true_rule",
)
###################################################
# always_true_match_any_test
###################################################
always_true_match_any_test = analysistest.make(_expect_matches)
def _always_true_match_any_test():
"""Tests that "match_any=['//conditions:default']" always matches."""
selects.config_setting_group(
name = "any_always_match",
match_any = ["//conditions:default"],
)
boolean_attr_rule(
name = "match_any_always_true_rule",
myboolean = select(
{
":any_always_match": True,
},
),
)
always_true_match_any_test(
name = "always_true_match_any_test",
target_under_test = ":match_any_always_true_rule",
)
###################################################
# empty_config_setting_group_not_allowed_test
###################################################
# config_setting_group with no parameters triggers a failure.
# TODO: how do we test this? This requires catching macro
# evaluation failure.
###################################################
# and_and_or_not_allowed_together_test
###################################################
# config_setting_group: setting both match_any and match_or
# triggers a failure.
# TODO: how do we test this? This requires catching macro
# evaluation failure.
###################################################
# buildifier: disable=unnamed-macro
def selects_test_suite():
"""Creates the test targets and test suite for selects.bzl tests."""
unittest.suite(
"selects_tests",
with_or_test,
)
_create_config_settings()
_create_config_setting_groups()
_and_config_setting_group_matches_test()
_and_config_setting_group_first_match_fails_test()
_and_config_setting_group_middle_match_fails_test()
_and_config_setting_group_last_match_fails_test()
_and_config_setting_group_multiple_matches_fail_test()
_and_config_setting_group_all_matches_fail_test()
_and_config_setting_group_single_setting_matches_test()
_and_config_setting_group_single_setting_fails_test()
_or_config_setting_group_no_matches_test()
_or_config_setting_group_first_cond_matches_test()
_or_config_setting_group_middle_cond_matches_test()
_or_config_setting_group_last_cond_matches_test()
_or_config_setting_group_multiple_conds_match_test()
_or_config_setting_group_all_conds_match_test()
_or_config_setting_group_single_setting_matches_test()
_or_config_setting_group_single_setting_fails_test()
_always_true_match_all_test()
_always_true_match_any_test()
# _empty_config_setting_group_not_allowed_test()
# _and_and_or_not_allowed_together_test()