Skip to content

Commit f52bbef

Browse files
committed
feat(tests): add Deployment tests (this can be removed in the future)
1 parent 09476aa commit f52bbef

14 files changed

Lines changed: 4984 additions & 0 deletions

rootfs/api/tests/deployments/__init__.py

Whitespace-only changes.

rootfs/api/tests/deployments/test_app.py

Lines changed: 533 additions & 0 deletions
Large diffs are not rendered by default.

rootfs/api/tests/deployments/test_build.py

Lines changed: 463 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
from django.contrib.auth.models import User
2+
from django.core.cache import cache
3+
from django.test import override_settings
4+
from rest_framework.test import APITestCase
5+
from rest_framework.authtoken.models import Token
6+
from django.core.exceptions import SuspiciousOperation
7+
8+
from api.models import App, Certificate
9+
from api.tests import TEST_ROOT
10+
11+
12+
@override_settings(DEIS_KUBERNETES_DEPLOYMENTS='1')
13+
class CertificateTest(APITestCase):
14+
15+
"""Tests creation of domain SSL certificates"""
16+
17+
fixtures = ['tests.json']
18+
19+
def setUp(self):
20+
self.user = User.objects.get(username='autotest')
21+
self.token = Token.objects.get(user=self.user).key
22+
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
23+
24+
self.url = '/v2/certs'
25+
self.app = App.objects.create(owner=self.user, id='test-app')
26+
self.domain = 'autotest.example.com'
27+
28+
with open('{}/certs/{}.key'.format(TEST_ROOT, self.domain)) as f:
29+
self.key = f.read()
30+
31+
with open('{}/certs/{}.cert'.format(TEST_ROOT, self.domain)) as f:
32+
self.cert = f.read()
33+
34+
def tearDown(self):
35+
# make sure every test has a clean slate for k8s mocking
36+
cache.clear()
37+
38+
def test_create_certificate_with_domain(self):
39+
"""Tests creating a certificate."""
40+
response = self.client.post(
41+
self.url,
42+
{
43+
'name': 'random-test-cert',
44+
'certificate': self.cert,
45+
'key': self.key
46+
}
47+
)
48+
self.assertEqual(response.status_code, 201, response.data)
49+
50+
def test_update_certificate(self):
51+
"""Tests update of a certificate."""
52+
response = self.client.post(
53+
self.url,
54+
{
55+
'name': 'random-test-cert',
56+
'certificate': self.cert,
57+
'key': self.key
58+
}
59+
)
60+
self.assertEqual(response.status_code, 201, response.data)
61+
62+
def test_create_certificate_with_different_common_name(self):
63+
"""
64+
Make sure common_name is read-only
65+
"""
66+
response = self.client.post(
67+
self.url,
68+
{
69+
'name': 'random-test-cert',
70+
'certificate': self.cert,
71+
'key': self.key,
72+
'common_name': 'foo.example.com'
73+
}
74+
)
75+
self.assertEqual(response.status_code, 201, response.data)
76+
self.assertEqual(response.data['common_name'], 'autotest.example.com')
77+
78+
def test_get_certificate_screens_data(self):
79+
"""
80+
When a user retrieves a certificate, only the common name and expiry date should be
81+
displayed.
82+
"""
83+
response = self.client.post(
84+
self.url,
85+
{
86+
'name': 'random-test-cert',
87+
'certificate': self.cert,
88+
'key': self.key
89+
}
90+
)
91+
self.assertEqual(response.status_code, 201, response.data)
92+
93+
response = self.client.get('{}/{}'.format(self.url, 'random-test-cert'))
94+
self.assertEqual(response.status_code, 200, response.data)
95+
96+
expected = {
97+
'common_name': 'autotest.example.com',
98+
'expires': '2016-03-05T17:14:27Z',
99+
'fingerprint': '37:24:D8:EB:DC:A4:2C:DA:88:55:C5:19:71:D3:9B:43:BA:AC:3A:CE:33:8E:07:52:1C:51:01:A0:97:43:C9:4D', # noqa
100+
'san': [],
101+
'domains': [],
102+
}
103+
for key, value in list(expected.items()):
104+
self.assertEqual(response.data[key], value, key)
105+
106+
def test_certficate_denied_requests(self):
107+
"""Disallow put/patch requests"""
108+
response = self.client.put(self.url)
109+
self.assertEqual(response.status_code, 405, response.content)
110+
response = self.client.patch(self.url)
111+
self.assertEqual(response.status_code, 405, response.content)
112+
113+
def test_delete_certificate(self):
114+
"""Destroying a certificate should generate a 204 response"""
115+
Certificate.objects.create(
116+
name='random-test-cert',
117+
owner=self.user,
118+
common_name='autotest.example.com',
119+
certificate=self.cert
120+
)
121+
url = '/v2/certs/random-test-cert'
122+
response = self.client.delete(url)
123+
self.assertEqual(response.status_code, 204, response.data)
124+
125+
def test_create_invalid_cert(self):
126+
"""Upload a cert that can't be loaded by pyopenssl"""
127+
response = self.client.post(
128+
self.url,
129+
{
130+
'name': 'random-test-cert',
131+
'certificate': 'i am bad data',
132+
'key': 'i am bad data as well'
133+
}
134+
)
135+
self.assertEqual(response.status_code, 400, response.data)
136+
# match partial since right now the rest is pyopenssl errors
137+
self.assertIn('Could not load certificate', response.data['certificate'][0])
138+
139+
def test_load_invalid_cert(self):
140+
"""Inject a cert that can't be loaded by pyopenssl"""
141+
142+
with self.assertRaises(SuspiciousOperation):
143+
Certificate.objects.create(
144+
owner=self.user,
145+
name='random-test-cert',
146+
certificate='i am bad data',
147+
key='i am bad data as well'
148+
)
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
from django.contrib.auth.models import User
2+
from django.core.cache import cache
3+
from django.test import override_settings
4+
from rest_framework.test import APITestCase
5+
from rest_framework.authtoken.models import Token
6+
7+
from api.models import App, Certificate, Domain
8+
from api.tests import TEST_ROOT
9+
10+
11+
@override_settings(DEIS_KUBERNETES_DEPLOYMENTS='1')
12+
class CertificateUseCase1Test(APITestCase):
13+
14+
"""
15+
Tests creation of domain SSL certificate and attach the
16+
certificate to a domain and then detach
17+
"""
18+
19+
fixtures = ['tests.json']
20+
21+
def setUp(self):
22+
self.user = User.objects.get(username='autotest')
23+
self.token = Token.objects.get(user=self.user).key
24+
self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
25+
26+
self.url = '/v2/certs'
27+
self.app = App.objects.create(owner=self.user, id='test-app-use-case-1')
28+
self.domain = Domain.objects.create(owner=self.user, app=self.app, domain='foo.com')
29+
self.name = 'foo-com' # certificate name
30+
31+
with open('{}/certs/{}.key'.format(TEST_ROOT, self.domain)) as f:
32+
self.key = f.read()
33+
34+
with open('{}/certs/{}.cert'.format(TEST_ROOT, self.domain)) as f:
35+
self.cert = f.read()
36+
37+
def tearDown(self):
38+
# make sure every test has a clean slate for k8s mocking
39+
cache.clear()
40+
41+
def test_create_certificate_with_domain(self):
42+
"""Tests creating a certificate."""
43+
response = self.client.post(
44+
self.url,
45+
{
46+
'name': self.name,
47+
'certificate': self.cert,
48+
'key': self.key
49+
}
50+
)
51+
self.assertEqual(response.status_code, 201, response.data)
52+
53+
def test_create_certificate_with_different_common_name(self):
54+
"""
55+
Make sure common_name is read-only
56+
"""
57+
response = self.client.post(
58+
self.url,
59+
{
60+
'name': self.name,
61+
'certificate': self.cert,
62+
'key': self.key,
63+
'common_name': 'foo.example.com'
64+
}
65+
)
66+
self.assertEqual(response.status_code, 201, response.data)
67+
self.assertEqual(response.data['common_name'], 'foo.com')
68+
69+
def test_get_certificate_screens_data(self):
70+
"""
71+
When a user retrieves a certificate make sure proper data is returned
72+
"""
73+
# Create certificate
74+
response = self.client.post(
75+
self.url,
76+
{
77+
'name': self.name,
78+
'certificate': self.cert,
79+
'key': self.key
80+
}
81+
)
82+
self.assertEqual(response.status_code, 201, response.data)
83+
84+
# Attach to domain that does not exist
85+
response = self.client.post(
86+
'{}/{}/domain/'.format(self.url, self.name),
87+
{'domain': 'random.com'}
88+
)
89+
self.assertEqual(response.status_code, 404)
90+
91+
# Attach domain to certificate
92+
response = self.client.post(
93+
'{}/{}/domain/'.format(self.url, self.name),
94+
{'domain': str(self.domain)}
95+
)
96+
self.assertEqual(response.status_code, 201, response.data)
97+
98+
# Assert data
99+
response = self.client.get('{}/{}'.format(self.url, self.name))
100+
self.assertEqual(response.status_code, 200, response.data)
101+
102+
expected = {
103+
'name': self.name,
104+
'common_name': str(self.domain),
105+
'expires': '2017-01-14T23:55:59Z',
106+
'fingerprint': 'AC:82:58:80:EA:C4:B9:75:C1:1C:52:48:40:28:15:1D:47:AC:ED:88:4B:D4:72:95:B2:C0:A0:DF:4A:A7:60:B6', # noqa
107+
'san': [],
108+
'domains': ['foo.com']
109+
}
110+
for key, value in list(expected.items()):
111+
self.assertEqual(response.data[key], value, key)
112+
113+
# detach domain from a certificate
114+
response = self.client.delete(
115+
'{}/{}/domain/{}'.format(self.url, self.name, self.domain)
116+
)
117+
self.assertEqual(response.status_code, 204, response.data)
118+
119+
# detach a domain that does not exist from a certificate
120+
response = self.client.delete(
121+
'{}/{}/domain/{}'.format(self.url, self.name, 'i-am-fake.com')
122+
)
123+
self.assertEqual(response.status_code, 404)
124+
125+
# Assert data
126+
response = self.client.get('{}/{}'.format(self.url, self.name))
127+
self.assertEqual(response.status_code, 200, response.data)
128+
self.assertEqual(response.data['domains'], [])
129+
130+
def test_certficate_denied_requests(self):
131+
"""Disallow put/patch requests"""
132+
response = self.client.put(self.url)
133+
self.assertEqual(response.status_code, 405, response.content)
134+
response = self.client.patch(self.url)
135+
self.assertEqual(response.status_code, 405, response.content)
136+
137+
def test_delete_certificate(self):
138+
"""Destroying a certificate should generate a 204 response"""
139+
Certificate.objects.create(
140+
owner=self.user,
141+
name=self.name,
142+
certificate=self.cert
143+
)
144+
145+
url = '/v2/certs/{}'.format(self.name)
146+
response = self.client.delete(url)
147+
self.assertEqual(response.status_code, 204, response.data)
148+
149+
def test_delete_certificate_with_attached_domain(self):
150+
"""
151+
Destroy a certificate with attached domain.
152+
Domain should not have assigned cert anymore
153+
"""
154+
# Create certificate
155+
response = self.client.post(
156+
self.url,
157+
{
158+
'name': self.name,
159+
'certificate': self.cert,
160+
'key': self.key
161+
}
162+
)
163+
self.assertEqual(response.status_code, 201, response.data)
164+
165+
# Attach domain to certificate
166+
response = self.client.post(
167+
'{}/{}/domain/'.format(self.url, self.name),
168+
{'domain': str(self.domain)}
169+
)
170+
self.assertEqual(response.status_code, 201, response.data)
171+
172+
# Assert data from cert side
173+
response = self.client.get('{}/{}'.format(self.url, self.name))
174+
self.assertEqual(response.status_code, 200, response.data)
175+
self.assertEqual(response.data['domains'], [str(self.domain)])
176+
177+
# Assert data from domain side
178+
domain = Domain.objects.get(id=self.domain.id)
179+
self.assertEqual(domain.certificate.name, self.name)
180+
181+
# Delete certificate
182+
url = '/v2/certs/{}'.format(self.name)
183+
response = self.client.delete(url)
184+
self.assertEqual(response.status_code, 204, response.data)
185+
186+
# verify certificate is not attached to domain anymore
187+
domain = Domain.objects.get(id=self.domain.id)
188+
self.assertEqual(domain.certificate, None)

0 commit comments

Comments
 (0)