From 481cebe46b3bc0014e5aedeff6cd31c47e6bfa10 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Thu, 15 Dec 2016 12:04:57 -0500 Subject: [PATCH] Fix pytests and enable parallel registry tests --- Dockerfile | 2 +- endpoints/v2/__init__.py | 4 +++- requirements-tests.txt | 1 + test/registry_tests.py | 15 +++++++-------- test/test_trigger.py | 2 +- test/testutil.py | 14 ++++++++++++++ tox.ini | 4 ++-- 7 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 test/testutil.py diff --git a/Dockerfile b/Dockerfile index 08ffd503a..c11857faf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -162,7 +162,7 @@ RUN if [ "$RUN_TESTS" = true ]; then \ fi RUN if [ "$RUN_TESTS" = true ]; then \ - TEST=true PYTHONPATH="." venv/bin/py.test --verbose --show-count -x --color=no test/registry_tests.py ; \ + TEST=true PYTHONPATH="." venv/bin/py.test --verbose --show-count -n auto -x --color=no test/registry_tests.py ; \ fi RUN PYTHONPATH=. venv/bin/alembic heads | grep -E '^[0-9a-f]+ \(head\)$' > ALEMBIC_HEAD diff --git a/endpoints/v2/__init__.py b/endpoints/v2/__init__.py index 26150f875..d6af69db0 100644 --- a/endpoints/v2/__init__.py +++ b/endpoints/v2/__init__.py @@ -1,4 +1,5 @@ import logging +import os.path from functools import wraps from urlparse import urlparse @@ -75,7 +76,8 @@ def paginate(limit_kwarg_name='limit', offset_kwarg_name='offset', return next_page_token = encrypt_page_token({'offset': limit + offset}) - link_url = get_app_url() + url_for(request.endpoint, **request.view_args) + + link_url = os.path.join(get_app_url(), url_for(request.endpoint, **request.view_args)) link_param = urlencode({'n': limit, 'next_page': next_page_token}) link = '<%s?%s>; rel="next"' % (link_url, link_param) response.headers['Link'] = link diff --git a/requirements-tests.txt b/requirements-tests.txt index 4704613ab..ab476edf3 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -3,4 +3,5 @@ pytest-cov python-coveralls pytest-flask pytest-runner +pytest-xdist -e git+https://github.com/ant31/pytest-sugar.git#egg=pytest-sugar diff --git a/test/registry_tests.py b/test/registry_tests.py index dd1b415e8..cefc319c0 100644 --- a/test/registry_tests.py +++ b/test/registry_tests.py @@ -42,6 +42,7 @@ from image.docker.schema1 import DockerSchema1ManifestBuilder from initdb import wipe_database, initialize_database, populate_database from jsonschema import validate as validate_schema from util.security.registry_jwt import decode_bearer_header +from test.testutil import get_open_port try: @@ -156,7 +157,6 @@ class TestFeature(object): headers={'Content-Type': 'application/json'}) -_PORT_NUMBER = 5001 _CLEAN_DATABASE_PATH = None _JWK = RSAKey(key=RSA.generate(2048)) @@ -236,14 +236,11 @@ def get_new_database_uri(): class RegistryTestCaseMixin(LiveServerTestCase): def create_app(self): - global _PORT_NUMBER - _PORT_NUMBER = _PORT_NUMBER + 1 - if os.environ.get('DEBUG') == 'true': app.config['DEBUG'] = True app.config['TESTING'] = True - app.config['LIVESERVER_PORT'] = _PORT_NUMBER + app.config['LIVESERVER_PORT'] = get_open_port() app.config['DB_URI'] = get_new_database_uri() return app @@ -1412,7 +1409,7 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix self.assertTrue(link.endswith('; rel="next"')) url, _ = link.split(';') - relative_url = url[len(self.get_server_url()):-1] + relative_url = url[url.find('/v2/'):-1] encountered.update(set(result_json['tags'])) @@ -1474,8 +1471,10 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix labels = self.conduct('GET', '/api/v1/repository/devtable/newrepo/manifest/' + digest + '/labels').json() self.assertEquals(2, len(labels['labels'])) - self.assertEquals('text/plain', labels['labels'][0]['media_type']) - self.assertEquals('application/json', labels['labels'][1]['media_type']) + media_types = set([label['media_type'] for label in labels['labels']]) + + self.assertTrue('text/plain' in media_types) + self.assertTrue('application/json' in media_types) def test_invalid_manifest_type(self): namespace = 'devtable' diff --git a/test/test_trigger.py b/test/test_trigger.py index 81970c338..a42314f84 100644 --- a/test/test_trigger.py +++ b/test/test_trigger.py @@ -34,7 +34,7 @@ class TestTags(unittest.TestCase): def assertTagsForRef(self, ref, tags): prepared = PreparedBuild() prepared.tags_from_ref(ref, default_branch='master') - self.assertEquals(tags, prepared._tags) + self.assertEquals(set(tags), set(prepared._tags)) def test_normal(self): self.assertTagsForRef('ref/heads/somebranch', ['somebranch']) diff --git a/test/testutil.py b/test/testutil.py new file mode 100644 index 000000000..6180cd13a --- /dev/null +++ b/test/testutil.py @@ -0,0 +1,14 @@ +import socket + +def get_open_port(): + """ Retrieves an open port on the system. """ + + # Bind a socket to a random port. We can then ask for the port number, + # and return it. + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + s.listen(1) + port = s.getsockname()[1] + s.close() + + return port diff --git a/tox.ini b/tox.ini index 554cf9cf4..dece33e2d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py27}-{unittest,api} +envlist = {py27}-{unittest,registry} skipsdist = True [testenv] @@ -11,7 +11,7 @@ deps = setenv = PYTHONPATH = {toxinidir}:{toxinidir} TEST=true - api: FILE="registry_tests.py" + registry: FILE="registry_tests.py" unittest: FILE="" commands = py.test --verbose test/{env:FILE} -vv {posargs}