1# Copyright 2024 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 17load("@rules_testing//lib:test_suite.bzl", "test_suite") 18load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "REPO_VERBOSITY_ENV_VAR", "repo_utils") # buildifier: disable=bzl-visibility 19load("//python/private/pypi:whl_target_platforms.bzl", "select_whls") # buildifier: disable=bzl-visibility 20 21WHL_LIST = [ 22 "pkg-0.0.1-cp311-cp311-macosx_10_9_universal2.whl", 23 "pkg-0.0.1-cp311-cp311-macosx_10_9_x86_64.whl", 24 "pkg-0.0.1-cp311-cp311-macosx_11_0_arm64.whl", 25 "pkg-0.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", 26 "pkg-0.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", 27 "pkg-0.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", 28 "pkg-0.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", 29 "pkg-0.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", 30 "pkg-0.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", 31 "pkg-0.0.1-cp311-cp311-musllinux_1_1_i686.whl", 32 "pkg-0.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", 33 "pkg-0.0.1-cp311-cp311-musllinux_1_1_s390x.whl", 34 "pkg-0.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", 35 "pkg-0.0.1-cp311-cp311-win32.whl", 36 "pkg-0.0.1-cp311-cp311-win_amd64.whl", 37 "pkg-0.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", 38 "pkg-0.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", 39 "pkg-0.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", 40 "pkg-0.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", 41 "pkg-0.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", 42 "pkg-0.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", 43 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", 44 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_i686.whl", 45 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", 46 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", 47 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", 48 "pkg-0.0.1-cp37-cp37m-win32.whl", 49 "pkg-0.0.1-cp37-cp37m-win_amd64.whl", 50 "pkg-0.0.1-cp39-cp39-macosx_10_9_universal2.whl", 51 "pkg-0.0.1-cp39-cp39-macosx_10_9_x86_64.whl", 52 "pkg-0.0.1-cp39-cp39-macosx_11_0_arm64.whl", 53 "pkg-0.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", 54 "pkg-0.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", 55 "pkg-0.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", 56 "pkg-0.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", 57 "pkg-0.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", 58 "pkg-0.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", 59 "pkg-0.0.1-cp39-cp39-musllinux_1_1_i686.whl", 60 "pkg-0.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", 61 "pkg-0.0.1-cp39-cp39-musllinux_1_1_s390x.whl", 62 "pkg-0.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", 63 "pkg-0.0.1-cp39-cp39-win32.whl", 64 "pkg-0.0.1-cp39-cp39-win_amd64.whl", 65 "pkg-0.0.1-cp39-abi3-any.whl", 66 "pkg-0.0.1-py310-abi3-any.whl", 67 "pkg-0.0.1-py3-abi3-any.whl", 68 "pkg-0.0.1-py3-none-any.whl", 69] 70 71def _match(env, got, *want_filenames): 72 if not want_filenames: 73 env.expect.that_collection(got).has_size(len(want_filenames)) 74 return 75 76 got_filenames = [g.filename for g in got] 77 env.expect.that_collection(got_filenames).contains_exactly(want_filenames) 78 79 if got: 80 # Check that we pass the original structs 81 env.expect.that_str(got[0].other).equals("dummy") 82 83def _select_whls(whls, debug = False, **kwargs): 84 return select_whls( 85 whls = [ 86 struct( 87 filename = f, 88 other = "dummy", 89 ) 90 for f in whls 91 ], 92 logger = repo_utils.logger(struct( 93 os = struct( 94 environ = { 95 REPO_DEBUG_ENV_VAR: "1", 96 REPO_VERBOSITY_ENV_VAR: "TRACE" if debug else "INFO", 97 }, 98 ), 99 ), "unit-test"), 100 **kwargs 101 ) 102 103_tests = [] 104 105def _test_simplest(env): 106 got = _select_whls( 107 whls = [ 108 "pkg-0.0.1-py2.py3-abi3-any.whl", 109 "pkg-0.0.1-py3-abi3-any.whl", 110 "pkg-0.0.1-py3-none-any.whl", 111 ], 112 want_platforms = ["cp30_ignored"], 113 ) 114 _match( 115 env, 116 got, 117 "pkg-0.0.1-py3-abi3-any.whl", 118 "pkg-0.0.1-py3-none-any.whl", 119 ) 120 121_tests.append(_test_simplest) 122 123def _test_select_by_supported_py_version(env): 124 for minor_version, match in { 125 8: "pkg-0.0.1-py3-abi3-any.whl", 126 11: "pkg-0.0.1-py311-abi3-any.whl", 127 }.items(): 128 got = _select_whls( 129 whls = [ 130 "pkg-0.0.1-py2.py3-abi3-any.whl", 131 "pkg-0.0.1-py3-abi3-any.whl", 132 "pkg-0.0.1-py311-abi3-any.whl", 133 ], 134 want_platforms = ["cp3{}_ignored".format(minor_version)], 135 ) 136 _match(env, got, match) 137 138_tests.append(_test_select_by_supported_py_version) 139 140def _test_select_by_supported_cp_version(env): 141 for minor_version, match in { 142 11: "pkg-0.0.1-cp311-abi3-any.whl", 143 8: "pkg-0.0.1-py3-abi3-any.whl", 144 }.items(): 145 got = _select_whls( 146 whls = [ 147 "pkg-0.0.1-py2.py3-abi3-any.whl", 148 "pkg-0.0.1-py3-abi3-any.whl", 149 "pkg-0.0.1-py311-abi3-any.whl", 150 "pkg-0.0.1-cp311-abi3-any.whl", 151 ], 152 want_platforms = ["cp3{}_ignored".format(minor_version)], 153 ) 154 _match(env, got, match) 155 156_tests.append(_test_select_by_supported_cp_version) 157 158def _test_supported_cp_version_manylinux(env): 159 for minor_version, match in { 160 8: "pkg-0.0.1-py3-none-manylinux_x86_64.whl", 161 11: "pkg-0.0.1-cp311-none-manylinux_x86_64.whl", 162 }.items(): 163 got = _select_whls( 164 whls = [ 165 "pkg-0.0.1-py2.py3-none-manylinux_x86_64.whl", 166 "pkg-0.0.1-py3-none-manylinux_x86_64.whl", 167 "pkg-0.0.1-py311-none-manylinux_x86_64.whl", 168 "pkg-0.0.1-cp311-none-manylinux_x86_64.whl", 169 ], 170 want_platforms = ["cp3{}_linux_x86_64".format(minor_version)], 171 ) 172 _match(env, got, match) 173 174_tests.append(_test_supported_cp_version_manylinux) 175 176def _test_ignore_unsupported(env): 177 got = _select_whls( 178 whls = [ 179 "pkg-0.0.1-xx3-abi3-any.whl", 180 ], 181 want_platforms = ["cp30_ignored"], 182 ) 183 _match(env, got) 184 185_tests.append(_test_ignore_unsupported) 186 187def _test_match_abi_and_not_py_version(env): 188 # Check we match the ABI and not the py version 189 got = _select_whls(whls = WHL_LIST, want_platforms = ["cp37_linux_x86_64"]) 190 _match( 191 env, 192 got, 193 "pkg-0.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", 194 "pkg-0.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", 195 "pkg-0.0.1-py3-abi3-any.whl", 196 "pkg-0.0.1-py3-none-any.whl", 197 ) 198 199_tests.append(_test_match_abi_and_not_py_version) 200 201def _test_select_filename_with_many_tags(env): 202 # Check we can select a filename with many platform tags 203 got = _select_whls(whls = WHL_LIST, want_platforms = ["cp39_linux_x86_32"]) 204 _match( 205 env, 206 got, 207 "pkg-0.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", 208 "pkg-0.0.1-cp39-cp39-musllinux_1_1_i686.whl", 209 "pkg-0.0.1-cp39-abi3-any.whl", 210 "pkg-0.0.1-py3-none-any.whl", 211 ) 212 213_tests.append(_test_select_filename_with_many_tags) 214 215def _test_osx_prefer_arch_specific(env): 216 # Check that we prefer the specific wheel 217 got = _select_whls( 218 whls = WHL_LIST, 219 want_platforms = ["cp311_osx_x86_64", "cp311_osx_x86_32"], 220 ) 221 _match( 222 env, 223 got, 224 "pkg-0.0.1-cp311-cp311-macosx_10_9_universal2.whl", 225 "pkg-0.0.1-cp311-cp311-macosx_10_9_x86_64.whl", 226 "pkg-0.0.1-cp39-abi3-any.whl", 227 "pkg-0.0.1-py3-none-any.whl", 228 ) 229 230 got = _select_whls(whls = WHL_LIST, want_platforms = ["cp311_osx_aarch64"]) 231 _match( 232 env, 233 got, 234 "pkg-0.0.1-cp311-cp311-macosx_10_9_universal2.whl", 235 "pkg-0.0.1-cp311-cp311-macosx_11_0_arm64.whl", 236 "pkg-0.0.1-cp39-abi3-any.whl", 237 "pkg-0.0.1-py3-none-any.whl", 238 ) 239 240_tests.append(_test_osx_prefer_arch_specific) 241 242def _test_osx_fallback_to_universal2(env): 243 # Check that we can use the universal2 if the arm wheel is not available 244 got = _select_whls( 245 whls = [w for w in WHL_LIST if "arm64" not in w], 246 want_platforms = ["cp311_osx_aarch64"], 247 ) 248 _match( 249 env, 250 got, 251 "pkg-0.0.1-cp311-cp311-macosx_10_9_universal2.whl", 252 "pkg-0.0.1-cp39-abi3-any.whl", 253 "pkg-0.0.1-py3-none-any.whl", 254 ) 255 256_tests.append(_test_osx_fallback_to_universal2) 257 258def _test_prefer_manylinux_wheels(env): 259 # Check we prefer platform specific wheels 260 got = _select_whls(whls = WHL_LIST, want_platforms = ["cp39_linux_x86_64"]) 261 _match( 262 env, 263 got, 264 "pkg-0.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", 265 "pkg-0.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", 266 "pkg-0.0.1-cp39-abi3-any.whl", 267 "pkg-0.0.1-py3-none-any.whl", 268 ) 269 270_tests.append(_test_prefer_manylinux_wheels) 271 272def select_whl_test_suite(name): 273 """Create the test suite. 274 275 Args: 276 name: the name of the test suite 277 """ 278 test_suite(name = name, basic_tests = _tests) 279