blob: 871808d38da433de9779a19353329a678de0a51e [file] [log] [blame]
"""Unittest to verify workspace status stamping is applied to environment files"""
load("@bazel_skylib//lib:unittest.bzl", "analysistest")
load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_test")
load(
"//test/unit:common.bzl",
"assert_action_mnemonic",
"assert_argv_contains",
"assert_argv_contains_not",
)
_STAMP_ATTR_VALUES = (0, 1, -1)
_BUILD_FLAG_VALUES = ("true", "false")
def _assert_stamped(env, action):
assert_argv_contains(env, action, "--volatile-status-file")
assert_argv_contains(env, action, "bazel-out/volatile-status.txt")
assert_argv_contains(env, action, "--stable-status-file")
assert_argv_contains(env, action, "bazel-out/stable-status.txt")
def _assert_not_stamped(env, action):
assert_argv_contains_not(env, action, "--volatile-status-file")
assert_argv_contains_not(env, action, "bazel-out/volatile-status.txt")
assert_argv_contains_not(env, action, "--stable-status-file")
assert_argv_contains_not(env, action, "bazel-out/stable-status.txt")
def _stamp_build_flag_test_impl(ctx, flag_value):
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
action = target.actions[0]
assert_action_mnemonic(env, action, "Rustc")
is_test = target[rust_common.crate_info].is_test
is_bin = target[rust_common.crate_info].type == "bin"
# bazel build --stamp should lead to stamped rust binaries, but not
# libraries and tests.
if flag_value:
if is_bin and not is_test:
_assert_stamped(env, action)
else:
_assert_not_stamped(env, action)
else:
_assert_not_stamped(env, action)
return analysistest.end(env)
def _stamp_build_flag_is_true_impl(ctx):
return _stamp_build_flag_test_impl(ctx, True)
def _stamp_build_flag_is_false_impl(ctx):
return _stamp_build_flag_test_impl(ctx, False)
stamp_build_flag_is_true_test = analysistest.make(
_stamp_build_flag_is_true_impl,
config_settings = {
"//command_line_option:stamp": True,
},
)
stamp_build_flag_is_false_test = analysistest.make(
_stamp_build_flag_is_false_impl,
config_settings = {
"//command_line_option:stamp": False,
},
)
def _build_flag_tests():
tests = []
for stamp_value in _BUILD_FLAG_VALUES:
if stamp_value == "true":
name = "default_with_build_flag_on"
features = ["always_stamp"]
build_flag_stamp_test = stamp_build_flag_is_true_test
else:
name = "default_with_build_flag_off"
features = ["never_stamp"]
build_flag_stamp_test = stamp_build_flag_is_false_test
rust_library(
name = "{}_lib".format(name),
srcs = ["stamp.rs"],
rustc_env_files = ["stamp.env"],
edition = "2018",
# Building with --stamp should not affect rust libraries
crate_features = ["never_stamp"],
)
rust_binary(
name = "{}_bin".format(name),
srcs = ["stamp_main.rs"],
edition = "2018",
deps = ["{}_lib".format(name)],
rustc_env_files = ["stamp.env"],
crate_features = features,
)
rust_test(
name = "{}_test".format(name),
crate = "{}_lib".format(name),
edition = "2018",
rustc_env_files = ["stamp.env"],
# Building with --stamp should not affect tests
crate_features = ["never_stamp"],
)
build_flag_stamp_test(
name = "lib_{}_test".format(name),
target_under_test = "{}_lib".format(name),
)
build_flag_stamp_test(
name = "bin_{}_test".format(name),
target_under_test = "{}_bin".format(name),
)
build_flag_stamp_test(
name = "test_{}_test".format(name),
target_under_test = "{}_test".format(name),
)
tests.extend([
"lib_{}_test".format(name),
"bin_{}_test".format(name),
"test_{}_test".format(name),
])
return tests
def _attribute_stamp_test_impl(ctx, attribute_value, build_flag_value):
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
action = target.actions[0]
assert_action_mnemonic(env, action, "Rustc")
if attribute_value == 1:
_assert_stamped(env, action)
elif attribute_value == 0:
_assert_not_stamped(env, action)
elif build_flag_value:
_assert_stamped(env, action)
else:
_assert_not_stamped(env, action)
return analysistest.end(env)
def _always_stamp_build_flag_is_true_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = 1, build_flag_value = True)
def _always_stamp_build_flag_is_false_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = 1, build_flag_value = False)
def _never_stamp_build_flag_is_true_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = 0, build_flag_value = True)
def _never_stamp_build_flag_is_false_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = 0, build_flag_value = False)
def _consult_build_flag_value_is_true_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = -1, build_flag_value = True)
def _consult_build_flag_value_is_false_test_impl(ctx):
return _attribute_stamp_test_impl(ctx, attribute_value = -1, build_flag_value = False)
always_stamp_test_build_flag_is_true_test = analysistest.make(
_always_stamp_build_flag_is_true_test_impl,
config_settings = {
"//command_line_option:stamp": True,
},
)
always_stamp_test_build_flag_is_false_test = analysistest.make(
_always_stamp_build_flag_is_false_test_impl,
config_settings = {
"//command_line_option:stamp": False,
},
)
never_stamp_test_build_flag_is_true_test = analysistest.make(
_never_stamp_build_flag_is_true_test_impl,
config_settings = {
"//command_line_option:stamp": True,
},
)
never_stamp_test_build_flag_is_false_test = analysistest.make(
_never_stamp_build_flag_is_false_test_impl,
config_settings = {
"//command_line_option:stamp": False,
},
)
consult_build_flag_value_is_true_test = analysistest.make(
_consult_build_flag_value_is_true_test_impl,
config_settings = {
"//command_line_option:stamp": True,
},
)
consult_build_flag_value_is_false_test = analysistest.make(
_consult_build_flag_value_is_false_test_impl,
config_settings = {
"//command_line_option:stamp": False,
},
)
def _stamp_attribute_tests():
tests = []
for stamp_value in _STAMP_ATTR_VALUES:
for flag_value in _BUILD_FLAG_VALUES:
if stamp_value == 1:
name = "always_stamp_build_flag_{}".format(flag_value)
features = ["always_stamp_build_flag_{}".format(flag_value)]
stamp_attr_test = always_stamp_test_build_flag_is_true_test if flag_value == "true" else always_stamp_test_build_flag_is_false_test
elif stamp_value == 0:
name = "never_stamp_build_flag_{}".format(flag_value)
features = ["never_stamp_build_flag_{}".format(flag_value)]
stamp_attr_test = never_stamp_test_build_flag_is_true_test if flag_value == "true" else never_stamp_test_build_flag_is_false_test
else:
name = "consult_cmdline_value_is_{}".format(flag_value)
features = ["consult_cmdline_value_is_{}".format(flag_value)]
stamp_attr_test = consult_build_flag_value_is_true_test if flag_value == "true" else consult_build_flag_value_is_false_test
rust_library(
name = "{}_lib".format(name),
srcs = ["stamp.rs"],
edition = "2018",
rustc_env_files = [":stamp.env"],
stamp = stamp_value,
crate_features = features,
)
rust_test(
name = "{}_unit_test".format(name),
crate = ":{}_lib".format(name),
edition = "2018",
rustc_env_files = [":stamp.env"],
stamp = stamp_value,
crate_features = features,
# We disable this test so that it doesn't try to run with bazel test //test/...
# The reason for this is because then it is sensitive to the --stamp value which
# we override in the unit test implementation.
tags = ["manual"],
)
rust_binary(
name = "{}_bin".format(name),
srcs = ["stamp_main.rs"],
edition = "2018",
deps = [":{}_lib".format(name)],
rustc_env_files = [":stamp.env"],
stamp = stamp_value,
crate_features = features,
)
stamp_attr_test(
name = "lib_{}_test".format(name),
target_under_test = "{}_lib".format(name),
)
stamp_attr_test(
name = "bin_{}_test".format(name),
target_under_test = "{}_bin".format(name),
)
stamp_attr_test(
name = "test_{}_test".format(name),
target_under_test = "{}_unit_test".format(name),
)
tests.extend([
"lib_{}_test".format(name),
"bin_{}_test".format(name),
"test_{}_test".format(name),
])
return tests
def _process_wrapper_with_stamp_test_impl(ctx):
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
action = target.actions[0]
assert_action_mnemonic(env, action, "Rustc")
_assert_not_stamped(env, action)
return analysistest.end(env)
process_wrapper_with_stamp_test = analysistest.make(
_process_wrapper_with_stamp_test_impl,
config_settings = {
"//command_line_option:stamp": True,
},
)
def _process_wrapper_tests():
process_wrapper_with_stamp_test(
name = "test_process_wrapper_with_stamp_test",
target_under_test = "//util/process_wrapper:process_wrapper",
)
return ["test_process_wrapper_with_stamp_test"]
def stamp_test_suite(name):
"""Entry-point macro called from the BUILD file.
Args:
name (str): Name of the macro.
"""
tests = _build_flag_tests() + _stamp_attribute_tests() + _process_wrapper_tests()
native.test_suite(
name = name,
tests = tests,
)