Merge branch 'master' into touchdown
Conflicts: static/js/app.js static/partials/organizations.html test/data/test.db
This commit is contained in:
commit
c630d7e948
65 changed files with 1843 additions and 273 deletions
Binary file not shown.
|
@ -36,6 +36,9 @@ from endpoints.api.repository import RepositoryList, RepositoryVisibility, Repos
|
|||
from endpoints.api.permission import (RepositoryUserPermission, RepositoryTeamPermission,
|
||||
RepositoryTeamPermissionList, RepositoryUserPermissionList)
|
||||
|
||||
from endpoints.api.superuser import SuperUserLogs, SeatUsage, SuperUserList, SuperUserManagement
|
||||
|
||||
|
||||
try:
|
||||
app.register_blueprint(api_bp, url_prefix='/api')
|
||||
except ValueError:
|
||||
|
@ -3275,5 +3278,87 @@ class TestUserAuthorization(ApiTestCase):
|
|||
self._run_test('DELETE', 404, 'devtable', None)
|
||||
|
||||
|
||||
class TestSuperUserLogs(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(SuperUserLogs)
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 403, None, None)
|
||||
|
||||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 403, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 403, 'reader', None)
|
||||
|
||||
def test_get_devtable(self):
|
||||
self._run_test('GET', 200, 'devtable', None)
|
||||
|
||||
|
||||
class TestSuperUserList(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(SuperUserList)
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 403, None, None)
|
||||
|
||||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 403, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 403, 'reader', None)
|
||||
|
||||
def test_get_devtable(self):
|
||||
self._run_test('GET', 200, 'devtable', None)
|
||||
|
||||
|
||||
|
||||
class TestSuperUserManagement(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(SuperUserManagement, username='freshuser')
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 403, None, None)
|
||||
|
||||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 403, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 403, 'reader', None)
|
||||
|
||||
def test_get_devtable(self):
|
||||
self._run_test('GET', 200, 'devtable', None)
|
||||
|
||||
|
||||
def test_put_anonymous(self):
|
||||
self._run_test('PUT', 403, None, {})
|
||||
|
||||
def test_put_freshuser(self):
|
||||
self._run_test('PUT', 403, 'freshuser', {})
|
||||
|
||||
def test_put_reader(self):
|
||||
self._run_test('PUT', 403, 'reader', {})
|
||||
|
||||
def test_put_devtable(self):
|
||||
self._run_test('PUT', 200, 'devtable', {})
|
||||
|
||||
|
||||
def test_delete_anonymous(self):
|
||||
self._run_test('DELETE', 403, None, None)
|
||||
|
||||
def test_delete_freshuser(self):
|
||||
self._run_test('DELETE', 403, 'freshuser', None)
|
||||
|
||||
def test_delete_reader(self):
|
||||
self._run_test('DELETE', 403, 'reader', None)
|
||||
|
||||
def test_delete_devtable(self):
|
||||
self._run_test('DELETE', 204, 'devtable', None)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -38,6 +38,7 @@ from endpoints.api.organization import (OrganizationList, OrganizationMember,
|
|||
from endpoints.api.repository import RepositoryList, RepositoryVisibility, Repository
|
||||
from endpoints.api.permission import (RepositoryUserPermission, RepositoryTeamPermission,
|
||||
RepositoryTeamPermissionList, RepositoryUserPermissionList)
|
||||
from endpoints.api.superuser import SuperUserLogs, SeatUsage, SuperUserList, SuperUserManagement
|
||||
|
||||
try:
|
||||
app.register_blueprint(api_bp, url_prefix='/api')
|
||||
|
@ -1939,5 +1940,66 @@ class TestUserAuthorizations(ApiTestCase):
|
|||
self.getJsonResponse(UserAuthorization, params=dict(access_token_uuid = authorization['uuid']),
|
||||
expected_code=404)
|
||||
|
||||
|
||||
class TestSuperUserLogs(ApiTestCase):
|
||||
def test_get_logs(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
json = self.getJsonResponse(SuperUserLogs)
|
||||
|
||||
assert 'logs' in json
|
||||
assert len(json['logs']) > 0
|
||||
|
||||
|
||||
class TestSuperUserList(ApiTestCase):
|
||||
def test_get_users(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
json = self.getJsonResponse(SuperUserList)
|
||||
|
||||
assert 'users' in json
|
||||
assert len(json['users']) > 0
|
||||
|
||||
|
||||
class TestSuperUserManagement(ApiTestCase):
|
||||
def test_get_user(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
json = self.getJsonResponse(SuperUserManagement, params=dict(username = 'freshuser'))
|
||||
self.assertEquals('freshuser', json['username'])
|
||||
self.assertEquals('no@thanks.com', json['email'])
|
||||
self.assertEquals(False, json['super_user'])
|
||||
|
||||
def test_delete_user(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Verify the user exists.
|
||||
json = self.getJsonResponse(SuperUserManagement, params=dict(username = 'freshuser'))
|
||||
self.assertEquals('freshuser', json['username'])
|
||||
|
||||
# Delete the user.
|
||||
self.deleteResponse(SuperUserManagement, params=dict(username = 'freshuser'), expected_code=204)
|
||||
|
||||
# Verify the user no longer exists.
|
||||
self.getResponse(SuperUserManagement, params=dict(username = 'freshuser'), expected_code=404)
|
||||
|
||||
|
||||
def test_update_user(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Verify the user exists.
|
||||
json = self.getJsonResponse(SuperUserManagement, params=dict(username = 'freshuser'))
|
||||
self.assertEquals('freshuser', json['username'])
|
||||
self.assertEquals('no@thanks.com', json['email'])
|
||||
|
||||
# Update the user.
|
||||
self.putJsonResponse(SuperUserManagement, params=dict(username='freshuser'), data=dict(email='foo@bar.com'))
|
||||
|
||||
# Verify the user was updated.
|
||||
json = self.getJsonResponse(SuperUserManagement, params=dict(username = 'freshuser'))
|
||||
self.assertEquals('freshuser', json['username'])
|
||||
self.assertEquals('foo@bar.com', json['email'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,9 @@ import unittest
|
|||
import json
|
||||
import time
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from app import app
|
||||
from initdb import setup_database_for_testing, finished_database_for_testing
|
||||
from data.queue import WorkQueue
|
||||
|
||||
|
@ -9,12 +12,47 @@ from data.queue import WorkQueue
|
|||
QUEUE_NAME = 'testqueuename'
|
||||
|
||||
|
||||
class SaveLastCountReporter(object):
|
||||
def __init__(self):
|
||||
self.currently_processing = None
|
||||
self.running_count = None
|
||||
self.total = None
|
||||
|
||||
def __call__(self, currently_processing, running_count, total_jobs):
|
||||
self.currently_processing = currently_processing
|
||||
self.running_count = running_count
|
||||
self.total = total_jobs
|
||||
|
||||
|
||||
class AutoUpdatingQueue(object):
|
||||
def __init__(self, queue_to_wrap):
|
||||
self._queue = queue_to_wrap
|
||||
|
||||
def _wrapper(self, func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
to_return = func(*args, **kwargs)
|
||||
self._queue.update_metrics()
|
||||
return to_return
|
||||
return wrapper
|
||||
|
||||
def __getattr__(self, attr_name):
|
||||
method_or_attr = getattr(self._queue, attr_name)
|
||||
if callable(method_or_attr):
|
||||
return self._wrapper(method_or_attr)
|
||||
else:
|
||||
return method_or_attr
|
||||
|
||||
|
||||
class QueueTestCase(unittest.TestCase):
|
||||
TEST_MESSAGE_1 = json.dumps({'data': 1})
|
||||
TEST_MESSAGE_2 = json.dumps({'data': 2})
|
||||
|
||||
def setUp(self):
|
||||
self.queue = WorkQueue(QUEUE_NAME)
|
||||
self.reporter = SaveLastCountReporter()
|
||||
self.transaction_factory = app.config['DB_TRANSACTION_FACTORY']
|
||||
self.queue = AutoUpdatingQueue(WorkQueue(QUEUE_NAME, self.transaction_factory,
|
||||
reporter=self.reporter))
|
||||
setup_database_for_testing(self)
|
||||
|
||||
def tearDown(self):
|
||||
|
@ -23,33 +61,57 @@ class QueueTestCase(unittest.TestCase):
|
|||
|
||||
class TestQueue(QueueTestCase):
|
||||
def test_same_canonical_names(self):
|
||||
self.assertEqual(self.reporter.currently_processing, None)
|
||||
self.assertEqual(self.reporter.running_count, None)
|
||||
self.assertEqual(self.reporter.total, None)
|
||||
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1)
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_2)
|
||||
self.assertEqual(self.reporter.currently_processing, False)
|
||||
self.assertEqual(self.reporter.running_count, 0)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
one = self.queue.get()
|
||||
self.assertNotEqual(None, one)
|
||||
self.assertEqual(self.TEST_MESSAGE_1, one.body)
|
||||
self.assertEqual(self.reporter.currently_processing, True)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
two_fail = self.queue.get()
|
||||
self.assertEqual(None, two_fail)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
self.queue.complete(one)
|
||||
self.assertEqual(self.reporter.currently_processing, False)
|
||||
self.assertEqual(self.reporter.running_count, 0)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
two = self.queue.get()
|
||||
self.assertNotEqual(None, two)
|
||||
self.assertEqual(self.reporter.currently_processing, True)
|
||||
self.assertEqual(self.TEST_MESSAGE_2, two.body)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
def test_different_canonical_names(self):
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1)
|
||||
self.queue.put(['abc', 'ghi'], self.TEST_MESSAGE_2)
|
||||
self.assertEqual(self.reporter.running_count, 0)
|
||||
self.assertEqual(self.reporter.total, 2)
|
||||
|
||||
one = self.queue.get()
|
||||
self.assertNotEqual(None, one)
|
||||
self.assertEqual(self.TEST_MESSAGE_1, one.body)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 2)
|
||||
|
||||
two = self.queue.get()
|
||||
self.assertNotEqual(None, two)
|
||||
self.assertEqual(self.TEST_MESSAGE_2, two.body)
|
||||
self.assertEqual(self.reporter.running_count, 2)
|
||||
self.assertEqual(self.reporter.total, 2)
|
||||
|
||||
def test_canonical_name(self):
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1)
|
||||
|
@ -63,23 +125,32 @@ class TestQueue(QueueTestCase):
|
|||
|
||||
def test_expiration(self):
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1)
|
||||
self.assertEqual(self.reporter.running_count, 0)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
one = self.queue.get(processing_time=0.5)
|
||||
self.assertNotEqual(None, one)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
one_fail = self.queue.get()
|
||||
self.assertEqual(None, one_fail)
|
||||
|
||||
time.sleep(1)
|
||||
self.queue.update_metrics()
|
||||
self.assertEqual(self.reporter.running_count, 0)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
one_again = self.queue.get()
|
||||
self.assertNotEqual(None, one_again)
|
||||
self.assertEqual(self.reporter.running_count, 1)
|
||||
self.assertEqual(self.reporter.total, 1)
|
||||
|
||||
def test_specialized_queue(self):
|
||||
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1)
|
||||
self.queue.put(['def', 'def'], self.TEST_MESSAGE_2)
|
||||
|
||||
my_queue = WorkQueue(QUEUE_NAME, ['def'])
|
||||
my_queue = AutoUpdatingQueue(WorkQueue(QUEUE_NAME, self.transaction_factory, ['def']))
|
||||
|
||||
two = my_queue.get()
|
||||
self.assertNotEqual(None, two)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
from config import DefaultConfig
|
||||
from test.testlogs import TestBuildLogs
|
||||
|
||||
|
@ -25,7 +27,16 @@ class TestConfig(DefaultConfig):
|
|||
STORAGE_TYPE = 'FakeStorage'
|
||||
|
||||
BUILDLOGS_MODULE_AND_CLASS = ('test.testlogs', 'testlogs.TestBuildLogs')
|
||||
BUILDLOGS_OPTIONS = ['logs.quay.io', 'devtable', 'building',
|
||||
'deadbeef-dead-beef-dead-beefdeadbeef']
|
||||
BUILDLOGS_OPTIONS = ['devtable', 'building', 'deadbeef-dead-beef-dead-beefdeadbeef']
|
||||
|
||||
USERFILES_TYPE = 'FakeUserfiles'
|
||||
|
||||
FEATURE_SUPER_USERS = True
|
||||
FEATURE_BILLING = True
|
||||
SUPER_USERS = ['devtable']
|
||||
|
||||
LICENSE_USER_LIMIT = 500
|
||||
LICENSE_EXPIRATION = datetime.now() + timedelta(weeks=520)
|
||||
LICENSE_EXPIRATION_WARNING = datetime.now() + timedelta(weeks=520)
|
||||
|
||||
FEATURE_GITHUB_BUILD = True
|
||||
|
|
Reference in a new issue