diff --git a/.gitignore b/.gitignore
index 4edf933..c68a9bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,8 +17,7 @@ ID
__pycache__/
/build/
/dist/
-/*.egg
-/.eggs
+/*.egg*
/MANIFEST
/README.html
/pypi-server-standalone.py
diff --git a/setup.py b/setup.py
index f38b1f9..f556740 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ import sys
from setuptools import setup
-tests_require = ['pytest']
+tests_require = ['pytest', 'twine']
if sys.version_info >= (3, 0):
exec("def do_exec(co, loc): exec(co, loc)\n")
else:
diff --git a/tests/centodeps/.gitignore b/tests/centodeps/.gitignore
new file mode 100644
index 0000000..c91898f
--- /dev/null
+++ b/tests/centodeps/.gitignore
@@ -0,0 +1,4 @@
+/wheelhouse
+/build
+/*egg*
+
diff --git a/tests/centodeps/dist/centodeps-0.0.0-cp34-none-win_amd64.whl b/tests/centodeps/dist/centodeps-0.0.0-cp34-none-win_amd64.whl
new file mode 100644
index 0000000..7e565ac
Binary files /dev/null and b/tests/centodeps/dist/centodeps-0.0.0-cp34-none-win_amd64.whl differ
diff --git a/tests/centodeps/setup.py b/tests/centodeps/setup.py
new file mode 100644
index 0000000..672f210
--- /dev/null
+++ b/tests/centodeps/setup.py
@@ -0,0 +1,15 @@
+## A test-distribution to check if
+# bottle supports uploading 100's of packages,
+# see: https://github.com/pypiserver/pypiserver/issues/82
+#
+# Has been run once `pip wheel .`, just to generate:
+# ./wheelhouse/centodeps-0.0.0-cp34-none-win_amd64.whl
+#
+from setuptools import setup
+setup(
+ name='centodeps',
+ install_requires=['a==1.0'] * 200,
+ options={
+ 'bdist_wheel': {'universal': True},
+ },
+)
diff --git a/tests/test_app.py b/tests/test_app.py
index 7602823..42534f9 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -1,13 +1,22 @@
#! /usr/bin/env py.test
-from pypiserver import __main__, bottle
-import pytest, webtest
+import contextlib
+import glob
import logging
+import os
+import subprocess
-## Enable logging to detect any problems with it
+import pytest
+import webtest
+
+from pypiserver import __main__, bottle
+
+
+# Enable logging to detect any problems with it
##
__main__.init_logging(level=logging.NOTSET)
+
@pytest.fixture()
def _app(app):
return app.module
@@ -41,7 +50,7 @@ def testpriv(priv):
return webtest.TestApp(priv)
-@pytest.fixture(params=[" ", ## Mustcontain test below fails when string is empty.
+@pytest.fixture(params=[" ", # Mustcontain test below fails when string is empty.
"Hey there!",
"
Hey there!",
])
@@ -54,7 +63,7 @@ def welcome_file_no_vars(request, root):
@pytest.fixture()
def welcome_file_all_vars(request, root):
- msg ="""
+ msg = """
{{URL}}
{{VERSION}}
{{NUMPKGS}}
@@ -102,7 +111,8 @@ def test_root_welcome_msg_all_vars(root, welcome_file_all_vars):
def test_root_welcome_msg_antiXSS(testapp):
"""https://github.com/pypiserver/pypiserver/issues/77"""
- resp = testapp.get("/?Red", headers={"Host": "somehost.org"})
+ resp = testapp.get(
+ "/?Red", headers={"Host": "somehost.org"})
resp.mustcontain("alert", "somehost.org", no="")
@@ -112,7 +122,7 @@ def test_root_remove_not_found_msg_antiXSS(testapp):
headers={"Host": "somehost.org"},
params={':action': 'remove_pkg',
'name': 'Red',
- 'version':'1.1.1'})
+ 'version': '1.1.1'})
resp.mustcontain("alert", "somehost.org", no="")
@@ -128,7 +138,8 @@ def test_favicon(testapp):
def test_fallback(root, _app, testapp):
assert _app.config.redirect_to_fallback
resp = testapp.get("/simple/pypiserver/", status=302)
- assert resp.headers["Location"] == "http://pypi.python.org/simple/pypiserver/"
+ assert resp.headers[
+ "Location"] == "http://pypi.python.org/simple/pypiserver/"
def test_no_fallback(root, _app, testapp):
@@ -218,7 +229,7 @@ def test_nonroot_simple_index(root, testpriv):
root.join("foobar-1.0.zip").write("")
for path in ["/priv/simple/foobar",
- "/priv/simple/foobar/"]:
+ "/priv/simple/foobar/"]:
resp = testpriv.get(path)
links = resp.html("a")
assert len(links) == 1
@@ -228,7 +239,7 @@ def test_nonroot_simple_index(root, testpriv):
def test_nonroot_simple_packages(root, testpriv):
root.join("foobar-1.0.zip").write("123")
for path in ["/priv/packages",
- "/priv/packages/"]:
+ "/priv/packages/"]:
resp = testpriv.get(path)
links = resp.html("a")
assert len(links) == 1
@@ -239,7 +250,8 @@ def test_root_no_relative_paths(testpriv):
"""https://github.com/pypiserver/pypiserver/issues/25"""
resp = testpriv.get("/priv/")
hrefs = [x["href"] for x in resp.html("a")]
- assert hrefs == ['/priv/packages/', '/priv/simple/', 'http://pypi.python.org/pypi/pypiserver']
+ assert hrefs == ['/priv/packages/', '/priv/simple/',
+ 'http://pypi.python.org/pypi/pypiserver']
def test_simple_index_list_no_duplicates(root, testapp):
diff --git a/tests/test_server.py b/tests/test_server.py
new file mode 100644
index 0000000..5a6a830
--- /dev/null
+++ b/tests/test_server.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env py.test
+
+import contextlib
+import subprocess
+import time
+
+from py import path # @UnresolvedImport
+import pytest
+
+
+@pytest.fixture
+def packdir(tmpdir):
+ return tmpdir.mkdir("dists")
+
+
+@contextlib.contextmanager
+def server(packdir):
+ cmd = "python -m pypiserver.__main__ -P. -a. %s" % packdir
+ try:
+ proc = subprocess.Popen(
+ cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ yield proc
+ finally:
+ try:
+ proc.terminate()
+ time.sleep(1)
+ finally:
+ proc.kill()
+
+
+def test_centodeps(packdir, monkeypatch):
+ from twine.commands import upload
+
+ pypirc_config = {"test": {"repository": "http://localhost:8080",
+ "username": 'a',
+ "password": 'a'
+ }
+ }
+
+ monkeypatch.setattr(upload, 'get_repository_from_config',
+ lambda *x: pypirc_config)
+ dist_path = path.local('tests/centodeps/wheelhouse/centodeps*.whl')
+
+ with server(packdir) as srv:
+ upload.upload([str(dist_path)], repository='test',
+ sign=None, identity=None,
+ username='a', password='a',
+ comment=None, sign_with=None)
+ time.sleep(1)
+ assert list(packdir.visit('centodeps*.whl'))
+
+ out = srv.communicate()
+ assert "serving on http:" in str(out[0])
+ assert "Listening on http:" in str(out[1])
diff --git a/tox.ini b/tox.ini
index c341ed6..10bbf4f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,6 +6,7 @@ deps=pytest>=2.3
webtest
beautifulsoup4
mock
+ twine>=1.6.0
commands=py.test []
sitepackages=False