xref: /aosp_15_r20/external/bazelbuild-rules_rust/test/toolchain/toolchain_test.bzl (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1*d4726bddSHONG Yifan"""End to end tests for rust toolchains."""
2*d4726bddSHONG Yifan
3*d4726bddSHONG Yifanload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
4*d4726bddSHONG Yifanload("@bazel_skylib//rules:write_file.bzl", "write_file")
5*d4726bddSHONG Yifanload("//rust:defs.bzl", "rust_library", "rust_shared_library")
6*d4726bddSHONG Yifanload("//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")
7*d4726bddSHONG Yifan
8*d4726bddSHONG YifanEXEC_TOOLCHAIN_FLAG = "missing"
9*d4726bddSHONG YifanTOOLCHAIN_FLAG = "before"
10*d4726bddSHONG YifanCONFIG_FLAG = "after"
11*d4726bddSHONG YifanCRATE_FLAGS = {"cdylib": ["cdylib_flag"], "rlib": ["rlib_flag"]}
12*d4726bddSHONG Yifan
13*d4726bddSHONG Yifandef _toolchain_adds_rustc_flags_impl(ctx, crate_type):
14*d4726bddSHONG Yifan    """ Tests adding extra_rustc_flags on the toolchain, asserts that:
15*d4726bddSHONG Yifan
16*d4726bddSHONG Yifan    - extra_rustc_flags added by the toolchain are applied BEFORE flags added by a config on the commandline
17*d4726bddSHONG Yifan    - The exec flags from the toolchain don't go on the commandline for a non-exec target
18*d4726bddSHONG Yifan    - crate type rustc flags are added
19*d4726bddSHONG Yifan    """
20*d4726bddSHONG Yifan    env = analysistest.begin(ctx)
21*d4726bddSHONG Yifan    target = analysistest.target_under_test(env)
22*d4726bddSHONG Yifan    action = target[DepActionsInfo].actions[0]
23*d4726bddSHONG Yifan
24*d4726bddSHONG Yifan    asserts.equals(env, "Rustc", action.mnemonic)
25*d4726bddSHONG Yifan
26*d4726bddSHONG Yifan    asserts.true(
27*d4726bddSHONG Yifan        env,
28*d4726bddSHONG Yifan        action.argv[-2:] == [TOOLCHAIN_FLAG, CONFIG_FLAG],
29*d4726bddSHONG Yifan        "Unexpected rustc flags: {}\nShould have ended with: {}".format(
30*d4726bddSHONG Yifan            action.argv,
31*d4726bddSHONG Yifan            [TOOLCHAIN_FLAG, CONFIG_FLAG],
32*d4726bddSHONG Yifan        ),
33*d4726bddSHONG Yifan    )
34*d4726bddSHONG Yifan
35*d4726bddSHONG Yifan    asserts.true(
36*d4726bddSHONG Yifan        env,
37*d4726bddSHONG Yifan        action.argv[-3] == CRATE_FLAGS[crate_type][0],
38*d4726bddSHONG Yifan        "Unexpected rustc flags: {}\nShould have contained: {}".format(
39*d4726bddSHONG Yifan            action.argv,
40*d4726bddSHONG Yifan            CRATE_FLAGS["rlib"],
41*d4726bddSHONG Yifan        ),
42*d4726bddSHONG Yifan    )
43*d4726bddSHONG Yifan
44*d4726bddSHONG Yifan    for type in CRATE_FLAGS.keys():
45*d4726bddSHONG Yifan        if type == crate_type:
46*d4726bddSHONG Yifan            continue
47*d4726bddSHONG Yifan        asserts.false(
48*d4726bddSHONG Yifan            env,
49*d4726bddSHONG Yifan            CRATE_FLAGS[type][0] in action.argv,
50*d4726bddSHONG Yifan            "Unexpected rustc flags: {}\nShould not contain: {}".format(
51*d4726bddSHONG Yifan                action.argv,
52*d4726bddSHONG Yifan                CRATE_FLAGS[type],
53*d4726bddSHONG Yifan            ),
54*d4726bddSHONG Yifan        )
55*d4726bddSHONG Yifan
56*d4726bddSHONG Yifan    asserts.true(
57*d4726bddSHONG Yifan        env,
58*d4726bddSHONG Yifan        EXEC_TOOLCHAIN_FLAG not in action.argv,
59*d4726bddSHONG Yifan        "Found exec toolchain flag ({}) in rustc flags: {}".format(EXEC_TOOLCHAIN_FLAG, action.argv),
60*d4726bddSHONG Yifan    )
61*d4726bddSHONG Yifan
62*d4726bddSHONG Yifan    found_sysroot = False
63*d4726bddSHONG Yifan    for arg in action.argv:
64*d4726bddSHONG Yifan        if arg.startswith("--sysroot") and arg.endswith("test/toolchain/rust_extra_flags_toolchain"):
65*d4726bddSHONG Yifan            found_sysroot = True
66*d4726bddSHONG Yifan    asserts.true(
67*d4726bddSHONG Yifan        env,
68*d4726bddSHONG Yifan        found_sysroot,
69*d4726bddSHONG Yifan        "Missing --sysroot flag or --sysroot does not point to correct sysroot directory",
70*d4726bddSHONG Yifan    )
71*d4726bddSHONG Yifan
72*d4726bddSHONG Yifan    return analysistest.end(env)
73*d4726bddSHONG Yifan
74*d4726bddSHONG Yifandef _toolchain_adds_rustc_flags_lib_impl(ctx):
75*d4726bddSHONG Yifan    return _toolchain_adds_rustc_flags_impl(ctx, "rlib")
76*d4726bddSHONG Yifan
77*d4726bddSHONG Yifandef _toolchain_adds_rustc_flags_shared_lib_impl(ctx):
78*d4726bddSHONG Yifan    return _toolchain_adds_rustc_flags_impl(ctx, "cdylib")
79*d4726bddSHONG Yifan
80*d4726bddSHONG Yifantoolchain_adds_rustc_flags_lib_test = analysistest.make(
81*d4726bddSHONG Yifan    _toolchain_adds_rustc_flags_lib_impl,
82*d4726bddSHONG Yifan    config_settings = {
83*d4726bddSHONG Yifan        str(Label("//:extra_rustc_flags")): [CONFIG_FLAG],
84*d4726bddSHONG Yifan        str(Label("//rust/settings:experimental_toolchain_generated_sysroot")): True,
85*d4726bddSHONG Yifan    },
86*d4726bddSHONG Yifan)
87*d4726bddSHONG Yifan
88*d4726bddSHONG Yifantoolchain_adds_rustc_flags_shared_lib_test = analysistest.make(
89*d4726bddSHONG Yifan    _toolchain_adds_rustc_flags_shared_lib_impl,
90*d4726bddSHONG Yifan    config_settings = {
91*d4726bddSHONG Yifan        str(Label("//:extra_rustc_flags")): [CONFIG_FLAG],
92*d4726bddSHONG Yifan        str(Label("//rust/settings:experimental_toolchain_generated_sysroot")): True,
93*d4726bddSHONG Yifan    },
94*d4726bddSHONG Yifan)
95*d4726bddSHONG Yifan
96*d4726bddSHONG Yifandef _extra_toolchain_transition_impl(settings, _attr):
97*d4726bddSHONG Yifan    return {"//command_line_option:extra_toolchains": [
98*d4726bddSHONG Yifan        "@rules_rust//test/toolchain:extra_flags_toolchain",
99*d4726bddSHONG Yifan    ] + settings["//command_line_option:extra_toolchains"]}
100*d4726bddSHONG Yifan
101*d4726bddSHONG Yifan_extra_toolchain_transition = transition(
102*d4726bddSHONG Yifan    implementation = _extra_toolchain_transition_impl,
103*d4726bddSHONG Yifan    inputs = ["//command_line_option:extra_toolchains"],
104*d4726bddSHONG Yifan    outputs = ["//command_line_option:extra_toolchains"],
105*d4726bddSHONG Yifan)
106*d4726bddSHONG Yifan
107*d4726bddSHONG YifanDepActionsInfo = provider(
108*d4726bddSHONG Yifan    "Contains information about dependencies actions.",
109*d4726bddSHONG Yifan    fields = {"actions": "List[Action]"},
110*d4726bddSHONG Yifan)
111*d4726bddSHONG Yifan
112*d4726bddSHONG Yifandef _collect_dep_actions_aspect_impl(target, ctx):
113*d4726bddSHONG Yifan    actions = []
114*d4726bddSHONG Yifan    actions.extend(target.actions)
115*d4726bddSHONG Yifan    for dep in ctx.rule.attr.deps:
116*d4726bddSHONG Yifan        actions.extend(dep[DepActionsInfo].actions)
117*d4726bddSHONG Yifan    return [DepActionsInfo(actions = actions)]
118*d4726bddSHONG Yifan
119*d4726bddSHONG Yifancollect_dep_actions_aspect = aspect(
120*d4726bddSHONG Yifan    implementation = _collect_dep_actions_aspect_impl,
121*d4726bddSHONG Yifan    attr_aspects = ["deps"],
122*d4726bddSHONG Yifan)
123*d4726bddSHONG Yifan
124*d4726bddSHONG Yifandef _extra_toolchain_wrapper_impl(ctx):
125*d4726bddSHONG Yifan    return [ctx.attr.dep[DepActionsInfo]]
126*d4726bddSHONG Yifan
127*d4726bddSHONG Yifanextra_toolchain_wrapper = rule(
128*d4726bddSHONG Yifan    implementation = _extra_toolchain_wrapper_impl,
129*d4726bddSHONG Yifan    attrs = {
130*d4726bddSHONG Yifan        "dep": attr.label(aspects = [collect_dep_actions_aspect]),
131*d4726bddSHONG Yifan        "_allowlist_function_transition": attr.label(
132*d4726bddSHONG Yifan            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
133*d4726bddSHONG Yifan        ),
134*d4726bddSHONG Yifan    },
135*d4726bddSHONG Yifan    cfg = _extra_toolchain_transition,
136*d4726bddSHONG Yifan)
137*d4726bddSHONG Yifan
138*d4726bddSHONG Yifandef _define_targets():
139*d4726bddSHONG Yifan    rust_library(
140*d4726bddSHONG Yifan        name = "lib",
141*d4726bddSHONG Yifan        srcs = ["lib.rs"],
142*d4726bddSHONG Yifan        edition = "2021",
143*d4726bddSHONG Yifan    )
144*d4726bddSHONG Yifan
145*d4726bddSHONG Yifan    rust_shared_library(
146*d4726bddSHONG Yifan        name = "shared_lib",
147*d4726bddSHONG Yifan        srcs = ["lib.rs"],
148*d4726bddSHONG Yifan        edition = "2021",
149*d4726bddSHONG Yifan    )
150*d4726bddSHONG Yifan
151*d4726bddSHONG Yifan    native.filegroup(
152*d4726bddSHONG Yifan        name = "stdlib_srcs",
153*d4726bddSHONG Yifan        srcs = ["config.txt"],
154*d4726bddSHONG Yifan    )
155*d4726bddSHONG Yifan    rust_stdlib_filegroup(
156*d4726bddSHONG Yifan        name = "std_libs",
157*d4726bddSHONG Yifan        srcs = [":stdlib_srcs"],
158*d4726bddSHONG Yifan    )
159*d4726bddSHONG Yifan    write_file(
160*d4726bddSHONG Yifan        name = "mock_rustc",
161*d4726bddSHONG Yifan        out = "mock_rustc.exe",
162*d4726bddSHONG Yifan        content = [],
163*d4726bddSHONG Yifan        is_executable = True,
164*d4726bddSHONG Yifan    )
165*d4726bddSHONG Yifan    write_file(
166*d4726bddSHONG Yifan        name = "mock_rustdoc",
167*d4726bddSHONG Yifan        out = "mock_rustdoc.exe",
168*d4726bddSHONG Yifan        content = [],
169*d4726bddSHONG Yifan        is_executable = True,
170*d4726bddSHONG Yifan    )
171*d4726bddSHONG Yifan
172*d4726bddSHONG Yifan    rust_toolchain(
173*d4726bddSHONG Yifan        name = "rust_extra_flags_toolchain",
174*d4726bddSHONG Yifan        binary_ext = "",
175*d4726bddSHONG Yifan        dylib_ext = ".so",
176*d4726bddSHONG Yifan        exec_triple = "x86_64-unknown-none",
177*d4726bddSHONG Yifan        target_triple = "x86_64-unknown-none",
178*d4726bddSHONG Yifan        rust_doc = ":mock_rustdoc",
179*d4726bddSHONG Yifan        rust_std = ":std_libs",
180*d4726bddSHONG Yifan        rustc = ":mock_rustc",
181*d4726bddSHONG Yifan        staticlib_ext = ".a",
182*d4726bddSHONG Yifan        stdlib_linkflags = [],
183*d4726bddSHONG Yifan        extra_rustc_flags = [TOOLCHAIN_FLAG],
184*d4726bddSHONG Yifan        extra_exec_rustc_flags = [EXEC_TOOLCHAIN_FLAG],
185*d4726bddSHONG Yifan        extra_rustc_flags_for_crate_types = CRATE_FLAGS,
186*d4726bddSHONG Yifan        visibility = ["//visibility:public"],
187*d4726bddSHONG Yifan    )
188*d4726bddSHONG Yifan
189*d4726bddSHONG Yifan    native.toolchain(
190*d4726bddSHONG Yifan        name = "extra_flags_toolchain",
191*d4726bddSHONG Yifan        toolchain = ":rust_extra_flags_toolchain",
192*d4726bddSHONG Yifan        toolchain_type = "@rules_rust//rust:toolchain",
193*d4726bddSHONG Yifan    )
194*d4726bddSHONG Yifan
195*d4726bddSHONG Yifan    extra_toolchain_wrapper(
196*d4726bddSHONG Yifan        name = "lib_with_extra_toolchain",
197*d4726bddSHONG Yifan        dep = ":lib",
198*d4726bddSHONG Yifan    )
199*d4726bddSHONG Yifan
200*d4726bddSHONG Yifan    extra_toolchain_wrapper(
201*d4726bddSHONG Yifan        name = "shared_lib_with_extra_toolchain",
202*d4726bddSHONG Yifan        dep = ":shared_lib",
203*d4726bddSHONG Yifan    )
204*d4726bddSHONG Yifan
205*d4726bddSHONG Yifandef _rust_stdlib_filegroup_provides_runfiles_test_impl(ctx):
206*d4726bddSHONG Yifan    env = analysistest.begin(ctx)
207*d4726bddSHONG Yifan    target = analysistest.target_under_test(env)
208*d4726bddSHONG Yifan    runfiles = target[DefaultInfo].default_runfiles
209*d4726bddSHONG Yifan    asserts.true(env, len(runfiles.files.to_list()) > 0)
210*d4726bddSHONG Yifan
211*d4726bddSHONG Yifan    return analysistest.end(env)
212*d4726bddSHONG Yifan
213*d4726bddSHONG Yifanrust_stdlib_filegroup_provides_runfiles_test = analysistest.make(
214*d4726bddSHONG Yifan    _rust_stdlib_filegroup_provides_runfiles_test_impl,
215*d4726bddSHONG Yifan)
216*d4726bddSHONG Yifan
217*d4726bddSHONG Yifandef toolchain_test_suite(name):
218*d4726bddSHONG Yifan    """ Instantiates tests for rust toolchains.
219*d4726bddSHONG Yifan
220*d4726bddSHONG Yifan    Args:
221*d4726bddSHONG Yifan        name: a name for the test suite
222*d4726bddSHONG Yifan    """
223*d4726bddSHONG Yifan    _define_targets()
224*d4726bddSHONG Yifan
225*d4726bddSHONG Yifan    toolchain_adds_rustc_flags_lib_test(
226*d4726bddSHONG Yifan        name = "toolchain_adds_rustc_flags_lib_test",
227*d4726bddSHONG Yifan        target_under_test = ":lib_with_extra_toolchain",
228*d4726bddSHONG Yifan    )
229*d4726bddSHONG Yifan
230*d4726bddSHONG Yifan    toolchain_adds_rustc_flags_shared_lib_test(
231*d4726bddSHONG Yifan        name = "toolchain_adds_rustc_flags_shared_lib_test",
232*d4726bddSHONG Yifan        target_under_test = ":shared_lib_with_extra_toolchain",
233*d4726bddSHONG Yifan    )
234*d4726bddSHONG Yifan
235*d4726bddSHONG Yifan    rust_stdlib_filegroup_provides_runfiles_test(
236*d4726bddSHONG Yifan        name = "rust_stdlib_filegroup_provides_runfiles_test",
237*d4726bddSHONG Yifan        target_under_test = ":std_libs",
238*d4726bddSHONG Yifan    )
239*d4726bddSHONG Yifan
240*d4726bddSHONG Yifan    native.test_suite(
241*d4726bddSHONG Yifan        name = name,
242*d4726bddSHONG Yifan        tests = [
243*d4726bddSHONG Yifan            ":toolchain_adds_rustc_flags_lib_test",
244*d4726bddSHONG Yifan            ":toolchain_adds_rustc_flags_shared_lib_test",
245*d4726bddSHONG Yifan            ":rust_stdlib_filegroup_provides_runfiles_test",
246*d4726bddSHONG Yifan        ],
247*d4726bddSHONG Yifan    )
248