github.com/misfo/deis@v1.0.1-0.20141111224634-e0eee0392b8a/controller/api/tests/test_release.py (about) 1 """ 2 Unit tests for the Deis api app. 3 4 Run the tests with "./manage.py test api" 5 """ 6 7 from __future__ import unicode_literals 8 9 import json 10 import mock 11 import requests 12 13 from django.contrib.auth.models import User 14 from django.test import TransactionTestCase 15 from rest_framework.authtoken.models import Token 16 17 from api.models import Release 18 19 20 def mock_import_repository_task(*args, **kwargs): 21 resp = requests.Response() 22 resp.status_code = 200 23 resp._content_consumed = True 24 return resp 25 26 27 class ReleaseTest(TransactionTestCase): 28 29 """Tests push notification from build system""" 30 31 fixtures = ['tests.json'] 32 33 def setUp(self): 34 self.user = User.objects.get(username='autotest') 35 self.token = Token.objects.get(user=self.user).key 36 37 @mock.patch('requests.post', mock_import_repository_task) 38 def test_release(self): 39 """ 40 Test that a release is created when an app is created, and 41 that updating config or build or triggers a new release 42 """ 43 url = '/v1/apps' 44 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 45 self.assertEqual(response.status_code, 201) 46 app_id = response.data['id'] 47 # check that updating config rolls a new release 48 url = '/v1/apps/{app_id}/config'.format(**locals()) 49 body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})} 50 response = self.client.post( 51 url, json.dumps(body), content_type='application/json', 52 HTTP_AUTHORIZATION='token {}'.format(self.token)) 53 self.assertEqual(response.status_code, 201) 54 self.assertIn('NEW_URL1', response.data['values']) 55 # check to see that an initial release was created 56 url = '/v1/apps/{app_id}/releases'.format(**locals()) 57 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 58 self.assertEqual(response.status_code, 200) 59 # account for the config release as well 60 self.assertEqual(response.data['count'], 2) 61 url = '/v1/apps/{app_id}/releases/v1'.format(**locals()) 62 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 63 self.assertEqual(response.status_code, 200) 64 release1 = response.data 65 self.assertIn('config', response.data) 66 self.assertIn('build', response.data) 67 self.assertEquals(release1['version'], 1) 68 # check to see that a new release was created 69 url = '/v1/apps/{app_id}/releases/v2'.format(**locals()) 70 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 71 self.assertEqual(response.status_code, 200) 72 release2 = response.data 73 self.assertNotEqual(release1['uuid'], release2['uuid']) 74 self.assertNotEqual(release1['config'], release2['config']) 75 self.assertEqual(release1['build'], release2['build']) 76 self.assertEquals(release2['version'], 2) 77 # check that updating the build rolls a new release 78 url = '/v1/apps/{app_id}/builds'.format(**locals()) 79 build_config = json.dumps({'PATH': 'bin:/usr/local/bin:/usr/bin:/bin'}) 80 body = {'image': 'autotest/example'} 81 response = self.client.post( 82 url, json.dumps(body), content_type='application/json', 83 HTTP_AUTHORIZATION='token {}'.format(self.token)) 84 self.assertEqual(response.status_code, 201) 85 self.assertEqual(response.data['image'], body['image']) 86 # check to see that a new release was created 87 url = '/v1/apps/{app_id}/releases/v3'.format(**locals()) 88 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 89 self.assertEqual(response.status_code, 200) 90 release3 = response.data 91 self.assertNotEqual(release2['uuid'], release3['uuid']) 92 self.assertNotEqual(release2['build'], release3['build']) 93 self.assertEquals(release3['version'], 3) 94 # check that we can fetch a previous release 95 url = '/v1/apps/{app_id}/releases/v2'.format(**locals()) 96 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 97 self.assertEqual(response.status_code, 200) 98 release2 = response.data 99 self.assertNotEqual(release2['uuid'], release3['uuid']) 100 self.assertNotEqual(release2['build'], release3['build']) 101 self.assertEquals(release2['version'], 2) 102 # disallow post/put/patch/delete 103 url = '/v1/apps/{app_id}/releases'.format(**locals()) 104 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 105 self.assertEqual(response.status_code, 405) 106 response = self.client.put(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 107 self.assertEqual(response.status_code, 405) 108 response = self.client.patch(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 109 self.assertEqual(response.status_code, 405) 110 response = self.client.delete(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 111 self.assertEqual(response.status_code, 405) 112 return release3 113 114 @mock.patch('requests.post', mock_import_repository_task) 115 def test_release_rollback(self): 116 url = '/v1/apps' 117 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 118 self.assertEqual(response.status_code, 201) 119 app_id = response.data['id'] 120 # try to rollback with only 1 release extant, expecting 400 121 url = "/v1/apps/{app_id}/releases/rollback/".format(**locals()) 122 response = self.client.post(url, content_type='application/json', 123 HTTP_AUTHORIZATION='token {}'.format(self.token)) 124 self.assertEqual(response.status_code, 400) 125 # update config to roll a new release 126 url = '/v1/apps/{app_id}/config'.format(**locals()) 127 body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})} 128 response = self.client.post( 129 url, json.dumps(body), content_type='application/json', 130 HTTP_AUTHORIZATION='token {}'.format(self.token)) 131 self.assertEqual(response.status_code, 201) 132 # update the build to roll a new release 133 url = '/v1/apps/{app_id}/builds'.format(**locals()) 134 body = {'image': 'autotest/example'} 135 response = self.client.post( 136 url, json.dumps(body), content_type='application/json', 137 HTTP_AUTHORIZATION='token {}'.format(self.token)) 138 self.assertEqual(response.status_code, 201) 139 # rollback and check to see that a 4th release was created 140 # with the build and config of release #2 141 url = "/v1/apps/{app_id}/releases/rollback/".format(**locals()) 142 response = self.client.post(url, content_type='application/json', 143 HTTP_AUTHORIZATION='token {}'.format(self.token)) 144 self.assertEqual(response.status_code, 201) 145 url = '/v1/apps/{app_id}/releases'.format(**locals()) 146 response = self.client.get(url, content_type='application/json', 147 HTTP_AUTHORIZATION='token {}'.format(self.token)) 148 self.assertEqual(response.status_code, 200) 149 self.assertEqual(response.data['count'], 4) 150 url = '/v1/apps/{app_id}/releases/v2'.format(**locals()) 151 response = self.client.get(url, content_type='application/json', 152 HTTP_AUTHORIZATION='token {}'.format(self.token)) 153 self.assertEqual(response.status_code, 200) 154 release2 = response.data 155 self.assertEquals(release2['version'], 2) 156 url = '/v1/apps/{app_id}/releases/v4'.format(**locals()) 157 response = self.client.get(url, content_type='application/json', 158 HTTP_AUTHORIZATION='token {}'.format(self.token)) 159 self.assertEqual(response.status_code, 200) 160 release4 = response.data 161 self.assertEquals(release4['version'], 4) 162 self.assertNotEqual(release2['uuid'], release4['uuid']) 163 self.assertEqual(release2['build'], release4['build']) 164 self.assertEqual(release2['config'], release4['config']) 165 # rollback explicitly to release #1 and check that a 5th release 166 # was created with the build and config of release #1 167 url = "/v1/apps/{app_id}/releases/rollback/".format(**locals()) 168 body = {'version': 1} 169 response = self.client.post( 170 url, json.dumps(body), content_type='application/json', 171 HTTP_AUTHORIZATION='token {}'.format(self.token)) 172 self.assertEqual(response.status_code, 201) 173 url = '/v1/apps/{app_id}/releases'.format(**locals()) 174 response = self.client.get(url, content_type='application/json', 175 HTTP_AUTHORIZATION='token {}'.format(self.token)) 176 self.assertEqual(response.status_code, 200) 177 self.assertEqual(response.data['count'], 5) 178 url = '/v1/apps/{app_id}/releases/v1'.format(**locals()) 179 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 180 self.assertEqual(response.status_code, 200) 181 release1 = response.data 182 url = '/v1/apps/{app_id}/releases/v5'.format(**locals()) 183 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 184 self.assertEqual(response.status_code, 200) 185 release5 = response.data 186 self.assertEqual(release5['version'], 5) 187 self.assertNotEqual(release1['uuid'], release5['uuid']) 188 self.assertEqual(release1['build'], release5['build']) 189 self.assertEqual(release1['config'], release5['config']) 190 # check to see that the current config is actually the initial one 191 url = "/v1/apps/{app_id}/config".format(**locals()) 192 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 193 self.assertEqual(response.status_code, 200) 194 self.assertEqual(response.data['values'], {}) 195 # rollback to #3 and see that it has the correct config 196 url = "/v1/apps/{app_id}/releases/rollback/".format(**locals()) 197 body = {'version': 3} 198 response = self.client.post( 199 url, json.dumps(body), content_type='application/json', 200 HTTP_AUTHORIZATION='token {}'.format(self.token)) 201 self.assertEqual(response.status_code, 201) 202 url = "/v1/apps/{app_id}/config".format(**locals()) 203 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 204 self.assertEqual(response.status_code, 200) 205 values = response.data['values'] 206 self.assertIn('NEW_URL1', values) 207 self.assertEqual('http://localhost:8080/', values['NEW_URL1']) 208 209 @mock.patch('requests.post', mock_import_repository_task) 210 def test_release_str(self): 211 """Test the text representation of a release.""" 212 release3 = self.test_release() 213 release = Release.objects.get(uuid=release3['uuid']) 214 self.assertEqual(str(release), "{}-v3".format(release3['app'])) 215 216 @mock.patch('requests.post', mock_import_repository_task) 217 def test_release_summary(self): 218 """Test the text summary of a release.""" 219 release3 = self.test_release() 220 release = Release.objects.get(uuid=release3['uuid']) 221 # check that the release has push and env change messages 222 self.assertIn('autotest deployed ', release.summary) 223 224 @mock.patch('requests.post', mock_import_repository_task) 225 def test_admin_can_create_release(self): 226 """If a non-user creates an app, an admin should be able to create releases.""" 227 user = User.objects.get(username='autotest2') 228 token = Token.objects.get(user=user).key 229 url = '/v1/apps' 230 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(token)) 231 self.assertEqual(response.status_code, 201) 232 app_id = response.data['id'] 233 # check that updating config rolls a new release 234 url = '/v1/apps/{app_id}/config'.format(**locals()) 235 body = {'values': json.dumps({'NEW_URL1': 'http://localhost:8080/'})} 236 response = self.client.post( 237 url, json.dumps(body), content_type='application/json', 238 HTTP_AUTHORIZATION='token {}'.format(self.token)) 239 self.assertEqual(response.status_code, 201) 240 self.assertIn('NEW_URL1', response.data['values']) 241 # check to see that an initial release was created 242 url = '/v1/apps/{app_id}/releases'.format(**locals()) 243 response = self.client.get(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 244 self.assertEqual(response.status_code, 200) 245 # account for the config release as well 246 self.assertEqual(response.data['count'], 2)