1# Copyright 2023 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"""Tests for py_test.""" 15 16load("@rules_testing//lib:analysis_test.bzl", "analysis_test") 17load("@rules_testing//lib:test_suite.bzl", "test_suite") 18load("@rules_testing//lib:util.bzl", "TestingAspectInfo", rt_util = "util") 19load("//python:py_info.bzl", "PyInfo") 20load("//python/config_settings:transition.bzl", py_binary_transitioned = "py_binary", py_test_transitioned = "py_test") 21load("//python/private:reexports.bzl", "BuiltinPyInfo") # buildifier: disable=bzl-visibility 22load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable=bzl-visibility 23load("//tests/support:support.bzl", "CC_TOOLCHAIN") 24 25# NOTE @aignas 2024-06-04: we are using here something that is registered in the MODULE.Bazel 26# and if you find tests failing, it could be because of the toolchain resolution issues here. 27# 28# If the toolchain is not resolved then you will have a weird message telling 29# you that your transition target does not have a PyRuntime provider, which is 30# caused by there not being a toolchain detected for the target. 31_PYTHON_VERSION = "3.11" 32 33_tests = [] 34 35def _test_py_test_with_transition(name): 36 rt_util.helper_target( 37 py_test_transitioned, 38 name = name + "_subject", 39 srcs = [name + "_subject.py"], 40 python_version = _PYTHON_VERSION, 41 ) 42 43 analysis_test( 44 name = name, 45 target = name + "_subject", 46 impl = _test_py_test_with_transition_impl, 47 ) 48 49def _test_py_test_with_transition_impl(env, target): 50 # Nothing to assert; we just want to make sure it builds 51 env.expect.that_target(target).has_provider(PyInfo) 52 if BuiltinPyInfo: 53 env.expect.that_target(target).has_provider(BuiltinPyInfo) 54 55_tests.append(_test_py_test_with_transition) 56 57def _test_py_binary_with_transition(name): 58 rt_util.helper_target( 59 py_binary_transitioned, 60 name = name + "_subject", 61 srcs = [name + "_subject.py"], 62 python_version = _PYTHON_VERSION, 63 ) 64 65 analysis_test( 66 name = name, 67 target = name + "_subject", 68 impl = _test_py_binary_with_transition_impl, 69 ) 70 71def _test_py_binary_with_transition_impl(env, target): 72 # Nothing to assert; we just want to make sure it builds 73 env.expect.that_target(target).has_provider(PyInfo) 74 if BuiltinPyInfo: 75 env.expect.that_target(target).has_provider(BuiltinPyInfo) 76 77_tests.append(_test_py_binary_with_transition) 78 79def _setup_py_binary_windows(name, *, impl, build_python_zip): 80 rt_util.helper_target( 81 py_binary_transitioned, 82 name = name + "_subject", 83 srcs = [name + "_subject.py"], 84 python_version = _PYTHON_VERSION, 85 ) 86 87 analysis_test( 88 name = name, 89 target = name + "_subject", 90 impl = impl, 91 config_settings = { 92 "//command_line_option:build_python_zip": build_python_zip, 93 "//command_line_option:extra_toolchains": CC_TOOLCHAIN, 94 "//command_line_option:platforms": str(Label("//tests/support:windows_x86_64")), 95 }, 96 ) 97 98def _test_py_binary_windows_build_python_zip_false(name): 99 _setup_py_binary_windows( 100 name, 101 build_python_zip = "false", 102 impl = _test_py_binary_windows_build_python_zip_false_impl, 103 ) 104 105def _test_py_binary_windows_build_python_zip_false_impl(env, target): 106 default_outputs = env.expect.that_target(target).default_outputs() 107 if IS_BAZEL_7_OR_HIGHER: 108 # TODO: These outputs aren't correct. The outputs shouldn't 109 # have the "_" prefix on them (those are coming from the underlying 110 # wrapped binary). 111 env.expect.that_target(target).default_outputs().contains_exactly([ 112 "{package}/_{test_name}_subject", 113 "{package}/_{test_name}_subject.exe", 114 "{package}/{test_name}_subject", 115 "{package}/{test_name}_subject.py", 116 ]) 117 else: 118 inner_exe = target[TestingAspectInfo].attrs.target[DefaultInfo].files_to_run.executable 119 default_outputs.contains_at_least([ 120 inner_exe.short_path, 121 ]) 122 123_tests.append(_test_py_binary_windows_build_python_zip_false) 124 125def _test_py_binary_windows_build_python_zip_true(name): 126 _setup_py_binary_windows( 127 name, 128 build_python_zip = "true", 129 impl = _test_py_binary_windows_build_python_zip_true_impl, 130 ) 131 132def _test_py_binary_windows_build_python_zip_true_impl(env, target): 133 default_outputs = env.expect.that_target(target).default_outputs() 134 if IS_BAZEL_7_OR_HIGHER: 135 # TODO: These outputs aren't correct. The outputs shouldn't 136 # have the "_" prefix on them (those are coming from the underlying 137 # wrapped binary). 138 default_outputs.contains_exactly([ 139 "{package}/_{test_name}_subject.exe", 140 "{package}/_{test_name}_subject.zip", 141 "{package}/{test_name}_subject.py", 142 "{package}/{test_name}_subject.zip", 143 ]) 144 else: 145 inner_exe = target[TestingAspectInfo].attrs.target[DefaultInfo].files_to_run.executable 146 default_outputs.contains_at_least([ 147 "{package}/{test_name}_subject.zip", 148 inner_exe.short_path, 149 ]) 150 151_tests.append(_test_py_binary_windows_build_python_zip_true) 152 153def multi_version_test_suite(name): 154 test_suite( 155 name = name, 156 tests = _tests, 157 ) 158