blob: acbd6676dc9261c358d28ba5e68fd79a6b69d2c1 [file] [log] [blame]
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""
load("@rules_testing//lib:test_suite.bzl", "test_suite")
load("//python/private:python.bzl", _parse_modules = "parse_modules") # buildifier: disable=bzl-visibility
_tests = []
def parse_modules(*, mctx, **kwargs):
return _parse_modules(module_ctx = mctx, **kwargs)
def _mock_mctx(*modules, environ = {}):
return struct(
os = struct(environ = environ),
modules = [
struct(
name = modules[0].name,
tags = modules[0].tags,
is_root = modules[0].is_root,
),
] + [
struct(
name = mod.name,
tags = mod.tags,
is_root = False,
)
for mod in modules[1:]
],
)
def _mod(*, name, toolchain = [], rules_python_private_testing = [], is_root = True):
return struct(
name = name,
tags = struct(
toolchain = toolchain,
rules_python_private_testing = rules_python_private_testing,
),
is_root = is_root,
)
def _toolchain(python_version, *, is_default = False, **kwargs):
return struct(
is_default = is_default,
python_version = python_version,
**kwargs
)
def _test_default(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(name = "rules_python", toolchain = [_toolchain("3.11")]),
),
)
env.expect.that_collection(py.defaults.keys()).contains_exactly([
"ignore_root_user_error",
])
env.expect.that_bool(py.defaults["ignore_root_user_error"]).equals(False)
env.expect.that_str(py.default_python_version).equals("3.11")
want_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([want_toolchain])
_tests.append(_test_default)
def _test_default_some_module(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(name = "rules_python", toolchain = [_toolchain("3.11")], is_root = False),
),
)
env.expect.that_collection(py.defaults.keys()).contains_exactly([
"ignore_root_user_error",
])
env.expect.that_str(py.default_python_version).equals("3.11")
want_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([want_toolchain])
_tests.append(_test_default_some_module)
def _test_default_with_patch_version(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(name = "rules_python", toolchain = [_toolchain("3.11.2")]),
),
)
env.expect.that_str(py.default_python_version).equals("3.11.2")
want_toolchain = struct(
name = "python_3_11_2",
python_version = "3.11.2",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([want_toolchain])
_tests.append(_test_default_with_patch_version)
def _test_default_non_rules_python(env):
py = parse_modules(
mctx = _mock_mctx(
# NOTE @aignas 2024-09-06: the first item in the module_ctx.modules
# could be a non-root module, which is the case if the root module
# does not make any calls to the extension.
_mod(name = "rules_python", toolchain = [_toolchain("3.11")], is_root = False),
),
)
env.expect.that_str(py.default_python_version).equals("3.11")
rules_python_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([rules_python_toolchain])
_tests.append(_test_default_non_rules_python)
def _test_default_non_rules_python_ignore_root_user_error(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(
name = "my_module",
toolchain = [_toolchain("3.12", ignore_root_user_error = True)],
),
_mod(name = "rules_python", toolchain = [_toolchain("3.11")]),
),
)
env.expect.that_bool(py.defaults["ignore_root_user_error"]).equals(True)
env.expect.that_str(py.default_python_version).equals("3.12")
my_module_toolchain = struct(
name = "python_3_12",
python_version = "3.12",
register_coverage_tool = False,
)
rules_python_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([
rules_python_toolchain,
my_module_toolchain,
]).in_order()
_tests.append(_test_default_non_rules_python_ignore_root_user_error)
def _test_default_non_rules_python_ignore_root_user_error_non_root_module(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(name = "my_module", toolchain = [_toolchain("3.13")]),
_mod(name = "some_module", toolchain = [_toolchain("3.12", ignore_root_user_error = True)]),
_mod(name = "rules_python", toolchain = [_toolchain("3.11")]),
),
)
env.expect.that_str(py.default_python_version).equals("3.13")
env.expect.that_bool(py.defaults["ignore_root_user_error"]).equals(False)
my_module_toolchain = struct(
name = "python_3_13",
python_version = "3.13",
register_coverage_tool = False,
)
some_module_toolchain = struct(
name = "python_3_12",
python_version = "3.12",
register_coverage_tool = False,
)
rules_python_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([
some_module_toolchain,
rules_python_toolchain,
my_module_toolchain, # this was the only toolchain, default to that
]).in_order()
_tests.append(_test_default_non_rules_python_ignore_root_user_error_non_root_module)
def _test_first_occurance_of_the_toolchain_wins(env):
py = parse_modules(
mctx = _mock_mctx(
_mod(name = "my_module", toolchain = [_toolchain("3.12")]),
_mod(name = "some_module", toolchain = [_toolchain("3.12", configure_coverage_tool = True)]),
_mod(name = "rules_python", toolchain = [_toolchain("3.11")]),
environ = {
"RULES_PYTHON_BZLMOD_DEBUG": "1",
},
),
)
env.expect.that_str(py.default_python_version).equals("3.12")
my_module_toolchain = struct(
name = "python_3_12",
python_version = "3.12",
# NOTE: coverage stays disabled even though `some_module` was
# configuring something else.
register_coverage_tool = False,
)
rules_python_toolchain = struct(
name = "python_3_11",
python_version = "3.11",
register_coverage_tool = False,
)
env.expect.that_collection(py.toolchains).contains_exactly([
rules_python_toolchain,
my_module_toolchain, # default toolchain is last
]).in_order()
env.expect.that_dict(py.debug_info).contains_exactly({
"toolchains_registered": [
{"ignore_root_user_error": False, "name": "python_3_12"},
{"ignore_root_user_error": False, "name": "python_3_11"},
],
})
_tests.append(_test_first_occurance_of_the_toolchain_wins)
def python_test_suite(name):
"""Create the test suite.
Args:
name: the name of the test suite
"""
test_suite(name = name, basic_tests = _tests)