Merge pull request #2252 from coreos-inc/parallel-tests
Fix pytests and enable parallel registry tests
This commit is contained in:
commit
732ab67b57
7 changed files with 29 additions and 13 deletions
|
@ -162,7 +162,7 @@ RUN if [ "$RUN_TESTS" = true ]; then \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RUN if [ "$RUN_TESTS" = true ]; then \
|
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
|
fi
|
||||||
|
|
||||||
RUN PYTHONPATH=. venv/bin/alembic heads | grep -E '^[0-9a-f]+ \(head\)$' > ALEMBIC_HEAD
|
RUN PYTHONPATH=. venv/bin/alembic heads | grep -E '^[0-9a-f]+ \(head\)$' > ALEMBIC_HEAD
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
import os.path
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
@ -75,7 +76,8 @@ def paginate(limit_kwarg_name='limit', offset_kwarg_name='offset',
|
||||||
return
|
return
|
||||||
|
|
||||||
next_page_token = encrypt_page_token({'offset': limit + offset})
|
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_param = urlencode({'n': limit, 'next_page': next_page_token})
|
||||||
link = '<%s?%s>; rel="next"' % (link_url, link_param)
|
link = '<%s?%s>; rel="next"' % (link_url, link_param)
|
||||||
response.headers['Link'] = link
|
response.headers['Link'] = link
|
||||||
|
|
|
@ -3,4 +3,5 @@ pytest-cov
|
||||||
python-coveralls
|
python-coveralls
|
||||||
pytest-flask
|
pytest-flask
|
||||||
pytest-runner
|
pytest-runner
|
||||||
|
pytest-xdist
|
||||||
-e git+https://github.com/ant31/pytest-sugar.git#egg=pytest-sugar
|
-e git+https://github.com/ant31/pytest-sugar.git#egg=pytest-sugar
|
||||||
|
|
|
@ -42,6 +42,7 @@ from image.docker.schema1 import DockerSchema1ManifestBuilder
|
||||||
from initdb import wipe_database, initialize_database, populate_database
|
from initdb import wipe_database, initialize_database, populate_database
|
||||||
from jsonschema import validate as validate_schema
|
from jsonschema import validate as validate_schema
|
||||||
from util.security.registry_jwt import decode_bearer_header
|
from util.security.registry_jwt import decode_bearer_header
|
||||||
|
from test.testutil import get_open_port
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -156,7 +157,6 @@ class TestFeature(object):
|
||||||
headers={'Content-Type': 'application/json'})
|
headers={'Content-Type': 'application/json'})
|
||||||
|
|
||||||
|
|
||||||
_PORT_NUMBER = 5001
|
|
||||||
_CLEAN_DATABASE_PATH = None
|
_CLEAN_DATABASE_PATH = None
|
||||||
_JWK = RSAKey(key=RSA.generate(2048))
|
_JWK = RSAKey(key=RSA.generate(2048))
|
||||||
|
|
||||||
|
@ -236,14 +236,11 @@ def get_new_database_uri():
|
||||||
|
|
||||||
class RegistryTestCaseMixin(LiveServerTestCase):
|
class RegistryTestCaseMixin(LiveServerTestCase):
|
||||||
def create_app(self):
|
def create_app(self):
|
||||||
global _PORT_NUMBER
|
|
||||||
_PORT_NUMBER = _PORT_NUMBER + 1
|
|
||||||
|
|
||||||
if os.environ.get('DEBUG') == 'true':
|
if os.environ.get('DEBUG') == 'true':
|
||||||
app.config['DEBUG'] = True
|
app.config['DEBUG'] = True
|
||||||
|
|
||||||
app.config['TESTING'] = 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()
|
app.config['DB_URI'] = get_new_database_uri()
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
@ -1412,7 +1409,7 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix
|
||||||
self.assertTrue(link.endswith('; rel="next"'))
|
self.assertTrue(link.endswith('; rel="next"'))
|
||||||
|
|
||||||
url, _ = link.split(';')
|
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']))
|
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()
|
labels = self.conduct('GET', '/api/v1/repository/devtable/newrepo/manifest/' + digest + '/labels').json()
|
||||||
self.assertEquals(2, len(labels['labels']))
|
self.assertEquals(2, len(labels['labels']))
|
||||||
|
|
||||||
self.assertEquals('text/plain', labels['labels'][0]['media_type'])
|
media_types = set([label['media_type'] for label in labels['labels']])
|
||||||
self.assertEquals('application/json', labels['labels'][1]['media_type'])
|
|
||||||
|
self.assertTrue('text/plain' in media_types)
|
||||||
|
self.assertTrue('application/json' in media_types)
|
||||||
|
|
||||||
def test_invalid_manifest_type(self):
|
def test_invalid_manifest_type(self):
|
||||||
namespace = 'devtable'
|
namespace = 'devtable'
|
||||||
|
|
|
@ -34,7 +34,7 @@ class TestTags(unittest.TestCase):
|
||||||
def assertTagsForRef(self, ref, tags):
|
def assertTagsForRef(self, ref, tags):
|
||||||
prepared = PreparedBuild()
|
prepared = PreparedBuild()
|
||||||
prepared.tags_from_ref(ref, default_branch='master')
|
prepared.tags_from_ref(ref, default_branch='master')
|
||||||
self.assertEquals(tags, prepared._tags)
|
self.assertEquals(set(tags), set(prepared._tags))
|
||||||
|
|
||||||
def test_normal(self):
|
def test_normal(self):
|
||||||
self.assertTagsForRef('ref/heads/somebranch', ['somebranch'])
|
self.assertTagsForRef('ref/heads/somebranch', ['somebranch'])
|
||||||
|
|
14
test/testutil.py
Normal file
14
test/testutil.py
Normal file
|
@ -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
|
4
tox.ini
4
tox.ini
|
@ -1,5 +1,5 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = {py27}-{unittest,api}
|
envlist = {py27}-{unittest,registry}
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -11,7 +11,7 @@ deps =
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONPATH = {toxinidir}:{toxinidir}
|
PYTHONPATH = {toxinidir}:{toxinidir}
|
||||||
TEST=true
|
TEST=true
|
||||||
api: FILE="registry_tests.py"
|
registry: FILE="registry_tests.py"
|
||||||
unittest: FILE=""
|
unittest: FILE=""
|
||||||
commands =
|
commands =
|
||||||
py.test --verbose test/{env:FILE} -vv {posargs}
|
py.test --verbose test/{env:FILE} -vv {posargs}
|
||||||
|
|
Reference in a new issue