Skip to content

Commit d640490

Browse files
committed
add a test and revert the old toolchain integration tests
1 parent a5079f5 commit d640490

File tree

3 files changed

+187
-171
lines changed

3 files changed

+187
-171
lines changed

tests/toolchains/defs.bzl

Lines changed: 4 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -14,190 +14,23 @@
1414

1515
""
1616

17-
load("@pythons_hub//:versions.bzl", "DEFAULT_PYTHON_VERSION", "MINOR_MAPPING")
18-
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
19-
load("@rules_testing//lib:test_suite.bzl", "test_suite")
20-
load("@rules_testing//lib:util.bzl", rt_util = "util")
2117
load("//python:versions.bzl", "PLATFORMS", "TOOL_VERSIONS")
22-
load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility
23-
load("//python/private:full_version.bzl", "full_version") # buildifier: disable=bzl-visibility
24-
load("//python/private:toolchain_types.bzl", "EXEC_TOOLS_TOOLCHAIN_TYPE") # buildifier: disable=bzl-visibility
2518
load("//tests/support:sh_py_run_test.bzl", "py_reconfig_test")
26-
load("//tests/support:support.bzl", "PYTHON_VERSION")
27-
28-
_analysis_tests = []
29-
30-
def _transition_impl(input_settings, attr):
31-
settings = {
32-
PYTHON_VERSION: input_settings[PYTHON_VERSION],
33-
}
34-
if attr.python_version:
35-
settings[PYTHON_VERSION] = attr.python_version
36-
return settings
37-
38-
_python_version_transition = transition(
39-
implementation = _transition_impl,
40-
inputs = [PYTHON_VERSION],
41-
outputs = [PYTHON_VERSION],
42-
)
43-
44-
TestInfo = provider(
45-
doc = "",
46-
fields = {
47-
"got": "",
48-
"want": "",
49-
},
50-
)
51-
52-
def _lock_impl(ctx):
53-
exec_tools = ctx.toolchains[EXEC_TOOLS_TOOLCHAIN_TYPE].exec_tools
54-
got_version = exec_tools.exec_interpreter[platform_common.ToolchainInfo].py3_runtime.interpreter_version_info
55-
return [
56-
TestInfo(
57-
got = "{}.{}.{}".format(
58-
got_version.major,
59-
got_version.minor,
60-
got_version.micro,
61-
),
62-
want = ctx.attr.want_version,
63-
),
64-
]
65-
66-
_simple_transition = rule(
67-
implementation = _lock_impl,
68-
attrs = {
69-
"python_version": attr.string(
70-
doc = "Public, see the docs in the macro.",
71-
),
72-
"want_version": attr.string(
73-
doc = "Public, see the docs in the macro.",
74-
),
75-
"_allowlist_function_transition": attr.label(
76-
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
77-
),
78-
},
79-
toolchains = [
80-
EXEC_TOOLS_TOOLCHAIN_TYPE,
81-
],
82-
cfg = _python_version_transition,
83-
)
84-
85-
def _test_toolchain_precedence(name):
86-
# First we expect the transitions with a specific version to always
87-
# give us that specific version
88-
exact_version_tests = {
89-
(v, v): v.replace(".", "_")
90-
for v in TOOL_VERSIONS
91-
}
92-
93-
if BZLMOD_ENABLED:
94-
# Then we expect to get the version in the MINOR_MAPPING if we provide
95-
# the version from the MINOR_MAPPING
96-
minor_mapping_tests = {
97-
(minor, full): minor.replace(".", "_")
98-
for minor, full in MINOR_MAPPING.items()
99-
}
100-
101-
# Lastly, if we don't provide any version to the transition, we should
102-
# get the default version
103-
default_version = full_version(
104-
version = DEFAULT_PYTHON_VERSION,
105-
minor_mapping = MINOR_MAPPING,
106-
)
107-
default_version_tests = {
108-
(None, default_version): "default",
109-
}
110-
tests = exact_version_tests | minor_mapping_tests | default_version_tests
111-
else:
112-
# Outside bzlmod the default version and the minor mapping tests do not
113-
# make sense because the user loading things in the WORKSPACE ultimately defines
114-
# the matching order.
115-
tests = exact_version_tests
116-
117-
analysis_test(
118-
name = name,
119-
impl = _test_toolchain_precedence_impl,
120-
targets = {
121-
"{}_{}".format(name, test_name): rt_util.helper_target(
122-
_simple_transition,
123-
name = "{}_{}".format(name, test_name),
124-
python_version = input_version,
125-
want_version = want_version,
126-
)
127-
for (input_version, want_version), test_name in tests.items()
128-
},
129-
)
130-
131-
def _test_toolchain_precedence_impl(env, targets):
132-
# Check that the forwarded PyRuntimeInfo looks vaguely correct.
133-
for target in dir(targets):
134-
test_info = env.expect.that_target(target).provider(
135-
TestInfo,
136-
factory = lambda v, meta: v,
137-
)
138-
env.expect.that_str(test_info.got).equals(test_info.want)
139-
140-
_analysis_tests.append(_test_toolchain_precedence)
14119

14220
def define_toolchain_tests(name):
14321
"""Define the toolchain tests.
14422
14523
Args:
14624
name: Only present to satisfy tooling.
14725
"""
148-
test_suite(
149-
name = name,
150-
tests = _analysis_tests,
151-
)
152-
15326
for platform_key, platform_info in PLATFORMS.items():
15427
native.config_setting(
15528
name = "_is_{}".format(platform_key),
15629
flag_values = platform_info.flag_values,
15730
constraint_values = platform_info.compatible_with,
15831
)
15932

160-
# First we expect the transitions with a specific version to always
161-
# give us that specific version
162-
exact_version_tests = {
163-
(v, v): "python_{}_test".format(v)
164-
for v in TOOL_VERSIONS
165-
}
166-
native.test_suite(
167-
name = "exact_version_tests",
168-
tests = exact_version_tests.values(),
169-
)
170-
171-
if BZLMOD_ENABLED:
172-
# Then we expect to get the version in the MINOR_MAPPING if we provide
173-
# the version from the MINOR_MAPPING
174-
minor_mapping_tests = {
175-
(minor, full): "python_{}_test".format(minor)
176-
for minor, full in MINOR_MAPPING.items()
177-
}
178-
native.test_suite(
179-
name = "minor_mapping_tests",
180-
tests = minor_mapping_tests.values(),
181-
)
182-
183-
# Lastly, if we don't provide any version to the transition, we should
184-
# get the default version
185-
default_version = full_version(
186-
version = DEFAULT_PYTHON_VERSION,
187-
minor_mapping = MINOR_MAPPING,
188-
)
189-
default_version_tests = {
190-
(None, default_version): "default_version_test",
191-
}
192-
tests = exact_version_tests | minor_mapping_tests | default_version_tests
193-
else:
194-
# Outside bzlmod the default version and the minor mapping tests do not
195-
# make sense because the user loading things in the WORKSPACE ultimately defines
196-
# the matching order.
197-
tests = exact_version_tests
198-
199-
for (input_python_version, expect_python_version), test_name in tests.items():
200-
meta = TOOL_VERSIONS[expect_python_version]
33+
for python_version, meta in TOOL_VERSIONS.items():
20134
target_compatible_with = {
20235
"//conditions:default": ["@platforms//:incompatible"],
20336
}
@@ -206,12 +39,12 @@ def define_toolchain_tests(name):
20639
target_compatible_with[is_platform] = []
20740

20841
py_reconfig_test(
209-
name = test_name,
42+
name = "python_{}_test".format(python_version),
21043
srcs = ["python_toolchain_test.py"],
21144
main = "python_toolchain_test.py",
212-
python_version = input_python_version,
45+
python_version = python_version,
21346
env = {
214-
"EXPECT_PYTHON_VERSION": expect_python_version,
47+
"EXPECT_PYTHON_VERSION": python_version,
21548
},
21649
deps = ["//python/runfiles"],
21750
data = ["//tests/support:current_build_settings"],
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
load(":transitions_tests.bzl", "transitions_test_suite")
2+
3+
transitions_test_suite(
4+
name = "transitions_tests",
5+
)
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Copyright 2022 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
""
16+
17+
load("@pythons_hub//:versions.bzl", "DEFAULT_PYTHON_VERSION", "MINOR_MAPPING")
18+
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
19+
load("@rules_testing//lib:test_suite.bzl", "test_suite")
20+
load("@rules_testing//lib:util.bzl", rt_util = "util")
21+
load("//python:versions.bzl", "TOOL_VERSIONS")
22+
load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility
23+
load("//python/private:full_version.bzl", "full_version") # buildifier: disable=bzl-visibility
24+
load("//python/private:toolchain_types.bzl", "EXEC_TOOLS_TOOLCHAIN_TYPE") # buildifier: disable=bzl-visibility
25+
load("//tests/support:support.bzl", "PYTHON_VERSION")
26+
27+
_analysis_tests = []
28+
29+
def _transition_impl(input_settings, attr):
30+
"""Transition based on python_version flag.
31+
32+
This is a simple transition impl that a user of rules_python may implement
33+
for their own rule.
34+
"""
35+
settings = {
36+
PYTHON_VERSION: input_settings[PYTHON_VERSION],
37+
}
38+
if attr.python_version:
39+
settings[PYTHON_VERSION] = attr.python_version
40+
return settings
41+
42+
_python_version_transition = transition(
43+
implementation = _transition_impl,
44+
inputs = [PYTHON_VERSION],
45+
outputs = [PYTHON_VERSION],
46+
)
47+
48+
TestInfo = provider(
49+
doc = "A simple test provider to forward the values for the assertion.",
50+
fields = {"got": "", "want": ""},
51+
)
52+
53+
def _impl(ctx):
54+
if ctx.attr.skip:
55+
return [TestInfo(got = "", want = "")]
56+
57+
exec_tools = ctx.toolchains[EXEC_TOOLS_TOOLCHAIN_TYPE].exec_tools
58+
got_version = exec_tools.exec_interpreter[platform_common.ToolchainInfo].py3_runtime.interpreter_version_info
59+
60+
return [
61+
TestInfo(
62+
got = "{}.{}.{}".format(
63+
got_version.major,
64+
got_version.minor,
65+
got_version.micro,
66+
),
67+
want = ctx.attr.want_version,
68+
),
69+
]
70+
71+
_simple_transition = rule(
72+
implementation = _impl,
73+
attrs = {
74+
"python_version": attr.string(
75+
doc = "The input python version which we transition on.",
76+
),
77+
"skip": attr.bool(
78+
doc = "Whether to skip the test",
79+
),
80+
"want_version": attr.string(
81+
doc = "The python version that we actually expect to receive.",
82+
),
83+
"_allowlist_function_transition": attr.label(
84+
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
85+
),
86+
},
87+
toolchains = [
88+
config_common.toolchain_type(
89+
EXEC_TOOLS_TOOLCHAIN_TYPE,
90+
mandatory = False,
91+
),
92+
],
93+
cfg = _python_version_transition,
94+
)
95+
96+
def _test_transitions(*, name, tests, skip = False):
97+
"""A reusable rule so that we can split the tests."""
98+
targets = {}
99+
for test_name, (input_version, want_version) in tests.items():
100+
target_name = "{}_{}".format(name, test_name)
101+
targets["python_" + test_name] = target_name
102+
rt_util.helper_target(
103+
_simple_transition,
104+
name = target_name,
105+
python_version = input_version,
106+
want_version = want_version,
107+
skip = skip,
108+
)
109+
110+
analysis_test(
111+
name = name,
112+
impl = _test_transition_impl,
113+
targets = targets,
114+
)
115+
116+
def _test_transition_impl(env, targets):
117+
# Check that the forwarded version from the PyRuntimeInfo is correct
118+
for target in dir(targets):
119+
test_info = env.expect.that_target(getattr(targets, target)).provider(
120+
TestInfo,
121+
factory = lambda v, meta: v,
122+
)
123+
env.expect.that_str(test_info.got).equals(test_info.want)
124+
125+
def _test_full_version(name):
126+
"""Check that python_version transitions work.
127+
128+
Expectation is to get the same full version that we input.
129+
"""
130+
_test_transitions(
131+
name = name,
132+
tests = {
133+
v.replace(".", "_"): (v, v)
134+
for v in TOOL_VERSIONS
135+
},
136+
)
137+
138+
_analysis_tests.append(_test_full_version)
139+
140+
def _test_minor_versions(name):
141+
"""Ensure that MINOR_MAPPING versions are correctly selected."""
142+
_test_transitions(
143+
name = name,
144+
skip = not BZLMOD_ENABLED,
145+
tests = {
146+
minor.replace(".", "_"): (minor, full)
147+
for minor, full in MINOR_MAPPING.items()
148+
},
149+
)
150+
151+
_analysis_tests.append(_test_minor_versions)
152+
153+
def _test_default(name):
154+
"""Check the default version.
155+
156+
Lastly, if we don't provide any version to the transition, we should
157+
get the default version
158+
"""
159+
default_version = full_version(
160+
version = DEFAULT_PYTHON_VERSION,
161+
minor_mapping = MINOR_MAPPING,
162+
) if DEFAULT_PYTHON_VERSION else ""
163+
164+
_test_transitions(
165+
name = name,
166+
skip = not BZLMOD_ENABLED,
167+
tests = {
168+
"default": (None, default_version),
169+
},
170+
)
171+
172+
_analysis_tests.append(_test_default)
173+
174+
def transitions_test_suite(name):
175+
test_suite(
176+
name = name,
177+
tests = _analysis_tests,
178+
)

0 commit comments

Comments
 (0)