1
# Copyright 2013 OpenStack Foundation
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
16
from tempest_lib.common.utils import data_utils
17
from tempest_lib import decorators
19
from neutron.tests.tempest.api.network import base
20
from neutron.tests.tempest import test
23
class LoadBalancerTestJSON(base.BaseNetworkTest):
26
Tests the following operations in the Neutron API using the REST client for
38
health monitoring operations
42
def resource_setup(cls):
43
super(LoadBalancerTestJSON, cls).resource_setup()
44
if not test.is_extension_enabled('lbaas', 'network'):
45
msg = "lbaas extension not enabled."
46
raise cls.skipException(msg)
47
cls.network = cls.create_network()
48
cls.name = cls.network['name']
49
cls.subnet = cls.create_subnet(cls.network)
50
pool_name = data_utils.rand_name('pool-')
51
vip_name = data_utils.rand_name('vip-')
52
cls.pool = cls.create_pool(pool_name, "ROUND_ROBIN",
54
cls.vip = cls.create_vip(name=vip_name,
59
cls.member = cls.create_member(80, cls.pool, cls._ip_version)
60
cls.member_address = ("10.0.9.47" if cls._ip_version == 4
62
cls.health_monitor = cls.create_health_monitor(delay=4,
67
def _check_list_with_filter(self, obj_name, attr_exceptions, **kwargs):
68
create_obj = getattr(self.client, 'create_' + obj_name)
69
delete_obj = getattr(self.client, 'delete_' + obj_name)
70
list_objs = getattr(self.client, 'list_' + obj_name + 's')
72
body = create_obj(**kwargs)
74
self.addCleanup(delete_obj, obj['id'])
75
for key, value in obj.iteritems():
76
# It is not relevant to filter by all arguments. That is why
77
# there is a list of attr to except
78
if key not in attr_exceptions:
79
body = list_objs(**{key: value})
80
objs = [v[key] for v in body[obj_name + 's']]
81
self.assertIn(value, objs)
83
@test.attr(type='smoke')
84
@test.idempotent_id('c96dbfab-4a80-4e74-a535-e950b5bedd47')
85
def test_list_vips(self):
86
# Verify the vIP exists in the list of all vIPs
87
body = self.client.list_vips()
89
self.assertIn(self.vip['id'], [v['id'] for v in vips])
91
@test.attr(type='smoke')
92
@test.idempotent_id('b8853f65-5089-4e69-befd-041a143427ff')
93
def test_list_vips_with_filter(self):
94
name = data_utils.rand_name('vip-')
95
body = self.client.create_pool(name=data_utils.rand_name("pool-"),
96
lb_method="ROUND_ROBIN",
98
subnet_id=self.subnet['id'])
100
self.addCleanup(self.client.delete_pool, pool['id'])
101
attr_exceptions = ['status', 'session_persistence',
102
'status_description']
103
self._check_list_with_filter(
104
'vip', attr_exceptions, name=name, protocol="HTTPS",
105
protocol_port=81, subnet_id=self.subnet['id'], pool_id=pool['id'],
106
description=data_utils.rand_name('description-'),
107
admin_state_up=False)
109
@test.attr(type='smoke')
110
@test.idempotent_id('27f56083-9af9-4a48-abe9-ca1bcc6c9035')
111
def test_create_update_delete_pool_vip(self):
113
name = data_utils.rand_name('vip-')
114
address = self.subnet['allocation_pools'][0]['end']
115
body = self.client.create_pool(
116
name=data_utils.rand_name("pool-"),
117
lb_method='ROUND_ROBIN',
119
subnet_id=self.subnet['id'])
121
body = self.client.create_vip(name=name,
124
subnet_id=self.subnet['id'],
129
# Confirm VIP's address correctness with a show
130
body = self.client.show_vip(vip_id)
132
self.assertEqual(address, vip['address'])
133
# Verification of vip update
135
new_description = "New description"
136
persistence_type = "HTTP_COOKIE"
137
update_data = {"session_persistence": {
138
"type": persistence_type}}
139
body = self.client.update_vip(vip_id,
141
description=new_description,
143
admin_state_up=False,
145
updated_vip = body['vip']
146
self.assertEqual(new_name, updated_vip['name'])
147
self.assertEqual(new_description, updated_vip['description'])
148
self.assertEqual(10, updated_vip['connection_limit'])
149
self.assertFalse(updated_vip['admin_state_up'])
150
self.assertEqual(persistence_type,
151
updated_vip['session_persistence']['type'])
152
self.client.delete_vip(vip['id'])
153
self.client.wait_for_resource_deletion('vip', vip['id'])
154
# Verification of pool update
155
new_name = "New_pool"
156
body = self.client.update_pool(pool['id'],
158
description="new_description",
159
lb_method='LEAST_CONNECTIONS')
160
updated_pool = body['pool']
161
self.assertEqual(new_name, updated_pool['name'])
162
self.assertEqual('new_description', updated_pool['description'])
163
self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method'])
164
self.client.delete_pool(pool['id'])
166
@test.attr(type='smoke')
167
@test.idempotent_id('0435a95e-1d19-4d90-9e9f-3b979e9ad089')
168
def test_show_vip(self):
169
# Verifies the details of a vip
170
body = self.client.show_vip(self.vip['id'])
172
for key, value in vip.iteritems():
173
# 'status' should not be confirmed in api tests
175
self.assertEqual(self.vip[key], value)
177
@test.attr(type='smoke')
178
@test.idempotent_id('6e7a7d31-8451-456d-b24a-e50479ce42a7')
179
def test_show_pool(self):
180
# Here we need to new pool without any dependence with vips
181
body = self.client.create_pool(name=data_utils.rand_name("pool-"),
182
lb_method='ROUND_ROBIN',
184
subnet_id=self.subnet['id'])
186
self.addCleanup(self.client.delete_pool, pool['id'])
187
# Verifies the details of a pool
188
body = self.client.show_pool(pool['id'])
189
shown_pool = body['pool']
190
for key, value in pool.iteritems():
191
# 'status' should not be confirmed in api tests
193
self.assertEqual(value, shown_pool[key])
195
@test.attr(type='smoke')
196
@test.idempotent_id('d1ab1ffa-e06a-487f-911f-56418cb27727')
197
def test_list_pools(self):
198
# Verify the pool exists in the list of all pools
199
body = self.client.list_pools()
200
pools = body['pools']
201
self.assertIn(self.pool['id'], [p['id'] for p in pools])
203
@test.attr(type='smoke')
204
@test.idempotent_id('27cc4c1a-caac-4273-b983-2acb4afaad4f')
205
def test_list_pools_with_filters(self):
206
attr_exceptions = ['status', 'vip_id', 'members', 'provider',
207
'status_description']
208
self._check_list_with_filter(
209
'pool', attr_exceptions, name=data_utils.rand_name("pool-"),
210
lb_method="ROUND_ROBIN", protocol="HTTPS",
211
subnet_id=self.subnet['id'],
212
description=data_utils.rand_name('description-'),
213
admin_state_up=False)
215
@test.attr(type='smoke')
216
@test.idempotent_id('282d0dfd-5c3a-4c9b-b39c-c99782f39193')
217
def test_list_members(self):
218
# Verify the member exists in the list of all members
219
body = self.client.list_members()
220
members = body['members']
221
self.assertIn(self.member['id'], [m['id'] for m in members])
223
@test.attr(type='smoke')
224
@test.idempotent_id('243b5126-24c6-4879-953e-7c7e32d8a57f')
225
def test_list_members_with_filters(self):
226
attr_exceptions = ['status', 'status_description']
227
self._check_list_with_filter('member', attr_exceptions,
228
address=self.member_address,
230
pool_id=self.pool['id'])
232
@test.attr(type='smoke')
233
@test.idempotent_id('fb833ee8-9e69-489f-b540-a409762b78b2')
234
def test_create_update_delete_member(self):
236
body = self.client.create_member(address=self.member_address,
238
pool_id=self.pool['id'])
239
member = body['member']
240
# Verification of member update
241
body = self.client.update_member(member['id'],
242
admin_state_up=False)
243
updated_member = body['member']
244
self.assertFalse(updated_member['admin_state_up'])
245
# Verification of member delete
246
self.client.delete_member(member['id'])
248
@test.attr(type='smoke')
249
@test.idempotent_id('893cd71f-a7dd-4485-b162-f6ab9a534914')
250
def test_show_member(self):
251
# Verifies the details of a member
252
body = self.client.show_member(self.member['id'])
253
member = body['member']
254
for key, value in member.iteritems():
255
# 'status' should not be confirmed in api tests
257
self.assertEqual(self.member[key], value)
259
@test.attr(type='smoke')
260
@test.idempotent_id('8e5822c5-68a4-4224-8d6c-a617741ebc2d')
261
def test_list_health_monitors(self):
262
# Verify the health monitor exists in the list of all health monitors
263
body = self.client.list_health_monitors()
264
health_monitors = body['health_monitors']
265
self.assertIn(self.health_monitor['id'],
266
[h['id'] for h in health_monitors])
268
@test.attr(type='smoke')
269
@test.idempotent_id('49bac58a-511c-4875-b794-366698211d25')
270
def test_list_health_monitors_with_filters(self):
271
attr_exceptions = ['status', 'status_description', 'pools']
272
self._check_list_with_filter('health_monitor', attr_exceptions,
273
delay=5, max_retries=4, type="TCP",
276
@test.attr(type='smoke')
277
@test.idempotent_id('e8ce05c4-d554-4d1e-a257-ad32ce134bb5')
278
def test_create_update_delete_health_monitor(self):
279
# Creates a health_monitor
280
body = self.client.create_health_monitor(delay=4,
284
health_monitor = body['health_monitor']
285
# Verification of health_monitor update
286
body = (self.client.update_health_monitor
287
(health_monitor['id'],
288
admin_state_up=False))
289
updated_health_monitor = body['health_monitor']
290
self.assertFalse(updated_health_monitor['admin_state_up'])
291
# Verification of health_monitor delete
292
body = self.client.delete_health_monitor(health_monitor['id'])
294
@test.attr(type='smoke')
295
@test.idempotent_id('d3e1aebc-06c2-49b3-9816-942af54012eb')
296
def test_create_health_monitor_http_type(self):
298
body = self.client.create_health_monitor(delay=4,
302
health_monitor = body['health_monitor']
303
self.addCleanup(self.client.delete_health_monitor,
304
health_monitor['id'])
305
self.assertEqual(hm_type, health_monitor['type'])
307
@test.attr(type='smoke')
308
@test.idempotent_id('0eff9f67-90fb-4bb1-b4ed-c5fda99fff0c')
309
def test_update_health_monitor_http_method(self):
310
body = self.client.create_health_monitor(delay=4,
314
health_monitor = body['health_monitor']
315
self.addCleanup(self.client.delete_health_monitor,
316
health_monitor['id'])
317
body = (self.client.update_health_monitor
318
(health_monitor['id'],
320
url_path="/home/user",
321
expected_codes="290"))
322
updated_health_monitor = body['health_monitor']
323
self.assertEqual("POST", updated_health_monitor['http_method'])
324
self.assertEqual("/home/user", updated_health_monitor['url_path'])
325
self.assertEqual("290", updated_health_monitor['expected_codes'])
327
@test.attr(type='smoke')
328
@test.idempotent_id('08e126ab-1407-483f-a22e-b11cc032ca7c')
329
def test_show_health_monitor(self):
330
# Verifies the details of a health_monitor
331
body = self.client.show_health_monitor(self.health_monitor['id'])
332
health_monitor = body['health_monitor']
333
for key, value in health_monitor.iteritems():
334
# 'status' should not be confirmed in api tests
336
self.assertEqual(self.health_monitor[key], value)
338
@test.attr(type='smoke')
339
@test.idempotent_id('87f7628e-8918-493d-af50-0602845dbb5b')
340
def test_associate_disassociate_health_monitor_with_pool(self):
341
# Verify that a health monitor can be associated with a pool
342
self.client.associate_health_monitor_with_pool(
343
self.health_monitor['id'], self.pool['id'])
344
body = self.client.show_health_monitor(
345
self.health_monitor['id'])
346
health_monitor = body['health_monitor']
347
body = self.client.show_pool(self.pool['id'])
349
self.assertIn(pool['id'],
350
[p['pool_id'] for p in health_monitor['pools']])
351
self.assertIn(health_monitor['id'], pool['health_monitors'])
352
# Verify that a health monitor can be disassociated from a pool
353
(self.client.disassociate_health_monitor_with_pool
354
(self.health_monitor['id'], self.pool['id']))
355
body = self.client.show_pool(self.pool['id'])
357
body = self.client.show_health_monitor(
358
self.health_monitor['id'])
359
health_monitor = body['health_monitor']
360
self.assertNotIn(health_monitor['id'], pool['health_monitors'])
361
self.assertNotIn(pool['id'],
362
[p['pool_id'] for p in health_monitor['pools']])
364
@test.attr(type='smoke')
365
@test.idempotent_id('525fc7dc-be24-408d-938d-822e9783e027')
366
def test_get_lb_pool_stats(self):
367
# Verify the details of pool stats
368
body = self.client.list_lb_pool_stats(self.pool['id'])
369
stats = body['stats']
370
self.assertIn("bytes_in", stats)
371
self.assertIn("total_connections", stats)
372
self.assertIn("active_connections", stats)
373
self.assertIn("bytes_out", stats)
375
@test.attr(type='smoke')
376
@test.idempotent_id('66236be2-5121-4047-8cde-db4b83b110a5')
377
def test_update_list_of_health_monitors_associated_with_pool(self):
378
(self.client.associate_health_monitor_with_pool
379
(self.health_monitor['id'], self.pool['id']))
380
self.client.update_health_monitor(
381
self.health_monitor['id'], admin_state_up=False)
382
body = self.client.show_pool(self.pool['id'])
383
health_monitors = body['pool']['health_monitors']
384
for health_monitor_id in health_monitors:
385
body = self.client.show_health_monitor(health_monitor_id)
386
self.assertFalse(body['health_monitor']['admin_state_up'])
387
(self.client.disassociate_health_monitor_with_pool
388
(self.health_monitor['id'], self.pool['id']))
390
@test.attr(type='smoke')
391
@test.idempotent_id('44ec9b40-b501-41e2-951f-4fc673b15ac0')
392
def test_update_admin_state_up_of_pool(self):
393
self.client.update_pool(self.pool['id'],
394
admin_state_up=False)
395
body = self.client.show_pool(self.pool['id'])
397
self.assertFalse(pool['admin_state_up'])
399
@test.attr(type='smoke')
400
@test.idempotent_id('466a9d4c-37c6-4ea2-b807-133437beb48c')
401
def test_show_vip_associated_with_pool(self):
402
body = self.client.show_pool(self.pool['id'])
404
body = self.client.show_vip(pool['vip_id'])
406
self.assertEqual(self.vip['name'], vip['name'])
407
self.assertEqual(self.vip['id'], vip['id'])
409
@test.attr(type='smoke')
410
@test.idempotent_id('7b97694e-69d0-4151-b265-e1052a465aa8')
411
def test_show_members_associated_with_pool(self):
412
body = self.client.show_pool(self.pool['id'])
413
members = body['pool']['members']
414
for member_id in members:
415
body = self.client.show_member(member_id)
416
self.assertIsNotNone(body['member']['status'])
417
self.assertEqual(member_id, body['member']['id'])
418
self.assertIsNotNone(body['member']['admin_state_up'])
420
@test.attr(type='smoke')
421
@test.idempotent_id('73ed6f27-595b-4b2c-969c-dbdda6b8ab34')
422
def test_update_pool_related_to_member(self):
424
body = self.client.create_pool(name=data_utils.rand_name("pool-"),
425
lb_method='ROUND_ROBIN',
427
subnet_id=self.subnet['id'])
428
new_pool = body['pool']
429
self.addCleanup(self.client.delete_pool, new_pool['id'])
430
# Update member with new pool's id
431
body = self.client.update_member(self.member['id'],
432
pool_id=new_pool['id'])
433
# Confirm with show that pool_id change
434
body = self.client.show_member(self.member['id'])
435
member = body['member']
436
self.assertEqual(member['pool_id'], new_pool['id'])
437
# Update member with old pool id, this is needed for clean up
438
body = self.client.update_member(self.member['id'],
439
pool_id=self.pool['id'])
441
@test.attr(type='smoke')
442
@test.idempotent_id('cf63f071-bbe3-40ba-97a0-a33e11923162')
443
def test_update_member_weight(self):
444
self.client.update_member(self.member['id'],
446
body = self.client.show_member(self.member['id'])
447
member = body['member']
448
self.assertEqual(2, member['weight'])
451
@decorators.skip_because(bug="1402007")
452
class LoadBalancerIpV6TestJSON(LoadBalancerTestJSON):