Skip to content

Commit 10840c4

Browse files
brandjonirengrig
authored andcommitted
Enable Python integration tests on Windows
Now that we have both a Python 2 and 3 interpreter on our CI machines (bazelbuild/continuous-integration#578), we can turn on these version tests for Windows. Since there's no autodetecting toolchain for Windows yet (bazelbuild#7844) we define an explicit toolchain. Fixes bazelbuild#8411. RELNOTES: None PiperOrigin-RevId: 250562174
1 parent a919be5 commit 10840c4

File tree

4 files changed

+118
-25
lines changed

4 files changed

+118
-25
lines changed

src/test/shell/bazel/BUILD

-4
Original file line numberDiff line numberDiff line change
@@ -720,10 +720,6 @@ sh_test(
720720
":test-deps",
721721
"@bazel_tools//tools/bash/runfiles",
722722
],
723-
tags = [
724-
# Disabled on windows and mac; see TODOs in the test suite.
725-
"no_windows",
726-
],
727723
)
728724

729725
sh_test(

src/test/shell/bazel/python_version_test.sh

+41-21
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ case "$(uname -s | tr [:upper:] [:lower:])" in
5252
msys*)
5353
# As of 2018-08-14, Bazel on Windows only supports MSYS Bash.
5454
declare -r is_windows=true
55-
# As of 2019-05-18, this test is disabled on Windows (via "no_windows" tag),
56-
# so this code shouldn't even have run.
57-
# TODO(#7844): Enable this test for Windows once our autodetecting toolchain
58-
# works transparently for this platform.
59-
fail "This test does not run on Windows."
6055
;;
6156
*)
6257
declare -r is_windows=false
@@ -72,7 +67,7 @@ fi
7267

7368
#### TESTS #############################################################
7469

75-
# Sanity test that our environment setup above works.
70+
# Sanity test that our environment setup works.
7671
function test_can_run_py_binaries() {
7772
mkdir -p test
7873

@@ -94,7 +89,6 @@ import platform
9489
print("I am Python " + platform.python_version_tuple()[0])
9590
EOF
9691
cp test/main2.py test/main3.py
97-
chmod u+x test/main2.py test/main3.py
9892

9993
bazel run //test:main2 \
10094
&> $TEST_log || fail "bazel run failed"
@@ -142,18 +136,23 @@ EOF
142136
}
143137

144138
# Regression test for #5104. This test ensures that it's possible to use
145-
# --build_python_zip in combination with a py_runtime (as opposed to not using
146-
# a py_runtime, i.e., the legacy --python_path mechanism).
147-
#
148-
# Note that with --incompatible_use_python_toolchains flipped, we're always
149-
# using a py_runtime, so in that case this amounts to a test that
150-
# --build_python_zip works at all.
139+
# --build_python_zip in combination with an in-workspace runtime, as opposed to
140+
# with a system runtime or not using a py_runtime at all (the legacy
141+
# --python_path mechanism).
151142
#
152143
# The specific issue #5104 was caused by file permissions being lost when
153144
# unzipping runfiles, which led to an unexecutable runtime.
154-
function test_build_python_zip_works_with_py_runtime() {
145+
function test_build_python_zip_works_with_workspace_runtime() {
155146
mkdir -p test
156147

148+
# The runfiles interpreter is either a sh script or bat script depending on
149+
# the current platform.
150+
if "$is_windows"; then
151+
INTERPRETER_FILE="mockpy.bat"
152+
else
153+
INTERPRETER_FILE="mockpy.sh"
154+
fi
155+
157156
cat > test/BUILD << EOF
158157
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
159158
@@ -164,7 +163,7 @@ py_binary(
164163
165164
py_runtime(
166165
name = "mock_runtime",
167-
interpreter = ":mockpy.sh",
166+
interpreter = ":$INTERPRETER_FILE",
168167
python_version = "PY3",
169168
)
170169
@@ -184,11 +183,17 @@ EOF
184183
# executes the Python code.
185184
print("I am pybin!")
186185
EOF
187-
cat > test/mockpy.sh <<EOF
188-
#!/bin/bash
186+
if "$is_windows"; then
187+
cat > "test/$INTERPRETER_FILE" << EOF
188+
@ECHO I am mockpy!
189+
EOF
190+
else
191+
cat > "test/$INTERPRETER_FILE" << EOF
192+
#!/bin/sh
189193
echo "I am mockpy!"
190194
EOF
191-
chmod u+x test/mockpy.sh
195+
chmod u+x test/mockpy.sh
196+
fi
192197

193198
bazel run //test:pybin \
194199
--extra_toolchains=//test:mock_toolchain --build_python_zip \
@@ -197,6 +202,11 @@ EOF
197202
}
198203

199204
function test_pybin_can_have_different_version_pybin_as_data_dep() {
205+
# TODO(#8503): Fix this test for windows.
206+
if "$is_windows"; then
207+
return
208+
fi
209+
200210
mkdir -p test
201211

202212
cat > test/BUILD << EOF
@@ -231,22 +241,22 @@ import platform
231241
232242
print("Inner bin uses Python " + platform.python_version_tuple()[0])
233243
EOF
234-
chmod u+x test/py2bin.py
235244
cp test/py2bin.py test/py3bin.py
236245

237246
cat > test/py2bin_calling_py3bin.py << EOF
238247
import platform
239248
import subprocess
240249
from bazel_tools.tools.python.runfiles import runfiles
241250
251+
print("Outer bin uses Python " + platform.python_version_tuple()[0])
252+
242253
r = runfiles.Create()
243254
bin_path = r.Rlocation("$WORKSPACE_NAME/test/py3bin")
255+
assert bin_path is not None
244256
245-
print("Outer bin uses Python " + platform.python_version_tuple()[0])
246257
subprocess.call([bin_path])
247258
EOF
248259
sed s/py3bin/py2bin/ test/py2bin_calling_py3bin.py > test/py3bin_calling_py2bin.py
249-
chmod u+x test/py2bin_calling_py3bin.py test/py3bin_calling_py2bin.py
250260

251261
EXPFLAG="--incompatible_allow_python_version_transitions=true \
252262
--incompatible_py3_is_default=false \
@@ -267,6 +277,11 @@ EOF
267277
}
268278

269279
function test_shbin_can_have_different_version_pybins_as_data_deps() {
280+
# Uses bash, disable on windows.
281+
if "$is_windows"; then
282+
return
283+
fi
284+
270285
mkdir -p test
271286

272287
cat > test/BUILD << EOF
@@ -394,6 +409,11 @@ EOF
394409
}
395410

396411
function test_can_build_same_target_for_both_versions_in_one_build() {
412+
# Uses bash, disable on windows.
413+
if "$is_windows"; then
414+
return
415+
fi
416+
397417
mkdir -p test
398418

399419
cat > test/BUILD << EOF

src/test/shell/integration/python_stub_test.sh

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ fi
5959

6060
# Tests in this file do not actually start a Python interpreter, but plug in a
6161
# fake stub executable to serve as the "interpreter".
62+
#
63+
# Note that this means this suite cannot be used for tests of the actual stub
64+
# script under Windows, since the stub script never runs (the launcher uses the
65+
# mock interpreter rather than a system interpreter, see discussion in #7947).
6266

6367
use_fake_python_runtimes_for_testsuite
6468

src/test/shell/testenv.sh

+73
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
# TODO(bazel-team): This file is currently an append of the old testenv.sh and
2020
# test-setup.sh files. This must be cleaned up eventually.
2121

22+
# TODO(bazel-team): Factor each test suite's is-this-windows setup check to use
23+
# this var instead, or better yet a common $IS_WINDOWS var.
2224
PLATFORM="$(uname -s | tr [:upper:] [:lower:])"
2325

2426
function is_darwin() {
@@ -363,6 +365,54 @@ java_import(
363365
EOF
364366
}
365367

368+
# If the current platform is Windows, defines a Python toolchain for our
369+
# Windows CI machines. Otherwise does nothing.
370+
#
371+
# Our Windows CI machines have Python 2 and 3 installed at C:\Python2 and
372+
# C:\Python3 respectively.
373+
#
374+
# Since the tools directory is not cleared between test cases, this only needs
375+
# to run once per suite. However, the toolchain must still be registered
376+
# somehow.
377+
#
378+
# TODO(#7844): Delete this custom (and machine-specific) test setup once we have
379+
# an autodetecting Python toolchain for Windows.
380+
function maybe_setup_python_windows_tools() {
381+
if [[ ! $PLATFORM =~ msys ]]; then
382+
return
383+
fi
384+
385+
mkdir -p tools/python/windows
386+
cat > tools/python/windows/BUILD << EOF
387+
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
388+
389+
py_runtime(
390+
name = "py2_runtime",
391+
interpreter_path = r"C:\Python2\python.exe",
392+
python_version = "PY2",
393+
)
394+
395+
py_runtime(
396+
name = "py3_runtime",
397+
interpreter_path = r"C:\Python3\python.exe",
398+
python_version = "PY3",
399+
)
400+
401+
py_runtime_pair(
402+
name = "py_runtime_pair",
403+
py2_runtime = ":py2_runtime",
404+
py3_runtime = ":py3_runtime",
405+
)
406+
407+
toolchain(
408+
name = "py_toolchain",
409+
toolchain = ":py_runtime_pair",
410+
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
411+
target_compatible_with = ["@bazel_tools//platforms:windows"],
412+
)
413+
EOF
414+
}
415+
366416
function setup_skylark_javatest_support() {
367417
setup_javatest_common
368418
grep -q "name = \"junit4-jars\"" third_party/BUILD \
@@ -402,6 +452,27 @@ EOF
402452
function write_workspace_file() {
403453
cat > WORKSPACE << EOF
404454
workspace(name = '$WORKSPACE_NAME')
455+
EOF
456+
457+
maybe_setup_python_windows_workspace
458+
}
459+
460+
# If the current platform is Windows, registers our custom Windows Python
461+
# toolchain. Otherwise does nothing.
462+
#
463+
# Since this modifies the WORKSPACE file, it must be called between test cases.
464+
function maybe_setup_python_windows_workspace() {
465+
if [[ ! $PLATFORM =~ msys ]]; then
466+
return
467+
fi
468+
469+
# --extra_toolchains has left-to-right precedence semantics, but the bazelrc
470+
# is processed before the command line. This means that any matching
471+
# toolchains added to the bazelrc will always take precedence over toolchains
472+
# set up by test cases. Instead, we add the toolchain to WORKSPACE so that it
473+
# has lower priority than whatever is passed on the command line.
474+
cat >> WORKSPACE << EOF
475+
register_toolchains("//tools/python/windows:py_toolchain")
405476
EOF
406477
}
407478

@@ -422,6 +493,8 @@ function create_new_workspace() {
422493
|| ln -s "${langtools_path}" third_party/java/jdk/langtools/javac-9+181-r4173-1.jar
423494

424495
write_workspace_file
496+
497+
maybe_setup_python_windows_tools
425498
}
426499

427500

0 commit comments

Comments
 (0)