File size: 8,974 Bytes
d1ceb73 |
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 |
import distutils.errors
import urllib.request
import urllib.error
import http.client
from inspect import cleandoc
import pytest
import setuptools.package_index
class TestPackageIndex:
def test_regex(self):
hash_url = 'http://other_url?:action=show_md5&'
hash_url += 'digest=0123456789abcdef0123456789abcdef'
doc = """
<a href="http://some_url">Name</a>
(<a title="MD5 hash"
href="{hash_url}">md5</a>)
""".lstrip().format(**locals())
assert setuptools.package_index.PYPI_MD5.match(doc)
def test_bad_url_bad_port(self):
index = setuptools.package_index.PackageIndex()
url = 'http://127.0.0.1:0/nonesuch/test_package_index'
try:
v = index.open_url(url)
except Exception as exc:
assert url in str(exc)
else:
assert isinstance(v, urllib.error.HTTPError)
def test_bad_url_typo(self):
# issue 16
# easy_install inquant.contentmirror.plone breaks because of a typo
# in its home URL
index = setuptools.package_index.PackageIndex(hosts=('www.example.com',))
url = (
'url:%20https://svn.plone.org/svn'
'/collective/inquant.contentmirror.plone/trunk'
)
try:
v = index.open_url(url)
except Exception as exc:
assert url in str(exc)
else:
assert isinstance(v, urllib.error.HTTPError)
def test_bad_url_bad_status_line(self):
index = setuptools.package_index.PackageIndex(hosts=('www.example.com',))
def _urlopen(*args):
raise http.client.BadStatusLine('line')
index.opener = _urlopen
url = 'http://example.com'
try:
index.open_url(url)
except Exception as exc:
assert 'line' in str(exc)
else:
raise AssertionError('Should have raise here!')
def test_bad_url_double_scheme(self):
"""
A bad URL with a double scheme should raise a DistutilsError.
"""
index = setuptools.package_index.PackageIndex(hosts=('www.example.com',))
# issue 20
url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
try:
index.open_url(url)
except distutils.errors.DistutilsError as error:
msg = str(error)
assert (
'nonnumeric port' in msg
or 'getaddrinfo failed' in msg
or 'Name or service not known' in msg
)
return
raise RuntimeError("Did not raise")
def test_url_ok(self):
index = setuptools.package_index.PackageIndex(hosts=('www.example.com',))
url = 'file:///tmp/test_package_index'
assert index.url_ok(url, True)
def test_parse_bdist_wininst(self):
parse = setuptools.package_index.parse_bdist_wininst
actual = parse('reportlab-2.5.win32-py2.4.exe')
expected = 'reportlab-2.5', '2.4', 'win32'
assert actual == expected
actual = parse('reportlab-2.5.win32.exe')
expected = 'reportlab-2.5', None, 'win32'
assert actual == expected
actual = parse('reportlab-2.5.win-amd64-py2.7.exe')
expected = 'reportlab-2.5', '2.7', 'win-amd64'
assert actual == expected
actual = parse('reportlab-2.5.win-amd64.exe')
expected = 'reportlab-2.5', None, 'win-amd64'
assert actual == expected
def test__vcs_split_rev_from_url(self):
"""
Test the basic usage of _vcs_split_rev_from_url
"""
vsrfu = setuptools.package_index.PackageIndex._vcs_split_rev_from_url
url, rev = vsrfu('https://example.com/bar@2995')
assert url == 'https://example.com/bar'
assert rev == '2995'
def test_local_index(self, tmpdir):
"""
local_open should be able to read an index from the file system.
"""
index_file = tmpdir / 'index.html'
with index_file.open('w') as f:
f.write('<div>content</div>')
url = 'file:' + urllib.request.pathname2url(str(tmpdir)) + '/'
res = setuptools.package_index.local_open(url)
assert 'content' in res.read()
def test_egg_fragment(self):
"""
EGG fragments must comply to PEP 440
"""
epoch = [
'',
'1!',
]
releases = [
'0',
'0.0',
'0.0.0',
]
pre = [
'a0',
'b0',
'rc0',
]
post = ['.post0']
dev = [
'.dev0',
]
local = [
('', ''),
('+ubuntu.0', '+ubuntu.0'),
('+ubuntu-0', '+ubuntu.0'),
('+ubuntu_0', '+ubuntu.0'),
]
versions = [
[''.join([e, r, p, loc]) for loc in locs]
for e in epoch
for r in releases
for p in sum([pre, post, dev], [''])
for locs in local
]
for v, vc in versions:
dists = list(
setuptools.package_index.distros_for_url(
'http://example.com/example-foo.zip#egg=example-foo-' + v
)
)
assert dists[0].version == ''
assert dists[1].version == vc
def test_download_git_with_rev(self, tmp_path, fp):
url = 'git+https://github.example/group/project@master#egg=foo'
index = setuptools.package_index.PackageIndex()
expected_dir = tmp_path / 'project@master'
fp.register([
'git',
'clone',
'--quiet',
'https://github.example/group/project',
expected_dir,
])
fp.register(['git', '-C', expected_dir, 'checkout', '--quiet', 'master'])
result = index.download(url, tmp_path)
assert result == str(expected_dir)
assert len(fp.calls) == 2
def test_download_git_no_rev(self, tmp_path, fp):
url = 'git+https://github.example/group/project#egg=foo'
index = setuptools.package_index.PackageIndex()
expected_dir = tmp_path / 'project'
fp.register([
'git',
'clone',
'--quiet',
'https://github.example/group/project',
expected_dir,
])
index.download(url, tmp_path)
def test_download_svn(self, tmp_path):
url = 'svn+https://svn.example/project#egg=foo'
index = setuptools.package_index.PackageIndex()
msg = r".*SVN download is not supported.*"
with pytest.raises(distutils.errors.DistutilsError, match=msg):
index.download(url, tmp_path)
class TestContentCheckers:
def test_md5(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478'
)
checker.feed('You should probably not be using MD5'.encode('ascii'))
assert checker.hash.hexdigest() == 'f12895fdffbd45007040d2e44df98478'
assert checker.is_valid()
def test_other_fragment(self):
"Content checks should succeed silently if no hash is present"
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#something%20completely%20different'
)
checker.feed('anything'.encode('ascii'))
assert checker.is_valid()
def test_blank_md5(self):
"Content checks should succeed if a hash is empty"
checker = setuptools.package_index.HashChecker.from_url('http://foo/bar#md5=')
checker.feed('anything'.encode('ascii'))
assert checker.is_valid()
def test_get_hash_name_md5(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478'
)
assert checker.hash_name == 'md5'
def test_report(self):
checker = setuptools.package_index.HashChecker.from_url(
'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478'
)
rep = checker.report(lambda x: x, 'My message about %s')
assert rep == 'My message about md5'
class TestPyPIConfig:
def test_percent_in_password(self, tmp_home_dir):
pypirc = tmp_home_dir / '.pypirc'
pypirc.write_text(
cleandoc(
"""
[pypi]
repository=https://pypi.org
username=jaraco
password=pity%
"""
),
encoding="utf-8",
)
cfg = setuptools.package_index.PyPIConfig()
cred = cfg.creds_by_repository['https://pypi.org']
assert cred.username == 'jaraco'
assert cred.password == 'pity%'
@pytest.mark.timeout(1)
def test_REL_DoS():
"""
REL should not hang on a contrived attack string.
"""
setuptools.package_index.REL.search('< rel=' + ' ' * 2**12)
|