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