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 (#7844) we define an explicit toolchain.
Fixes #8411.
RELNOTES: None
PiperOrigin-RevId: 250562174
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 471c6f9..93dc52d 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -720,10 +720,6 @@
":test-deps",
"@bazel_tools//tools/bash/runfiles",
],
- tags = [
- # Disabled on windows and mac; see TODOs in the test suite.
- "no_windows",
- ],
)
sh_test(
diff --git a/src/test/shell/bazel/python_version_test.sh b/src/test/shell/bazel/python_version_test.sh
index a01977a..73b1735 100755
--- a/src/test/shell/bazel/python_version_test.sh
+++ b/src/test/shell/bazel/python_version_test.sh
@@ -52,11 +52,6 @@
msys*)
# As of 2018-08-14, Bazel on Windows only supports MSYS Bash.
declare -r is_windows=true
- # As of 2019-05-18, this test is disabled on Windows (via "no_windows" tag),
- # so this code shouldn't even have run.
- # TODO(#7844): Enable this test for Windows once our autodetecting toolchain
- # works transparently for this platform.
- fail "This test does not run on Windows."
;;
*)
declare -r is_windows=false
@@ -72,7 +67,7 @@
#### TESTS #############################################################
-# Sanity test that our environment setup above works.
+# Sanity test that our environment setup works.
function test_can_run_py_binaries() {
mkdir -p test
@@ -94,7 +89,6 @@
print("I am Python " + platform.python_version_tuple()[0])
EOF
cp test/main2.py test/main3.py
- chmod u+x test/main2.py test/main3.py
bazel run //test:main2 \
&> $TEST_log || fail "bazel run failed"
@@ -142,18 +136,23 @@
}
# Regression test for #5104. This test ensures that it's possible to use
-# --build_python_zip in combination with a py_runtime (as opposed to not using
-# a py_runtime, i.e., the legacy --python_path mechanism).
-#
-# Note that with --incompatible_use_python_toolchains flipped, we're always
-# using a py_runtime, so in that case this amounts to a test that
-# --build_python_zip works at all.
+# --build_python_zip in combination with an in-workspace runtime, as opposed to
+# with a system runtime or not using a py_runtime at all (the legacy
+# --python_path mechanism).
#
# The specific issue #5104 was caused by file permissions being lost when
# unzipping runfiles, which led to an unexecutable runtime.
-function test_build_python_zip_works_with_py_runtime() {
+function test_build_python_zip_works_with_workspace_runtime() {
mkdir -p test
+ # The runfiles interpreter is either a sh script or bat script depending on
+ # the current platform.
+ if "$is_windows"; then
+ INTERPRETER_FILE="mockpy.bat"
+ else
+ INTERPRETER_FILE="mockpy.sh"
+ fi
+
cat > test/BUILD << EOF
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
@@ -164,7 +163,7 @@
py_runtime(
name = "mock_runtime",
- interpreter = ":mockpy.sh",
+ interpreter = ":$INTERPRETER_FILE",
python_version = "PY3",
)
@@ -184,11 +183,17 @@
# executes the Python code.
print("I am pybin!")
EOF
- cat > test/mockpy.sh <<EOF
-#!/bin/bash
+ if "$is_windows"; then
+ cat > "test/$INTERPRETER_FILE" << EOF
+@ECHO I am mockpy!
+EOF
+ else
+ cat > "test/$INTERPRETER_FILE" << EOF
+#!/bin/sh
echo "I am mockpy!"
EOF
- chmod u+x test/mockpy.sh
+ chmod u+x test/mockpy.sh
+ fi
bazel run //test:pybin \
--extra_toolchains=//test:mock_toolchain --build_python_zip \
@@ -197,6 +202,11 @@
}
function test_pybin_can_have_different_version_pybin_as_data_dep() {
+ # TODO(#8503): Fix this test for windows.
+ if "$is_windows"; then
+ return
+ fi
+
mkdir -p test
cat > test/BUILD << EOF
@@ -231,7 +241,6 @@
print("Inner bin uses Python " + platform.python_version_tuple()[0])
EOF
- chmod u+x test/py2bin.py
cp test/py2bin.py test/py3bin.py
cat > test/py2bin_calling_py3bin.py << EOF
@@ -239,14 +248,15 @@
import subprocess
from bazel_tools.tools.python.runfiles import runfiles
+print("Outer bin uses Python " + platform.python_version_tuple()[0])
+
r = runfiles.Create()
bin_path = r.Rlocation("$WORKSPACE_NAME/test/py3bin")
+assert bin_path is not None
-print("Outer bin uses Python " + platform.python_version_tuple()[0])
subprocess.call([bin_path])
EOF
sed s/py3bin/py2bin/ test/py2bin_calling_py3bin.py > test/py3bin_calling_py2bin.py
- chmod u+x test/py2bin_calling_py3bin.py test/py3bin_calling_py2bin.py
EXPFLAG="--incompatible_allow_python_version_transitions=true \
--incompatible_py3_is_default=false \
@@ -267,6 +277,11 @@
}
function test_shbin_can_have_different_version_pybins_as_data_deps() {
+ # Uses bash, disable on windows.
+ if "$is_windows"; then
+ return
+ fi
+
mkdir -p test
cat > test/BUILD << EOF
@@ -394,6 +409,11 @@
}
function test_can_build_same_target_for_both_versions_in_one_build() {
+ # Uses bash, disable on windows.
+ if "$is_windows"; then
+ return
+ fi
+
mkdir -p test
cat > test/BUILD << EOF
diff --git a/src/test/shell/integration/python_stub_test.sh b/src/test/shell/integration/python_stub_test.sh
index 1808cb4..ff957df 100755
--- a/src/test/shell/integration/python_stub_test.sh
+++ b/src/test/shell/integration/python_stub_test.sh
@@ -59,6 +59,10 @@
# Tests in this file do not actually start a Python interpreter, but plug in a
# fake stub executable to serve as the "interpreter".
+#
+# Note that this means this suite cannot be used for tests of the actual stub
+# script under Windows, since the stub script never runs (the launcher uses the
+# mock interpreter rather than a system interpreter, see discussion in #7947).
use_fake_python_runtimes_for_testsuite
diff --git a/src/test/shell/testenv.sh b/src/test/shell/testenv.sh
index 65f0ce0..73316d4 100755
--- a/src/test/shell/testenv.sh
+++ b/src/test/shell/testenv.sh
@@ -19,6 +19,8 @@
# TODO(bazel-team): This file is currently an append of the old testenv.sh and
# test-setup.sh files. This must be cleaned up eventually.
+# TODO(bazel-team): Factor each test suite's is-this-windows setup check to use
+# this var instead, or better yet a common $IS_WINDOWS var.
PLATFORM="$(uname -s | tr [:upper:] [:lower:])"
function is_darwin() {
@@ -363,6 +365,54 @@
EOF
}
+# If the current platform is Windows, defines a Python toolchain for our
+# Windows CI machines. Otherwise does nothing.
+#
+# Our Windows CI machines have Python 2 and 3 installed at C:\Python2 and
+# C:\Python3 respectively.
+#
+# Since the tools directory is not cleared between test cases, this only needs
+# to run once per suite. However, the toolchain must still be registered
+# somehow.
+#
+# TODO(#7844): Delete this custom (and machine-specific) test setup once we have
+# an autodetecting Python toolchain for Windows.
+function maybe_setup_python_windows_tools() {
+ if [[ ! $PLATFORM =~ msys ]]; then
+ return
+ fi
+
+ mkdir -p tools/python/windows
+ cat > tools/python/windows/BUILD << EOF
+load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
+
+py_runtime(
+ name = "py2_runtime",
+ interpreter_path = r"C:\Python2\python.exe",
+ python_version = "PY2",
+)
+
+py_runtime(
+ name = "py3_runtime",
+ interpreter_path = r"C:\Python3\python.exe",
+ python_version = "PY3",
+)
+
+py_runtime_pair(
+ name = "py_runtime_pair",
+ py2_runtime = ":py2_runtime",
+ py3_runtime = ":py3_runtime",
+)
+
+toolchain(
+ name = "py_toolchain",
+ toolchain = ":py_runtime_pair",
+ toolchain_type = "@bazel_tools//tools/python:toolchain_type",
+ target_compatible_with = ["@bazel_tools//platforms:windows"],
+)
+EOF
+}
+
function setup_skylark_javatest_support() {
setup_javatest_common
grep -q "name = \"junit4-jars\"" third_party/BUILD \
@@ -403,6 +453,27 @@
cat > WORKSPACE << EOF
workspace(name = '$WORKSPACE_NAME')
EOF
+
+ maybe_setup_python_windows_workspace
+}
+
+# If the current platform is Windows, registers our custom Windows Python
+# toolchain. Otherwise does nothing.
+#
+# Since this modifies the WORKSPACE file, it must be called between test cases.
+function maybe_setup_python_windows_workspace() {
+ if [[ ! $PLATFORM =~ msys ]]; then
+ return
+ fi
+
+ # --extra_toolchains has left-to-right precedence semantics, but the bazelrc
+ # is processed before the command line. This means that any matching
+ # toolchains added to the bazelrc will always take precedence over toolchains
+ # set up by test cases. Instead, we add the toolchain to WORKSPACE so that it
+ # has lower priority than whatever is passed on the command line.
+ cat >> WORKSPACE << EOF
+register_toolchains("//tools/python/windows:py_toolchain")
+EOF
}
workspaces=()
@@ -422,6 +493,8 @@
|| ln -s "${langtools_path}" third_party/java/jdk/langtools/javac-9+181-r4173-1.jar
write_workspace_file
+
+ maybe_setup_python_windows_tools
}