pyodide/pyodide-build/pyodide_build/tests/test_build_env.py

250 lines
8.6 KiB
Python
Raw Normal View History

# flake8: noqa
# This file contains tests that ensure build environment is properly initialized in
# both in-tree and out-of-tree builds.
import os
import pytest
from conftest import ROOT_PATH
from pyodide_build import build_env, common
from .fixture import reset_cache, reset_env_vars, xbuildenv
class TestInTree:
def test_init_environment(self, reset_env_vars, reset_cache):
assert "PYODIDE_ROOT" not in os.environ
build_env.init_environment()
assert "PYODIDE_ROOT" in os.environ
assert os.environ["PYODIDE_ROOT"] == str(ROOT_PATH)
def test_init_environment_pyodide_root_already_set(
self, reset_env_vars, reset_cache
):
assert "PYODIDE_ROOT" not in os.environ
os.environ["PYODIDE_ROOT"] = "/set_by_user"
build_env.init_environment()
assert os.environ["PYODIDE_ROOT"] == "/set_by_user"
def test_get_pyodide_root(self, reset_env_vars, reset_cache):
assert "PYODIDE_ROOT" not in os.environ
assert build_env.get_pyodide_root() == ROOT_PATH
def test_get_pyodide_root_pyodide_root_already_set(
self, reset_env_vars, reset_cache
):
assert "PYODIDE_ROOT" not in os.environ
os.environ["PYODIDE_ROOT"] = "/set_by_user"
assert str(build_env.get_pyodide_root()) == "/set_by_user"
def test_search_pyodide_root(self, tmp_path, reset_env_vars, reset_cache):
pyproject_file = tmp_path / "pyproject.toml"
pyproject_file.write_text("[tool.pyodide]")
assert build_env.search_pyodide_root(tmp_path) == tmp_path
assert build_env.search_pyodide_root(tmp_path / "subdir") == tmp_path
assert build_env.search_pyodide_root(tmp_path / "subdir" / "subdir") == tmp_path
pyproject_file.unlink()
with pytest.raises(FileNotFoundError):
build_env.search_pyodide_root(tmp_path)
def test_in_xbuildenv(self, reset_env_vars, reset_cache):
assert not build_env.in_xbuildenv()
def test_get_build_environment_vars(self, reset_env_vars, reset_cache):
build_vars = build_env.get_build_environment_vars()
extra_vars = set(
["PYODIDE", "PKG_CONFIG_PATH", "CMAKE_TOOLCHAIN_FILE", "PYO3_CONFIG_FILE"]
)
for var in build_vars:
assert var in build_env.BUILD_VARS | extra_vars, f"Unknown {var}"
# Additionally we set these variables
for var in extra_vars:
assert var in build_vars, f"Missing {var}"
def test_get_make_environment_vars(self, reset_env_vars, reset_cache):
make_vars = build_env._get_make_environment_vars()
assert make_vars["PYODIDE_ROOT"] == str(ROOT_PATH)
make_vars = build_env._get_make_environment_vars(pyodide_root=ROOT_PATH)
assert make_vars["PYODIDE_ROOT"] == str(ROOT_PATH)
def test_get_build_flag(self, reset_env_vars, reset_cache):
for key, val in build_env.get_build_environment_vars().items():
assert build_env.get_build_flag(key) == val
with pytest.raises(ValueError):
build_env.get_build_flag("UNKNOWN_VAR")
def test_get_build_environment_vars_host_env(
self, monkeypatch, reset_env_vars, reset_cache
):
# host environment variables should have precedence over
# variables defined in Makefile.envs
import os
e = build_env.get_build_environment_vars()
assert e["PYODIDE"] == "1"
monkeypatch.setenv("HOME", "/home/user")
monkeypatch.setenv("PATH", "/usr/bin:/bin")
monkeypatch.setenv("PKG_CONFIG_PATH", "/x/y/z:/c/d/e")
build_env.get_build_environment_vars.cache_clear()
e_host = build_env.get_build_environment_vars()
assert e_host.get("HOME") == os.environ.get("HOME")
assert e_host.get("PATH") == os.environ.get("PATH")
assert e_host["PKG_CONFIG_PATH"].endswith("/x/y/z:/c/d/e")
assert e_host.get("HOME") != e.get("HOME")
assert e_host.get("PATH") != e.get("PATH")
assert e_host.get("PKG_CONFIG_PATH") != e.get("PKG_CONFIG_PATH")
build_env.get_build_environment_vars.cache_clear()
monkeypatch.delenv("HOME")
monkeypatch.setenv("RANDOM_ENV", "1234")
build_env.get_build_environment_vars.cache_clear()
e = build_env.get_build_environment_vars()
assert "HOME" not in e
assert "RANDOM_ENV" not in e
class TestOutOfTree(TestInTree):
# Note: other tests are inherited from TestInTree
def test_init_environment(self, xbuildenv, reset_env_vars, reset_cache):
assert "PYODIDE_ROOT" not in os.environ
build_env.init_environment()
assert "PYODIDE_ROOT" in os.environ
assert os.environ["PYODIDE_ROOT"] == str(
xbuildenv / ".pyodide-xbuildenv/xbuildenv/pyodide-root"
)
def test_get_pyodide_root(self, xbuildenv, reset_env_vars, reset_cache):
assert "PYODIDE_ROOT" not in os.environ
assert (
build_env.get_pyodide_root()
== xbuildenv / ".pyodide-xbuildenv/xbuildenv/pyodide-root"
)
def test_in_xbuildenv(self, xbuildenv, reset_env_vars, reset_cache):
assert build_env.in_xbuildenv()
def test_get_make_environment_vars(self, xbuildenv, reset_env_vars, reset_cache):
xbuildenv_root = xbuildenv / ".pyodide-xbuildenv/xbuildenv/pyodide-root"
make_vars = build_env._get_make_environment_vars()
assert make_vars["PYODIDE_ROOT"] == str(xbuildenv_root)
make_vars = build_env._get_make_environment_vars(pyodide_root=xbuildenv_root)
assert make_vars["PYODIDE_ROOT"] == str(xbuildenv_root)
def test_check_emscripten_version(monkeypatch):
s = None
def get_emscripten_version_info():
nonlocal s
return s
needed_version = build_env.emscripten_version()
monkeypatch.setattr(
build_env, "get_emscripten_version_info", get_emscripten_version_info
)
s = """\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.4 (14cd48e6ead13b02a79f47df1a252abc501a3269)
clang version 15.0.0 (https://github.com/llvm/llvm-project ce5588fdf478b6af724977c11a405685cebc3d26)
Target: wasm32-unknown-emscripten
Thread model: posix
"""
with pytest.raises(
RuntimeError,
match=f"Incorrect Emscripten version 3.1.4. Need Emscripten version {needed_version}",
):
build_env.check_emscripten_version()
s = """\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.39.20
clang version 12.0.0 (/b/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-llvm-llvm--project 55fa315b0352b63454206600d6803fafacb42d5e)
"""
with pytest.raises(
RuntimeError,
match=f"Incorrect Emscripten version 1.39.20. Need Emscripten version {needed_version}",
):
build_env.check_emscripten_version()
s = f"""\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) {build_env.emscripten_version()} (4343cbec72b7db283ea3bda1adc6cb1811ae9a73)
clang version 15.0.0 (https://github.com/llvm/llvm-project 7effcbda49ba32991b8955821b8fdbd4f8f303e2)
"""
build_env.check_emscripten_version()
def get_emscripten_version_info(): # type: ignore[no-redef]
raise FileNotFoundError()
monkeypatch.setattr(
build_env, "get_emscripten_version_info", get_emscripten_version_info
)
with pytest.raises(
RuntimeError,
match=f"No Emscripten compiler found. Need Emscripten version {needed_version}",
):
build_env.check_emscripten_version()
def test_wheel_paths():
from pathlib import Path
old_version = "cp38"
PYMAJOR = int(build_env.get_build_flag("PYMAJOR"))
PYMINOR = int(build_env.get_build_flag("PYMINOR"))
PLATFORM = build_env.platform()
current_version = f"cp{PYMAJOR}{PYMINOR}"
future_version = f"cp{PYMAJOR}{PYMINOR + 1}"
strings = []
for interp in [
old_version,
current_version,
future_version,
"py3",
"py2",
"py2.py3",
]:
for abi in [interp, "abi3", "none"]:
for arch in [PLATFORM, "linux_x86_64", "any"]:
strings.append(f"wrapt-1.13.3-{interp}-{abi}-{arch}.whl")
paths = [Path(x) for x in strings]
assert [
x.stem.split("-", 2)[-1]
for x in common.find_matching_wheels(paths, build_env.pyodide_tags())
] == [
f"{current_version}-{current_version}-{PLATFORM}",
f"{current_version}-abi3-{PLATFORM}",
f"{current_version}-none-{PLATFORM}",
f"{old_version}-abi3-{PLATFORM}",
f"py3-none-{PLATFORM}",
f"py2.py3-none-{PLATFORM}",
"py3-none-any",
"py2.py3-none-any",
f"{current_version}-none-any",
]