Skip to content

Commit

Permalink
Add 'unique' field parameter
Browse files Browse the repository at this point in the history
* Make user username and email unique
* Update tests to create unique usernames
* Update tests to clean up created resources
  • Loading branch information
Ekaterina Chernova committed Apr 24, 2018
1 parent fa80866 commit 5fecf21
Show file tree
Hide file tree
Showing 15 changed files with 342 additions and 218 deletions.
3 changes: 3 additions & 0 deletions kqueen/auth/test_ldap.py
Expand Up @@ -16,6 +16,9 @@ def setup(self, user):

self.auth_class = LDAPAuth(uri='ldap://127.0.0.1', admin_dn='cn=admin,dc=example,dc=org', _password='heslo123')

def teardown(self):
self.user.delete()

def test_raise_on_missing_creds(self):
with pytest.raises(Exception, msg='Failed to configure LDAP, please provide valid LDAP credentials'):
LDAPAuth()
Expand Down
75 changes: 45 additions & 30 deletions kqueen/blueprints/api/test_cluster.py
@@ -1,19 +1,29 @@
from .test_crud import BaseTestCRUD
from flask import url_for
from kqueen.config import current_config
from kqueen.conftest import cluster
from uuid import uuid4
from kqueen.conftest import ClusterFixture, ProvisionerFixture

import json
import pytest
from uuid import uuid4

config = current_config()


class TestClusterCRUD(BaseTestCRUD):
def get_object(self):
obj = cluster()

def setup(self):
super().setup()
self.user = self.test_user.obj
self.test_provisioner = ProvisionerFixture(self.test_user)
self.provisioner = self.test_provisioner.obj

def teardown(self):
super().teardown()
self.test_provisioner.destroy()

def get_object(self):
obj = ClusterFixture()
return obj

def get_edit_data(self):
Expand Down Expand Up @@ -74,7 +84,7 @@ def test_crud_list(self):
)
assert obj.get_dict(expand=True) in data

@pytest.mark.parametrize('cluster_id,status_code', [
@pytest.mark.parametrize('cluster_id, status_code', [
(uuid4(), 404),
('wrong-uuid', 404),
])
Expand Down Expand Up @@ -148,14 +158,13 @@ def test_progress_format(self):
assert 'progress' in response.json
assert 'result' in response.json

def test_create(self, provisioner, user):
provisioner.save()
user.save()
def test_create(self):

self.provisioner.save()
post_data = {
'name': 'Testing cluster',
'provisioner': 'Provisioner:{}'.format(provisioner.id),
'owner': 'User:{}'.format(user.id)
'provisioner': 'Provisioner:{}'.format(self.provisioner.id),
'owner': 'User:{}'.format(self.user.id)
}

response = self.client.post(
Expand All @@ -169,24 +178,24 @@ def test_create(self, provisioner, user):

assert 'id' in response.json
assert response.json['name'] == post_data['name']
assert response.json['provisioner'] == provisioner.get_dict(expand=True)
assert response.json['provisioner'] == self.provisioner.get_dict(expand=True)

def test_provision_after_create(self, provisioner, user, monkeypatch):
provisioner.save()
user.save()
def test_provision_after_create(self, monkeypatch):
self.provisioner.save()
self.user.save()

def fake_provision(self, *args, **kwargs):
self.cluster.name = 'Provisioned'
self.cluster.save()

return True, None

monkeypatch.setattr(provisioner.get_engine_cls(), 'provision', fake_provision)
monkeypatch.setattr(self.provisioner.get_engine_cls(), 'provision', fake_provision)

post_data = {
'name': 'Testing cluster',
'provisioner': 'Provisioner:{}'.format(provisioner.id),
'owner': 'User:{}'.format(user.id)
'provisioner': 'Provisioner:{}'.format(self.provisioner.id),
'owner': 'User:{}'.format(self.user.id)
}

response = self.client.post(
Expand All @@ -202,19 +211,19 @@ def fake_provision(self, *args, **kwargs):
assert response.status_code == 200
assert obj.name == 'Provisioned'

def test_provision_failed(self, provisioner, user, monkeypatch):
provisioner.save()
user.save()
def test_provision_failed(self, monkeypatch):
self.provisioner.save()
self.user.save()

def fake_provision(self, *args, **kwargs):
return False, 'Testing msg'

monkeypatch.setattr(provisioner.get_engine_cls(), 'provision', fake_provision)
monkeypatch.setattr(self.provisioner.get_engine_cls(), 'provision', fake_provision)

post_data = {
'name': 'Testing cluster',
'provisioner': 'Provisioner:{}'.format(provisioner.id),
'owner': 'User:{}'.format(user.id)
'provisioner': 'Provisioner:{}'.format(self.provisioner.id),
'owner': 'User:{}'.format(self.user.id)
}

response = self.client.post(
Expand All @@ -230,15 +239,15 @@ def fake_provision(self, *args, **kwargs):
config.get('PROVISIONER_UNKNOWN_STATE'),
config.get('PROVISIONER_ERROR_STATE')
])
def test_provision_failed_with_unhealthy_provisioner(self, provisioner, user, provisioner_state):
provisioner.state = provisioner_state
provisioner.save(check_status=False)
user.save()
def test_provision_failed_with_unhealthy_provisioner(self, provisioner_state):
self.provisioner.state = provisioner_state
self.provisioner.save(check_status=False)
self.user.save()

post_data = {
'name': 'Testing cluster',
'provisioner': 'Provisioner:{}'.format(provisioner.id),
'owner': 'User:{}'.format(user.id)
'provisioner': 'Provisioner:{}'.format(self.provisioner.id),
'owner': 'User:{}'.format(self.user.id)
}

response = self.client.post(
Expand Down Expand Up @@ -274,8 +283,11 @@ def test_error_codes(self, data, code, content_type):
assert response.status_code == code

def test_cluster_list_run_get_state(self, monkeypatch):
clusters_to_remove = []
for _ in range(10):
c = cluster()
test_cluster = ClusterFixture()
clusters_to_remove.append(test_cluster)
c = test_cluster.obj
c.save()

def fake_get_state(self):
Expand All @@ -298,3 +310,6 @@ def fake_get_state(self):

assert obj.metadata, 'get_state wasn\'t executed for cluster {}'.format(obj)
assert obj.metadata['executed'], 'get_state wasn\'t executed'

for c in clusters_to_remove:
c.destroy()
84 changes: 38 additions & 46 deletions kqueen/blueprints/api/test_crud.py
@@ -1,14 +1,15 @@
from flask import url_for
from kqueen.conftest import auth_header, user_with_namespace, get_auth_token
from kqueen.conftest import AuthHeader, UserWithNamespaceFixture, UserFixture
from kqueen.config import current_config

import faker
import json
import pytest

config = current_config()


@pytest.mark.usefixtures('client_class')
@pytest.mark.usefixtures('client_class', 'etcd_setup')
class BaseTestCRUD:
def get_object(self):
raise NotImplementedError
Expand Down Expand Up @@ -52,13 +53,20 @@ def get_urls(self, pk=None):
}

def setup(self):
self.obj = self.get_object()
self.test_object = self.get_object()
self.obj = self.test_object.obj
self.obj.save()

self.auth_header = auth_header(self.client)
self.test_user = UserFixture()
self.test_auth_header = AuthHeader(self.test_user)
self.auth_header = self.test_auth_header.get(self.client)
self.namespace = self.auth_header['X-Test-Namespace']

self.urls = self.get_urls()

def teardown(self):
self.test_auth_header.destroy()
self.test_object.destroy()

def test_crud_create(self):
data = self.get_create_data()

Expand Down Expand Up @@ -117,7 +125,7 @@ def test_crud_get(self):
def test_crud_list(self):
response = self.client.get(
self.urls['list'],
headers=self.auth_header,
headers=self.auth_header
)

data = response.json
Expand Down Expand Up @@ -186,7 +194,7 @@ def fake_save(self, *args, **kwargs):
def test_crud_delete(self):
response = self.client.delete(
self.urls['delete'],
headers=self.auth_header,
headers=self.auth_header
)

assert response.status_code == 200
Expand All @@ -197,48 +205,38 @@ def test_crud_delete(self):
)

def test_crud_delete_failed(self, monkeypatch):
original_delete = getattr(self.obj.__class__, 'delete')

def fake_delete(self, *args, **kwargs):
raise Exception('Testing')

monkeypatch.setattr(self.obj.__class__, 'delete', fake_delete)

response = self.client.delete(
self.urls['delete'],
headers=self.auth_header,
)
response = self.client.delete(self.urls['delete'], headers=self.auth_header)

assert response.status_code == 500
monkeypatch.setattr(self.obj.__class__, 'delete', original_delete)

#
# namespacing tests
#
@pytest.fixture
def setup_namespace(self):
self.user1 = user_with_namespace()
self.user2 = user_with_namespace()

@pytest.mark.usefixtures('setup_namespace')
def test_namespacing(self, client):
obj = self.get_object()
def test_namespacing(self):
user1 = UserWithNamespaceFixture()
user1.auth_header = AuthHeader(user1).get(self.client)
user2 = UserWithNamespaceFixture()
user2.auth_header = AuthHeader(user2).get(self.client)

# skip if object class isn't namespaced
if not obj.__class__.is_namespaced():
pytest.skip('Class {} isn\'t namespaced'.format(obj.__class__.__name__))
if not self.obj.__class__.is_namespaced():
pytest.skip('Class {} isn\'t namespaced'.format(self.obj.__class__.__name__))

objs = {}

# create objects for both users
for u in [self.user1, self.user2]:
for u in [user1, user2]:
data = self.get_create_data()

auth_header = get_auth_token(self.client, u)
headers = {
'Authorization': '{} {}'.format(
config.get('JWT_AUTH_HEADER_PREFIX'),
auth_header
)
}

# TODO: fix this
# Dirty hack to make testing data namespaced.
organization_data = {
Expand All @@ -248,13 +246,14 @@ def test_namespacing(self, client):
response = self.client.post(
url_for('api.organization_create'),
data=json.dumps(organization_data),
headers=headers,
headers=u.auth_header,
content_type='application/json',
)
organization_ref = 'Organization:{}'.format(response.json['id'])
profile = faker.Faker().simple_profile()
owner_data = {
'username': 'Test owner',
'email': 'owner@pytest.org',
'username': profile['username'],
'email': profile['mail'],
'password': 'pytest',
'organization': organization_ref,
'role': 'admin',
Expand All @@ -263,7 +262,7 @@ def test_namespacing(self, client):
response = self.client.post(
url_for('api.user_create'),
data=json.dumps(owner_data),
headers=headers,
headers=u.auth_header,
content_type='application/json',
)
if 'owner' in data:
Expand All @@ -277,44 +276,37 @@ def test_namespacing(self, client):
response = self.client.post(
url_for('api.provisioner_create'),
data=json.dumps(provisioner_data),
headers=headers,
headers=u.auth_header,
content_type='application/json',
)
data['provisioner'] = 'Provisioner:{}'.format(response.json['id'])

response = self.client.post(
self.urls['create'],
data=json.dumps(data),
headers=headers,
headers=u.auth_header,
content_type='application/json',
)

print(response.data.decode(response.charset))
objs[u.namespace] = response.json['id']
objs[u.obj.namespace] = response.json['id']

print(response.json)

# test use can't read other's object
for u in [self.user1, self.user2]:
auth_header = get_auth_token(self.client, u)
headers = {
'Authorization': '{} {}'.format(
config.get('JWT_AUTH_HEADER_PREFIX'),
auth_header
)
}
for u in [user1, user2]:

for ns, pk in objs.items():
url = self.get_urls(pk)['get']

if ns == u.namespace:
if ns == u.obj.namespace:
req_code = 200
else:
req_code = 404

response = self.client.get(
url,
headers=headers,
headers=u.auth_header,
content_type='application/json',
)

Expand Down

0 comments on commit 5fecf21

Please sign in to comment.