35 |
35 |
|
36 |
36 |
from django.utils import simplejson as json
|
37 |
37 |
from django.test import TestCase
|
38 |
|
from django.test.client import Client
|
39 |
|
|
40 |
|
from synnefo.db.models import *
|
41 |
|
from synnefo.logic.utils import get_rsapi_state
|
42 |
38 |
|
43 |
39 |
from mock import patch, Mock
|
44 |
|
|
45 |
40 |
from contextlib import contextmanager
|
|
41 |
from functools import wraps
|
|
42 |
|
|
43 |
from synnefo.db.models import *
|
46 |
44 |
from synnefo.db import models_factory as mfactory
|
|
45 |
from synnefo.logic.utils import get_rsapi_state
|
47 |
46 |
|
48 |
|
from synnefo.api import util
|
49 |
47 |
from synnefo.api import faults
|
50 |
48 |
|
51 |
49 |
|
52 |
|
def get_image_mock(request, *Args, **kwargs):
|
53 |
|
return {'backend_id': '1234',
|
54 |
|
'location': 'pithos://dummyimage',
|
55 |
|
'disk_format': 'drbd'}
|
56 |
|
util.get_image = get_image_mock
|
57 |
|
|
58 |
|
|
59 |
50 |
@contextmanager
|
60 |
51 |
def astakos_user(user):
|
61 |
52 |
"""
|
... | ... | |
66 |
57 |
.... make api calls ....
|
67 |
58 |
|
68 |
59 |
"""
|
69 |
|
from synnefo.lib import astakos
|
70 |
|
from synnefo.api import util
|
71 |
|
orig_method = astakos.get_user
|
72 |
|
|
73 |
60 |
def dummy_get_user(request, *args, **kwargs):
|
74 |
61 |
request.user = {'username': user, 'groups': []}
|
75 |
62 |
request.user_uniq = user
|
76 |
|
astakos.get_user = dummy_get_user
|
77 |
|
util.get_user = dummy_get_user
|
78 |
|
yield
|
79 |
|
astakos.get_user = orig_method
|
80 |
|
|
81 |
|
|
82 |
|
class AaiClient(Client):
|
83 |
|
def request(self, **request):
|
84 |
|
request['HTTP_X_AUTH_TOKEN'] = '0000'
|
85 |
|
return super(AaiClient, self).request(**request)
|
86 |
|
|
87 |
|
|
88 |
|
def create_flavors(num):
|
89 |
|
return [mfactory.FlavorFactory() for x in range(num)]
|
90 |
63 |
|
91 |
|
|
92 |
|
class APITest(TestCase):
|
93 |
|
|
94 |
|
def test_api_version(self):
|
95 |
|
"""Check API version."""
|
96 |
|
with astakos_user('user'):
|
97 |
|
response = self.client.get('/api/v1.1/')
|
98 |
|
self.assertEqual(response.status_code, 200)
|
99 |
|
api_version = json.loads(response.content)['version']
|
100 |
|
self.assertEqual(api_version['id'], 'v1.1')
|
101 |
|
self.assertEqual(api_version['status'], 'CURRENT')
|
|
64 |
with patch('synnefo.api.util.get_user') as m:
|
|
65 |
m.side_effect = dummy_get_user
|
|
66 |
yield
|
102 |
67 |
|
103 |
68 |
|
104 |
|
class BaseTestCase(TestCase):
|
105 |
|
def get(self, url, user='user'):
|
|
69 |
class BaseAPITest(TestCase):
|
|
70 |
def get(self, url, user='user', *args, **kwargs):
|
106 |
71 |
with astakos_user(user):
|
107 |
|
response = self.client.get(url)
|
|
72 |
response = self.client.get(url, *args, **kwargs)
|
108 |
73 |
return response
|
109 |
74 |
|
110 |
75 |
def delete(self, url, user='user'):
|
... | ... | |
112 |
77 |
response = self.client.delete(url)
|
113 |
78 |
return response
|
114 |
79 |
|
115 |
|
def post(self, url, user='user', params={}, ctype='json'):
|
|
80 |
def post(self, url, user='user', params={}, ctype='json', *args, **kwargs):
|
116 |
81 |
if ctype == 'json':
|
117 |
82 |
content_type = 'application/json'
|
118 |
83 |
with astakos_user(user):
|
119 |
|
response = self.client.post(url, params, content_type=content_type)
|
|
84 |
response = self.client.post(url, params, content_type=content_type,
|
|
85 |
*args, **kwargs)
|
120 |
86 |
return response
|
121 |
87 |
|
122 |
|
def put(self, url, user='user', params={}, ctype='json'):
|
|
88 |
def put(self, url, user='user', params={}, ctype='json', *args, **kwargs):
|
123 |
89 |
if ctype == 'json':
|
124 |
90 |
content_type = 'application/json'
|
125 |
91 |
with astakos_user(user):
|
126 |
|
response = self.client.put(url, params, content_type=content_type)
|
|
92 |
response = self.client.put(url, params, content_type=content_type,
|
|
93 |
*args, **kwargs)
|
127 |
94 |
return response
|
128 |
95 |
|
129 |
96 |
def assertSuccess(self, response):
|
130 |
|
self.assertTrue(response.status_code in [200, 203])
|
|
97 |
self.assertTrue(response.status_code in [200, 203, 204])
|
131 |
98 |
|
132 |
99 |
def assertFault(self, response, status_code, name):
|
133 |
100 |
self.assertEqual(response.status_code, status_code)
|
... | ... | |
141 |
108 |
self.assertFault(response, 404, 'itemNotFound')
|
142 |
109 |
|
143 |
110 |
|
144 |
|
class FlavorAPITest(BaseTestCase):
|
|
111 |
class FlavorAPITest(BaseAPITest):
|
145 |
112 |
|
146 |
113 |
def setUp(self):
|
147 |
114 |
self.flavor1 = mfactory.FlavorFactory()
|
... | ... | |
150 |
117 |
|
151 |
118 |
def test_flavor_list(self):
|
152 |
119 |
"""Test if the expected list of flavors is returned by."""
|
153 |
|
|
154 |
|
# with astakos_user('user'):
|
155 |
|
# response = self.client.get('/api/v1.1/flavors')
|
156 |
120 |
response = self.get('/api/v1.1/flavors')
|
|
121 |
self.assertSuccess(response)
|
157 |
122 |
|
158 |
123 |
flavors_from_api = json.loads(response.content)['flavors']['values']
|
159 |
124 |
flavors_from_db = Flavor.objects.filter(deleted=False)
|
160 |
125 |
self.assertEqual(len(flavors_from_api), len(flavors_from_db))
|
161 |
|
self.assertTrue(response.status_code in [200, 203])
|
162 |
126 |
for flavor_from_api in flavors_from_api:
|
163 |
127 |
flavor_from_db = Flavor.objects.get(id=flavor_from_api['id'])
|
164 |
128 |
self.assertEqual(flavor_from_api['id'], flavor_from_db.id)
|
... | ... | |
167 |
131 |
def test_flavors_details(self):
|
168 |
132 |
"""Test if the flavors details are returned."""
|
169 |
133 |
response = self.get('/api/v1.1/flavors/detail')
|
|
134 |
self.assertSuccess(response)
|
170 |
135 |
|
171 |
136 |
flavors_from_db = Flavor.objects.filter(deleted=False)
|
172 |
137 |
flavors_from_api = json.loads(response.content)['flavors']['values']
|
... | ... | |
190 |
155 |
self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
|
191 |
156 |
self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
|
192 |
157 |
|
193 |
|
# Check if we have the right status_code
|
194 |
|
self.assertTrue(response.status_code in [200, 203])
|
195 |
|
|
196 |
158 |
def test_flavor_details(self):
|
197 |
159 |
"""Test if the expected flavor is returned."""
|
198 |
160 |
flavor = self.flavor3
|
199 |
161 |
|
200 |
162 |
response = self.get('/api/v1.1/flavors/%d' % flavor.id)
|
|
163 |
self.assertSuccess(response)
|
201 |
164 |
|
202 |
165 |
flavor_from_api = json.loads(response.content)['flavor']
|
203 |
166 |
flavor_from_db = Flavor.objects.get(id=flavor.id)
|
... | ... | |
206 |
169 |
self.assertEqual(flavor_from_api['disk'], flavor_from_db.disk)
|
207 |
170 |
self.assertEqual(flavor_from_api['name'], flavor_from_db.name)
|
208 |
171 |
self.assertEqual(flavor_from_api['ram'], flavor_from_db.ram)
|
209 |
|
self.assertTrue(response.status_code in [200, 203])
|
210 |
172 |
|
211 |
173 |
def test_deleted_flavor_details(self):
|
212 |
174 |
"""Test that API returns details for deleted flavors"""
|
213 |
175 |
flavor = self.flavor2
|
214 |
176 |
response = self.get('/api/v1.1/flavors/%d' % flavor.id)
|
|
177 |
self.assertSuccess(response)
|
215 |
178 |
flavor_from_api = json.loads(response.content)['flavor']
|
216 |
|
self.assertEqual(response.status_code, 200)
|
217 |
179 |
self.assertEquals(flavor_from_api['name'], flavor.name)
|
218 |
180 |
|
219 |
181 |
def test_deleted_flavors_list(self):
|
220 |
182 |
"""Test that deleted flavors do not appear to flavors list"""
|
221 |
183 |
response = self.get('/api/v1.1/flavors')
|
|
184 |
self.assertSuccess(response)
|
222 |
185 |
flavors_from_api = json.loads(response.content)['flavors']['values']
|
223 |
186 |
self.assertEqual(len(flavors_from_api), 2)
|
224 |
187 |
|
... | ... | |
226 |
189 |
"""Test that deleted flavors do not appear to flavors detail list"""
|
227 |
190 |
mfactory.FlavorFactory(deleted=True)
|
228 |
191 |
response = self.get('/api/v1.1/flavors/detail')
|
|
192 |
self.assertSuccess(response)
|
229 |
193 |
flavors_from_api = json.loads(response.content)['flavors']['values']
|
230 |
194 |
self.assertEqual(len(flavors_from_api), 2)
|
231 |
195 |
|
... | ... | |
233 |
197 |
"""Test 404 result when requesting a flavor that does not exist."""
|
234 |
198 |
|
235 |
199 |
response = self.get('/api/v1.1/flavors/%d' % 22)
|
236 |
|
self.assertTrue(response.status_code in [404])
|
|
200 |
self.assertItemNotFound(response)
|
237 |
201 |
|
238 |
202 |
|
239 |
|
class ServerAPITest(BaseTestCase):
|
|
203 |
class ServerAPITest(BaseAPITest):
|
240 |
204 |
def setUp(self):
|
241 |
205 |
self.user1 = 'user1'
|
242 |
206 |
self.user2 = 'user2'
|
... | ... | |
249 |
213 |
def test_server_list_1(self):
|
250 |
214 |
"""Test if the expected list of servers is returned."""
|
251 |
215 |
response = self.get('/api/v1.1/servers')
|
252 |
|
self.assertTrue(response.status_code in [200, 203])
|
|
216 |
self.assertSuccess(response)
|
253 |
217 |
servers = json.loads(response.content)['servers']['values']
|
254 |
218 |
self.assertEqual(servers, [])
|
255 |
219 |
|
256 |
220 |
def test_server_list_2(self):
|
257 |
221 |
"""Test if the expected list of servers is returned."""
|
258 |
222 |
response = self.get('/api/v1.1/servers', self.user1)
|
259 |
|
self.assertTrue(response.status_code in [200, 203])
|
|
223 |
self.assertSuccess(response)
|
260 |
224 |
servers = json.loads(response.content)['servers']['values']
|
261 |
225 |
db_server = self.vm1
|
262 |
226 |
self.assertEqual(servers, [{'name': db_server.name,
|
... | ... | |
279 |
243 |
self.assertEqual(api_vm['imageRef'], db_vm.imageid)
|
280 |
244 |
self.assertEqual(api_vm['name'], db_vm.name)
|
281 |
245 |
self.assertEqual(api_vm['status'], get_rsapi_state(db_vm))
|
282 |
|
self.assertTrue(response.status_code in [200, 203])
|
|
246 |
self.assertSuccess(response)
|
283 |
247 |
|
284 |
248 |
def test_server_detail(self):
|
285 |
249 |
"""Test if a server details are returned."""
|
... | ... | |
300 |
264 |
metadata = server['metadata']['values']
|
301 |
265 |
self.assertEqual(len(metadata), 1)
|
302 |
266 |
self.assertEqual(metadata[db_vm_meta.meta_key], db_vm_meta.meta_value)
|
303 |
|
self.assertTrue(response.status_code in [200, 203])
|
|
267 |
self.assertSuccess(response)
|
304 |
268 |
|
305 |
269 |
def test_noauthorized(self):
|
306 |
270 |
"""Test 404 for detail of other user vm"""
|
307 |
271 |
db_vm = self.vm2
|
308 |
272 |
|
309 |
273 |
response = self.get('/api/v1.1/servers/%d' % db_vm.id, 'wrong_user')
|
310 |
|
self.assertEqual(response.status_code, 404)
|
|
274 |
self.assertItemNotFound(response)
|
311 |
275 |
|
312 |
276 |
def test_wrong_server(self):
|
313 |
277 |
"""Test 404 response if server does not exist."""
|
314 |
278 |
response = self.get('/api/v1.1/servers/%d' % 5000)
|
315 |
|
self.assertEqual(response.status_code, 404)
|
|
279 |
self.assertItemNotFound(response)
|
316 |
280 |
|
317 |
281 |
def test_create_server_empty(self):
|
318 |
282 |
"""Test if the create server call returns a 400 badRequest if
|
319 |
283 |
no attributes are specified."""
|
320 |
284 |
|
321 |
285 |
response = self.post('/api/v1.1/servers', params={})
|
322 |
|
self.assertEqual(response.status_code, 400)
|
|
286 |
self.assertBadRequest(response)
|
323 |
287 |
|
324 |
288 |
|
325 |
289 |
@patch('synnefo.api.util.get_image')
|
326 |
290 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
|
327 |
|
class ServerCreateAPITest(BaseTestCase):
|
|
291 |
class ServerCreateAPITest(BaseAPITest):
|
328 |
292 |
def test_create_server(self, mrapi, mimage):
|
329 |
293 |
"""Test if the create server call returns the expected response
|
330 |
294 |
if a valid request has been speficied."""
|
... | ... | |
384 |
348 |
|
385 |
349 |
|
386 |
350 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
|
387 |
|
class ServerDestroyAPITest(BaseTestCase):
|
|
351 |
class ServerDestroyAPITest(BaseAPITest):
|
388 |
352 |
def test_delete_server(self, mrapi):
|
389 |
353 |
vm = mfactory.VirtualMachineFactory()
|
390 |
354 |
response = self.delete('/api/v1.1/servers/%d' % vm.id, vm.userid)
|
... | ... | |
400 |
364 |
|
401 |
365 |
@patch('synnefo.api.util.get_image')
|
402 |
366 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
|
403 |
|
class ServerActionAPITest(BaseTestCase):
|
|
367 |
class ServerActionAPITest(BaseAPITest):
|
404 |
368 |
def test_actions(self, mrapi, mimage):
|
405 |
369 |
actions = ['start', 'shutdown', 'reboot']
|
406 |
370 |
vm = mfactory.VirtualMachineFactory()
|
... | ... | |
430 |
394 |
mrapi().ModifyInstance.assert_called_once()
|
431 |
395 |
|
432 |
396 |
|
433 |
|
class ServerMetadataAPITest(BaseTestCase):
|
|
397 |
class ServerMetadataAPITest(BaseAPITest):
|
434 |
398 |
def setUp(self):
|
435 |
399 |
self.vm = mfactory.VirtualMachineFactory()
|
436 |
400 |
self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm)
|
... | ... | |
501 |
465 |
|
502 |
466 |
|
503 |
467 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient')
|
504 |
|
class NetworkAPITest(BaseTestCase):
|
|
468 |
class NetworkAPITest(BaseAPITest):
|
505 |
469 |
def setUp(self):
|
506 |
470 |
self.mac_prefixes = mfactory.MacPrefixPoolTableFactory()
|
507 |
471 |
self.bridges = mfactory.BridgePoolTableFactory()
|
... | ... | |
674 |
638 |
self.assertBadRequest(response)
|
675 |
639 |
|
676 |
640 |
|
677 |
|
class ServerVNCConsole(BaseTestCase):
|
|
641 |
class ServerVNCConsole(BaseAPITest):
|
678 |
642 |
|
679 |
643 |
def test_not_active_server(self):
|
680 |
644 |
"""Test console req for not ACTIVE server returns badRequest"""
|
... | ... | |
702 |
666 |
set(['type', 'host', 'port', 'password']))
|
703 |
667 |
|
704 |
668 |
|
|
669 |
def assert_backend_closed(func):
|
|
670 |
@wraps(func)
|
|
671 |
def wrapper(self, backend):
|
|
672 |
result = func(self, backend)
|
|
673 |
if backend.called is True:
|
|
674 |
backend.return_value.close.assert_called_once_with()
|
|
675 |
return result
|
|
676 |
return wrapper
|
|
677 |
|
|
678 |
|
705 |
679 |
@patch('synnefo.api.images.ImageBackend')
|
706 |
|
class ImageAPITest(BaseTestCase):
|
|
680 |
class ImageAPITest(BaseAPITest):
|
|
681 |
@assert_backend_closed
|
707 |
682 |
def test_create_image(self, mimage):
|
708 |
683 |
"""Test that create image is not implemented"""
|
709 |
684 |
response = self.post('/api/v1.1/images/', 'user', json.dumps(''),
|
710 |
685 |
'json')
|
711 |
686 |
self.assertEqual(response.status_code, 503)
|
712 |
687 |
|
|
688 |
@assert_backend_closed
|
713 |
689 |
def test_list_images(self, mimage):
|
714 |
690 |
"""Test that expected list of images is returned"""
|
715 |
691 |
images = [{'id': 1, 'name': 'image-1'},
|
... | ... | |
721 |
697 |
api_images = json.loads(response.content)['images']['values']
|
722 |
698 |
self.assertEqual(images, api_images)
|
723 |
699 |
|
|
700 |
@assert_backend_closed
|
724 |
701 |
def test_list_images_detail(self, mimage):
|
725 |
702 |
images = [{'id': 1,
|
726 |
703 |
'name': 'image-1',
|
... | ... | |
770 |
747 |
self.assertEqual(len(result_images), len(api_images))
|
771 |
748 |
self.assertEqual(result_images, api_images)
|
772 |
749 |
|
|
750 |
@assert_backend_closed
|
773 |
751 |
def test_get_image_details(self, mimage):
|
774 |
752 |
image = {'id': 42,
|
775 |
753 |
'name': 'image-1',
|
... | ... | |
793 |
771 |
api_image = json.loads(response.content)['image']
|
794 |
772 |
self.assertEqual(api_image, result_image)
|
795 |
773 |
|
|
774 |
@assert_backend_closed
|
796 |
775 |
def test_invalid_image(self, mimage):
|
797 |
776 |
with patch('synnefo.api.util.get_image') as m:
|
798 |
777 |
m.side_effect = faults.ItemNotFound('Image not found')
|
... | ... | |
804 |
783 |
pass
|
805 |
784 |
|
806 |
785 |
|
807 |
|
class ImageMetadataAPITest(BaseTestCase):
|
|
786 |
@patch('synnefo.api.util.ImageBackend')
|
|
787 |
class ImageMetadataAPITest(BaseAPITest):
|
808 |
788 |
def setUp(self):
|
809 |
789 |
self.image = {'id': 42,
|
810 |
790 |
'name': 'image-1',
|
... | ... | |
821 |
801 |
'created': '2012-11-26T11:52:54+00:00',
|
822 |
802 |
'updated': '2012-12-26T11:52:54+00:00',
|
823 |
803 |
'metadata': {'values': {'foo': 'bar'}}}
|
824 |
|
self.mock_get_image = Mock('synnefo.api.util.get_image')
|
825 |
|
self.mock_get_image.result = self.image
|
826 |
|
self.mock_image_backend = Mock('synnefo.api.images.ImageBackend')
|
827 |
804 |
|
828 |
|
def test_list_metadata(self):
|
829 |
|
with patch('synnefo.api.util.get_image') as m:
|
830 |
|
m.return_value = self.image
|
831 |
|
response = self.get('/api/v1.1/images/42/meta', 'user')
|
|
805 |
@assert_backend_closed
|
|
806 |
def test_list_metadata(self, backend):
|
|
807 |
backend.return_value.get_image.return_value = self.image
|
|
808 |
response = self.get('/api/v1.1/images/42/meta', 'user')
|
832 |
809 |
self.assertSuccess(response)
|
833 |
810 |
meta = json.loads(response.content)['metadata']['values']
|
834 |
811 |
self.assertEqual(meta, self.image['properties'])
|
835 |
812 |
|
836 |
|
def test_get_metadata(self):
|
837 |
|
with patch('synnefo.api.util.get_image') as m:
|
838 |
|
m.return_value = self.image
|
839 |
|
response = self.get('/api/v1.1/images/42/meta/foo', 'user')
|
|
813 |
@assert_backend_closed
|
|
814 |
def test_get_metadata(self, backend):
|
|
815 |
backend.return_value.get_image.return_value = self.image
|
|
816 |
response = self.get('/api/v1.1/images/42/meta/foo', 'user')
|
840 |
817 |
self.assertSuccess(response)
|
841 |
818 |
meta = json.loads(response.content)['meta']
|
842 |
819 |
self.assertEqual(meta['foo'], 'bar')
|
843 |
820 |
|
844 |
|
def test_get_invalid_metadata(self):
|
845 |
|
with patch('synnefo.api.util.get_image') as m:
|
846 |
|
m.return_value = self.image
|
847 |
|
response = self.get('/api/v1.1/images/42/meta/not_found', 'user')
|
|
821 |
@assert_backend_closed
|
|
822 |
def test_get_invalid_metadata(self, backend):
|
|
823 |
backend.return_value.get_image.return_value = self.image
|
|
824 |
response = self.get('/api/v1.1/images/42/meta/not_found', 'user')
|
848 |
825 |
self.assertItemNotFound(response)
|
849 |
826 |
|
850 |
|
def test_delete_metadata_item(self):
|
851 |
|
with patch('synnefo.api.util.get_image') as m:
|
852 |
|
with patch('synnefo.api.images.ImageBackend') as mimage:
|
853 |
|
m.return_value = self.image
|
854 |
|
response = self.delete('/api/v1.1/images/42/meta/foo', 'user')
|
855 |
|
self.assertEqual(response.status_code, 204)
|
856 |
|
mimage().update.assert_called_once_with('42',
|
857 |
|
{'properties': {'foo2': 'bar2'}})
|
858 |
|
|
859 |
|
def test_create_metadata_item(self):
|
860 |
|
with patch('synnefo.api.util.get_image') as m:
|
861 |
|
with patch('synnefo.api.images.ImageBackend') as mimage:
|
862 |
|
m.return_value = self.image
|
|
827 |
@assert_backend_closed
|
|
828 |
def test_delete_metadata_item(self, backend):
|
|
829 |
backend.return_value.get_image.return_value = self.image
|
|
830 |
with patch("synnefo.api.images.ImageBackend") as m:
|
|
831 |
response = self.delete('/api/v1.1/images/42/meta/foo', 'user')
|
|
832 |
self.assertEqual(response.status_code, 204)
|
|
833 |
m.return_value.update.assert_called_once_with('42',
|
|
834 |
{'properties': {'foo2': 'bar2'}})
|
|
835 |
|
|
836 |
@assert_backend_closed
|
|
837 |
def test_create_metadata_item(self, backend):
|
|
838 |
backend.return_value.get_image.return_value = self.image
|
|
839 |
with patch("synnefo.api.images.ImageBackend") as m:
|
863 |
840 |
request = {'meta': {'foo3': 'bar3'}}
|
864 |
841 |
response = self.put('/api/v1.1/images/42/meta/foo3', 'user',
|
865 |
842 |
json.dumps(request), 'json')
|
866 |
843 |
self.assertEqual(response.status_code, 201)
|
867 |
|
mimage().update.assert_called_once_with('42',
|
|
844 |
m.return_value.update.assert_called_once_with('42',
|
868 |
845 |
{'properties':
|
869 |
846 |
{'foo': 'bar', 'foo2': 'bar2', 'foo3': 'bar3'}})
|
870 |
847 |
|
871 |
|
def test_update_metadata_item(self):
|
872 |
|
with patch('synnefo.api.util.get_image') as m:
|
873 |
|
with patch('synnefo.api.images.ImageBackend') as mimage:
|
874 |
|
m.return_value = self.image
|
|
848 |
@assert_backend_closed
|
|
849 |
def test_update_metadata_item(self, backend):
|
|
850 |
backend.return_value.get_image.return_value = self.image
|
|
851 |
with patch("synnefo.api.images.ImageBackend") as m:
|
875 |
852 |
request = {'metadata': {'foo': 'bar_new', 'foo4': 'bar4'}}
|
876 |
853 |
response = self.post('/api/v1.1/images/42/meta', 'user',
|
877 |
854 |
json.dumps(request), 'json')
|
878 |
855 |
self.assertEqual(response.status_code, 201)
|
879 |
|
mimage().update.assert_called_once_with('42', {'properties':
|
880 |
|
{'foo': 'bar_new', 'foo2': 'bar2', 'foo4': 'bar4'}})
|
|
856 |
m.return_value.update.assert_called_once_with('42',
|
|
857 |
{'properties':
|
|
858 |
{'foo': 'bar_new', 'foo2': 'bar2', 'foo4': 'bar4'}
|
|
859 |
})
|
|
860 |
|
|
861 |
|
|
862 |
class APITest(TestCase):
|
|
863 |
def test_api_version(self):
|
|
864 |
"""Check API version."""
|
|
865 |
with astakos_user('user'):
|
|
866 |
response = self.client.get('/api/v1.1/')
|
|
867 |
self.assertEqual(response.status_code, 200)
|
|
868 |
api_version = json.loads(response.content)['version']
|
|
869 |
self.assertEqual(api_version['id'], 'v1.1')
|
|
870 |
self.assertEqual(api_version['status'], 'CURRENT')
|