| """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, |
| ) |