github.com/misfo/deis@v1.0.1-0.20141111224634-e0eee0392b8a/controller/api/tests/test_build.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 Build 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 BuildTest(TransactionTestCase): 28 29 """Tests build 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_build(self): 39 """ 40 Test that a null build is created and that users can post new builds 41 """ 42 url = '/v1/apps' 43 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 44 self.assertEqual(response.status_code, 201) 45 app_id = response.data['id'] 46 # check to see that no initial build was created 47 url = "/v1/apps/{app_id}/builds".format(**locals()) 48 response = self.client.get(url, 49 HTTP_AUTHORIZATION='token {}'.format(self.token)) 50 self.assertEqual(response.status_code, 200) 51 self.assertEqual(response.data['count'], 0) 52 # post a new build 53 body = {'image': 'autotest/example'} 54 response = self.client.post(url, json.dumps(body), content_type='application/json', 55 HTTP_AUTHORIZATION='token {}'.format(self.token)) 56 self.assertEqual(response.status_code, 201) 57 build_id = response.data['uuid'] 58 build1 = response.data 59 self.assertEqual(response.data['image'], body['image']) 60 # read the build 61 url = "/v1/apps/{app_id}/builds/{build_id}".format(**locals()) 62 response = self.client.get(url, 63 HTTP_AUTHORIZATION='token {}'.format(self.token)) 64 self.assertEqual(response.status_code, 200) 65 build2 = response.data 66 self.assertEqual(build1, build2) 67 # post a new build 68 url = "/v1/apps/{app_id}/builds".format(**locals()) 69 body = {'image': 'autotest/example'} 70 response = self.client.post(url, json.dumps(body), content_type='application/json', 71 HTTP_AUTHORIZATION='token {}'.format(self.token)) 72 self.assertEqual(response.status_code, 201) 73 self.assertIn('x-deis-release', response._headers) 74 build3 = response.data 75 self.assertEqual(response.data['image'], body['image']) 76 self.assertNotEqual(build2['uuid'], build3['uuid']) 77 # disallow put/patch/delete 78 response = self.client.put(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 79 self.assertEqual(response.status_code, 405) 80 response = self.client.patch(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 81 self.assertEqual(response.status_code, 405) 82 response = self.client.delete(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 83 self.assertEqual(response.status_code, 405) 84 85 @mock.patch('requests.post', mock_import_repository_task) 86 def test_build_default_containers(self): 87 url = '/v1/apps' 88 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 89 self.assertEqual(response.status_code, 201) 90 app_id = response.data['id'] 91 # post an image as a build 92 url = "/v1/apps/{app_id}/builds".format(**locals()) 93 body = {'image': 'autotest/example'} 94 response = self.client.post(url, json.dumps(body), content_type='application/json', 95 HTTP_AUTHORIZATION='token {}'.format(self.token)) 96 self.assertEqual(response.status_code, 201) 97 url = "/v1/apps/{app_id}/containers/cmd".format(**locals()) 98 response = self.client.get(url, 99 HTTP_AUTHORIZATION='token {}'.format(self.token)) 100 self.assertEqual(response.status_code, 200) 101 self.assertEqual(len(response.data['results']), 1) 102 container = response.data['results'][0] 103 self.assertEqual(container['type'], 'cmd') 104 self.assertEqual(container['num'], 1) 105 # start with a new app 106 url = '/v1/apps' 107 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 108 self.assertEqual(response.status_code, 201) 109 app_id = response.data['id'] 110 # post a new build with procfile 111 url = "/v1/apps/{app_id}/builds".format(**locals()) 112 body = {'image': 'autotest/example', 113 'sha': 'a'*40, 114 'dockerfile': "FROM scratch"} 115 response = self.client.post(url, json.dumps(body), content_type='application/json', 116 HTTP_AUTHORIZATION='token {}'.format(self.token)) 117 self.assertEqual(response.status_code, 201) 118 url = "/v1/apps/{app_id}/containers/cmd".format(**locals()) 119 response = self.client.get(url, 120 HTTP_AUTHORIZATION='token {}'.format(self.token)) 121 self.assertEqual(response.status_code, 200) 122 self.assertEqual(len(response.data['results']), 1) 123 container = response.data['results'][0] 124 self.assertEqual(container['type'], 'cmd') 125 self.assertEqual(container['num'], 1) 126 # start with a new app 127 url = '/v1/apps' 128 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 129 self.assertEqual(response.status_code, 201) 130 app_id = response.data['id'] 131 # post a new build with procfile 132 url = "/v1/apps/{app_id}/builds".format(**locals()) 133 body = {'image': 'autotest/example', 134 'sha': 'a'*40, 135 'dockerfile': "FROM scratch", 136 'procfile': {'worker': 'node worker.js'}} 137 response = self.client.post(url, json.dumps(body), content_type='application/json', 138 HTTP_AUTHORIZATION='token {}'.format(self.token)) 139 self.assertEqual(response.status_code, 201) 140 url = "/v1/apps/{app_id}/containers/cmd".format(**locals()) 141 response = self.client.get(url, 142 HTTP_AUTHORIZATION='token {}'.format(self.token)) 143 self.assertEqual(response.status_code, 200) 144 self.assertEqual(len(response.data['results']), 1) 145 container = response.data['results'][0] 146 self.assertEqual(container['type'], 'cmd') 147 self.assertEqual(container['num'], 1) 148 # start with a new app 149 url = '/v1/apps' 150 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 151 self.assertEqual(response.status_code, 201) 152 app_id = response.data['id'] 153 # post a new build with procfile 154 url = "/v1/apps/{app_id}/builds".format(**locals()) 155 body = {'image': 'autotest/example', 156 'sha': 'a'*40, 157 'procfile': json.dumps({'web': 'node server.js', 158 'worker': 'node worker.js'})} 159 response = self.client.post(url, json.dumps(body), content_type='application/json', 160 HTTP_AUTHORIZATION='token {}'.format(self.token)) 161 self.assertEqual(response.status_code, 201) 162 url = "/v1/apps/{app_id}/containers/web".format(**locals()) 163 response = self.client.get(url, 164 HTTP_AUTHORIZATION='token {}'.format(self.token)) 165 self.assertEqual(response.status_code, 200) 166 self.assertEqual(len(response.data['results']), 1) 167 container = response.data['results'][0] 168 self.assertEqual(container['type'], 'web') 169 self.assertEqual(container['num'], 1) 170 171 @mock.patch('requests.post', mock_import_repository_task) 172 def test_build_str(self): 173 """Test the text representation of a build.""" 174 url = '/v1/apps' 175 response = self.client.post(url) 176 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(self.token)) 177 self.assertEqual(response.status_code, 201) 178 app_id = response.data['id'] 179 # post a new build 180 url = "/v1/apps/{app_id}/builds".format(**locals()) 181 body = {'image': 'autotest/example'} 182 response = self.client.post(url, json.dumps(body), content_type='application/json', 183 HTTP_AUTHORIZATION='token {}'.format(self.token)) 184 self.assertEqual(response.status_code, 201) 185 build = Build.objects.get(uuid=response.data['uuid']) 186 self.assertEqual(str(build), "{}-{}".format( 187 response.data['app'], response.data['uuid'][:7])) 188 189 @mock.patch('requests.post', mock_import_repository_task) 190 def test_admin_can_create_builds_on_other_apps(self): 191 """If a user creates an application, an administrator should be able 192 to push builds. 193 """ 194 # create app as non-admin 195 user = User.objects.get(username='autotest2') 196 token = Token.objects.get(user=user).key 197 url = '/v1/apps' 198 response = self.client.post(url, HTTP_AUTHORIZATION='token {}'.format(token)) 199 self.assertEqual(response.status_code, 201) 200 app_id = response.data['id'] 201 # post a new build as admin 202 url = "/v1/apps/{app_id}/builds".format(**locals()) 203 body = {'image': 'autotest/example'} 204 response = self.client.post(url, json.dumps(body), content_type='application/json', 205 HTTP_AUTHORIZATION='token {}'.format(self.token)) 206 self.assertEqual(response.status_code, 201) 207 build = Build.objects.get(uuid=response.data['uuid']) 208 self.assertEqual(str(build), "{}-{}".format( 209 response.data['app'], response.data['uuid'][:7]))