-
Notifications
You must be signed in to change notification settings - Fork 3k
/
test_lib.py
260 lines (227 loc) · 8.43 KB
/
test_lib.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
"""Test the test support."""
import filecmp
import pathlib
import re
import sys
from contextlib import contextmanager
from os.path import isdir, join
from typing import Any, Dict, Iterator, Type
import pytest
from tests.lib import SRC_DIR, PipTestEnvironment
@contextmanager
def assert_error_startswith(
exc_type: Type[Exception], expected_start: str
) -> Iterator[None]:
"""
Assert that an exception is raised starting with a certain message.
"""
with pytest.raises(exc_type) as err:
yield
assert str(err.value).startswith(expected_start), f"full message: {err.value}"
def test_tmp_dir_exists_in_env(script: PipTestEnvironment) -> None:
"""
Test that $TMPDIR == env.temp_path and path exists and env.assert_no_temp()
passes (in fast env)
"""
# need these tests to ensure the assert_no_temp feature of scripttest is
# working
script.assert_no_temp() # this fails if env.tmp_path doesn't exist
assert pathlib.Path(script.environ["TMPDIR"]) == script.temp_path
assert isdir(script.temp_path)
def test_correct_pip_version(script: PipTestEnvironment) -> None:
"""
Check we are running proper version of pip in run_pip.
"""
if script.zipapp:
pytest.skip("Test relies on the pip under test being in the filesystem")
# output is like:
# pip PIPVERSION from PIPDIRECTORY (python PYVERSION)
result = script.pip("--version")
# compare the directory tree of the invoked pip with that of this source
# distribution
match = re.match(
r"pip \d+(\.[\d]+)+(\.?(b|rc|dev|pre|post)\d+)? from (.*) "
r"\(python \d+(\.[\d]+)+\)$",
result.stdout,
)
assert match is not None
pip_folder_outputed = match.group(4)
pip_folder = join(SRC_DIR, "src", "pip")
diffs = filecmp.dircmp(pip_folder, pip_folder_outputed)
# If any non-matching .py files exist, we have a problem: run_pip
# is picking up some other version! N.B. if this project acquires
# primary resources other than .py files, this code will need
# maintenance
mismatch_py = [
x
for x in diffs.left_only + diffs.right_only + diffs.diff_files
if x.endswith(".py")
]
assert not mismatch_py, (
f"mismatched source files in {pip_folder!r} "
f"and {pip_folder_outputed!r}: {mismatch_py!r}"
)
def test_as_import(script: PipTestEnvironment) -> None:
"""test that pip.__init__.py does not shadow
the command submodule with a dictionary
"""
import pip._internal.commands.install as inst
assert inst is not None
class TestPipTestEnvironment:
def run_stderr_with_prefix(
self, script: PipTestEnvironment, prefix: str, **kwargs: Any
) -> None:
"""
Call run() that prints stderr with the given prefix.
"""
text = f"{prefix}: hello, world\\n"
command = f'import sys; sys.stderr.write("{text}")'
args = [sys.executable, "-c", command]
script.run(*args, **kwargs)
def run_with_log_command(
self, script: PipTestEnvironment, sub_string: str, **kwargs: Any
) -> None:
"""
Call run() on a command that logs a "%"-style format string using
the given substring as the string's replacement field.
"""
command = (
"import logging; logging.basicConfig(level='INFO'); "
f"logging.getLogger().info('sub: {sub_string}', 'foo')"
)
args = [sys.executable, "-c", command]
script.run(*args, **kwargs)
@pytest.mark.parametrize(
"prefix",
[
"DEBUG",
"INFO",
"FOO",
],
)
def test_run__allowed_stderr(self, script: PipTestEnvironment, prefix: str) -> None:
"""
Test calling run() with allowed stderr.
"""
# Check that no error happens.
self.run_stderr_with_prefix(script, prefix)
def test_run__allow_stderr_warning(self, script: PipTestEnvironment) -> None:
"""
Test passing allow_stderr_warning=True.
"""
# Check that no error happens.
self.run_stderr_with_prefix(
script,
"WARNING",
allow_stderr_warning=True,
)
# Check that an error still happens with ERROR.
expected_start = "stderr has an unexpected error"
with assert_error_startswith(RuntimeError, expected_start):
self.run_stderr_with_prefix(
script,
"ERROR",
allow_stderr_warning=True,
)
@pytest.mark.parametrize(
"prefix",
[
"WARNING",
"ERROR",
],
)
def test_run__allow_stderr_error(
self, script: PipTestEnvironment, prefix: str
) -> None:
"""
Test passing allow_stderr_error=True.
"""
# Check that no error happens.
self.run_stderr_with_prefix(script, prefix, allow_stderr_error=True)
@pytest.mark.parametrize(
"prefix, expected_start",
[
("WARNING", "stderr has an unexpected warning"),
("ERROR", "stderr has an unexpected error"),
],
)
def test_run__unexpected_stderr(
self, script: PipTestEnvironment, prefix: str, expected_start: str
) -> None:
"""
Test calling run() with unexpected stderr output.
"""
with assert_error_startswith(RuntimeError, expected_start):
self.run_stderr_with_prefix(script, prefix)
def test_run__logging_error(self, script: PipTestEnvironment) -> None:
"""
Test calling run() with an unexpected logging error.
"""
# Pass a good substitution string.
self.run_with_log_command(script, sub_string="%r")
expected_start = "stderr has a logging error, which is never allowed"
with assert_error_startswith(RuntimeError, expected_start):
# Pass a bad substitution string. Also, pass
# allow_stderr_error=True to check that the RuntimeError occurs
# even under the stricter test condition of when we are allowing
# other types of errors.
self.run_with_log_command(
script,
sub_string="{!r}",
allow_stderr_error=True,
)
def test_run__allow_stderr_error_false_error_with_expect_error(
self, script: PipTestEnvironment
) -> None:
"""
Test passing allow_stderr_error=False with expect_error=True.
"""
expected_start = "cannot pass allow_stderr_error=False with expect_error=True"
with assert_error_startswith(RuntimeError, expected_start):
script.run("python", allow_stderr_error=False, expect_error=True)
def test_run__allow_stderr_warning_false_error_with_expect_stderr(
self, script: PipTestEnvironment
) -> None:
"""
Test passing allow_stderr_warning=False with expect_stderr=True.
"""
expected_start = (
"cannot pass allow_stderr_warning=False with expect_stderr=True"
)
with assert_error_startswith(RuntimeError, expected_start):
script.run(
"python",
allow_stderr_warning=False,
expect_stderr=True,
)
@pytest.mark.parametrize(
"arg_name",
[
"expect_error",
"allow_stderr_error",
],
)
def test_run__allow_stderr_warning_false_error(
self, script: PipTestEnvironment, arg_name: str
) -> None:
"""
Test passing allow_stderr_warning=False when it is not allowed.
"""
kwargs: Dict[str, Any] = {"allow_stderr_warning": False, arg_name: True}
expected_start = (
"cannot pass allow_stderr_warning=False with allow_stderr_error=True"
)
with assert_error_startswith(RuntimeError, expected_start):
script.run("python", **kwargs)
def test_run__expect_error_fails_when_zero_returncode(
self, script: PipTestEnvironment
) -> None:
expected_start = "Script passed unexpectedly"
with assert_error_startswith(AssertionError, expected_start):
script.run("python", expect_error=True)
def test_run__no_expect_error_fails_when_nonzero_returncode(
self, script: PipTestEnvironment
) -> None:
expected_start = "Script returned code: 1"
with assert_error_startswith(AssertionError, expected_start):
script.run("python", "-c", "import sys; sys.exit(1)")