1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2011 Cisco Systems
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
# not use this file except in compliance with the License. You may obtain
8
# a copy of the License at
10
# http://www.apache.org/licenses/LICENSE-2.0
12
# Unless required by applicable law or agreed to in writing, software
13
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
# License for the specific language governing permissions and limitations
17
# @author: Tyler Smith, Cisco Systems
23
from quantumclient.common import exceptions
24
from quantumclient.common.serializer import Serializer
25
from quantumclient import Client
28
LOG = logging.getLogger('quantumclient.tests.test_api')
31
# Set a couple tenants to use for testing
37
"""This class stubs a basic server for the API client to talk to"""
39
class Response(object):
40
"""This class stubs a basic response to send the API client"""
41
def __init__(self, content=None, status=None):
42
self.content = content
51
# To test error codes, set the host to 10.0.0.1, and the port to the code
52
def __init__(self, host, port=9696, key_file="", cert_file=""):
55
self.key_file = key_file
56
self.cert_file = cert_file
58
def request(self, method, action, body, headers):
63
def status(self, status=None):
66
def getresponse(self):
67
res = self.Response(status=self.status())
69
# If the host is 10.0.0.1, return the port as an error code
70
if self.host == "10.0.0.1":
71
res.status = self.port
74
# Extract important information from the action string to assure sanity
75
match = re.search('tenants/(.+?)/(.+)\.(json|xml)$', self.action)
77
tenant = match.group(1)
79
format = match.group(3)
81
data = {'data': {'method': self.method, 'action': self.action,
82
'body': self.body, 'tenant': tenant, 'path': path,
83
'format': format, 'key_file': self.key_file,
84
'cert_file': self.cert_file}}
86
# Serialize it to the proper format so the API client can handle it
87
if data['data']['format'] == 'json':
88
res.content = Serializer().serialize(data, "application/json")
90
res.content = Serializer().serialize(data, "application/xml")
94
class APITest(unittest.TestCase):
97
""" Setups a test environment for the API client """
102
self.client = Client(HOST, PORT, USE_SSL, TENANT_1, 'json', ServerStub)
104
def _assert_sanity(self, call, status, method, path, data=[], params={}):
105
""" Perform common assertions to test the sanity of client requests """
107
# Handle an error case first
109
(self.client.host, self.client.port) = ("10.0.0.1", status)
110
self.assertRaises(Exception, call, *data, **params)
113
# Make the call, then get the data from the root node and assert it
114
data = call(*data, **params)['data']
116
self.assertEqual(data['method'], method)
117
self.assertEqual(data['format'], params['format'])
118
self.assertEqual(data['tenant'], params['tenant'])
119
self.assertEqual(data['path'], path)
123
def _test_list_networks(self, tenant=TENANT_1, format='json', status=200):
124
LOG.debug("_test_list_networks - tenant:%s "
125
"- format:%s - START", format, tenant)
127
self._assert_sanity(self.client.list_networks,
132
params={'tenant': tenant, 'format': format})
134
LOG.debug("_test_list_networks - tenant:%s - format:%s - END",
137
def _test_list_networks_details(self,
138
tenant=TENANT_1, format='json',
140
LOG.debug("_test_list_networks_details - tenant:%s "
141
"- format:%s - START", format, tenant)
143
self._assert_sanity(self.client.list_networks_details,
148
params={'tenant': tenant, 'format': format})
150
LOG.debug("_test_list_networks_details - tenant:%s "
151
"- format:%s - END", format, tenant)
153
def _test_show_network(self,
154
tenant=TENANT_1, format='json', status=200):
155
LOG.debug("_test_show_network - tenant:%s "
156
"- format:%s - START", format, tenant)
158
self._assert_sanity(self.client.show_network,
163
params={'tenant': tenant, 'format': format})
165
LOG.debug("_test_show_network - tenant:%s "
166
"- format:%s - END", format, tenant)
168
def _test_show_network_details(self,
169
tenant=TENANT_1, format='json', status=200):
170
LOG.debug("_test_show_network_details - tenant:%s "
171
"- format:%s - START", format, tenant)
173
self._assert_sanity(self.client.show_network_details,
176
"networks/001/detail",
178
params={'tenant': tenant, 'format': format})
180
LOG.debug("_test_show_network_details - tenant:%s "
181
"- format:%s - END", format, tenant)
183
def _test_create_network(self, tenant=TENANT_1, format='json', status=200):
184
LOG.debug("_test_create_network - tenant:%s "
185
"- format:%s - START", format, tenant)
187
self._assert_sanity(self.client.create_network,
191
data=[{'network': {'net-name': 'testNetwork'}}],
192
params={'tenant': tenant, 'format': format})
194
LOG.debug("_test_create_network - tenant:%s "
195
"- format:%s - END", format, tenant)
197
def _test_update_network(self, tenant=TENANT_1, format='json', status=200):
198
LOG.debug("_test_update_network - tenant:%s "
199
"- format:%s - START", format, tenant)
201
self._assert_sanity(self.client.update_network,
206
{'network': {'net-name': 'newName'}}],
207
params={'tenant': tenant, 'format': format})
209
LOG.debug("_test_update_network - tenant:%s "
210
"- format:%s - END", format, tenant)
212
def _test_delete_network(self, tenant=TENANT_1, format='json', status=200):
213
LOG.debug("_test_delete_network - tenant:%s "
214
"- format:%s - START", format, tenant)
216
self._assert_sanity(self.client.delete_network,
221
params={'tenant': tenant, 'format': format})
223
LOG.debug("_test_delete_network - tenant:%s "
224
"- format:%s - END", format, tenant)
226
def _test_list_ports(self, tenant=TENANT_1, format='json', status=200):
227
LOG.debug("_test_list_ports - tenant:%s "
228
"- format:%s - START", format, tenant)
230
self._assert_sanity(self.client.list_ports,
233
"networks/001/ports",
235
params={'tenant': tenant, 'format': format})
237
LOG.debug("_test_list_ports - tenant:%s "
238
"- format:%s - END", format, tenant)
240
def _test_list_ports_details(self,
241
tenant=TENANT_1, format='json', status=200):
242
LOG.debug("_test_list_ports_details - tenant:%s "
243
"- format:%s - START", format, tenant)
245
self._assert_sanity(self.client.list_ports_details,
248
"networks/001/ports/detail",
250
params={'tenant': tenant, 'format': format})
252
LOG.debug("_test_list_ports_details - tenant:%s "
253
"- format:%s - END", format, tenant)
255
def _test_show_port(self, tenant=TENANT_1, format='json', status=200):
256
LOG.debug("_test_show_port - tenant:%s "
257
"- format:%s - START", format, tenant)
259
self._assert_sanity(self.client.show_port,
262
"networks/001/ports/001",
264
params={'tenant': tenant, 'format': format})
266
LOG.debug("_test_show_port - tenant:%s "
267
"- format:%s - END", format, tenant)
269
def _test_show_port_details(self,
270
tenant=TENANT_1, format='json', status=200):
271
LOG.debug("_test_show_port_details - tenant:%s "
272
"- format:%s - START", format, tenant)
274
self._assert_sanity(self.client.show_port_details,
277
"networks/001/ports/001/detail",
279
params={'tenant': tenant, 'format': format})
281
LOG.debug("_test_show_port_details - tenant:%s "
282
"- format:%s - END", format, tenant)
284
def _test_create_port(self, tenant=TENANT_1, format='json', status=200):
285
LOG.debug("_test_create_port - tenant:%s "
286
"- format:%s - START", format, tenant)
288
self._assert_sanity(self.client.create_port,
291
"networks/001/ports",
293
params={'tenant': tenant, 'format': format})
295
LOG.debug("_test_create_port - tenant:%s "
296
"- format:%s - END", format, tenant)
298
def _test_delete_port(self, tenant=TENANT_1, format='json', status=200):
299
LOG.debug("_test_delete_port - tenant:%s "
300
"- format:%s - START", format, tenant)
302
self._assert_sanity(self.client.delete_port,
305
"networks/001/ports/001",
307
params={'tenant': tenant, 'format': format})
309
LOG.debug("_test_delete_port - tenant:%s "
310
"- format:%s - END", format, tenant)
312
def _test_update_port(self, tenant=TENANT_1, format='json', status=200):
313
LOG.debug("_test_update_port - tenant:%s "
314
"- format:%s - START", format, tenant)
316
self._assert_sanity(self.client.update_port,
319
"networks/001/ports/001",
321
{'port': {'state': 'ACTIVE'}}],
322
params={'tenant': tenant, 'format': format})
324
LOG.debug("_test_update_port - tenant:%s "
325
"- format:%s - END", format, tenant)
327
def _test_show_port_attachment(self,
328
tenant=TENANT_1, format='json', status=200):
329
LOG.debug("_test_show_port_attachment - tenant:%s "
330
"- format:%s - START", format, tenant)
332
self._assert_sanity(self.client.show_port_attachment,
335
"networks/001/ports/001/attachment",
337
params={'tenant': tenant, 'format': format})
339
LOG.debug("_test_show_port_attachment - tenant:%s "
340
"- format:%s - END", format, tenant)
342
def _test_attach_resource(self, tenant=TENANT_1,
343
format='json', status=200):
344
LOG.debug("_test_attach_resource - tenant:%s "
345
"- format:%s - START", format, tenant)
347
self._assert_sanity(self.client.attach_resource,
350
"networks/001/ports/001/attachment",
352
{'resource': {'id': '1234'}}],
353
params={'tenant': tenant, 'format': format})
355
LOG.debug("_test_attach_resource - tenant:%s "
356
"- format:%s - END", format, tenant)
358
def _test_detach_resource(self, tenant=TENANT_1,
359
format='json', status=200):
360
LOG.debug("_test_detach_resource - tenant:%s "
361
"- format:%s - START", format, tenant)
363
self._assert_sanity(self.client.detach_resource,
366
"networks/001/ports/001/attachment",
368
params={'tenant': tenant, 'format': format})
370
LOG.debug("_test_detach_resource - tenant:%s "
371
"- format:%s - END", format, tenant)
373
def _test_ssl_certificates(self, tenant=TENANT_1,
374
format='json', status=200):
375
LOG.debug("_test_ssl_certificates - tenant:%s "
376
"- format:%s - START", format, tenant)
378
# Set SSL, and our cert file
379
self.client.use_ssl = True
380
cert_file = "/fake.cert"
381
self.client.key_file = self.client.cert_file = cert_file
383
data = self._assert_sanity(self.client.list_networks,
388
params={'tenant': tenant, 'format': format})
390
self.assertEquals(data["key_file"], cert_file)
391
self.assertEquals(data["cert_file"], cert_file)
393
LOG.debug("_test_ssl_certificates - tenant:%s "
394
"- format:%s - END", format, tenant)
396
def test_list_networks_json(self):
397
self._test_list_networks(format='json')
399
def test_list_networks_xml(self):
400
self._test_list_networks(format='xml')
402
def test_list_networks_alt_tenant(self):
403
self._test_list_networks(tenant=TENANT_2)
405
def test_list_networks_error_470(self):
406
self._test_list_networks(status=470)
408
def test_list_networks_error_401(self):
409
self._test_list_networks(status=401)
411
def test_list_networks_details_json(self):
412
self._test_list_networks_details(format='json')
414
def test_list_networks_details_xml(self):
415
self._test_list_networks_details(format='xml')
417
def test_list_networks_details_alt_tenant(self):
418
self._test_list_networks_details(tenant=TENANT_2)
420
def test_list_networks_details_error_470(self):
421
self._test_list_networks_details(status=470)
423
def test_list_networks_details_error_401(self):
424
self._test_list_networks_details(status=401)
426
def test_show_network_json(self):
427
self._test_show_network(format='json')
429
def test_show_network__xml(self):
430
self._test_show_network(format='xml')
432
def test_show_network_alt_tenant(self):
433
self._test_show_network(tenant=TENANT_2)
435
def test_show_network_error_470(self):
436
self._test_show_network(status=470)
438
def test_show_network_error_401(self):
439
self._test_show_network(status=401)
441
def test_show_network_error_420(self):
442
self._test_show_network(status=420)
444
def test_show_network_details_json(self):
445
self._test_show_network_details(format='json')
447
def test_show_network_details_xml(self):
448
self._test_show_network_details(format='xml')
450
def test_show_network_details_alt_tenant(self):
451
self._test_show_network_details(tenant=TENANT_2)
453
def test_show_network_details_error_470(self):
454
self._test_show_network_details(status=470)
456
def test_show_network_details_error_401(self):
457
self._test_show_network_details(status=401)
459
def test_show_network_details_error_420(self):
460
self._test_show_network_details(status=420)
462
def test_create_network_json(self):
463
self._test_create_network(format='json')
465
def test_create_network_xml(self):
466
self._test_create_network(format='xml')
468
def test_create_network_alt_tenant(self):
469
self._test_create_network(tenant=TENANT_2)
471
def test_create_network_error_470(self):
472
self._test_create_network(status=470)
474
def test_create_network_error_401(self):
475
self._test_create_network(status=401)
477
def test_create_network_error_400(self):
478
self._test_create_network(status=400)
480
def test_create_network_error_422(self):
481
self._test_create_network(status=422)
483
def test_update_network_json(self):
484
self._test_update_network(format='json')
486
def test_update_network_xml(self):
487
self._test_update_network(format='xml')
489
def test_update_network_alt_tenant(self):
490
self._test_update_network(tenant=TENANT_2)
492
def test_update_network_error_470(self):
493
self._test_update_network(status=470)
495
def test_update_network_error_401(self):
496
self._test_update_network(status=401)
498
def test_update_network_error_400(self):
499
self._test_update_network(status=400)
501
def test_update_network_error_420(self):
502
self._test_update_network(status=420)
504
def test_update_network_error_422(self):
505
self._test_update_network(status=422)
507
def test_delete_network_json(self):
508
self._test_delete_network(format='json')
510
def test_delete_network_xml(self):
511
self._test_delete_network(format='xml')
513
def test_delete_network_alt_tenant(self):
514
self._test_delete_network(tenant=TENANT_2)
516
def test_delete_network_error_470(self):
517
self._test_delete_network(status=470)
519
def test_delete_network_error_401(self):
520
self._test_delete_network(status=401)
522
def test_delete_network_error_420(self):
523
self._test_delete_network(status=420)
525
def test_delete_network_error_421(self):
526
self._test_delete_network(status=421)
528
def test_list_ports_json(self):
529
self._test_list_ports(format='json')
531
def test_list_ports_xml(self):
532
self._test_list_ports(format='xml')
534
def test_list_ports_alt_tenant(self):
535
self._test_list_ports(tenant=TENANT_2)
537
def test_list_ports_error_470(self):
538
self._test_list_ports(status=470)
540
def test_list_ports_error_401(self):
541
self._test_list_ports(status=401)
543
def test_list_ports_error_420(self):
544
self._test_list_ports(status=420)
546
def test_list_ports_details_json(self):
547
self._test_list_ports_details(format='json')
549
def test_list_ports_details_xml(self):
550
self._test_list_ports_details(format='xml')
552
def test_list_ports_details_alt_tenant(self):
553
self._test_list_ports_details(tenant=TENANT_2)
555
def test_list_ports_details_error_470(self):
556
self._test_list_ports_details(status=470)
558
def test_list_ports_details_error_401(self):
559
self._test_list_ports_details(status=401)
561
def test_list_ports_details_error_420(self):
562
self._test_list_ports_details(status=420)
564
def test_show_port_json(self):
565
self._test_show_port(format='json')
567
def test_show_port_xml(self):
568
self._test_show_port(format='xml')
570
def test_show_port_alt_tenant(self):
571
self._test_show_port(tenant=TENANT_2)
573
def test_show_port_error_470(self):
574
self._test_show_port(status=470)
576
def test_show_port_error_401(self):
577
self._test_show_port(status=401)
579
def test_show_port_error_420(self):
580
self._test_show_port(status=420)
582
def test_show_port_error_430(self):
583
self._test_show_port(status=430)
585
def test_show_port_details_json(self):
586
self._test_show_port_details(format='json')
588
def test_show_port_details_xml(self):
589
self._test_show_port_details(format='xml')
591
def test_show_port_details_alt_tenant(self):
592
self._test_show_port_details(tenant=TENANT_2)
594
def test_show_port_details_error_470(self):
595
self._test_show_port_details(status=470)
597
def test_show_port_details_error_401(self):
598
self._test_show_port_details(status=401)
600
def test_show_port_details_error_420(self):
601
self._test_show_port_details(status=420)
603
def test_show_port_details_error_430(self):
604
self._test_show_port_details(status=430)
606
def test_create_port_json(self):
607
self._test_create_port(format='json')
609
def test_create_port_xml(self):
610
self._test_create_port(format='xml')
612
def test_create_port_alt_tenant(self):
613
self._test_create_port(tenant=TENANT_2)
615
def test_create_port_error_470(self):
616
self._test_create_port(status=470)
618
def test_create_port_error_401(self):
619
self._test_create_port(status=401)
621
def test_create_port_error_400(self):
622
self._test_create_port(status=400)
624
def test_create_port_error_420(self):
625
self._test_create_port(status=420)
627
def test_create_port_error_430(self):
628
self._test_create_port(status=430)
630
def test_create_port_error_431(self):
631
self._test_create_port(status=431)
633
def test_delete_port_json(self):
634
self._test_delete_port(format='json')
636
def test_delete_port_xml(self):
637
self._test_delete_port(format='xml')
639
def test_delete_port_alt_tenant(self):
640
self._test_delete_port(tenant=TENANT_2)
642
def test_delete_port_error_470(self):
643
self._test_delete_port(status=470)
645
def test_delete_port_error_401(self):
646
self._test_delete_port(status=401)
648
def test_delete_port_error_420(self):
649
self._test_delete_port(status=420)
651
def test_delete_port_error_430(self):
652
self._test_delete_port(status=430)
654
def test_delete_port_error_432(self):
655
self._test_delete_port(status=432)
657
def test_update_port_json(self):
658
self._test_update_port(format='json')
660
def test_update_port_xml(self):
661
self._test_update_port(format='xml')
663
def test_update_port_alt_tenant(self):
664
self._test_update_port(tenant=TENANT_2)
666
def test_update_port_error_470(self):
667
self._test_update_port(status=470)
669
def test_update_port_error_401(self):
670
self._test_update_port(status=401)
672
def test_update_port_error_400(self):
673
self._test_update_port(status=400)
675
def test_update_port_error_420(self):
676
self._test_update_port(status=420)
678
def test_update_port_error_430(self):
679
self._test_update_port(status=430)
681
def test_update_port_error_431(self):
682
self._test_update_port(status=431)
684
def test_show_port_attachment_json(self):
685
self._test_show_port_attachment(format='json')
687
def test_show_port_attachment_xml(self):
688
self._test_show_port_attachment(format='xml')
690
def test_show_port_attachment_alt_tenant(self):
691
self._test_show_port_attachment(tenant=TENANT_2)
693
def test_show_port_attachment_error_470(self):
694
self._test_show_port_attachment(status=470)
696
def test_show_port_attachment_error_401(self):
697
self._test_show_port_attachment(status=401)
699
def test_show_port_attachment_error_400(self):
700
self._test_show_port_attachment(status=400)
702
def test_show_port_attachment_error_420(self):
703
self._test_show_port_attachment(status=420)
705
def test_show_port_attachment_error_430(self):
706
self._test_show_port_attachment(status=430)
708
def test_attach_resource_json(self):
709
self._test_attach_resource(format='json')
711
def test_attach_resource_xml(self):
712
self._test_attach_resource(format='xml')
714
def test_attach_resource_alt_tenant(self):
715
self._test_attach_resource(tenant=TENANT_2)
717
def test_attach_resource_error_470(self):
718
self._test_attach_resource(status=470)
720
def test_attach_resource_error_401(self):
721
self._test_attach_resource(status=401)
723
def test_attach_resource_error_400(self):
724
self._test_attach_resource(status=400)
726
def test_attach_resource_error_420(self):
727
self._test_attach_resource(status=420)
729
def test_attach_resource_error_430(self):
730
self._test_attach_resource(status=430)
732
def test_attach_resource_error_432(self):
733
self._test_attach_resource(status=432)
735
def test_attach_resource_error_440(self):
736
self._test_attach_resource(status=440)
738
def test_detach_resource_json(self):
739
self._test_detach_resource(format='json')
741
def test_detach_resource_xml(self):
742
self._test_detach_resource(format='xml')
744
def test_detach_resource_alt_tenant(self):
745
self._test_detach_resource(tenant=TENANT_2)
747
def test_detach_resource_error_470(self):
748
self._test_detach_resource(status=470)
750
def test_detach_resource_error_401(self):
751
self._test_detach_resource(status=401)
753
def test_detach_resource_error_420(self):
754
self._test_detach_resource(status=420)
756
def test_detach_resource_error_430(self):
757
self._test_detach_resource(status=430)
759
def test_ssl_certificates(self):
760
self._test_ssl_certificates()
762
def test_connection_retry_failure(self):
763
self.client = Client(port=55555, tenant=TENANT_1, retries=1,
766
self.client.list_networks()
767
except exceptions.ConnectionFailed as exc:
768
self.assertTrue('Maximum attempts reached' in str(exc))
770
self.fail('ConnectionFailed not raised')