From 88bc93d6075209f641736d4b2f4dfdf48d36e397 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Thu, 17 Sep 2015 16:48:08 -0400 Subject: [PATCH] Better test performance for registry tests --- test/registry_tests.py | 75 ++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/test/registry_tests.py b/test/registry_tests.py index b31c7c2a6..5c2ca41b7 100644 --- a/test/registry_tests.py +++ b/test/registry_tests.py @@ -2,6 +2,8 @@ import unittest import requests import os + +import Crypto.Random from flask import request, jsonify from flask.blueprints import Blueprint from flask.ext.testing import LiveServerTestCase @@ -56,13 +58,16 @@ def set_feature(feature_name): features._FEATURES[feature_name].value = request.get_json()['value'] return jsonify({'old_value': old_value}) -@testbp.route('/reloaddb', methods=['POST']) -def reload_db(): +@testbp.route('/reloadapp', methods=['POST']) +def reload_app(): # Close any existing connection. close_db_filter(None) # Reload the database config. configure(app.config) + + # Reload random after the process split, as it cannot be used uninitialized across forks. + Crypto.Random.atfork() return 'OK' app.register_blueprint(testbp, url_prefix='/__test') @@ -118,12 +123,13 @@ def get_new_database_uri(): return 'sqlite:///{0}'.format(local_db_file.name) -class RegistryTestCase(LiveServerTestCase): +class RegistryTestCaseMixin(LiveServerTestCase): maxDiff = None def create_app(self): global _PORT_NUMBER _PORT_NUMBER = _PORT_NUMBER + 1 + app.config['DEBUG'] = True app.config['TESTING'] = True app.config['LIVESERVER_PORT'] = _PORT_NUMBER app.config['DB_URI'] = get_new_database_uri() @@ -132,22 +138,34 @@ class RegistryTestCase(LiveServerTestCase): def setUp(self): 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 # the remote reload method to force it to pick up the changes to DB_URI set in the create_app # method. - self.conduct('POST', '/__test/reloaddb') + self.conduct('POST', '/__test/reloadapp') def clearSession(self): self.session = requests.Session() self.signature = None self.docker_token = 'true' + self.jwt = None # 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 BaseRegistryMixin(object): def conduct(self, method, url, headers=None, data=None, auth=None, params=None, expected_code=200): params = params or {} @@ -183,12 +201,6 @@ class BaseRegistryMixin(object): return response - def clearSession(self): - self.signature = None - self.docker_token = 'true' - self.jwt = None - - class V1RegistryMixin(BaseRegistryMixin): def v1_ping(self): self.conduct('GET', '/v1/_ping') @@ -365,43 +377,6 @@ class V2RegistryPullMixin(V2RegistryMixin): 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): def test_pull_publicrepo_anonymous(self): # 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. """ class V1PushV2PullRegistryTests(V2RegistryPullMixin, V1RegistryPushMixin, RegistryTestsMixin, - RegistryTestCaseMixin, LiveServerTestCase): + RegistryTestCaseMixin, LiveServerTestCase): """ Tests for V1 push, V2 pull registry. """ class V1PullV2PushRegistryTests(V1RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMixin, - RegistryTestCaseMixin, LiveServerTestCase): + RegistryTestCaseMixin, LiveServerTestCase): """ Tests for V1 pull, V2 push registry. """ if __name__ == '__main__':