1"""Unittests for propagation of linker inputs through Rust libraries"""
2
3load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
4
5def _shared_lib_is_propagated_test_impl(ctx):
6    env = analysistest.begin(ctx)
7    tut = analysistest.target_under_test(env)
8    link_action = [action for action in tut.actions if action.mnemonic == "CppLink"][0]
9
10    lib_name = _get_lib_name(ctx, name = "foo_shared")
11    asserts.true(env, _contains_input(link_action.inputs, lib_name))
12
13    return analysistest.end(env)
14
15def _static_lib_is_not_propagated_test_impl(ctx):
16    env = analysistest.begin(ctx)
17    tut = analysistest.target_under_test(env)
18    link_action = [action for action in tut.actions if action.mnemonic == "CppLink"][0]
19
20    lib_name = _get_lib_name(ctx, name = "foo")
21    asserts.false(env, _contains_input(link_action.inputs, lib_name))
22
23    return analysistest.end(env)
24
25def _contains_input(inputs, name):
26    for input in inputs.to_list():
27        # We cannot check for name equality because rlib outputs contain
28        # a hash in their name.
29        if input.basename.startswith(name):
30            return True
31    return False
32
33def _get_lib_name(ctx, name):
34    if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
35        return name
36    else:
37        return "lib{}".format(name)
38
39static_lib_is_not_propagated_test = analysistest.make(
40    _static_lib_is_not_propagated_test_impl,
41    attrs = {
42        "_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
43    },
44)
45
46shared_lib_is_propagated_test = analysistest.make(
47    _shared_lib_is_propagated_test_impl,
48    attrs = {
49        "_macos_constraint": attr.label(default = Label("@platforms//os:macos")),
50        "_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
51    },
52)
53
54def _linker_inputs_propagation_test():
55    static_lib_is_not_propagated_test(
56        name = "depends_on_foo_via_staticlib",
57        target_under_test = "//test/linker_inputs_propagation:depends_on_foo_via_staticlib",
58    )
59
60    shared_lib_is_propagated_test(
61        name = "depends_on_shared_foo_via_staticlib",
62        target_under_test = "//test/linker_inputs_propagation:depends_on_shared_foo_via_staticlib",
63    )
64
65    static_lib_is_not_propagated_test(
66        name = "depends_on_foo_via_sharedlib",
67        target_under_test = "//test/linker_inputs_propagation:depends_on_foo_via_sharedlib",
68    )
69
70    shared_lib_is_propagated_test(
71        name = "depends_on_shared_foo_via_sharedlib",
72        target_under_test = "//test/linker_inputs_propagation:depends_on_shared_foo_via_sharedlib",
73    )
74
75def linker_inputs_propagation_test_suite(name):
76    """Entry-point macro called from the BUILD file.
77
78    Args:
79        name: Name of the macro.
80    """
81    _linker_inputs_propagation_test()
82
83    native.test_suite(
84        name = name,
85        tests = [
86            ":depends_on_foo_via_staticlib",
87            ":depends_on_shared_foo_via_staticlib",
88            ":depends_on_foo_via_sharedlib",
89            ":depends_on_shared_foo_via_sharedlib",
90        ],
91    )
92