Revision a26e5a4d snf-cyclades-app/synnefo/api/test/servers.py
b/snf-cyclades-app/synnefo/api/test/servers.py | ||
---|---|---|
37 | 37 |
from synnefo.db.models import VirtualMachine, VirtualMachineMetadata |
38 | 38 |
from synnefo.db import models_factory as mfactory |
39 | 39 |
from synnefo.logic.utils import get_rsapi_state |
40 |
from synnefo.cyclades_settings import cyclades_services |
|
41 |
from synnefo.lib.services import get_service_path |
|
42 |
from synnefo.lib import join_urls |
|
40 | 43 |
|
41 | 44 |
from mock import patch |
42 | 45 |
|
43 | 46 |
|
44 |
class ServerAPITest(BaseAPITest): |
|
47 |
class ComputeAPITest(BaseAPITest): |
|
48 |
def setUp(self, *args, **kwargs): |
|
49 |
super(ComputeAPITest, self).setUp(*args, **kwargs) |
|
50 |
self.compute_path = get_service_path(cyclades_services, 'compute', |
|
51 |
version='v2.0') |
|
52 |
def myget(self, path, *args, **kwargs): |
|
53 |
path = join_urls(self.compute_path, path) |
|
54 |
return self.get(path, *args, **kwargs) |
|
55 |
|
|
56 |
def myput(self, path, *args, **kwargs): |
|
57 |
path = join_urls(self.compute_path, path) |
|
58 |
return self.put(path, *args, **kwargs) |
|
59 |
|
|
60 |
def mypost(self, path, *args, **kwargs): |
|
61 |
path = join_urls(self.compute_path, path) |
|
62 |
return self.post(path, *args, **kwargs) |
|
63 |
|
|
64 |
def mydelete(self, path, *args, **kwargs): |
|
65 |
path = join_urls(self.compute_path, path) |
|
66 |
return self.delete(path, *args, **kwargs) |
|
67 |
|
|
68 |
|
|
69 |
class ServerAPITest(ComputeAPITest): |
|
45 | 70 |
def setUp(self): |
46 | 71 |
self.user1 = 'user1' |
47 | 72 |
self.user2 = 'user2' |
... | ... | |
50 | 75 |
self.vm3 = mfactory.VirtualMachineFactory(deleted=True, |
51 | 76 |
userid=self.user1) |
52 | 77 |
self.vm4 = mfactory.VirtualMachineFactory(userid=self.user2) |
78 |
super(ServerAPITest, self).setUp() |
|
53 | 79 |
|
54 | 80 |
def test_server_list_1(self): |
55 | 81 |
"""Test if the expected list of servers is returned.""" |
56 |
response = self.get('/api/v1.1/servers')
|
|
82 |
response = self.myget('servers')
|
|
57 | 83 |
self.assertSuccess(response) |
58 | 84 |
servers = json.loads(response.content)['servers'] |
59 | 85 |
self.assertEqual(servers, []) |
60 | 86 |
|
61 | 87 |
def test_server_list_2(self): |
62 | 88 |
"""Test if the expected list of servers is returned.""" |
63 |
response = self.get('/api/v1.1/servers', self.user1)
|
|
89 |
response = self.myget('servers', self.user1)
|
|
64 | 90 |
self.assertSuccess(response) |
65 | 91 |
servers = json.loads(response.content)['servers'] |
66 | 92 |
db_server = self.vm1 |
... | ... | |
73 | 99 |
user_vms = {self.vm2.id: self.vm2, |
74 | 100 |
self.vm4.id: self.vm4} |
75 | 101 |
|
76 |
response = self.get('/api/v1.1/servers/detail', user)
|
|
102 |
response = self.myget('servers/detail', user)
|
|
77 | 103 |
servers = json.loads(response.content)['servers'] |
78 | 104 |
self.assertEqual(len(servers), len(user_vms)) |
79 | 105 |
for api_vm in servers: |
... | ... | |
95 | 121 |
|
96 | 122 |
db_vm_meta = mfactory.VirtualMachineMetadataFactory(vm=db_vm) |
97 | 123 |
|
98 |
response = self.get('/api/v1.1/servers/%d' % db_vm.id, user)
|
|
124 |
response = self.myget('servers/%d' % db_vm.id, user)
|
|
99 | 125 |
server = json.loads(response.content)['server'] |
100 | 126 |
|
101 | 127 |
self.assertEqual(server['flavor'], db_vm.flavor.id) |
... | ... | |
130 | 156 |
mfactory.NetworkInterfaceFactory(machine=self.vm2, network=net3, |
131 | 157 |
state="BUILDING") |
132 | 158 |
|
133 |
response = self.get('/api/v1.1/servers/%d' % db_vm.id, user)
|
|
159 |
response = self.myget('servers/%d' % db_vm.id, user)
|
|
134 | 160 |
server = json.loads(response.content)['server'] |
135 | 161 |
nics = server["attachments"] |
136 | 162 |
self.assertEqual(len(nics), 1) |
... | ... | |
140 | 166 |
"""Test 404 for detail of other user vm""" |
141 | 167 |
db_vm = self.vm2 |
142 | 168 |
|
143 |
response = self.get('/api/v1.1/servers/%d' % db_vm.id, 'wrong_user')
|
|
169 |
response = self.myget('servers/%d' % db_vm.id, 'wrong_user')
|
|
144 | 170 |
self.assertItemNotFound(response) |
145 | 171 |
|
146 | 172 |
def test_wrong_server(self): |
147 | 173 |
"""Test 404 response if server does not exist.""" |
148 |
response = self.get('/api/v1.1/servers/%d' % 5000)
|
|
174 |
response = self.myget('servers/%d' % 5000)
|
|
149 | 175 |
self.assertItemNotFound(response) |
150 | 176 |
|
151 | 177 |
def test_create_server_empty(self): |
152 | 178 |
"""Test if the create server call returns a 400 badRequest if |
153 | 179 |
no attributes are specified.""" |
154 | 180 |
|
155 |
response = self.post('/api/v1.1/servers', params={})
|
|
181 |
response = self.mypost('servers', params={})
|
|
156 | 182 |
self.assertBadRequest(response) |
157 | 183 |
|
158 | 184 |
def test_rename_server(self): |
159 | 185 |
vm = self.vm2 |
160 | 186 |
request = {'server': {'name': 'new_name'}} |
161 |
response = self.put('/api/v1.1/servers/%d' % vm.id, vm.userid,
|
|
162 |
json.dumps(request), 'json') |
|
187 |
response = self.myput('servers/%d' % vm.id, vm.userid,
|
|
188 |
json.dumps(request), 'json')
|
|
163 | 189 |
self.assertSuccess(response) |
164 | 190 |
self.assertEqual(VirtualMachine.objects.get(id=vm.id).name, "new_name") |
165 | 191 |
|
166 | 192 |
|
167 | 193 |
@patch('synnefo.api.util.get_image') |
168 | 194 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient') |
169 |
class ServerCreateAPITest(BaseAPITest):
|
|
195 |
class ServerCreateAPITest(ComputeAPITest):
|
|
170 | 196 |
def test_create_server(self, mrapi, mimage): |
171 | 197 |
"""Test if the create server call returns the expected response |
172 | 198 |
if a valid request has been speficied.""" |
... | ... | |
195 | 221 |
} |
196 | 222 |
} |
197 | 223 |
with mocked_quotaholder(): |
198 |
response = self.post('/api/v1.1/servers', 'test_user',
|
|
199 |
json.dumps(request), 'json')
|
|
224 |
response = self.mypost('servers', 'test_user',
|
|
225 |
json.dumps(request), 'json') |
|
200 | 226 |
self.assertEqual(response.status_code, 202) |
201 | 227 |
mrapi().CreateInstance.assert_called_once() |
202 | 228 |
|
... | ... | |
215 | 241 |
network.drained = True |
216 | 242 |
network.save() |
217 | 243 |
with mocked_quotaholder(): |
218 |
response = self.post('/api/v1.1/servers', 'test_user',
|
|
219 |
json.dumps(request), 'json')
|
|
244 |
response = self.mypost('servers', 'test_user',
|
|
245 |
json.dumps(request), 'json') |
|
220 | 246 |
self.assertEqual(response.status_code, 503, "serviceUnavailable") |
221 | 247 |
|
222 | 248 |
def test_create_server_no_flavor(self, mrapi, mimage): |
... | ... | |
232 | 258 |
"personality": [] |
233 | 259 |
} |
234 | 260 |
} |
235 |
response = self.post('/api/v1.1/servers', 'test_user',
|
|
236 |
json.dumps(request), 'json')
|
|
261 |
response = self.mypost('servers', 'test_user',
|
|
262 |
json.dumps(request), 'json') |
|
237 | 263 |
self.assertItemNotFound(response) |
238 | 264 |
|
239 | 265 |
|
240 | 266 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient') |
241 |
class ServerDestroyAPITest(BaseAPITest):
|
|
267 |
class ServerDestroyAPITest(ComputeAPITest):
|
|
242 | 268 |
def test_delete_server(self, mrapi): |
243 | 269 |
vm = mfactory.VirtualMachineFactory() |
244 |
response = self.delete('/api/v1.1/servers/%d' % vm.id, vm.userid)
|
|
270 |
response = self.mydelete('servers/%d' % vm.id, vm.userid)
|
|
245 | 271 |
self.assertEqual(response.status_code, 204) |
246 | 272 |
mrapi().DeleteInstance.assert_called_once() |
247 | 273 |
|
248 | 274 |
def test_non_existing_delete_server(self, mrapi): |
249 | 275 |
vm = mfactory.VirtualMachineFactory() |
250 |
response = self.delete('/api/v1.1/servers/%d' % 42, vm.userid)
|
|
276 |
response = self.mydelete('servers/%d' % 42, vm.userid)
|
|
251 | 277 |
self.assertItemNotFound(response) |
252 | 278 |
self.assertFalse(mrapi.mock_calls) |
253 | 279 |
|
254 | 280 |
|
255 |
class ServerMetadataAPITest(BaseAPITest):
|
|
281 |
class ServerMetadataAPITest(ComputeAPITest):
|
|
256 | 282 |
def setUp(self): |
257 | 283 |
self.vm = mfactory.VirtualMachineFactory() |
258 | 284 |
self.metadata = mfactory.VirtualMachineMetadataFactory(vm=self.vm) |
285 |
super(ServerMetadataAPITest, self).setUp() |
|
259 | 286 |
|
260 | 287 |
def test_get_metadata(self): |
261 | 288 |
vm = self.vm |
262 | 289 |
create_meta = lambda: mfactory.VirtualMachineMetadataFactory(vm=vm) |
263 | 290 |
metadata = [create_meta(), create_meta(), create_meta()] |
264 |
response = self.get('/api/v1.1/servers/%d/metadata' % vm.id, vm.userid)
|
|
291 |
response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
|
|
265 | 292 |
self.assertTrue(response.status_code in [200, 203]) |
266 | 293 |
api_metadata = json.loads(response.content)['metadata'] |
267 | 294 |
self.assertEqual(len(api_metadata), len(metadata) + 1) |
... | ... | |
272 | 299 |
{'foo': 'bar'}, |
273 | 300 |
metadata[0].meta_key: 'bar2' |
274 | 301 |
} |
275 |
response = self.post('/api/v1.1/servers/%d/metadata' % vm.id,
|
|
302 |
response = self.mypost('servers/%d/metadata' % vm.id,
|
|
276 | 303 |
vm.userid, json.dumps(request), 'json') |
277 | 304 |
metadata2 = VirtualMachineMetadata.objects.filter(vm=vm) |
278 |
response = self.get('/api/v1.1/servers/%d/metadata' % vm.id, vm.userid)
|
|
305 |
response = self.myget('servers/%d/metadata' % vm.id, vm.userid)
|
|
279 | 306 |
self.assertTrue(response.status_code in [200, 203]) |
280 | 307 |
api_metadata2 = json.loads(response.content)['metadata'] |
281 | 308 |
self.assertTrue('foo' in api_metadata2.keys()) |
... | ... | |
286 | 313 |
|
287 | 314 |
# Create new meta |
288 | 315 |
request = {'meta': {'foo2': 'bar2'}} |
289 |
response = self.put('/api/v1.1/servers/%d/metadata/foo2' % vm.id,
|
|
290 |
vm.userid, json.dumps(request), 'json') |
|
316 |
response = self.myput('servers/%d/metadata/foo2' % vm.id,
|
|
317 |
vm.userid, json.dumps(request), 'json')
|
|
291 | 318 |
|
292 | 319 |
# Get the new meta |
293 |
response = self.get('/api/v1.1/servers/%d/metadata/foo2' % vm.id, |
|
294 |
vm.userid) |
|
320 |
response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid) |
|
295 | 321 |
meta = json.loads(response.content)['meta'] |
296 | 322 |
self.assertEqual(meta['foo2'], 'bar2') |
297 | 323 |
|
298 | 324 |
# Delete the new meta |
299 |
response = self.delete('/api/v1.1/servers/%d/metadata/foo2' % vm.id, |
|
300 |
vm.userid) |
|
325 |
response = self.mydelete('servers/%d/metadata/foo2' % vm.id, vm.userid) |
|
301 | 326 |
self.assertEqual(response.status_code, 204) |
302 | 327 |
|
303 | 328 |
# Try to get the deleted meta: should raise 404 |
304 |
response = self.get('/api/v1.1/servers/%d/metadata/foo2' % vm.id, |
|
305 |
vm.userid) |
|
329 |
response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid) |
|
306 | 330 |
self.assertEqual(response.status_code, 404) |
307 | 331 |
|
308 | 332 |
def test_invalid_metadata(self): |
309 | 333 |
vm = self.vm |
310 |
response = self.post('/api/v1.1/servers/%d/metadata' % vm.id, |
|
311 |
vm.userid) |
|
334 |
response = self.mypost('servers/%d/metadata' % vm.id, vm.userid) |
|
312 | 335 |
self.assertBadRequest(response) |
313 | 336 |
self.assertEqual(len(vm.metadata.all()), 1) |
314 | 337 |
|
315 | 338 |
def test_invalid_metadata_server(self): |
316 |
response = self.post('/api/v1.1/servers/42/metadata', 'user')
|
|
339 |
response = self.mypost('servers/42/metadata', 'user')
|
|
317 | 340 |
self.assertItemNotFound(response) |
318 | 341 |
|
319 | 342 |
def test_get_meta_invalid_key(self): |
320 | 343 |
vm = self.vm |
321 |
response = self.get('/api/v1.1/servers/%d/metadata/foo2' % vm.id, |
|
322 |
vm.userid) |
|
344 |
response = self.myget('servers/%d/metadata/foo2' % vm.id, vm.userid) |
|
323 | 345 |
self.assertItemNotFound(response) |
324 | 346 |
|
325 | 347 |
|
326 | 348 |
@patch('synnefo.api.util.get_image') |
327 | 349 |
@patch('synnefo.logic.rapi_pool.GanetiRapiClient') |
328 |
class ServerActionAPITest(BaseAPITest):
|
|
350 |
class ServerActionAPITest(ComputeAPITest):
|
|
329 | 351 |
def test_actions(self, mrapi, mimage): |
330 | 352 |
actions = ['start', 'shutdown', 'reboot'] |
331 | 353 |
vm = mfactory.VirtualMachineFactory() |
... | ... | |
334 | 356 |
for action in actions: |
335 | 357 |
val = {'type': 'HARD'} if action == 'reboot' else {} |
336 | 358 |
request = {action: val} |
337 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
338 |
vm.userid, json.dumps(request), 'json') |
|
359 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
360 |
vm.userid, json.dumps(request), 'json')
|
|
339 | 361 |
self.assertEqual(response.status_code, 202) |
340 | 362 |
if action == 'shutdown': |
341 | 363 |
self.assertEqual(VirtualMachine.objects.get(id=vm.id).action, |
... | ... | |
348 | 370 |
"""Test building in progress""" |
349 | 371 |
vm = mfactory.VirtualMachineFactory() |
350 | 372 |
request = {'start': '{}'} |
351 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
352 |
vm.userid, json.dumps(request), 'json') |
|
373 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
374 |
vm.userid, json.dumps(request), 'json')
|
|
353 | 375 |
self.assertEqual(response.status_code, 409) |
354 | 376 |
self.assertFalse(mrapi.mock_calls) |
355 | 377 |
|
356 | 378 |
def test_destroy_build_vm(self, mrapi, mimage): |
357 | 379 |
"""Test building in progress""" |
358 | 380 |
vm = mfactory.VirtualMachineFactory() |
359 |
response = self.delete('/api/v1.1/servers/%d' % vm.id, |
|
360 |
vm.userid) |
|
381 |
response = self.mydelete('servers/%d' % vm.id, vm.userid) |
|
361 | 382 |
self.assertSuccess(response) |
362 | 383 |
mrapi().RemoveInstance.assert_called_once() |
363 | 384 |
|
... | ... | |
366 | 387 |
vm.operstate = "STOPPED" |
367 | 388 |
vm.save() |
368 | 389 |
request = {'firewallProfile': {'profile': 'PROTECTED'}} |
369 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
370 |
vm.userid, json.dumps(request), 'json') |
|
390 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
391 |
vm.userid, json.dumps(request), 'json')
|
|
371 | 392 |
self.assertEqual(response.status_code, 202) |
372 | 393 |
mrapi().ModifyInstance.assert_called_once() |
373 | 394 |
|
... | ... | |
376 | 397 |
vm.operstate = "STOPPED" |
377 | 398 |
vm.save() |
378 | 399 |
request = {'firewallProfile': {'profile': 'FOO'}} |
379 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
380 |
vm.userid, json.dumps(request), 'json') |
|
400 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
401 |
vm.userid, json.dumps(request), 'json')
|
|
381 | 402 |
self.assertBadRequest(response) |
382 | 403 |
self.assertFalse(mrapi.mock_calls) |
383 | 404 |
|
384 | 405 |
|
385 |
class ServerVNCConsole(BaseAPITest):
|
|
406 |
class ServerVNCConsole(ComputeAPITest):
|
|
386 | 407 |
def test_not_active_server(self): |
387 | 408 |
"""Test console req for not ACTIVE server returns badRequest""" |
388 | 409 |
vm = mfactory.VirtualMachineFactory() |
389 | 410 |
data = json.dumps({'console': {'type': 'vnc'}}) |
390 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
391 |
vm.userid, data, 'json') |
|
411 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
412 |
vm.userid, data, 'json')
|
|
392 | 413 |
self.assertBadRequest(response) |
393 | 414 |
|
394 | 415 |
def test_active_server(self): |
... | ... | |
398 | 419 |
vm.save() |
399 | 420 |
|
400 | 421 |
data = json.dumps({'console': {'type': 'vnc'}}) |
401 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
402 |
vm.userid, data, 'json') |
|
422 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
423 |
vm.userid, data, 'json')
|
|
403 | 424 |
self.assertEqual(response.status_code, 200) |
404 | 425 |
reply = json.loads(response.content) |
405 | 426 |
self.assertEqual(reply.keys(), ['console']) |
... | ... | |
415 | 436 |
vm.save() |
416 | 437 |
|
417 | 438 |
data = json.dumps({'console': {'type': 'foo'}}) |
418 |
response = self.post('/api/v1.1/servers/%d/action' % vm.id,
|
|
419 |
vm.userid, data, 'json') |
|
439 |
response = self.mypost('servers/%d/action' % vm.id,
|
|
440 |
vm.userid, data, 'json')
|
|
420 | 441 |
self.assertBadRequest(response) |
Also available in: Unified diff