forked from tox-dev/tox
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_session.py
380 lines (314 loc) · 11.4 KB
/
test_session.py
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
import os
import sys
import textwrap
from threading import Thread
import pytest
import tox
from tox.exception import MissingDependency, MissingDirectory
from tox.package import resolve_package
from tox.reporter import Verbosity
if sys.version_info >= (3, 3):
from shlex import quote as shlex_quote
else:
from pipes import quote as shlex_quote
def test_resolve_pkg_missing_directory(tmpdir, mocksession):
distshare = tmpdir.join("distshare")
spec = distshare.join("pkg123-*")
with pytest.raises(MissingDirectory):
resolve_package(spec)
def test_resolve_pkg_missing_directory_in_distshare(tmpdir, mocksession):
distshare = tmpdir.join("distshare")
spec = distshare.join("pkg123-*")
distshare.ensure(dir=1)
with pytest.raises(MissingDependency):
resolve_package(spec)
def test_resolve_pkg_multiple_valid_versions(tmpdir, mocksession):
mocksession.logging_levels(quiet=Verbosity.DEFAULT, verbose=Verbosity.DEBUG)
distshare = tmpdir.join("distshare")
distshare.ensure("pkg123-1.3.5.zip")
p = distshare.ensure("pkg123-1.4.5.zip")
result = resolve_package(distshare.join("pkg123-*"))
assert result == p
mocksession.report.expect("info", "determin*pkg123*")
def test_resolve_pkg_with_invalid_version(tmpdir, mocksession):
distshare = tmpdir.join("distshare")
distshare.ensure("pkg123-1.something_bad.zip")
distshare.ensure("pkg123-1.3.5.zip")
p = distshare.ensure("pkg123-1.4.5.zip")
result = resolve_package(distshare.join("pkg123-*"))
mocksession.report.expect("warning", "*1.something_bad*")
assert result == p
def test_resolve_pkg_with_alpha_version(tmpdir, mocksession):
distshare = tmpdir.join("distshare")
distshare.ensure("pkg123-1.3.5.zip")
distshare.ensure("pkg123-1.4.5a1.tar.gz")
p = distshare.ensure("pkg123-1.4.5.zip")
result = resolve_package(distshare.join("pkg123-*"))
assert result == p
def test_resolve_pkg_doubledash(tmpdir, mocksession):
distshare = tmpdir.join("distshare")
p = distshare.ensure("pkg-mine-1.3.0.zip")
res = resolve_package(distshare.join("pkg-mine*"))
assert res == p
distshare.ensure("pkg-mine-1.3.0a1.zip")
res = resolve_package(distshare.join("pkg-mine*"))
assert res == p
def test_skip_sdist(cmd, initproj):
initproj(
"pkg123-0.7",
filedefs={
"tests": {"test_hello.py": "def test_hello(): pass"},
"setup.py": """
syntax error
""",
"tox.ini": """
[tox]
skipsdist=True
[testenv]
commands=python -c "print('done')"
""",
},
)
result = cmd()
result.assert_success()
def test_skip_install_skip_package(cmd, initproj, mock_venv):
initproj(
"pkg123-0.7",
filedefs={
"setup.py": """raise RuntimeError""",
"tox.ini": """
[tox]
envlist = py
[testenv]
skip_install = true
""",
},
)
result = cmd("--notest")
result.assert_success()
@pytest.fixture()
def venv_filter_project(initproj, cmd):
def func(*args):
initproj(
"pkg123-0.7",
filedefs={
"tox.ini": """
[tox]
envlist = {py27,py36}-{nocov,cov,diffcov}{,-extra}
skipsdist = true
[testenv]
skip_install = true
commands = python -c 'print("{envname}")'
""",
},
)
result = cmd(*args)
result.assert_success(is_run_test_env=False)
active = [i.name for i in result.session.existing_venvs.values()]
return active, result
yield func
def test_venv_filter_empty_all_active(venv_filter_project, monkeypatch):
monkeypatch.delenv("TOX_SKIP_ENV", raising=False)
active, result = venv_filter_project("-a")
assert result.outlines == [
"py27-nocov",
"py27-nocov-extra",
"py27-cov",
"py27-cov-extra",
"py27-diffcov",
"py27-diffcov-extra",
"py36-nocov",
"py36-nocov-extra",
"py36-cov",
"py36-cov-extra",
"py36-diffcov",
"py36-diffcov-extra",
]
assert active == result.outlines
def test_venv_filter_match_all_none_active(venv_filter_project, monkeypatch):
monkeypatch.setenv("TOX_SKIP_ENV", ".*")
active, result = venv_filter_project("-a")
assert not active
existing_envs = result.outlines
_, result = venv_filter_project("-avv")
for name in existing_envs:
msg = "skip environment {}, matches filter '.*'".format(name)
assert msg in result.outlines
def test_venv_filter_match_some_some_active(venv_filter_project, monkeypatch):
monkeypatch.setenv("TOX_SKIP_ENV", "py27.*")
active, result = venv_filter_project("-avvv")
assert active == [
"py36-nocov",
"py36-nocov-extra",
"py36-cov",
"py36-cov-extra",
"py36-diffcov",
"py36-diffcov-extra",
]
@pytest.fixture()
def popen_env_test(initproj, cmd, monkeypatch):
def func(tox_env, isolated_build):
files = {
"tox.ini": """
[tox]
isolated_build = {}
[testenv:{}]
commands = python -c "print('ok')"
""".format(
"True" if isolated_build else "False",
tox_env,
),
}
if isolated_build:
files[
"pyproject.toml"
] = """
[build-system]
requires = ["setuptools >= 35.0.2", "setuptools_scm >= 2.0.0, <3"]
build-backend = 'setuptools.build_meta'
"""
initproj("env_var_test", filedefs=files)
class IsolatedResult(object):
def __init__(self):
self.popens = []
self.cwd = None
res = IsolatedResult()
class EnvironmentTestRun(Thread):
"""we wrap this invocation into a thread to avoid modifying in any way the
current threads environment variable (e.g. on failure of this test incorrect teardown)
"""
def run(self):
prev_build = tox.session.build_session
def build_session(config):
res.session = prev_build(config)
res._popen = res.session.popen
monkeypatch.setattr(res.session, "popen", popen)
return res.session
monkeypatch.setattr(tox.session, "build_session", build_session)
def popen(cmd, **kwargs):
activity_id = _actions[-1].name
activity_name = _actions[-1].activity
ret = "NOTSET"
try:
ret = res._popen(cmd, **kwargs)
except tox.exception.InvocationError as exception:
ret = exception
finally:
res.popens.append(
(activity_id, activity_name, kwargs.get("env"), ret, cmd),
)
return ret
_actions = []
from tox.action import Action
_prev_enter = Action.__enter__
def enter(self):
_actions.append(self)
return _prev_enter(self)
monkeypatch.setattr(Action, "__enter__", enter)
_prev_exit = Action.__exit__
def exit_func(self, *args, **kwargs):
del _actions[_actions.index(self)]
_prev_exit(self, *args, **kwargs)
monkeypatch.setattr(Action, "__exit__", exit_func)
res.result = cmd("-e", tox_env)
res.cwd = os.getcwd()
thread = EnvironmentTestRun()
thread.start()
thread.join()
return res
yield func
@pytest.mark.network
def test_tox_env_var_flags_inserted_non_isolated(popen_env_test):
res = popen_env_test("py", False)
assert_popen_env(res)
@pytest.mark.network
def test_tox_env_var_flags_inserted_isolated(popen_env_test):
res = popen_env_test("py", True)
assert_popen_env(res)
def assert_popen_env(res):
res.result.assert_success()
for tox_id, _, env, __, ___ in res.popens:
assert env["TOX_WORK_DIR"] == os.path.join(res.cwd, ".tox")
if tox_id != "GLOB":
assert env["TOX_ENV_NAME"] == tox_id
assert env["TOX_ENV_DIR"] == os.path.join(res.cwd, ".tox", tox_id)
# ensure native strings for environ for windows
for k, v in env.items():
assert type(k) is str, (k, v, type(k))
assert type(v) is str, (k, v, type(v))
def test_command_prev_post_ok(cmd, initproj, mock_venv):
initproj(
"pkg_command_test_123-0.7",
filedefs={
"tox.ini": """
[tox]
envlist = py
[testenv]
commands_pre = python -c 'print("pre")'
commands = python -c 'print("command")'
commands_post = python -c 'print("post")'
""",
},
)
result = cmd()
result.assert_success()
expected = textwrap.dedent(
"""
py run-test-pre: commands[0] | python -c 'print("pre")'
pre
py run-test: commands[0] | python -c 'print("command")'
command
py run-test-post: commands[0] | python -c 'print("post")'
post
___________________________________ summary ___________________________________{}
py: commands succeeded
congratulations :)
""".format(
"_" if sys.platform != "win32" else "",
),
).lstrip()
have = result.out.replace(os.linesep, "\n")
actual = have[len(have) - len(expected) :]
assert actual == expected
def test_command_prev_fail_command_skip_post_run(cmd, initproj, mock_venv):
initproj(
"pkg_command_test_123-0.7",
filedefs={
"tox.ini": """
[tox]
envlist = py
[testenv]
commands_pre = python -c 'raise SystemExit(2)'
commands = python -c 'print("command")'
commands_post = python -c 'print("post")'
""",
},
)
result = cmd()
result.assert_fail()
expected = textwrap.dedent(
"""
py run-test-pre: commands[0] | python -c 'raise SystemExit(2)'
ERROR: InvocationError for command {} -c 'raise SystemExit(2)' (exited with code 2)
py run-test-post: commands[0] | python -c 'print("post")'
post
___________________________________ summary ___________________________________{}
ERROR: py: commands failed
""".format(
shlex_quote(sys.executable),
"_" if sys.platform != "win32" else "",
),
)
have = result.out.replace(os.linesep, "\n")
actual = have[len(have) - len(expected) :]
assert actual == expected
def test_help_compound_ve_works(cmd, initproj, monkeypatch):
initproj("test-0.1", {"tox.ini": ""})
result = cmd("-ve", "py", "-a")
result.assert_success(is_run_test_env=False)
assert not result.err
assert result.outlines[0].startswith("using")
assert result.outlines[1].startswith("using")
assert result.outlines[2] == "additional environments:"
assert result.outlines[3] == "py -> [no description]"
assert len(result.outlines) == 4