root / snf-cyclades-app / synnefo / api / tests / images.py @ ba777b02
History | View | Annotate | Download (15.7 kB)
1 | 039e3e61 | Christos Stavrakakis | # Copyright 2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 039e3e61 | Christos Stavrakakis | #
|
3 | 039e3e61 | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or
|
4 | 039e3e61 | Christos Stavrakakis | # without modification, are permitted provided that the following
|
5 | 039e3e61 | Christos Stavrakakis | # conditions are met:
|
6 | 039e3e61 | Christos Stavrakakis | #
|
7 | 039e3e61 | Christos Stavrakakis | # 1. Redistributions of source code must retain the above
|
8 | 039e3e61 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
9 | 039e3e61 | Christos Stavrakakis | # disclaimer.
|
10 | 039e3e61 | Christos Stavrakakis | #
|
11 | 039e3e61 | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above
|
12 | 039e3e61 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
13 | 039e3e61 | Christos Stavrakakis | # disclaimer in the documentation and/or other materials
|
14 | 039e3e61 | Christos Stavrakakis | # provided with the distribution.
|
15 | 039e3e61 | Christos Stavrakakis | #
|
16 | 039e3e61 | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 039e3e61 | Christos Stavrakakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 039e3e61 | Christos Stavrakakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 039e3e61 | Christos Stavrakakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 039e3e61 | Christos Stavrakakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 039e3e61 | Christos Stavrakakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 039e3e61 | Christos Stavrakakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 039e3e61 | Christos Stavrakakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 039e3e61 | Christos Stavrakakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 039e3e61 | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 039e3e61 | Christos Stavrakakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 039e3e61 | Christos Stavrakakis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 039e3e61 | Christos Stavrakakis | #
|
29 | 039e3e61 | Christos Stavrakakis | # The views and conclusions contained in the software and
|
30 | 039e3e61 | Christos Stavrakakis | # documentation are those of the authors and should not be
|
31 | 039e3e61 | Christos Stavrakakis | # interpreted as representing official policies, either expressed
|
32 | 039e3e61 | Christos Stavrakakis | # or implied, of GRNET S.A.
|
33 | 039e3e61 | Christos Stavrakakis | |
34 | 039e3e61 | Christos Stavrakakis | import json |
35 | 039e3e61 | Christos Stavrakakis | |
36 | bd40abfa | Christos Stavrakakis | from snf_django.lib.api import faults |
37 | d2b8ec7b | Christos Stavrakakis | from snf_django.utils.testing import BaseAPITest |
38 | dc99330c | Georgios D. Tsoukalas | from synnefo.lib.services import get_service_path |
39 | dc99330c | Georgios D. Tsoukalas | from synnefo.cyclades_settings import cyclades_services |
40 | dc99330c | Georgios D. Tsoukalas | from synnefo.lib import join_urls |
41 | 039e3e61 | Christos Stavrakakis | |
42 | 039e3e61 | Christos Stavrakakis | from mock import patch |
43 | 039e3e61 | Christos Stavrakakis | from functools import wraps |
44 | 039e3e61 | Christos Stavrakakis | |
45 | 039e3e61 | Christos Stavrakakis | |
46 | 039e3e61 | Christos Stavrakakis | def assert_backend_closed(func): |
47 | 039e3e61 | Christos Stavrakakis | """Decorator for ensuring that ImageBackend is returned to pool."""
|
48 | 039e3e61 | Christos Stavrakakis | @wraps(func)
|
49 | 039e3e61 | Christos Stavrakakis | def wrapper(self, backend): |
50 | 039e3e61 | Christos Stavrakakis | result = func(self, backend)
|
51 | 039e3e61 | Christos Stavrakakis | if backend.called is True: |
52 | 184a2a8c | Christos Stavrakakis | backend.return_value.close.asssert_called |
53 | 039e3e61 | Christos Stavrakakis | return result
|
54 | 039e3e61 | Christos Stavrakakis | return wrapper
|
55 | 039e3e61 | Christos Stavrakakis | |
56 | 039e3e61 | Christos Stavrakakis | |
57 | dc99330c | Georgios D. Tsoukalas | class ComputeAPITest(BaseAPITest): |
58 | dc99330c | Georgios D. Tsoukalas | def setUp(self, *args, **kwargs): |
59 | dc99330c | Georgios D. Tsoukalas | super(ComputeAPITest, self).setUp(*args, **kwargs) |
60 | dc99330c | Georgios D. Tsoukalas | self.compute_path = get_service_path(cyclades_services, 'compute', |
61 | dc99330c | Georgios D. Tsoukalas | version='v2.0')
|
62 | dc99330c | Georgios D. Tsoukalas | def myget(self, path, *args, **kwargs): |
63 | dc99330c | Georgios D. Tsoukalas | path = join_urls(self.compute_path, path)
|
64 | dc99330c | Georgios D. Tsoukalas | return self.get(path, *args, **kwargs) |
65 | dc99330c | Georgios D. Tsoukalas | |
66 | dc99330c | Georgios D. Tsoukalas | def myput(self, path, *args, **kwargs): |
67 | dc99330c | Georgios D. Tsoukalas | path = join_urls(self.compute_path, path)
|
68 | dc99330c | Georgios D. Tsoukalas | return self.put(path, *args, **kwargs) |
69 | dc99330c | Georgios D. Tsoukalas | |
70 | dc99330c | Georgios D. Tsoukalas | def mypost(self, path, *args, **kwargs): |
71 | dc99330c | Georgios D. Tsoukalas | path = join_urls(self.compute_path, path)
|
72 | dc99330c | Georgios D. Tsoukalas | return self.post(path, *args, **kwargs) |
73 | dc99330c | Georgios D. Tsoukalas | |
74 | dc99330c | Georgios D. Tsoukalas | def mydelete(self, path, *args, **kwargs): |
75 | dc99330c | Georgios D. Tsoukalas | path = join_urls(self.compute_path, path)
|
76 | dc99330c | Georgios D. Tsoukalas | return self.delete(path, *args, **kwargs) |
77 | dc99330c | Georgios D. Tsoukalas | |
78 | dc99330c | Georgios D. Tsoukalas | |
79 | cda71050 | Christos Stavrakakis | @patch('synnefo.plankton.backend.ImageBackend') |
80 | dc99330c | Georgios D. Tsoukalas | class ImageAPITest(ComputeAPITest): |
81 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
82 | 039e3e61 | Christos Stavrakakis | def test_create_image(self, mimage): |
83 | 039e3e61 | Christos Stavrakakis | """Test that create image is not implemented"""
|
84 | dc99330c | Georgios D. Tsoukalas | response = self.mypost('images/', 'user', json.dumps(''), 'json') |
85 | bd40abfa | Christos Stavrakakis | self.assertEqual(response.status_code, 501) |
86 | 039e3e61 | Christos Stavrakakis | |
87 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
88 | 039e3e61 | Christos Stavrakakis | def test_list_images(self, mimage): |
89 | 039e3e61 | Christos Stavrakakis | """Test that expected list of images is returned"""
|
90 | 039e3e61 | Christos Stavrakakis | images = [{'id': 1, 'name': 'image-1'}, |
91 | 039e3e61 | Christos Stavrakakis | {'id': 2, 'name': 'image-2'}, |
92 | 039e3e61 | Christos Stavrakakis | {'id': 3, 'name': 'image-3'}] |
93 | 14c94c48 | Christos Stavrakakis | mimage().list_images.return_value = images |
94 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images', 'user') |
95 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
96 | 2d04422f | Christos Stavrakakis | api_images = json.loads(response.content)['images']
|
97 | 039e3e61 | Christos Stavrakakis | self.assertEqual(images, api_images)
|
98 | 039e3e61 | Christos Stavrakakis | |
99 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
100 | 039e3e61 | Christos Stavrakakis | def test_list_images_detail(self, mimage): |
101 | 039e3e61 | Christos Stavrakakis | images = [{'id': 1, |
102 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
103 | 039e3e61 | Christos Stavrakakis | 'status':'available', |
104 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
105 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
106 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
107 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
108 | 039e3e61 | Christos Stavrakakis | 'properties': {'foo':'bar'}}, |
109 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
110 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
111 | 039e3e61 | Christos Stavrakakis | 'status': 'deleted', |
112 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
113 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
114 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
115 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '2012-12-27 11:52:54', |
116 | 039e3e61 | Christos Stavrakakis | 'properties': ''}, |
117 | 039e3e61 | Christos Stavrakakis | {'id': 3, |
118 | 039e3e61 | Christos Stavrakakis | 'name': 'image-3', |
119 | 039e3e61 | Christos Stavrakakis | 'status': 'available', |
120 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
121 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
122 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
123 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
124 | 039e3e61 | Christos Stavrakakis | 'properties': ''}] |
125 | 039e3e61 | Christos Stavrakakis | result_images = [ |
126 | 039e3e61 | Christos Stavrakakis | {'id': 1, |
127 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
128 | 039e3e61 | Christos Stavrakakis | 'status':'ACTIVE', |
129 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
130 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
131 | 039e3e61 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
132 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
133 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
134 | 2d04422f | Christos Stavrakakis | 'metadata': {'foo':'bar'}}, |
135 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
136 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
137 | 039e3e61 | Christos Stavrakakis | 'status': 'DELETED', |
138 | 039e3e61 | Christos Stavrakakis | 'progress': 0, |
139 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
140 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
141 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
142 | 936e0be3 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
143 | 936e0be3 | Christos Stavrakakis | 'metadata': {}},
|
144 | 039e3e61 | Christos Stavrakakis | {'id': 3, |
145 | 039e3e61 | Christos Stavrakakis | 'name': 'image-3', |
146 | 039e3e61 | Christos Stavrakakis | 'status': 'ACTIVE', |
147 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
148 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
149 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
150 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
151 | 936e0be3 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
152 | 936e0be3 | Christos Stavrakakis | 'metadata': {}}]
|
153 | 14c94c48 | Christos Stavrakakis | mimage().list_images.return_value = images |
154 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/detail', 'user') |
155 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
156 | 2d04422f | Christos Stavrakakis | api_images = json.loads(response.content)['images']
|
157 | 039e3e61 | Christos Stavrakakis | self.assertEqual(len(result_images), len(api_images)) |
158 | c25cf3ea | Christos Stavrakakis | map(lambda image: image.pop("links"), api_images) |
159 | 039e3e61 | Christos Stavrakakis | self.assertEqual(result_images, api_images)
|
160 | 039e3e61 | Christos Stavrakakis | |
161 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
162 | 039e3e61 | Christos Stavrakakis | def test_list_images_detail_since(self, mimage): |
163 | 039e3e61 | Christos Stavrakakis | from datetime import datetime, timedelta |
164 | 039e3e61 | Christos Stavrakakis | from time import sleep |
165 | 039e3e61 | Christos Stavrakakis | old_time = datetime.now() |
166 | 039e3e61 | Christos Stavrakakis | new_time = old_time + timedelta(seconds=0.1)
|
167 | 039e3e61 | Christos Stavrakakis | sleep(0.1)
|
168 | 039e3e61 | Christos Stavrakakis | images = [ |
169 | 039e3e61 | Christos Stavrakakis | {'id': 1, |
170 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
171 | 039e3e61 | Christos Stavrakakis | 'status':'available', |
172 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
173 | 039e3e61 | Christos Stavrakakis | 'created_at': old_time.isoformat(),
|
174 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
175 | 039e3e61 | Christos Stavrakakis | 'updated_at': old_time.isoformat(),
|
176 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
177 | 039e3e61 | Christos Stavrakakis | 'properties': ''}, |
178 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
179 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
180 | 039e3e61 | Christos Stavrakakis | 'status': 'deleted', |
181 | 039e3e61 | Christos Stavrakakis | 'progress': 0, |
182 | 936e0be3 | Christos Stavrakakis | 'owner': 'user2', |
183 | 039e3e61 | Christos Stavrakakis | 'created_at': new_time.isoformat(),
|
184 | 039e3e61 | Christos Stavrakakis | 'updated_at': new_time.isoformat(),
|
185 | 039e3e61 | Christos Stavrakakis | 'deleted_at': new_time.isoformat(),
|
186 | 039e3e61 | Christos Stavrakakis | 'properties': ''}] |
187 | 14c94c48 | Christos Stavrakakis | mimage().list_images.return_value = images |
188 | 039e3e61 | Christos Stavrakakis | response =\ |
189 | dc99330c | Georgios D. Tsoukalas | self.myget('images/detail?changes-since=%sUTC' % new_time) |
190 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
191 | 2d04422f | Christos Stavrakakis | api_images = json.loads(response.content)['images']
|
192 | 039e3e61 | Christos Stavrakakis | self.assertEqual(1, len(api_images)) |
193 | 039e3e61 | Christos Stavrakakis | |
194 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
195 | 039e3e61 | Christos Stavrakakis | def test_get_image_details(self, mimage): |
196 | 039e3e61 | Christos Stavrakakis | image = {'id': 42, |
197 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
198 | 039e3e61 | Christos Stavrakakis | 'status': 'available', |
199 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
200 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
201 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
202 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
203 | 039e3e61 | Christos Stavrakakis | 'properties': {'foo': 'bar'}} |
204 | 039e3e61 | Christos Stavrakakis | result_image = \ |
205 | 039e3e61 | Christos Stavrakakis | {'id': 42, |
206 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
207 | 039e3e61 | Christos Stavrakakis | 'status': 'ACTIVE', |
208 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
209 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
210 | 039e3e61 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
211 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
212 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
213 | 2d04422f | Christos Stavrakakis | 'metadata': {'foo': 'bar'}} |
214 | cda71050 | Christos Stavrakakis | mimage.return_value.get_image.return_value = image |
215 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42', 'user') |
216 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
217 | 039e3e61 | Christos Stavrakakis | api_image = json.loads(response.content)['image']
|
218 | c25cf3ea | Christos Stavrakakis | api_image.pop("links")
|
219 | 039e3e61 | Christos Stavrakakis | self.assertEqual(api_image, result_image)
|
220 | 039e3e61 | Christos Stavrakakis | |
221 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
222 | 039e3e61 | Christos Stavrakakis | def test_invalid_image(self, mimage): |
223 | cda71050 | Christos Stavrakakis | mimage.return_value.get_image.side_effect = faults.ItemNotFound('Image not found')
|
224 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42', 'user') |
225 | 039e3e61 | Christos Stavrakakis | self.assertItemNotFound(response)
|
226 | 039e3e61 | Christos Stavrakakis | |
227 | cda71050 | Christos Stavrakakis | @assert_backend_closed
|
228 | 039e3e61 | Christos Stavrakakis | def test_delete_image(self, mimage): |
229 | dc99330c | Georgios D. Tsoukalas | response = self.mydelete("images/42", "user") |
230 | 039e3e61 | Christos Stavrakakis | self.assertEqual(response.status_code, 204) |
231 | f13aab5d | Christos Stavrakakis | mimage.return_value.unregister.assert_called_once_with('42')
|
232 | f13aab5d | Christos Stavrakakis | mimage.return_value._delete.assert_not_called('42')
|
233 | 039e3e61 | Christos Stavrakakis | |
234 | a3accf03 | Georgios D. Tsoukalas | @assert_backend_closed
|
235 | a3accf03 | Georgios D. Tsoukalas | def test_catch_wrong_api_paths(self, *args): |
236 | a3accf03 | Georgios D. Tsoukalas | response = self.myget('nonexistent') |
237 | a3accf03 | Georgios D. Tsoukalas | self.assertEqual(response.status_code, 400) |
238 | a3accf03 | Georgios D. Tsoukalas | try:
|
239 | a3accf03 | Georgios D. Tsoukalas | error = json.loads(response.content) |
240 | a3accf03 | Georgios D. Tsoukalas | except ValueError: |
241 | a3accf03 | Georgios D. Tsoukalas | self.assertTrue(False) |
242 | a3accf03 | Georgios D. Tsoukalas | |
243 | 16437e4d | Kostas Papadimitriou | @assert_backend_closed
|
244 | 16437e4d | Kostas Papadimitriou | def test_method_not_allowed(self, *args): |
245 | 16437e4d | Kostas Papadimitriou | # /images/ allows only POST, GET
|
246 | 16437e4d | Kostas Papadimitriou | response = self.myput('images', '', '') |
247 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
248 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images') |
249 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
250 | 16437e4d | Kostas Papadimitriou | |
251 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/ allows only GET, DELETE
|
252 | 16437e4d | Kostas Papadimitriou | response = self.mypost("images/42") |
253 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
254 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42', '', '') |
255 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
256 | 16437e4d | Kostas Papadimitriou | |
257 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/ allows only POST, GET
|
258 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42/metadata', '', '') |
259 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
260 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images/42/metadata') |
261 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
262 | 16437e4d | Kostas Papadimitriou | |
263 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/ allows only POST, GET
|
264 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42/metadata', '', '') |
265 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
266 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images/42/metadata') |
267 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
268 | 16437e4d | Kostas Papadimitriou | |
269 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/<key> allows only PUT, GET, DELETE
|
270 | 16437e4d | Kostas Papadimitriou | response = self.mypost('images/42/metadata/foo') |
271 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
272 | 16437e4d | Kostas Papadimitriou | |
273 | 039e3e61 | Christos Stavrakakis | |
274 | cda71050 | Christos Stavrakakis | @patch('synnefo.plankton.backend.ImageBackend') |
275 | dc99330c | Georgios D. Tsoukalas | class ImageMetadataAPITest(ComputeAPITest): |
276 | 039e3e61 | Christos Stavrakakis | def setUp(self): |
277 | 039e3e61 | Christos Stavrakakis | self.image = {'id': 42, |
278 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
279 | 039e3e61 | Christos Stavrakakis | 'status': 'available', |
280 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
281 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
282 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
283 | 039e3e61 | Christos Stavrakakis | 'properties': {'foo': 'bar', 'foo2': 'bar2'}} |
284 | 039e3e61 | Christos Stavrakakis | self.result_image = \
|
285 | 039e3e61 | Christos Stavrakakis | {'id': 42, |
286 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
287 | 039e3e61 | Christos Stavrakakis | 'status': 'ACTIVE', |
288 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
289 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
290 | 039e3e61 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
291 | 2d04422f | Christos Stavrakakis | 'metadata': {'foo': 'bar'}} |
292 | dc99330c | Georgios D. Tsoukalas | super(ImageMetadataAPITest, self).setUp() |
293 | 039e3e61 | Christos Stavrakakis | |
294 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
295 | 039e3e61 | Christos Stavrakakis | def test_list_metadata(self, backend): |
296 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
297 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata', 'user') |
298 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
299 | 2d04422f | Christos Stavrakakis | meta = json.loads(response.content)['metadata']
|
300 | 039e3e61 | Christos Stavrakakis | self.assertEqual(meta, self.image['properties']) |
301 | 039e3e61 | Christos Stavrakakis | |
302 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
303 | 039e3e61 | Christos Stavrakakis | def test_get_metadata(self, backend): |
304 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
305 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata/foo', 'user') |
306 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
307 | 039e3e61 | Christos Stavrakakis | meta = json.loads(response.content)['meta']
|
308 | 039e3e61 | Christos Stavrakakis | self.assertEqual(meta['foo'], 'bar') |
309 | 039e3e61 | Christos Stavrakakis | |
310 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
311 | 039e3e61 | Christos Stavrakakis | def test_get_invalid_metadata(self, backend): |
312 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
313 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata/not_found', 'user') |
314 | 039e3e61 | Christos Stavrakakis | self.assertItemNotFound(response)
|
315 | 039e3e61 | Christos Stavrakakis | |
316 | 039e3e61 | Christos Stavrakakis | def test_delete_metadata_item(self, backend): |
317 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
318 | dc99330c | Georgios D. Tsoukalas | response = self.mydelete('images/42/metadata/foo', 'user') |
319 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 204) |
320 | 14c94c48 | Christos Stavrakakis | backend.return_value.update_metadata.assert_called_once_with('42', {'properties': {'foo2': |
321 | b3fd98ae | Christos Stavrakakis | 'bar2'}})
|
322 | 039e3e61 | Christos Stavrakakis | |
323 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
324 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_item(self, backend): |
325 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
326 | b3fd98ae | Christos Stavrakakis | request = {'meta': {'foo3': 'bar3'}} |
327 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
328 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
329 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 201) |
330 | 14c94c48 | Christos Stavrakakis | backend.return_value.update_metadata.assert_called_once_with('42',
|
331 | b3fd98ae | Christos Stavrakakis | {'properties':
|
332 | b3fd98ae | Christos Stavrakakis | {'foo': 'bar', 'foo2': 'bar2', 'foo3': 'bar3'}}) |
333 | 039e3e61 | Christos Stavrakakis | |
334 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
335 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_1(self, backend): |
336 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
337 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3'}} |
338 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
339 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
340 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
341 | 039e3e61 | Christos Stavrakakis | |
342 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
343 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_2(self, backend): |
344 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
345 | 2d04422f | Christos Stavrakakis | request = {'metadata': [('foo3', 'bar3')]} |
346 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
347 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
348 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
349 | 039e3e61 | Christos Stavrakakis | |
350 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
351 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_3(self, backend): |
352 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
353 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3', 'foo4': 'bar4'}} |
354 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
355 | b3fd98ae | Christos Stavrakakis | json.dumps(request), 'json')
|
356 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
357 | 039e3e61 | Christos Stavrakakis | |
358 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
359 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_4(self, backend): |
360 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
361 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3'}} |
362 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo4', 'user', |
363 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
364 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
365 | 039e3e61 | Christos Stavrakakis | |
366 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
367 | 039e3e61 | Christos Stavrakakis | def test_update_metadata_item(self, backend): |
368 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
369 | b3fd98ae | Christos Stavrakakis | request = {'metadata': {'foo': 'bar_new', 'foo4': 'bar4'}} |
370 | dc99330c | Georgios D. Tsoukalas | response = self.mypost('images/42/metadata', 'user', |
371 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
372 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 201) |
373 | 14c94c48 | Christos Stavrakakis | backend.return_value.update_metadata.assert_called_once_with('42',
|
374 | b3fd98ae | Christos Stavrakakis | {'properties':
|
375 | b3fd98ae | Christos Stavrakakis | {'foo': 'bar_new', 'foo2': 'bar2', 'foo4': 'bar4'} |
376 | b3fd98ae | Christos Stavrakakis | }) |
377 | 039e3e61 | Christos Stavrakakis | |
378 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
379 | 039e3e61 | Christos Stavrakakis | def test_update_metadata_malformed(self, backend): |
380 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
381 | b3fd98ae | Christos Stavrakakis | request = {'meta': {'foo': 'bar_new', 'foo4': 'bar4'}} |
382 | dc99330c | Georgios D. Tsoukalas | response = self.mypost('images/42/metadata', 'user', |
383 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
384 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response) |