-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_runtime.py
More file actions
177 lines (111 loc) · 6.13 KB
/
Copy pathtest_runtime.py
File metadata and controls
177 lines (111 loc) · 6.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import os
import sys
import pytest
from ghpython_componentizer import runtime
@pytest.fixture
def macos(monkeypatch):
"""Pretend we are on macOS, with a Homebrew-installed libgdiplus."""
monkeypatch.setattr(runtime.platform, "system", lambda: "Darwin")
monkeypatch.setattr(runtime.shutil, "which", lambda cmd: "/opt/homebrew/bin/" + cmd)
monkeypatch.setattr(runtime, "find_libgdiplus_dirs", lambda: ["/opt/homebrew/lib"])
monkeypatch.delenv(runtime.RELAUNCH_FLAG, raising=False)
monkeypatch.delenv("PYTHONNET_RUNTIME", raising=False)
monkeypatch.delenv("DYLD_LIBRARY_PATH", raising=False)
monkeypatch.setattr(runtime, "_drawing_checked", False)
@pytest.fixture
def not_macos(monkeypatch):
monkeypatch.setattr(runtime.platform, "system", lambda: "Windows")
# Anything that loaded the .NET runtime before may have selected mono.
monkeypatch.delenv("PYTHONNET_RUNTIME", raising=False)
monkeypatch.setattr(runtime, "_drawing_checked", False)
def test_componentizer_env_is_unchanged_outside_macos(not_macos):
env = runtime.componentizer_env({"PATH": "/usr/bin"})
assert env == {"PATH": "/usr/bin"}
def test_componentizer_env_selects_mono_and_library_path(macos):
env = runtime.componentizer_env({})
assert env["PYTHONNET_RUNTIME"] == "mono"
assert env["DYLD_LIBRARY_PATH"] == "/opt/homebrew/lib"
def test_componentizer_env_keeps_existing_settings(macos):
env = runtime.componentizer_env({"PYTHONNET_RUNTIME": "coreclr", "DYLD_LIBRARY_PATH": "/somewhere/lib"})
assert env["PYTHONNET_RUNTIME"] == "coreclr"
assert env["DYLD_LIBRARY_PATH"] == os.pathsep.join(["/opt/homebrew/lib", "/somewhere/lib"])
def test_componentizer_env_does_not_select_mono_without_mono(macos, monkeypatch):
monkeypatch.setattr(runtime.shutil, "which", lambda cmd: None)
assert "PYTHONNET_RUNTIME" not in runtime.componentizer_env({})
def test_componentizer_env_without_libgdiplus(macos, monkeypatch):
monkeypatch.setattr(runtime, "find_libgdiplus_dirs", list)
assert "DYLD_LIBRARY_PATH" not in runtime.componentizer_env({})
def test_find_libgdiplus_dirs(tmp_path, monkeypatch):
monkeypatch.setattr(runtime.subprocess, "check_output", _brew_is_missing)
(tmp_path / runtime.LIBGDIPLUS).write_bytes(b"not really a library")
monkeypatch.setattr(runtime, "FALLBACK_LIB_DIRS", (str(tmp_path), "/nowhere/to/be/found"))
assert runtime.find_libgdiplus_dirs() == [str(tmp_path)]
def test_prepare_runtime_outside_macos_leaves_environment_alone(not_macos):
runtime.prepare_runtime()
assert "PYTHONNET_RUNTIME" not in os.environ
def test_prepare_runtime_selects_mono(macos):
runtime.prepare_runtime()
assert os.environ["PYTHONNET_RUNTIME"] == "mono"
def test_require_drawing_support_is_a_noop_outside_macos(not_macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
runtime.require_drawing_support()
def test_require_drawing_support_passes_with_loadable_library(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: True)
runtime.require_drawing_support()
def test_require_drawing_support_reports_missing_library(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
monkeypatch.setattr(runtime, "find_libgdiplus_dirs", list)
with pytest.raises(RuntimeError, match="brew install mono-libgdiplus"):
runtime.require_drawing_support()
def test_require_drawing_support_reports_unreachable_library(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
with pytest.raises(RuntimeError, match="DYLD_LIBRARY_PATH"):
runtime.require_drawing_support()
def test_require_drawing_support_reports_stripped_environment(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
monkeypatch.setenv(runtime.RELAUNCH_FLAG, "1")
with pytest.raises(RuntimeError, match="protected binary"):
runtime.require_drawing_support()
def test_relaunch_is_a_noop_outside_macos(not_macos, monkeypatch):
monkeypatch.setattr(os, "execve", _fail_on_execve)
runtime.relaunch_for_macos(["components", "build"])
def test_relaunch_is_a_noop_once_relaunched(macos, monkeypatch):
monkeypatch.setenv(runtime.RELAUNCH_FLAG, "1")
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
monkeypatch.setattr(os, "execve", _fail_on_execve)
runtime.relaunch_for_macos(["components", "build"])
def test_relaunch_is_a_noop_when_library_is_reachable(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: True)
monkeypatch.setattr(os, "execve", _fail_on_execve)
runtime.relaunch_for_macos(["components", "build"])
def test_relaunch_restarts_with_a_fixed_environment(macos, monkeypatch):
monkeypatch.setattr(runtime, "libgdiplus_is_loadable", lambda: False)
calls = []
monkeypatch.setattr(os, "execve", lambda *args: calls.append(args))
runtime.relaunch_for_macos(["components", "build"])
executable, command, env = calls[0]
assert executable == sys.executable
assert command == [
sys.executable,
"-m",
"ghpython_componentizer",
"components",
"build",
]
assert env[runtime.RELAUNCH_FLAG] == "1"
assert env["DYLD_LIBRARY_PATH"] == "/opt/homebrew/lib"
def test_run_componentizer_builds_a_command(monkeypatch):
calls = []
monkeypatch.setattr(runtime, "componentizer_env", lambda: {"PATH": "/usr/bin"})
monkeypatch.setattr(runtime.subprocess, "run", lambda cmd, **kwargs: calls.append((cmd, kwargs)))
runtime.run_componentizer("components", "build", version="0.1.2", prefix="(GKR) ")
command, kwargs = calls[0]
assert command[:3] == [sys.executable, "-m", "ghpython_componentizer"]
assert command[3:5] == [os.path.abspath("components"), os.path.abspath("build")]
assert command[5:] == ["--version", "0.1.2", "--prefix", "(GKR) "]
assert kwargs["check"] is True
assert kwargs["env"]
def _brew_is_missing(*args, **kwargs):
raise OSError("no brew around here")
def _fail_on_execve(*args):
raise AssertionError("should not have relaunched")