Remove pytest-pypi package included in tests/

This commit is contained in:
Oz Tiram
2022-12-28 15:46:53 +01:00
parent abcb3e2df4
commit 3a2e708001
24 changed files with 0 additions and 815 deletions
-5
View File
@@ -1,5 +0,0 @@
pytest-pypi
===========
Easily test your HTTP library against a local copy of PyPI.
This is an internal pytest plugin of pipenv.
-4
View File
@@ -1,4 +0,0 @@
# If using Python 2.6 or less, then have to include package data, even though
# it's already declared in setup.py
include pytest_httpbin/certs/*
include DESCRIPTION.rst
-4
View File
@@ -1,4 +0,0 @@
# pytest-pypi
Easily test your HTTP library against a local copy of PyPI.
This is an internal pytest plugin of pipenv.
-3
View File
@@ -1,3 +0,0 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta:__legacy__"
-14
View File
@@ -1,14 +0,0 @@
import os
import pytest
here = os.path.dirname(__file__)
version_file = os.path.join(here, "version.py")
with open(version_file) as f:
code = compile(f.read(), version_file, 'exec')
exec(code)
use_class_based_httpbin = pytest.mark.usefixtures("class_based_pypi")
use_class_based_httpbin_secure = pytest.mark.usefixtures("class_based_pypi_secure")
-239
View File
@@ -1,239 +0,0 @@
import collections
import contextlib
import io
import json
import os
from tarfile import is_tarfile
from zipfile import is_zipfile
import distlib.wheel
import requests
from six.moves import xmlrpc_client
from flask import Flask, redirect, abort, render_template, send_file, jsonify
ReleaseTuple = collections.namedtuple("ReleaseTuple", ["path", "requires_python", "hash"])
app = Flask(__name__)
session = requests.Session()
packages = {}
ARTIFACTS = {}
@contextlib.contextmanager
def xml_pypi_server(server):
transport = xmlrpc_client.Transport()
client = xmlrpc_client.ServerProxy(server, transport)
try:
yield client
finally:
transport.close()
def get_pypi_package_names():
pypi_packages = set()
with xml_pypi_server("https://pypi.org/pypi") as client:
pypi_packages = set(client.list_packages())
return pypi_packages
class Package:
"""Package represents a collection of releases from one or more directories"""
def __init__(self, name):
super().__init__()
self.name = name
self.releases = {}
self._package_dirs = set()
@property
def json(self):
for path, _ in self._package_dirs:
try:
with open(os.path.join(path, 'api.json')) as f:
return json.load(f)
except FileNotFoundError:
r = session.get(f'https://pypi.org/pypi/{self.name}/json')
response = r.json()
releases = response["releases"]
files = {
pkg for pkg_dir in self._package_dirs
for pkg in os.listdir(pkg_dir.path)
}
for release in list(releases.keys()):
values = (
r for r in releases[release] if r["filename"] in files
)
values = list(values)
if values:
releases[release] = values
else:
del releases[release]
response["releases"] = releases
with open(os.path.join(path, "api.json"), "w") as fh:
json.dump(response, fh, indent=4)
return response
def __repr__(self):
return f"<Package name={self.name!r} releases={len(self.releases)!r}"
def add_release(self, path_to_binary):
path_to_binary = os.path.abspath(path_to_binary)
path, release = os.path.split(path_to_binary)
requires_python = ""
hash_value = ""
if path_to_binary.endswith(".whl"):
pkg = distlib.wheel.Wheel(path_to_binary)
md_dict = pkg.metadata.todict()
requires_python = md_dict.get("requires_python", "")
if requires_python.count(".") > 1:
requires_python, _, _ = requires_python.rpartition(".")
if os.path.isfile(path_to_binary + ".sha256"):
with open(path_to_binary + ".sha256") as f:
hash_value = f.read().strip()
self.releases[release] = ReleaseTuple(path_to_binary, requires_python, hash_value)
self._package_dirs.add(ReleaseTuple(path, requires_python, hash_value))
class Artifact:
"""Represents an artifact for download"""
def __init__(self, name):
super().__init__()
self.name = name
self.files = {}
self._artifact_dirs = set()
def __repr__(self):
return f"<Artifact name={self.name!r} files={len(self.files)!r}"
def add_file(self, path):
path = os.path.abspath(path)
base_path, fn = os.path.split(path)
self.files[fn] = path
self._artifact_dirs.add(base_path)
def prepare_fixtures(path):
path = os.path.abspath(path)
if not (os.path.exists(path) and os.path.isdir(path)):
raise ValueError(f"{path} is not a directory!")
for root, dirs, files in os.walk(path):
package_name, _, _ = os.path.relpath(root, start=path).partition(os.path.sep)
if package_name not in ARTIFACTS:
ARTIFACTS[package_name] = Artifact(package_name)
for file in files:
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, start=path)
_, _, subpkg = rel_path.partition(os.path.sep)
subpkg, _, _ = subpkg.partition(os.path.sep)
pkg, ext = os.path.splitext(subpkg)
if not (is_tarfile(file_path) or is_zipfile(file_path) or ext == ".git"):
continue
if subpkg not in ARTIFACTS[package_name].files:
ARTIFACTS[package_name].add_file(os.path.join(root, file))
ARTIFACTS[package_name].add_file(os.path.join(root, file))
def prepare_packages(path):
"""Add packages in path to the registry."""
path = os.path.abspath(path)
if not (os.path.exists(path) and os.path.isdir(path)):
raise ValueError(f"{path} is not a directory!")
for root, dirs, files in os.walk(path):
if all([setup_file in list(files) for setup_file in ("setup.py", "setup.cfg")]):
continue
for file in files:
if not file.startswith('.') and not file.endswith('.json'):
package_name = os.path.basename(root)
if package_name and package_name == "fixtures":
prepare_fixtures(root)
continue
package_name = package_name.replace("_", "-")
if package_name not in packages:
packages[package_name] = Package(package_name)
packages[package_name].add_release(os.path.join(root, file))
# remaining = get_pypi_package_names() - set(list(packages.keys()))
# for pypi_pkg in remaining:
# packages[pypi_pkg] = Package(pypi_pkg)
@app.route('/')
def hello_world():
return redirect('/simple', code=302)
@app.route('/simple')
def simple():
return render_template('simple.html', packages=packages.values())
@app.route('/artifacts')
def artifacts():
return render_template('artifacts.html', artifacts=ARTIFACTS.values())
@app.route('/simple/<package>/')
def simple_package(package):
if package in packages and packages[package].releases:
return render_template('package.html', package=packages[package])
else:
try:
r = requests.get(f"https://pypi.org/simple/{package}")
r.raise_for_status()
except Exception:
abort(404)
else:
return render_template(
'package_pypi.html', package_contents=r.text
)
@app.route('/artifacts/<artifact>/')
def simple_artifact(artifact):
if artifact in ARTIFACTS:
return render_template('artifact.html', artifact=ARTIFACTS[artifact])
else:
abort(404)
@app.route('/<package>/<release>')
def serve_package(package, release):
if package in packages:
package = packages[package]
if release in package.releases:
return send_file(package.releases[release].path)
abort(404)
@app.route('/artifacts/<artifact>/<fn>')
def serve_artifact(artifact, fn):
if artifact in ARTIFACTS:
artifact = ARTIFACTS[artifact]
if fn in artifact.files:
return send_file(artifact.files[fn])
abort(404)
@app.route('/pypi/<package>/json')
def json_for_package(package):
return jsonify(packages[package].json)
# try:
# except Exception:
# r = session.get('https://pypi.org/pypi/{0}/json'.format(package))
# return jsonify(r.json())
if __name__ == '__main__':
PYPI_VENDOR_DIR = os.environ.get('PYPI_VENDOR_DIR', './pypi')
PYPI_VENDOR_DIR = os.path.abspath(PYPI_VENDOR_DIR)
prepare_packages(PYPI_VENDOR_DIR)
prepare_fixtures(os.path.join(PYPI_VENDOR_DIR, "fixtures"))
app.run()
-22
View File
@@ -1,22 +0,0 @@
"""
certs.py
~~~~~~~~
This module returns the preferred default CA certificate bundle.
If you are packaging pytest-httpbin, e.g., for a Linux distribution or a
managed environment, you can change the definition of where() to return a
separately packaged CA bundle.
"""
import os.path
def where():
"""Return the preferred certificate bundle."""
# vendored bundle inside Requests
return os.path.join(os.path.abspath(os.path.dirname(__file__)), 'certs', 'cacert.pem')
if __name__ == '__main__':
print(where())
@@ -1,63 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
dd:39:30:16:60:55:90:7c
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority
Validity
Not Before: Jun 26 18:16:59 2015 GMT
Not After : Jun 18 18:16:59 2045 GMT
Subject: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:bd:80:fd:e4:96:0e:3b:5e:35:9b:83:00:34:88:
64:5a:50:53:0e:1d:94:76:c9:dc:e7:b5:59:1e:d4:
82:55:36:a6:b4:41:2c:60:ad:76:f0:cd:42:a0:0f:
4a:1c:0d:d7:29:da:c3:d9:c0:ea:f1:48:e0:66:4d:
4b:7c:ff:d6:5e:e0:73:89:53:8b:6e:6c:57:7d:bd:
e9:d0:46:39:5d:85:a5:f1:3a:d4:3d:83:19:03:44:
93:71:2c:5e:d7:61:8e:db:cc:80:d0:f1:c0:47:bf:
98:8f:06:40:e1:f7:41:ee:ed:a7:57:0d:a6:4c:26:
75:8e:f1:78:d3:80:ad:9c:e9
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA
X509v3 Authority Key Identifier:
keyid:AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA
DirName:/C=US/ST=Hawaii/O=kevin1024/CN=pytest-httpbin Certificate Authority
serial:DD:39:30:16:60:55:90:7C
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
bc:0c:b4:21:03:bf:35:bf:88:9f:de:06:23:f4:e3:8f:bc:34:
b5:8b:af:bf:31:5d:17:44:2c:72:c9:88:25:d1:c7:d0:1c:70:
06:82:a5:fa:fa:d7:b9:16:64:c2:08:54:1e:4c:93:9f:22:4e:
e5:4f:a7:71:e5:6e:14:31:e9:41:e2:33:23:8b:c8:01:c3:2a:
66:a8:d8:df:ef:ee:7b:bb:84:f4:78:a6:ca:8f:29:aa:d5:fa:
8a:73:94:0c:32:53:c8:93:bd:fc:c4:60:4d:9a:80:4f:c6:d4:
27:44:a2:37:63:6c:97:04:ce:e3:6a:6f:d3:84:0d:b4:74:1f:
49:eb
-----BEGIN CERTIFICATE-----
MIIDBzCCAnCgAwIBAgIJAN05MBZgVZB8MA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV
BAYTAlVTMQ8wDQYDVQQIEwZIYXdhaWkxEjAQBgNVBAoTCWtldmluMTAyNDEtMCsG
A1UEAxMkcHl0ZXN0LWh0dHBiaW4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE1
MDYyNjE4MTY1OVoXDTQ1MDYxODE4MTY1OVowYTELMAkGA1UEBhMCVVMxDzANBgNV
BAgTBkhhd2FpaTESMBAGA1UEChMJa2V2aW4xMDI0MS0wKwYDVQQDEyRweXRlc3Qt
aHR0cGJpbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAL2A/eSWDjteNZuDADSIZFpQUw4dlHbJ3Oe1WR7UglU2prRBLGCt
dvDNQqAPShwN1ynaw9nA6vFI4GZNS3z/1l7gc4lTi25sV3296dBGOV2FpfE61D2D
GQNEk3EsXtdhjtvMgNDxwEe/mI8GQOH3Qe7tp1cNpkwmdY7xeNOArZzpAgMBAAGj
gcYwgcMwHQYDVR0OBBYEFK4F772pzrum2A7rxIxyLxPlzarKMIGTBgNVHSMEgYsw
gYiAFK4F772pzrum2A7rxIxyLxPlzarKoWWkYzBhMQswCQYDVQQGEwJVUzEPMA0G
A1UECBMGSGF3YWlpMRIwEAYDVQQKEwlrZXZpbjEwMjQxLTArBgNVBAMTJHB5dGVz
dC1odHRwYmluIENlcnRpZmljYXRlIEF1dGhvcml0eYIJAN05MBZgVZB8MAwGA1Ud
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvAy0IQO/Nb+In94GI/Tjj7w0tYuv
vzFdF0QscsmIJdHH0BxwBoKl+vrXuRZkwghUHkyTnyJO5U+nceVuFDHpQeIzI4vI
AcMqZqjY3+/ue7uE9Himyo8pqtX6inOUDDJTyJO9/MRgTZqAT8bUJ0SiN2NslwTO
42pv04QNtHQfSes=
-----END CERTIFICATE-----
@@ -1,73 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
dd:39:30:16:60:55:90:7e
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, ST=Hawaii, O=kevin1024, CN=pytest-httpbin Certificate Authority
Validity
Not Before: Jun 26 18:20:35 2015 GMT
Not After : Jun 23 18:20:35 2025 GMT
Subject: C=US, ST=Hawaii, O=kevin1024, OU=kevin1024, CN=127.0.0.1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:ce:b4:0f:0b:86:17:68:24:6f:7c:25:32:73:81:
bd:55:38:05:ae:09:29:00:c0:f1:99:30:5a:7f:05:
9f:e7:e9:d3:ce:d0:dd:4f:73:c8:bf:65:04:94:e5:
11:8e:1d:91:f0:88:85:3e:48:d3:09:5b:3f:8f:97:
95:34:bf:8d:00:cb:70:d2:c1:2b:34:dd:99:1d:86:
9b:90:54:a5:de:18:c4:03:3d:53:f0:dd:cc:6d:ec:
fb:b9:93:ab:19:85:05:63:2d:34:a6:47:42:71:3b:
e4:1e:4a:4c:d9:60:d4:6b:d6:51:a8:4a:30:70:2e:
6c:62:a2:34:da:cf:30:34:97:a4:9d:17:72:0b:b2:
37:69:e2:ca:b6:d5:9f:46:c5:eb:cf:dc:46:b0:fe:
ef:37:5e:4f:eb:f3:50:4d:2c:4e:c2:0c:e4:0c:63:
c2:d8:ab:a3:d6:a0:12:bf:d6:fc:3f:b6:4c:dc:2b:
9b:c5:ae:83:4d:3b:3c:19:85:50:88:82:a2:5f:ff:
de:98:60:fc:12:3a:55:c3:4f:0a:e9:1f:aa:12:cb:
f8:ce:14:d6:ed:89:ff:c7:ea:3b:fe:97:87:54:eb:
62:de:cd:ef:6b:e2:9e:47:82:77:55:59:4f:b8:ad:
1b:e0:9d:1a:28:16:9f:6a:cb:b2:44:f9:65:c3:c4:
03:09
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
1E:28:41:6B:12:03:41:29:64:0D:E5:C3:E3:F7:9E:82:0C:66:1E:B9
X509v3 Authority Key Identifier:
keyid:AE:05:EF:BD:A9:CE:BB:A6:D8:0E:EB:C4:8C:72:2F:13:E5:CD:AA:CA
Signature Algorithm: sha1WithRSAEncryption
67:8c:6d:a1:2f:b3:35:87:a3:c0:04:92:5d:8a:8b:f8:51:6e:
94:88:59:ed:66:b2:54:b0:a2:3d:7a:05:ee:19:17:a6:0b:3b:
20:f7:d2:73:2c:f0:b9:ad:2e:5d:45:11:5d:8d:33:5c:69:7f:
4a:c5:8c:10:3e:35:b4:39:d7:52:66:bc:02:d8:4d:d0:ba:a1:
ae:55:f5:36:01:17:97:40:1a:9d:6a:e0:b8:33:be:2d:98:b7:
5b:92:6a:77:a7:d9:f5:5b:a4:5f:fa:aa:5b:c1:6b:4d:0c:b7:
5a:4c:47:b2:f7:90:a3:ff:6f:8c:fd:f2:60:38:53:29:71:48:
d7:69
-----BEGIN CERTIFICATE-----
MIIDODCCAqGgAwIBAgIJAN05MBZgVZB+MA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV
BAYTAlVTMQ8wDQYDVQQIEwZIYXdhaWkxEjAQBgNVBAoTCWtldmluMTAyNDEtMCsG
A1UEAxMkcHl0ZXN0LWh0dHBiaW4gQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE1
MDYyNjE4MjAzNVoXDTI1MDYyMzE4MjAzNVowWjELMAkGA1UEBhMCVVMxDzANBgNV
BAgTBkhhd2FpaTESMBAGA1UEChMJa2V2aW4xMDI0MRIwEAYDVQQLEwlrZXZpbjEw
MjQxEjAQBgNVBAMTCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAM60DwuGF2gkb3wlMnOBvVU4Ba4JKQDA8ZkwWn8Fn+fp087Q3U9zyL9l
BJTlEY4dkfCIhT5I0wlbP4+XlTS/jQDLcNLBKzTdmR2Gm5BUpd4YxAM9U/DdzG3s
+7mTqxmFBWMtNKZHQnE75B5KTNlg1GvWUahKMHAubGKiNNrPMDSXpJ0XcguyN2ni
yrbVn0bF68/cRrD+7zdeT+vzUE0sTsIM5Axjwtiro9agEr/W/D+2TNwrm8Wug007
PBmFUIiCol//3phg/BI6VcNPCukfqhLL+M4U1u2J/8fqO/6Xh1TrYt7N72vinkeC
d1VZT7itG+CdGigWn2rLskT5ZcPEAwkCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg
hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
BBYEFB4oQWsSA0EpZA3lw+P3noIMZh65MB8GA1UdIwQYMBaAFK4F772pzrum2A7r
xIxyLxPlzarKMA0GCSqGSIb3DQEBBQUAA4GBAGeMbaEvszWHo8AEkl2Ki/hRbpSI
We1mslSwoj16Be4ZF6YLOyD30nMs8LmtLl1FEV2NM1xpf0rFjBA+NbQ511JmvALY
TdC6oa5V9TYBF5dAGp1q4Lgzvi2Yt1uSanen2fVbpF/6qlvBa00Mt1pMR7L3kKP/
b4z98mA4UylxSNdp
-----END CERTIFICATE-----
@@ -1,28 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzrQPC4YXaCRvfCUyc4G9VTgFrgkpAMDxmTBafwWf5+nTztDd
T3PIv2UElOURjh2R8IiFPkjTCVs/j5eVNL+NAMtw0sErNN2ZHYabkFSl3hjEAz1T
8N3Mbez7uZOrGYUFYy00pkdCcTvkHkpM2WDUa9ZRqEowcC5sYqI02s8wNJeknRdy
C7I3aeLKttWfRsXrz9xGsP7vN15P6/NQTSxOwgzkDGPC2Kuj1qASv9b8P7ZM3Cub
xa6DTTs8GYVQiIKiX//emGD8EjpVw08K6R+qEsv4zhTW7Yn/x+o7/peHVOti3s3v
a+KeR4J3VVlPuK0b4J0aKBafasuyRPllw8QDCQIDAQABAoIBAQCJ//iTbwCtjLXJ
omPebd3jyTUxjfgMAsTJy1h/uVea06ePSi6W3uxFq8G1ToG76c4HUn3yqVgLxRnY
WhFJWCFhSHGYo1KfRtr0tWuinoDmmI40w3sJMmtLcI5WxVnT/dUs839VC/o18xBH
kL9h2Z24KSv3OSDBpJzD9Rtogi7izK8DSQoANBMDEmPPJ5UJBLPjdZn04i6BYZCM
U/+ZADHKXbq6I+7RAcbPJbkvrbBEP234KZvIdw1eIAIZufQBQuDhnwS0Fi9iY/EP
awoYa9HLgFjh+iprhwh+2SDyIp8DA+4HrY1tXAyzCqjgLn/X8wifOUrZECYj1i65
EOiryxMBAoGBAPjmvIwBRxnr1OsKX3gCFoZr+Zu5RjACD9IOSV17cv7glZQVfXBR
REDBoL7CmZrhsW4zBK0YWz30Dx7TGBniTFJ3e8IZJ7Th8PSOhIRYWqqFQ78YBHFi
VcpPOBswy1i8BM9FE0GyF1zusmz8Ak2hFr/IHVkIqHwWvkTI6gGhbJ2RAoGBANSZ
OqEWJKbRX9nuRqSdROqLOtUgWXZ78yvcQaaifyZHEFSKZZjc5MXT96lVd1PyGGAY
uyjAqdd5LiwsS9Rw1cuC5fix2ihH5KFq7EnEJA/zdy91YdO6xmAyBOtjuTHsNj93
if4ilib290/mRKXeI1zpzzWHsvL9Az5spqlkljH5AoGAfln7ewMnCfSbCJoibrR4
pNJpSvEZvUM+rr6L5cXGUbbGl/70x7CpekoRBOWavnI19SA3Dnvfzap4hohYosMr
RW3cSGMmsf9Ep5E1mk2T8R5njrltf/WQYXwnmj4B7FC+DE4fgWkbzRRrRUIFFU1i
VAcNRuZLSXruKdLoX92HWtECgYEAhpTlf3n0A8JBKkVjZOvF56/xs19CIvY+LsLE
sIbndMTBurLNs+IJ1I3llsVqv7Je6d5eBGNKYQPuTbpQ2o//V1Bq4m88CgnQ2rpE
EEJhDdPy3BEzt4Ph9p1Tbet4HflJMg4rRbyBTvNCBctgI5wmyLeeG2Xmy1mNhyPi
sRLi3YkCgYEAiHMsniJc1gZBevjtnqGTPdUo0syAnkZ7RUk/Piur/c0Altkgu5vK
I7p3DbkHBAMDjpAZs1kpfmR4sTYKke+IQDxj2pOZEyYnmQxlGdy8xxoE9dWQeDeg
Le+R83OAKjU4LHpH7hhJMR8X60MJaWC1BDACFO35kqIzvtCYxgEoOiI=
-----END RSA PRIVATE KEY-----
-42
View File
@@ -1,42 +0,0 @@
import pytest
from .app import app as pypi_app
from . import serve, certs
@pytest.fixture(scope='session')
def pypi(request):
server = serve.Server(application=pypi_app)
server.start()
request.addfinalizer(server.stop)
return server
@pytest.fixture(scope='session')
def pypi_secure(request):
server = serve.SecureServer(application=pypi_app)
server.start()
request.addfinalizer(server.stop)
return server
@pytest.fixture(scope='session', params=['http', 'https'])
def pypi_both(request, pypi, pypi_secure):
if request.param == 'http':
return pypi
elif request.param == 'https':
return pypi_secure
@pytest.fixture(scope='class')
def class_based_pypi(request, pypi):
request.cls.pypi = pypi
@pytest.fixture(scope='class')
def class_based_pypi_secure(request, pypi_secure):
request.cls.pypi_secure = pypi_secure
@pytest.fixture(scope='function')
def pypi_ca_bundle(monkeypatch):
monkeypatch.setenv('REQUESTS_CA_BUNDLE', certs.where())
-134
View File
@@ -1,134 +0,0 @@
import os
import threading
import ssl
from wsgiref.simple_server import WSGIServer, make_server, WSGIRequestHandler
from wsgiref.handlers import SimpleHandler
from six.moves.urllib.parse import urljoin
CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs')
class ServerHandler(SimpleHandler):
server_software = 'Pytest-HTTPBIN/0.1.0'
http_version = '1.1'
def cleanup_headers(self):
SimpleHandler.cleanup_headers(self)
self.headers['Connection'] = 'Close'
def close(self):
try:
self.request_handler.log_request(
self.status.split(' ', 1)[0], self.bytes_sent
)
finally:
SimpleHandler.close(self)
class Handler(WSGIRequestHandler):
def handle(self):
"""Handle a single HTTP request"""
self.raw_requestline = self.rfile.readline()
if not self.parse_request(): # An error code has been sent, just exit
return
handler = ServerHandler(
self.rfile, self.wfile, self.get_stderr(), self.get_environ()
)
handler.request_handler = self # backpointer for logging
handler.run(self.server.get_app())
def get_environ(self):
"""
wsgiref simple server adds content-type text/plain to everything, this
removes it if it's not actually in the headers.
"""
# Note: Can't use super since this is an oldstyle class in python 2.x
environ = WSGIRequestHandler.get_environ(self).copy()
if self.headers.get('content-type') is None:
del environ['CONTENT_TYPE']
return environ
class SecureWSGIServer(WSGIServer):
def finish_request(self, request, client_address):
"""
Negotiates SSL and then mimics BaseServer behavior.
"""
request.settimeout(1.0)
try:
ssock = ssl.wrap_socket(
request,
keyfile=os.path.join(CERT_DIR, 'key.pem'),
certfile=os.path.join(CERT_DIR, 'cert.pem'),
server_side=True,
suppress_ragged_eofs=False,
)
self.RequestHandlerClass(ssock, client_address, self)
except Exception as e:
print("pytest-httpbin server hit an exception serving request: %s" % e)
print("attempting to ignore so the rest of the tests can run")
# WSGIRequestHandler seems to close the socket for us.
# Thanks, WSGIRequestHandler!!
class Server:
"""
HTTP server running a WSGI application in its own thread.
"""
port_envvar = 'HTTPBIN_HTTP_PORT'
def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
self.app = application
if self.port_envvar in os.environ:
port = int(os.environ[self.port_envvar])
self._server = make_server(
host,
port,
self.app,
handler_class=Handler,
**kwargs
)
self.host = self._server.server_address[0]
self.port = self._server.server_address[1]
self.protocol = 'http'
self._thread = threading.Thread(
name=self.__class__,
target=self._server.serve_forever,
)
def __del__(self):
if hasattr(self, '_server'):
self.stop()
def start(self):
self._thread.start()
def __add__(self, other):
return self.url + other
def stop(self):
self._server.shutdown()
@property
def url(self):
return f'{self.protocol}://{self.host}:{self.port}'
def join(self, url, allow_fragments=True):
return urljoin(self.url, url, allow_fragments=allow_fragments)
class SecureServer(Server):
port_envvar = 'HTTPBIN_HTTPS_PORT'
def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
kwargs['server_class'] = SecureWSGIServer
super().__init__(host, port, application, **kwargs)
self.protocol = 'https'
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Links for {{ artifact.name }}</title>
</head>
<body>
<h1>Links for {{ artifact.name }}</h1>
{% for fn in artifact.files %}
<a href="/{{ artifact.name }}/{{ fn }}">{{ fn }}</a>
<br>
{% endfor %}
</body>
</html>
@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Artifact Index</title>
</head>
<body>
{% for artifact in artifacts %}
<a href="/artifacts/{{ artifact.name }}/" rel="internal">{{ artifact.name }}</a>
<br>
{% endfor %}
</body>
</html>
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Links for {{ package.name }}</title>
</head>
<body>
<h1>Links for {{ package.name }}</h1>
{% for release, value in package.releases.items() %}
<a href="/{{ package.name }}/{{ release }}{%- if value.hash %}#sha256={{ value.hash }}{% endif %}"{%- if value.requires_python %} data-requires-python="{{ value.requires_python }}"{% endif %}>{{ release }}</a>
<br>
{% endfor %}
</body>
</html>
@@ -1,4 +0,0 @@
{% autoescape false %}
{{ package_contents }}
{% endautoescape %}
@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Index</title>
</head>
<body>
{% for package in packages %}
<a href="/simple/{{ package.name }}/" rel="internal">{{ package.name }}</a>
<br>
{% endfor %}
</body>
</html>
-1
View File
@@ -1 +0,0 @@
__version__ = '0.1.1'
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
py.test $1 -v -s
-5
View File
@@ -1,5 +0,0 @@
[bdist_wheel]
# This flag says that the code is written to work on both Python 2 and Python
# 3. If at all possible, it is good practice to do this. If you cannot, you
# will need to generate wheels for each Python version that you support.
universal=1
-107
View File
@@ -1,107 +0,0 @@
from setuptools import setup, find_packages, Command
import codecs
import os
import re
import sys
from shutil import rmtree
with open("pytest_pypi/version.py") as f:
code = compile(f.read(), "pytest_pypi/version.py", 'exec')
exec(code)
here = os.path.abspath(os.path.dirname(__file__))
# Get the long description from the relevant file
with codecs.open(os.path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f:
long_description = f.read()
class UploadCommand(Command):
"""Support setup.py upload."""
description = 'Build and publish the package.'
user_options = []
@staticmethod
def status(s):
"""Prints things in bold."""
print(f'\033[1m{s}\033[0m')
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
self.status('Removing previous builds...')
rmtree(os.path.join(here, 'dist'))
except OSError:
pass
self.status('Building Source and Wheel (universal) distribution...')
os.system(f'{sys.executable} setup.py sdist bdist_wheel --universal')
self.status('Uploading the package to PyPI via Twine...')
os.system('twine upload dist/*')
self.status('Pushing git tags...')
os.system(f'git tag v{__version__}')
os.system('git push --tags')
sys.exit()
setup(
name="pytest-pypi",
# There are various approaches to referencing the version. For a discussion,
# see http://packaging.python.org/en/latest/tutorial.html#version
version=__version__,
description="Easily test your HTTP library against a local copy of pypi",
long_description=long_description,
# The project URL.
url='https://github.com/pypa/pipenv/tree/master/tests/pytest-pypi',
# Author details
author='Kenneth Reitz',
author_email='me@kennethreitz.org',
# Choose your license
license='MIT',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Testing',
'Topic :: Software Development :: Libraries',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
# What does your project relate to?
keywords='pytest-pypi testing pytest pypi',
packages=find_packages(exclude=["contrib", "docs", "tests*"]),
include_package_data = True, # include files listed in MANIFEST.in
install_requires = [
'Flask',
'six',
'importlib-metadata'],
# the following makes a plugin available to pytest
entry_points = {
'pytest11': [
'pypi = pytest_pypi.plugin',
]
},
cmdclass={
'upload': UploadCommand,
},
)
-10
View File
@@ -1,10 +0,0 @@
# content of: tox.ini , put in same dir as setup.py
[tox]
envlist = py26, py27, py33, py34, py35, py36, pypy, pypy3
[testenv]
deps = pytest
requests
py26: httpbin==0.5.0
commands = ./runtests.sh {posargs:tests/}