Merge pull request #511 from coreos-inc/python-registry-v2-testperf

Better test performance for registry tests
This commit is contained in:
josephschorr 2015-09-18 14:41:40 -04:00
commit 4ffda39d39

View file

@ -2,6 +2,8 @@ import unittest
import requests import requests
import os import os
import Crypto.Random
from flask import request, jsonify from flask import request, jsonify
from flask.blueprints import Blueprint from flask.blueprints import Blueprint
from flask.ext.testing import LiveServerTestCase from flask.ext.testing import LiveServerTestCase
@ -56,13 +58,16 @@ def set_feature(feature_name):
features._FEATURES[feature_name].value = request.get_json()['value'] features._FEATURES[feature_name].value = request.get_json()['value']
return jsonify({'old_value': old_value}) return jsonify({'old_value': old_value})
@testbp.route('/reloaddb', methods=['POST']) @testbp.route('/reloadapp', methods=['POST'])
def reload_db(): def reload_app():
# Close any existing connection. # Close any existing connection.
close_db_filter(None) close_db_filter(None)
# Reload the database config. # Reload the database config.
configure(app.config) configure(app.config)
# Reload random after the process split, as it cannot be used uninitialized across forks.
Crypto.Random.atfork()
return 'OK' return 'OK'
app.register_blueprint(testbp, url_prefix='/__test') app.register_blueprint(testbp, url_prefix='/__test')
@ -118,12 +123,13 @@ def get_new_database_uri():
return 'sqlite:///{0}'.format(local_db_file.name) return 'sqlite:///{0}'.format(local_db_file.name)
class RegistryTestCase(LiveServerTestCase): class RegistryTestCaseMixin(LiveServerTestCase):
maxDiff = None maxDiff = None
def create_app(self): def create_app(self):
global _PORT_NUMBER global _PORT_NUMBER
_PORT_NUMBER = _PORT_NUMBER + 1 _PORT_NUMBER = _PORT_NUMBER + 1
app.config['DEBUG'] = True
app.config['TESTING'] = True app.config['TESTING'] = True
app.config['LIVESERVER_PORT'] = _PORT_NUMBER app.config['LIVESERVER_PORT'] = _PORT_NUMBER
app.config['DB_URI'] = get_new_database_uri() app.config['DB_URI'] = get_new_database_uri()
@ -132,22 +138,34 @@ class RegistryTestCase(LiveServerTestCase):
def setUp(self): def setUp(self):
self.clearSession() self.clearSession()
# Tell the remote running app to reload the database. By default, the app forks from the # Tell the remote running app to reload the database and app. By default, the app forks from the
# current context and has already loaded the DB config with the *original* DB URL. We call # current context and has already loaded the DB config with the *original* DB URL. We call
# the remote reload method to force it to pick up the changes to DB_URI set in the create_app # the remote reload method to force it to pick up the changes to DB_URI set in the create_app
# method. # method.
self.conduct('POST', '/__test/reloaddb') self.conduct('POST', '/__test/reloadapp')
def clearSession(self): def clearSession(self):
self.session = requests.Session() self.session = requests.Session()
self.signature = None self.signature = None
self.docker_token = 'true' self.docker_token = 'true'
self.jwt = None
# Load the CSRF token. # Load the CSRF token.
self.csrf_token = '' self.csrf_token = ''
self.csrf_token = self.conduct('GET', '/__test/csrf').text self.csrf_token = self.conduct('GET', '/__test/csrf').text
def conduct_api_login(self, username, password):
self.conduct('POST', '/api/v1/signin',
data=json.dumps(dict(username=username, password=password)),
headers={'Content-Type': 'application/json'})
def change_repo_visibility(self, repository, namespace, visibility):
self.conduct('POST', '/api/v1/repository/%s/%s/changevisibility' % (repository, namespace),
data=json.dumps(dict(visibility=visibility)),
headers={'Content-Type': 'application/json'})
class BaseRegistryMixin(object): class BaseRegistryMixin(object):
def conduct(self, method, url, headers=None, data=None, auth=None, params=None, expected_code=200): def conduct(self, method, url, headers=None, data=None, auth=None, params=None, expected_code=200):
params = params or {} params = params or {}
@ -183,12 +201,6 @@ class BaseRegistryMixin(object):
return response return response
def clearSession(self):
self.signature = None
self.docker_token = 'true'
self.jwt = None
class V1RegistryMixin(BaseRegistryMixin): class V1RegistryMixin(BaseRegistryMixin):
def v1_ping(self): def v1_ping(self):
self.conduct('GET', '/v1/_ping') self.conduct('GET', '/v1/_ping')
@ -365,43 +377,6 @@ class V2RegistryPullMixin(V2RegistryMixin):
expected_code=200, auth='jwt') expected_code=200, auth='jwt')
class RegistryTestCaseMixin(object):
maxDiff = None
def create_app(self):
app.config['TESTING'] = True
return app
def setUp(self):
# Note: We cannot use the normal savepoint-based DB setup here because we are accessing
# different app instances remotely via a live webserver, which is multiprocess. Therefore, we
# completely clear the database between tests.
wipe_database()
initialize_database()
populate_database()
self.clearTestSession()
def clearTestSession(self):
self.session = requests.Session()
self.clearSession()
# Load the CSRF token.
self.csrf_token = ''
self.csrf_token = self.conduct('GET', '/__test/csrf').text
def conduct_api_login(self, username, password):
self.conduct('POST', '/api/v1/signin',
data=json.dumps(dict(username=username, password=password)),
headers={'Content-Type': 'application/json'})
def change_repo_visibility(self, repository, namespace, visibility):
self.conduct('POST', '/api/v1/repository/%s/%s/changevisibility' % (repository, namespace),
data=json.dumps(dict(visibility=visibility)),
headers={'Content-Type': 'application/json'})
class RegistryTestsMixin(object): class RegistryTestsMixin(object):
def test_pull_publicrepo_anonymous(self): def test_pull_publicrepo_anonymous(self):
# Add a new repository under the public user, so we have a real repository to pull. # Add a new repository under the public user, so we have a real repository to pull.
@ -585,11 +560,11 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix
""" Tests for V2 registry. """ """ Tests for V2 registry. """
class V1PushV2PullRegistryTests(V2RegistryPullMixin, V1RegistryPushMixin, RegistryTestsMixin, class V1PushV2PullRegistryTests(V2RegistryPullMixin, V1RegistryPushMixin, RegistryTestsMixin,
RegistryTestCaseMixin, LiveServerTestCase): RegistryTestCaseMixin, LiveServerTestCase):
""" Tests for V1 push, V2 pull registry. """ """ Tests for V1 push, V2 pull registry. """
class V1PullV2PushRegistryTests(V1RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMixin, class V1PullV2PushRegistryTests(V1RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMixin,
RegistryTestCaseMixin, LiveServerTestCase): RegistryTestCaseMixin, LiveServerTestCase):
""" Tests for V1 pull, V2 push registry. """ """ Tests for V1 pull, V2 push registry. """
if __name__ == '__main__': if __name__ == '__main__':