root / snf-cyclades-app / synnefo / api / tests / images.py @ d984eedc
History | View | Annotate | Download (16.5 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 | 3768eb67 | Christos Stavrakakis | self.maxDiff = None |
102 | 039e3e61 | Christos Stavrakakis | images = [{'id': 1, |
103 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
104 | d984eedc | Christos Stavrakakis | 'status': 'available', |
105 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
106 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
107 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
108 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
109 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
110 | d984eedc | Christos Stavrakakis | 'is_public': True, |
111 | d984eedc | Christos Stavrakakis | 'properties': {'foo': 'bar'}}, |
112 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
113 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
114 | 039e3e61 | Christos Stavrakakis | 'status': 'deleted', |
115 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
116 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
117 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
118 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '2012-12-27 11:52:54', |
119 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
120 | d984eedc | Christos Stavrakakis | 'is_public': True, |
121 | 039e3e61 | Christos Stavrakakis | 'properties': ''}, |
122 | 039e3e61 | Christos Stavrakakis | {'id': 3, |
123 | 039e3e61 | Christos Stavrakakis | 'name': 'image-3', |
124 | 039e3e61 | Christos Stavrakakis | 'status': 'available', |
125 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
126 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
127 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
128 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
129 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
130 | d984eedc | Christos Stavrakakis | 'is_public': False, |
131 | 039e3e61 | Christos Stavrakakis | 'properties': ''}] |
132 | 039e3e61 | Christos Stavrakakis | result_images = [ |
133 | 039e3e61 | Christos Stavrakakis | {'id': 1, |
134 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
135 | d984eedc | Christos Stavrakakis | 'status': 'ACTIVE', |
136 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
137 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
138 | 039e3e61 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
139 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
140 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
141 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
142 | d984eedc | Christos Stavrakakis | 'public': True, |
143 | d984eedc | Christos Stavrakakis | 'metadata': {'foo': 'bar'}}, |
144 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
145 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
146 | 039e3e61 | Christos Stavrakakis | 'status': 'DELETED', |
147 | 039e3e61 | Christos Stavrakakis | 'progress': 0, |
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 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
153 | d984eedc | Christos Stavrakakis | 'public': True, |
154 | 936e0be3 | Christos Stavrakakis | 'metadata': {}},
|
155 | 039e3e61 | Christos Stavrakakis | {'id': 3, |
156 | 039e3e61 | Christos Stavrakakis | 'name': 'image-3', |
157 | 039e3e61 | Christos Stavrakakis | 'status': 'ACTIVE', |
158 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
159 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
160 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
161 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
162 | 936e0be3 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
163 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
164 | d984eedc | Christos Stavrakakis | 'public': False, |
165 | 936e0be3 | Christos Stavrakakis | 'metadata': {}}]
|
166 | 14c94c48 | Christos Stavrakakis | mimage().list_images.return_value = images |
167 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/detail', 'user') |
168 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
169 | 2d04422f | Christos Stavrakakis | api_images = json.loads(response.content)['images']
|
170 | 039e3e61 | Christos Stavrakakis | self.assertEqual(len(result_images), len(api_images)) |
171 | c25cf3ea | Christos Stavrakakis | map(lambda image: image.pop("links"), api_images) |
172 | 039e3e61 | Christos Stavrakakis | self.assertEqual(result_images, api_images)
|
173 | 039e3e61 | Christos Stavrakakis | |
174 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
175 | 039e3e61 | Christos Stavrakakis | def test_list_images_detail_since(self, mimage): |
176 | 039e3e61 | Christos Stavrakakis | from datetime import datetime, timedelta |
177 | 039e3e61 | Christos Stavrakakis | from time import sleep |
178 | 039e3e61 | Christos Stavrakakis | old_time = datetime.now() |
179 | 039e3e61 | Christos Stavrakakis | new_time = old_time + timedelta(seconds=0.1)
|
180 | 039e3e61 | Christos Stavrakakis | sleep(0.1)
|
181 | 039e3e61 | Christos Stavrakakis | images = [ |
182 | 039e3e61 | Christos Stavrakakis | {'id': 1, |
183 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
184 | d984eedc | Christos Stavrakakis | 'status': 'available', |
185 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
186 | 039e3e61 | Christos Stavrakakis | 'created_at': old_time.isoformat(),
|
187 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
188 | 039e3e61 | Christos Stavrakakis | 'updated_at': old_time.isoformat(),
|
189 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
190 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
191 | d984eedc | Christos Stavrakakis | 'is_public': True, |
192 | 039e3e61 | Christos Stavrakakis | 'properties': ''}, |
193 | 039e3e61 | Christos Stavrakakis | {'id': 2, |
194 | 039e3e61 | Christos Stavrakakis | 'name': 'image-2', |
195 | 039e3e61 | Christos Stavrakakis | 'status': 'deleted', |
196 | 039e3e61 | Christos Stavrakakis | 'progress': 0, |
197 | 936e0be3 | Christos Stavrakakis | 'owner': 'user2', |
198 | 039e3e61 | Christos Stavrakakis | 'created_at': new_time.isoformat(),
|
199 | 039e3e61 | Christos Stavrakakis | 'updated_at': new_time.isoformat(),
|
200 | 039e3e61 | Christos Stavrakakis | 'deleted_at': new_time.isoformat(),
|
201 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
202 | d984eedc | Christos Stavrakakis | 'is_public': False, |
203 | 039e3e61 | Christos Stavrakakis | 'properties': ''}] |
204 | 14c94c48 | Christos Stavrakakis | mimage().list_images.return_value = images |
205 | 039e3e61 | Christos Stavrakakis | response =\ |
206 | dc99330c | Georgios D. Tsoukalas | self.myget('images/detail?changes-since=%sUTC' % new_time) |
207 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
208 | 2d04422f | Christos Stavrakakis | api_images = json.loads(response.content)['images']
|
209 | 039e3e61 | Christos Stavrakakis | self.assertEqual(1, len(api_images)) |
210 | 039e3e61 | Christos Stavrakakis | |
211 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
212 | 039e3e61 | Christos Stavrakakis | def test_get_image_details(self, mimage): |
213 | 3768eb67 | Christos Stavrakakis | self.maxDiff = None |
214 | 039e3e61 | Christos Stavrakakis | image = {'id': 42, |
215 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
216 | 039e3e61 | Christos Stavrakakis | 'status': 'available', |
217 | 039e3e61 | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
218 | 039e3e61 | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
219 | 039e3e61 | Christos Stavrakakis | 'deleted_at': '', |
220 | 936e0be3 | Christos Stavrakakis | 'owner': 'user1', |
221 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
222 | d984eedc | Christos Stavrakakis | 'is_public': True, |
223 | 039e3e61 | Christos Stavrakakis | 'properties': {'foo': 'bar'}} |
224 | 039e3e61 | Christos Stavrakakis | result_image = \ |
225 | 039e3e61 | Christos Stavrakakis | {'id': 42, |
226 | 039e3e61 | Christos Stavrakakis | 'name': 'image-1', |
227 | 039e3e61 | Christos Stavrakakis | 'status': 'ACTIVE', |
228 | 039e3e61 | Christos Stavrakakis | 'progress': 100, |
229 | 039e3e61 | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
230 | 039e3e61 | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
231 | 936e0be3 | Christos Stavrakakis | 'user_id': 'user1', |
232 | c25cf3ea | Christos Stavrakakis | 'tenant_id': 'user1', |
233 | 3768eb67 | Christos Stavrakakis | 'is_snapshot': False, |
234 | d984eedc | Christos Stavrakakis | 'public': True, |
235 | 2d04422f | Christos Stavrakakis | 'metadata': {'foo': 'bar'}} |
236 | cda71050 | Christos Stavrakakis | mimage.return_value.get_image.return_value = image |
237 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42', 'user') |
238 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
239 | 039e3e61 | Christos Stavrakakis | api_image = json.loads(response.content)['image']
|
240 | c25cf3ea | Christos Stavrakakis | api_image.pop("links")
|
241 | 039e3e61 | Christos Stavrakakis | self.assertEqual(api_image, result_image)
|
242 | 039e3e61 | Christos Stavrakakis | |
243 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
244 | 039e3e61 | Christos Stavrakakis | def test_invalid_image(self, mimage): |
245 | d984eedc | Christos Stavrakakis | mimage.return_value.get_image.side_effect = \ |
246 | d984eedc | Christos Stavrakakis | faults.ItemNotFound('Image not found')
|
247 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42', 'user') |
248 | 039e3e61 | Christos Stavrakakis | self.assertItemNotFound(response)
|
249 | 039e3e61 | Christos Stavrakakis | |
250 | cda71050 | Christos Stavrakakis | @assert_backend_closed
|
251 | 039e3e61 | Christos Stavrakakis | def test_delete_image(self, mimage): |
252 | dc99330c | Georgios D. Tsoukalas | response = self.mydelete("images/42", "user") |
253 | 039e3e61 | Christos Stavrakakis | self.assertEqual(response.status_code, 204) |
254 | f13aab5d | Christos Stavrakakis | mimage.return_value.unregister.assert_called_once_with('42')
|
255 | f13aab5d | Christos Stavrakakis | mimage.return_value._delete.assert_not_called('42')
|
256 | 039e3e61 | Christos Stavrakakis | |
257 | a3accf03 | Georgios D. Tsoukalas | @assert_backend_closed
|
258 | a3accf03 | Georgios D. Tsoukalas | def test_catch_wrong_api_paths(self, *args): |
259 | a3accf03 | Georgios D. Tsoukalas | response = self.myget('nonexistent') |
260 | a3accf03 | Georgios D. Tsoukalas | self.assertEqual(response.status_code, 400) |
261 | a3accf03 | Georgios D. Tsoukalas | try:
|
262 | d984eedc | Christos Stavrakakis | json.loads(response.content) |
263 | a3accf03 | Georgios D. Tsoukalas | except ValueError: |
264 | a3accf03 | Georgios D. Tsoukalas | self.assertTrue(False) |
265 | a3accf03 | Georgios D. Tsoukalas | |
266 | 16437e4d | Kostas Papadimitriou | @assert_backend_closed
|
267 | 16437e4d | Kostas Papadimitriou | def test_method_not_allowed(self, *args): |
268 | 16437e4d | Kostas Papadimitriou | # /images/ allows only POST, GET
|
269 | 16437e4d | Kostas Papadimitriou | response = self.myput('images', '', '') |
270 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
271 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images') |
272 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
273 | 16437e4d | Kostas Papadimitriou | |
274 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/ allows only GET, DELETE
|
275 | 16437e4d | Kostas Papadimitriou | response = self.mypost("images/42") |
276 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
277 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42', '', '') |
278 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
279 | 16437e4d | Kostas Papadimitriou | |
280 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/ allows only POST, GET
|
281 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42/metadata', '', '') |
282 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
283 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images/42/metadata') |
284 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
285 | 16437e4d | Kostas Papadimitriou | |
286 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/ allows only POST, GET
|
287 | 16437e4d | Kostas Papadimitriou | response = self.myput('images/42/metadata', '', '') |
288 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
289 | 16437e4d | Kostas Papadimitriou | response = self.mydelete('images/42/metadata') |
290 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
291 | 16437e4d | Kostas Papadimitriou | |
292 | 16437e4d | Kostas Papadimitriou | # /images/<imgid>/metadata/<key> allows only PUT, GET, DELETE
|
293 | 16437e4d | Kostas Papadimitriou | response = self.mypost('images/42/metadata/foo') |
294 | 16437e4d | Kostas Papadimitriou | self.assertMethodNotAllowed(response)
|
295 | 16437e4d | Kostas Papadimitriou | |
296 | 039e3e61 | Christos Stavrakakis | |
297 | cda71050 | Christos Stavrakakis | @patch('synnefo.plankton.backend.ImageBackend') |
298 | dc99330c | Georgios D. Tsoukalas | class ImageMetadataAPITest(ComputeAPITest): |
299 | 039e3e61 | Christos Stavrakakis | def setUp(self): |
300 | 039e3e61 | Christos Stavrakakis | self.image = {'id': 42, |
301 | d984eedc | Christos Stavrakakis | 'name': 'image-1', |
302 | d984eedc | Christos Stavrakakis | 'status': 'available', |
303 | d984eedc | Christos Stavrakakis | 'created_at': '2012-11-26 11:52:54', |
304 | d984eedc | Christos Stavrakakis | 'updated_at': '2012-12-26 11:52:54', |
305 | d984eedc | Christos Stavrakakis | 'deleted_at': '', |
306 | d984eedc | Christos Stavrakakis | 'properties': {'foo': 'bar', 'foo2': 'bar2'}} |
307 | 039e3e61 | Christos Stavrakakis | self.result_image = \
|
308 | d984eedc | Christos Stavrakakis | {'id': 42, |
309 | d984eedc | Christos Stavrakakis | 'name': 'image-1', |
310 | d984eedc | Christos Stavrakakis | 'status': 'ACTIVE', |
311 | d984eedc | Christos Stavrakakis | 'progress': 100, |
312 | d984eedc | Christos Stavrakakis | 'created': '2012-11-26T11:52:54+00:00', |
313 | d984eedc | Christos Stavrakakis | 'updated': '2012-12-26T11:52:54+00:00', |
314 | d984eedc | Christos Stavrakakis | 'metadata': {'foo': 'bar'}} |
315 | dc99330c | Georgios D. Tsoukalas | super(ImageMetadataAPITest, self).setUp() |
316 | 039e3e61 | Christos Stavrakakis | |
317 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
318 | 039e3e61 | Christos Stavrakakis | def test_list_metadata(self, backend): |
319 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
320 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata', 'user') |
321 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
322 | 2d04422f | Christos Stavrakakis | meta = json.loads(response.content)['metadata']
|
323 | 039e3e61 | Christos Stavrakakis | self.assertEqual(meta, self.image['properties']) |
324 | 039e3e61 | Christos Stavrakakis | |
325 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
326 | 039e3e61 | Christos Stavrakakis | def test_get_metadata(self, backend): |
327 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
328 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata/foo', 'user') |
329 | 039e3e61 | Christos Stavrakakis | self.assertSuccess(response)
|
330 | 039e3e61 | Christos Stavrakakis | meta = json.loads(response.content)['meta']
|
331 | 039e3e61 | Christos Stavrakakis | self.assertEqual(meta['foo'], 'bar') |
332 | 039e3e61 | Christos Stavrakakis | |
333 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
334 | 039e3e61 | Christos Stavrakakis | def test_get_invalid_metadata(self, backend): |
335 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
336 | dc99330c | Georgios D. Tsoukalas | response = self.myget('images/42/metadata/not_found', 'user') |
337 | 039e3e61 | Christos Stavrakakis | self.assertItemNotFound(response)
|
338 | 039e3e61 | Christos Stavrakakis | |
339 | 039e3e61 | Christos Stavrakakis | def test_delete_metadata_item(self, backend): |
340 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
341 | dc99330c | Georgios D. Tsoukalas | response = self.mydelete('images/42/metadata/foo', 'user') |
342 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 204) |
343 | d984eedc | Christos Stavrakakis | backend.return_value.update_metadata\ |
344 | d984eedc | Christos Stavrakakis | .assert_called_once_with('42', {'properties': {'foo2': 'bar2'}}) |
345 | 039e3e61 | Christos Stavrakakis | |
346 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
347 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_item(self, backend): |
348 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
349 | b3fd98ae | Christos Stavrakakis | request = {'meta': {'foo3': 'bar3'}} |
350 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
351 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
352 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 201) |
353 | 14c94c48 | Christos Stavrakakis | backend.return_value.update_metadata.assert_called_once_with('42',
|
354 | b3fd98ae | Christos Stavrakakis | {'properties':
|
355 | b3fd98ae | Christos Stavrakakis | {'foo': 'bar', 'foo2': 'bar2', 'foo3': 'bar3'}}) |
356 | 039e3e61 | Christos Stavrakakis | |
357 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
358 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_1(self, backend): |
359 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
360 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3'}} |
361 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
362 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
363 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
364 | 039e3e61 | Christos Stavrakakis | |
365 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
366 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_2(self, backend): |
367 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
368 | 2d04422f | Christos Stavrakakis | request = {'metadata': [('foo3', 'bar3')]} |
369 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
370 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
371 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
372 | 039e3e61 | Christos Stavrakakis | |
373 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
374 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_3(self, backend): |
375 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
376 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3', 'foo4': 'bar4'}} |
377 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo3', 'user', |
378 | d984eedc | Christos Stavrakakis | json.dumps(request), 'json')
|
379 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
380 | 039e3e61 | Christos Stavrakakis | |
381 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
382 | 039e3e61 | Christos Stavrakakis | def test_create_metadata_malformed_4(self, backend): |
383 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
384 | b3fd98ae | Christos Stavrakakis | request = {'met': {'foo3': 'bar3'}} |
385 | dc99330c | Georgios D. Tsoukalas | response = self.myput('images/42/metadata/foo4', 'user', |
386 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
387 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response)
|
388 | 039e3e61 | Christos Stavrakakis | |
389 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
390 | 039e3e61 | Christos Stavrakakis | def test_update_metadata_item(self, backend): |
391 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
392 | b3fd98ae | Christos Stavrakakis | request = {'metadata': {'foo': 'bar_new', 'foo4': 'bar4'}} |
393 | dc99330c | Georgios D. Tsoukalas | response = self.mypost('images/42/metadata', 'user', |
394 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
395 | b3fd98ae | Christos Stavrakakis | self.assertEqual(response.status_code, 201) |
396 | 14c94c48 | Christos Stavrakakis | backend.return_value.update_metadata.assert_called_once_with('42',
|
397 | b3fd98ae | Christos Stavrakakis | {'properties':
|
398 | b3fd98ae | Christos Stavrakakis | {'foo': 'bar_new', 'foo2': 'bar2', 'foo4': 'bar4'} |
399 | b3fd98ae | Christos Stavrakakis | }) |
400 | 039e3e61 | Christos Stavrakakis | |
401 | 039e3e61 | Christos Stavrakakis | @assert_backend_closed
|
402 | 039e3e61 | Christos Stavrakakis | def test_update_metadata_malformed(self, backend): |
403 | 039e3e61 | Christos Stavrakakis | backend.return_value.get_image.return_value = self.image
|
404 | b3fd98ae | Christos Stavrakakis | request = {'meta': {'foo': 'bar_new', 'foo4': 'bar4'}} |
405 | dc99330c | Georgios D. Tsoukalas | response = self.mypost('images/42/metadata', 'user', |
406 | dc99330c | Georgios D. Tsoukalas | json.dumps(request), 'json')
|
407 | b3fd98ae | Christos Stavrakakis | self.assertBadRequest(response) |