• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""End to end tests for rust toolchains."""
2
3load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
4load("@bazel_skylib//rules:write_file.bzl", "write_file")
5load("//rust:defs.bzl", "rust_library")
6load("//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")
7
8EXEC_TOOLCHAIN_FLAG = "missing"
9TOOLCHAIN_FLAG = "before"
10CONFIG_FLAG = "after"
11
12def _toolchain_adds_rustc_flags_impl(ctx):
13    """ Tests adding extra_rustc_flags on the toolchain, asserts that:
14
15    - extra_rustc_flags added by the toolchain are applied BEFORE flags added by a config on the commandline
16    - The exec flags from the toolchain don't go on the commandline for a non-exec target
17    """
18    env = analysistest.begin(ctx)
19    target = analysistest.target_under_test(env)
20    action = target[DepActionsInfo].actions[0]
21
22    asserts.equals(env, "Rustc", action.mnemonic)
23
24    asserts.true(
25        env,
26        action.argv[-2:] == [TOOLCHAIN_FLAG, CONFIG_FLAG],
27        "Unexpected rustc flags: {}\nShould have ended with: {}".format(
28            action.argv,
29            [TOOLCHAIN_FLAG, CONFIG_FLAG],
30        ),
31    )
32
33    asserts.true(
34        env,
35        EXEC_TOOLCHAIN_FLAG not in action.argv,
36        "Found exec toolchain flag ({}) in rustc flags: {}".format(EXEC_TOOLCHAIN_FLAG, action.argv),
37    )
38
39    found_sysroot = False
40    for arg in action.argv:
41        if arg.startswith("--sysroot") and arg.endswith("test/toolchain/rust_extra_flags_toolchain"):
42            found_sysroot = True
43    asserts.true(
44        env,
45        found_sysroot,
46        "Missing --sysroot flag or --sysroot does not point to correct sysroot directory",
47    )
48
49    return analysistest.end(env)
50
51toolchain_adds_rustc_flags_test = analysistest.make(
52    _toolchain_adds_rustc_flags_impl,
53    config_settings = {
54        str(Label("//:extra_rustc_flags")): [CONFIG_FLAG],
55        str(Label("//rust/settings:experimental_toolchain_generated_sysroot")): True,
56    },
57)
58
59def _extra_toolchain_transition_impl(settings, _attr):
60    return {"//command_line_option:extra_toolchains": [
61        "@rules_rust//test/toolchain:extra_flags_toolchain",
62    ] + settings["//command_line_option:extra_toolchains"]}
63
64_extra_toolchain_transition = transition(
65    implementation = _extra_toolchain_transition_impl,
66    inputs = ["//command_line_option:extra_toolchains"],
67    outputs = ["//command_line_option:extra_toolchains"],
68)
69
70DepActionsInfo = provider(
71    "Contains information about dependencies actions.",
72    fields = {"actions": "List[Action]"},
73)
74
75def _collect_dep_actions_aspect_impl(target, ctx):
76    actions = []
77    actions.extend(target.actions)
78    for dep in ctx.rule.attr.deps:
79        actions.extend(dep[DepActionsInfo].actions)
80    return [DepActionsInfo(actions = actions)]
81
82collect_dep_actions_aspect = aspect(
83    implementation = _collect_dep_actions_aspect_impl,
84    attr_aspects = ["deps"],
85)
86
87def _extra_toolchain_wrapper_impl(ctx):
88    return [ctx.attr.dep[DepActionsInfo]]
89
90extra_toolchain_wrapper = rule(
91    implementation = _extra_toolchain_wrapper_impl,
92    attrs = {
93        "dep": attr.label(aspects = [collect_dep_actions_aspect]),
94        "_allowlist_function_transition": attr.label(
95            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
96        ),
97    },
98    cfg = _extra_toolchain_transition,
99)
100
101def _define_targets():
102    rust_library(
103        name = "lib",
104        srcs = ["lib.rs"],
105        edition = "2021",
106    )
107
108    native.filegroup(
109        name = "stdlib_srcs",
110        srcs = ["config.txt"],
111    )
112    rust_stdlib_filegroup(
113        name = "std_libs",
114        srcs = [":stdlib_srcs"],
115    )
116    write_file(
117        name = "mock_rustc",
118        out = "mock_rustc.exe",
119        content = [],
120        is_executable = True,
121    )
122    write_file(
123        name = "mock_rustdoc",
124        out = "mock_rustdoc.exe",
125        content = [],
126        is_executable = True,
127    )
128
129    rust_toolchain(
130        name = "rust_extra_flags_toolchain",
131        binary_ext = "",
132        dylib_ext = ".so",
133        exec_triple = "x86_64-unknown-none",
134        target_triple = "x86_64-unknown-none",
135        rust_doc = ":mock_rustdoc",
136        rust_std = ":std_libs",
137        rustc = ":mock_rustc",
138        staticlib_ext = ".a",
139        stdlib_linkflags = [],
140        extra_rustc_flags = [TOOLCHAIN_FLAG],
141        extra_exec_rustc_flags = [EXEC_TOOLCHAIN_FLAG],
142        visibility = ["//visibility:public"],
143    )
144
145    native.toolchain(
146        name = "extra_flags_toolchain",
147        toolchain = ":rust_extra_flags_toolchain",
148        toolchain_type = "@rules_rust//rust:toolchain",
149    )
150
151    extra_toolchain_wrapper(
152        name = "lib_with_extra_toolchain",
153        dep = ":lib",
154    )
155
156def _rust_stdlib_filegroup_provides_runfiles_test_impl(ctx):
157    env = analysistest.begin(ctx)
158    target = analysistest.target_under_test(env)
159    runfiles = target[DefaultInfo].default_runfiles
160    asserts.true(env, len(runfiles.files.to_list()) > 0)
161
162    return analysistest.end(env)
163
164rust_stdlib_filegroup_provides_runfiles_test = analysistest.make(
165    _rust_stdlib_filegroup_provides_runfiles_test_impl,
166)
167
168def toolchain_test_suite(name):
169    _define_targets()
170
171    toolchain_adds_rustc_flags_test(
172        name = "toolchain_adds_rustc_flags_test",
173        target_under_test = ":lib_with_extra_toolchain",
174    )
175
176    rust_stdlib_filegroup_provides_runfiles_test(
177        name = "rust_stdlib_filegroup_provides_runfiles_test",
178        target_under_test = ":std_libs",
179    )
180
181    native.test_suite(
182        name = name,
183        tests = [
184            ":toolchain_adds_rustc_flags_test",
185            ":rust_stdlib_filegroup_provides_runfiles_test",
186        ],
187    )
188