mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-30 12:21:05 +00:00
Require numpy for the plugin tests in CI
This commit is contained in:
@@ -44,6 +44,14 @@ jobs:
|
|||||||
uses: actions/download-artifact@v8
|
uses: actions/download-artifact@v8
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.artifact }}
|
name: ${{ inputs.artifact }}
|
||||||
|
# run_unit_tests.sh installs the plugin tests' numpy with the uv the build stages
|
||||||
|
# beside them; the Windows arm64 build bundles none, so put one on PATH there.
|
||||||
|
- name: Install uv
|
||||||
|
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
||||||
|
uses: astral-sh/setup-uv@v10.2.0
|
||||||
|
with:
|
||||||
|
version: "0.11.21" # ORCA_UV_VERSION in CMakeLists.txt
|
||||||
|
enable-cache: false
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
with:
|
with:
|
||||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||||
|
|||||||
+38
-41
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
# This file is made to support the unit tests workflow.
|
# This file is made to support the unit tests workflow.
|
||||||
# It should only require the directories build/tests, scripts/, and tests/ to function,
|
# It should only require the directories build/tests, scripts/, and tests/ to function,
|
||||||
# and cmake (with ctest) installed.
|
# and cmake (with ctest) installed -- plus network access to PyPI whenever numpy has to
|
||||||
|
# be installed into a freshly built test tree (see below).
|
||||||
# (otherwise, update the workflow too, but try to avoid to keep things self-contained)
|
# (otherwise, update the workflow too, but try to avoid to keep things self-contained)
|
||||||
#
|
#
|
||||||
# Usage: run_unit_tests.sh [TEST_DIR] [BUILD_CONFIG]
|
# Usage: run_unit_tests.sh [TEST_DIR] [BUILD_CONFIG]
|
||||||
@@ -19,52 +20,48 @@ TEST_DIR="${1:-build/tests}"
|
|||||||
BUILD_CONFIG="${2:-}"
|
BUILD_CONFIG="${2:-}"
|
||||||
|
|
||||||
# The slic3rutils plugin-host tests build numpy arrays through the CPython copied next
|
# The slic3rutils plugin-host tests build numpy arrays through the CPython copied next
|
||||||
# to the test binary (see tests/slic3rutils/CMakeLists.txt); that runtime ships no numpy,
|
# to the test binary (see tests/slic3rutils/CMakeLists.txt), which ships no numpy.
|
||||||
# so those tests SKIP without it. Install it into that interpreter's own site-packages --
|
# Install it with the uv staged beside that runtime -- the tool the app installs plugin
|
||||||
# no PYTHONPATH needed, and re-checked every run because a rebuild of the test target
|
# dependencies with -- straight into the interpreter's own site-packages: no pip needed
|
||||||
# wipes and re-copies the runtime. Needs network on the first run only; a failure here is
|
# in the runtime, no PYTHONPATH. Re-checked every run because a rebuild of the test
|
||||||
# not fatal, the tests just keep skipping.
|
# target re-copies the runtime; needs network whenever it installs. Pinned so a numpy
|
||||||
|
# release cannot change results on its own.
|
||||||
|
NUMPY_VERSION="2.5.3"
|
||||||
|
|
||||||
|
# Without numpy those tests assert the numpy-absent error path instead, so a local run
|
||||||
|
# only warns. Under CI it fails the run, which would otherwise stay green while silently
|
||||||
|
# dropping the array coverage. (The Flatpak leg runs this inside `flatpak build`, whose
|
||||||
|
# minimal environment has no CI, and its offline build stages no uv, so numpy stays
|
||||||
|
# best-effort there.)
|
||||||
|
numpy_unavailable() {
|
||||||
|
if [ -n "${CI:-}" ]; then
|
||||||
|
echo "error: $1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "warning: $1; the numpy-backed binding tests will cover only the numpy-absent path."
|
||||||
|
}
|
||||||
|
|
||||||
|
has_pinned_numpy() {
|
||||||
|
"${python_exe}" -c "import sys, numpy; sys.exit(numpy.__version__ != '${NUMPY_VERSION}')" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
find_args=("${TEST_DIR}" \( -path '*/python/bin/python3' -o -path '*/python/python.exe' \))
|
find_args=("${TEST_DIR}" \( -path '*/python/bin/python3' -o -path '*/python/python.exe' \))
|
||||||
# Multi-config trees hold one copy per configuration; only bootstrap the one being run.
|
# Multi-config trees hold one copy per configuration; only bootstrap the one being run.
|
||||||
[ -n "${BUILD_CONFIG}" ] && find_args+=(-path "*/${BUILD_CONFIG}/*")
|
[ -n "${BUILD_CONFIG}" ] && find_args+=(-path "*/${BUILD_CONFIG}/*")
|
||||||
python_exe="$(find "${find_args[@]}" -print -quit 2>/dev/null)"
|
python_exe="$(find "${find_args[@]}" -print -quit 2>/dev/null)"
|
||||||
|
|
||||||
# Unix stages the runtime with `make install`, which runs ensurepip; the Windows layout
|
|
||||||
# (deps/python3/stage_windows.cmake) ships no pip, so drive the install from whatever pip
|
|
||||||
# the host has, resolving wheels for the embedded interpreter's tags and not the host's.
|
|
||||||
install_numpy_from_host_pip() {
|
|
||||||
local py_ver py_abi py_plat py_site host_py
|
|
||||||
# tr strips the CR that a Windows interpreter's print() puts on every line.
|
|
||||||
{ read -r py_ver; read -r py_abi; read -r py_plat; read -r py_site; } < <(
|
|
||||||
"${python_exe}" -c 'import sys, sysconfig
|
|
||||||
v = sys.version_info
|
|
||||||
print("%d.%d" % v[:2])
|
|
||||||
print("cp%d%d" % v[:2])
|
|
||||||
print(sysconfig.get_platform().replace("-", "_").replace(".", "_"))
|
|
||||||
print(sysconfig.get_paths()["purelib"])' 2>/dev/null | tr -d '\r')
|
|
||||||
[ -n "${py_site}" ] || return 1
|
|
||||||
for host_py in python3 python py; do
|
|
||||||
# Skips a Windows Store stub, which resolves but has no pip behind it.
|
|
||||||
"${host_py}" -m pip --version >/dev/null 2>&1 || continue
|
|
||||||
"${host_py}" -m pip install --quiet --disable-pip-version-check --retries 1 \
|
|
||||||
--target "${py_site}" --only-binary=:all: --implementation cp \
|
|
||||||
--python-version "${py_ver}" --abi "${py_abi}" --platform "${py_plat}" \
|
|
||||||
"numpy<3"
|
|
||||||
return $?
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "${python_exe}" ]; then
|
if [ -z "${python_exe}" ]; then
|
||||||
echo "No bundled Python under ${TEST_DIR}; numpy-backed binding tests will skip."
|
numpy_unavailable "no bundled Python under ${TEST_DIR}"
|
||||||
elif ! "${python_exe}" -c "import numpy" >/dev/null 2>&1; then
|
elif ! has_pinned_numpy; then
|
||||||
echo "Installing numpy into the embedded test interpreter (${python_exe})..."
|
uv_exe="${python_exe%/python/*}/tools/uv/uv"
|
||||||
if "${python_exe}" -m pip --version >/dev/null 2>&1; then
|
# Builds that bundle no uv (Windows arm64) fall back to one on PATH.
|
||||||
"${python_exe}" -m pip install --quiet --disable-pip-version-check --retries 1 "numpy<3" \
|
[ -x "${uv_exe}" ] || uv_exe="$(command -v uv)"
|
||||||
|| echo "numpy install failed; numpy-backed binding tests will skip."
|
echo "Installing numpy ${NUMPY_VERSION} into the embedded test interpreter (${python_exe})..."
|
||||||
else
|
if [ -z "${uv_exe}" ]; then
|
||||||
install_numpy_from_host_pip \
|
numpy_unavailable "no uv staged beside the tests or on PATH"
|
||||||
|| echo "numpy install failed; numpy-backed binding tests will skip."
|
elif ! "${uv_exe}" pip install --python "${python_exe}" --only-binary :all: "numpy==${NUMPY_VERSION}" \
|
||||||
|
|| ! has_pinned_numpy; then
|
||||||
|
numpy_unavailable "could not install numpy ${NUMPY_VERSION} into ${python_exe}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -83,4 +83,16 @@ elseif (FLATPAK)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# scripts/run_unit_tests.sh installs the tests' numpy into that runtime with this uv,
|
||||||
|
# staged where the app build tree keeps it (<exe dir>/tools/uv, see src/CMakeLists.txt).
|
||||||
|
if (ORCA_BUNDLED_UV_EXECUTABLE)
|
||||||
|
add_custom_command(TARGET ${_TEST_NAME}_tests POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${_TEST_NAME}_tests>/tools/uv"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ORCA_BUNDLED_UV_EXECUTABLE}"
|
||||||
|
"$<TARGET_FILE_DIR:${_TEST_NAME}_tests>/tools/uv/${ORCA_BUNDLED_UV_FILENAME}"
|
||||||
|
COMMENT "Copying uv for the plugin host API tests"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
orcaslicer_discover_tests(${_TEST_NAME}_tests)
|
orcaslicer_discover_tests(${_TEST_NAME}_tests)
|
||||||
|
|||||||
Reference in New Issue
Block a user