1
# Copyright 2015 Rackspace US Inc.
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 oslo_log import log as logging
17
from tempest_lib.common.utils import data_utils
18
from tempest_lib import exceptions as ex
20
from neutron_lbaas.tests.tempest.lib import config
21
from neutron_lbaas.tests.tempest.lib import test
22
from neutron_lbaas.tests.tempest.v2.api import base
26
LOG = logging.getLogger(__name__)
29
class MemberTestJSON(base.BaseTestCase):
32
Test the following operations in Neutron-LBaaS API using the
33
REST client for members:
35
list members of a pool
36
create a member of a Pool
42
def resource_setup(cls):
43
super(MemberTestJSON, cls).resource_setup()
44
if not test.is_extension_enabled("lbaas", "network"):
45
msg = "lbaas extension not enabled."
46
raise cls.skipException(msg)
47
network_name = data_utils.rand_name('network-')
48
cls.network = cls.create_network(network_name)
49
cls.subnet = cls.create_subnet(cls.network)
50
cls.tenant_id = cls.subnet.get('tenant_id')
51
cls.subnet_id = cls.subnet.get('id')
52
cls.load_balancer = cls._create_active_load_balancer(
53
tenant_id=cls.tenant_id,
54
vip_subnet_id=cls.subnet.get('id'))
55
cls.load_balancer_id = cls.load_balancer.get("id")
56
cls.listener = cls._create_listener(
57
loadbalancer_id=cls.load_balancer.get('id'),
58
protocol='HTTP', protocol_port=80)
59
cls.listener_id = cls.listener.get('id')
60
cls.pool = cls._create_pool(protocol='HTTP',
61
tenant_id=cls.tenant_id,
62
lb_algorithm='ROUND_ROBIN',
63
listener_id=cls.listener_id)
64
cls.pool_id = cls.pool.get('id')
67
def resource_cleanup(cls):
68
super(MemberTestJSON, cls).resource_cleanup()
70
@test.attr(type='smoke')
71
def test_list_empty_members(self):
72
"""Test that pool members are empty."""
73
members = self.members_client.list_members(self.pool_id)
74
self.assertEmpty(members,
75
msg='Initial pool was supposed to be empty')
77
@test.attr(type='smoke')
78
def test_list_3_members(self):
79
"""Test that we can list members. """
80
member_ips_exp = set([u"127.0.0.0", u"127.0.0.1", u"127.0.0.2"])
81
for ip in member_ips_exp:
82
member_opts = self.build_member_opts()
83
member_opts["address"] = ip
84
self._create_member(self.pool_id, **member_opts)
85
members = self.members_client.list_members(self.pool_id)
86
self.assertEqual(3, len(members))
87
for member in members:
88
self.assertEqual(member["tenant_id"], self.tenant_id)
89
self.assertEqual(member["protocol_port"], 80)
90
self.assertEqual(member["subnet_id"], self.subnet_id)
91
found_member_ips = set([m["address"] for m in members])
92
self.assertEqual(found_member_ips, member_ips_exp)
93
for member in members:
94
self._delete_member(self.pool_id,
97
@test.attr(type='smoke')
98
def test_add_member(self):
99
"""Test that we can add a single member."""
100
expect_empty_members = self.members_client.list_members(self.pool_id)
101
self.assertEmpty(expect_empty_members)
102
member_opts = self.build_member_opts()
103
member = self._create_member(self.pool_id, **member_opts)
104
member_id = member.get("id")
105
self.assertEqual(member_opts["address"], member["address"])
106
self.assertEqual(self.tenant_id, member["tenant_id"])
107
self.assertEqual(80, member["protocol_port"])
108
self.assertEqual(self.subnet_id, member["subnet_id"])
109
# Should have default values for admin_state_up and weight
110
self.assertEqual(True, member["admin_state_up"])
111
self.assertEqual(1, member["weight"])
112
self._delete_member(self.pool_id, member_id)
113
self.assertEmpty(self.members_client.list_members(self.pool_id))
115
@test.attr(type='smoke')
116
def test_get_member(self):
117
"""Test that we can fetch a member by id."""
118
member_opts = self.build_member_opts()
119
member_id = self._create_member(self.pool_id,
121
member = self.members_client.get_member(self.pool_id, member_id)
122
self.assertEqual(member_id, member["id"])
123
self.assertEqual(member_opts["address"], member["address"])
124
self.assertEqual(member_opts["tenant_id"], member["tenant_id"])
125
self.assertEqual(member_opts["protocol_port"], member["protocol_port"])
126
self.assertEqual(member_opts["subnet_id"], member["subnet_id"])
127
self._delete_member(self.pool_id, member_id)
128
self.assertEmpty(self.members_client.list_members(self.pool_id))
130
@test.attr(type='smoke')
131
def test_create_member_missing_required_field_tenant_id(self):
132
"""Test if a non_admin user can create a member with tenant_id
136
member_opts['address'] = "127.0.0.1"
137
member_opts['protocol_port'] = 80
138
member_opts['subnet_id'] = self.subnet_id
139
member = self._create_member(self.pool_id, **member_opts)
140
self._delete_member(self.pool_id, member['id'])
141
self.assertEmpty(self.members_client.list_members(self.pool_id))
143
@test.attr(type='negative')
144
def test_create_member_missing_required_field_address(self):
145
"""Test create a member with missing field address"""
147
member_opts['protocol_port'] = 80
148
member_opts['subnet_id'] = self.subnet_id
149
self.assertRaises(ex.BadRequest, self._create_member,
150
self.pool_id, **member_opts)
152
@test.attr(type='negative')
153
def test_create_member_missing_required_field_protocol_port(self):
154
"""Test create a member with missing field protocol_port"""
156
member_opts['address'] = "127.0.0.1"
157
member_opts['subnet_id'] = self.subnet_id
158
self.assertRaises(ex.BadRequest, self._create_member,
159
self.pool_id, **member_opts)
161
@test.attr(type='negative')
162
def test_create_member_missing_required_field_subnet_id(self):
163
"""Test create a member with missing field subnet_id """
165
member_opts['protocol_port'] = 80
166
member_opts['address'] = "127.0.0.1"
167
self.assertRaises(ex.BadRequest, self._create_member,
168
self.pool_id, **member_opts)
170
@test.attr(type='negative')
171
def test_raises_BadRequest_when_missing_attrs_during_member_create(self):
172
"""Test failure on missing attributes on member create."""
174
self.assertRaises(ex.BadRequest, self._create_member,
175
self.pool_id, **member_opts)
177
@test.attr(type='negative')
178
def test_create_member_invalid_tenant_id(self):
179
"""Test create member with invalid tenant_id"""
181
member_opts['address'] = "127.0.0.1"
182
member_opts['protocol_port'] = 80
183
member_opts['subnet_id'] = self.subnet_id
184
member_opts['tenant_id'] = "$232!$pw"
185
self.assertRaises(ex.BadRequest, self._create_member,
186
self.pool_id, **member_opts)
188
@test.attr(type='negative')
189
def test_create_member_invalid_address(self):
190
"""Test create member with invalid address"""
192
member_opts['address'] = "127$%<ki"
193
member_opts['protocol_port'] = 80
194
member_opts['subnet_id'] = self.subnet_id
195
self.assertRaises(ex.BadRequest, self._create_member,
196
self.pool_id, **member_opts)
198
@test.attr(type='negative')
199
def test_create_member_invalid_protocol_port(self):
200
"""Test create member with invalid protocol_port"""
202
member_opts['address'] = "127.0.0.1"
203
member_opts['protocol_port'] = 8090000
204
member_opts['subnet_id'] = self.subnet_id
205
self.assertRaises(ex.BadRequest, self._create_member,
206
self.pool_id, **member_opts)
208
@test.attr(type='negative')
209
def test_create_member_invalid_subnet_id(self):
210
"""Test create member with invalid subnet_id"""
212
member_opts['address'] = "127.0.0.1"
213
member_opts['protocol_port'] = 80
214
member_opts['subnet_id'] = "45k%^"
215
self.assertRaises(ex.BadRequest, self._create_member,
216
self.pool_id, **member_opts)
218
@test.attr(type='negative')
219
def test_create_member_invalid_admin_state_up(self):
220
"""Test create member with invalid admin_state_up"""
222
member_opts['address'] = "127.0.0.1"
223
member_opts['protocol_port'] = 80
224
member_opts['subnet_id'] = self.subnet_id
225
member_opts['admin_state_up'] = "$232!$pw"
226
self.assertRaises(ex.BadRequest, self._create_member,
227
self.pool_id, **member_opts)
229
@test.attr(type='negative')
230
def test_create_member_invalid_weight(self):
231
"""Test create member with invalid weight"""
233
member_opts['address'] = "127.0.0.1"
234
member_opts['protocol_port'] = 80
235
member_opts['subnet_id'] = self.subnet_id
236
member_opts['weight'] = "$232!$pw"
237
self.assertRaises(ex.BadRequest, self._create_member,
238
self.pool_id, **member_opts)
240
@test.attr(type='negative')
241
def test_create_member_empty_tenant_id(self):
242
"""Test create member with an empty tenant_id"""
244
member_opts['address'] = "127.0.0.1"
245
member_opts['protocol_port'] = 80
246
member_opts['subnet_id'] = self.subnet_id
247
member_opts['tenant_id'] = ""
248
self.assertRaises(ex.BadRequest, self._create_member,
249
self.pool_id, **member_opts)
251
@test.attr(type='negative')
252
def test_create_member_empty_address(self):
253
"""Test create member with an empty address"""
255
member_opts['address'] = ""
256
member_opts['protocol_port'] = 80
257
member_opts['subnet_id'] = self.subnet_id
258
self.assertRaises(ex.BadRequest, self._create_member,
259
self.pool_id, **member_opts)
261
@test.attr(type='negative')
262
def test_create_member_empty_protocol_port(self):
263
"""Test create member with an empty protocol_port"""
265
member_opts['address'] = "127.0.0.1"
266
member_opts['protocol_port'] = ""
267
member_opts['subnet_id'] = self.subnet_id
268
self.assertRaises(ex.BadRequest, self._create_member,
269
self.pool_id, **member_opts)
271
@test.attr(type='negative')
272
def test_create_member_empty_subnet_id(self):
273
"""Test create member with empty subnet_id"""
275
member_opts['address'] = "127.0.0.1"
276
member_opts['protocol_port'] = 80
277
member_opts['subnet_id'] = ""
278
self.assertRaises(ex.BadRequest, self._create_member,
279
self.pool_id, **member_opts)
281
@test.attr(type='negative')
282
def test_create_member_empty_admin_state_up(self):
283
"""Test create member with an empty admin_state_up"""
285
member_opts['address'] = "127.0.0.1"
286
member_opts['protocol_port'] = 80
287
member_opts['subnet_id'] = self.subnet_id
288
member_opts['admin_state_up'] = ""
289
self.assertRaises(ex.BadRequest, self._create_member,
290
self.pool_id, **member_opts)
292
@test.attr(type='negative')
293
def test_create_member_empty_weight(self):
294
"""Test create member with an empty weight"""
296
member_opts['address'] = "127.0.0.1"
297
member_opts['protocol_port'] = 80
298
member_opts['subnet_id'] = self.subnet_id
299
member_opts['weight'] = ""
300
self.assertRaises(ex.BadRequest, self._create_member,
301
self.pool_id, **member_opts)
303
@test.attr(type='smoke')
304
def test_delete_member(self):
305
"""Test that we can delete a member by id."""
306
member_opts = self.build_member_opts()
307
member_id = self._create_member(self.pool_id,
309
members = self.members_client.list_members(self.pool_id)
310
self.assertEqual(1, len(members))
311
self._delete_member(self.pool_id, member_id)
312
members = self.members_client.list_members(self.pool_id)
313
self.assertEmpty(members)
315
@test.attr(type='smoke')
316
def test_update_member(self):
317
"""Test that we can update a member."""
318
member_opts = self.build_member_opts()
319
member = self._create_member(self.pool_id,
321
member_id = member["id"]
322
# Make sure the defaults are correct
323
self.assertEqual(True, member["admin_state_up"])
324
self.assertEqual(1, member["weight"])
325
# Lets overwrite the defaults
326
member_opts = {"weight": 10, "admin_state_up": False}
327
member = self._update_member(self.pool_id, member_id,
329
# And make sure they stick
330
self.assertEqual(False, member["admin_state_up"])
331
self.assertEqual(10, member["weight"])
332
self._delete_member(self.pool_id, member["id"])
333
members = self.members_client.list_members(self.pool_id)
334
self.assertEmpty(members)
336
@test.attr(type='smoke')
337
def test_update_member_missing_admin_state_up(self):
338
"""Test that we can update a member with missing admin_state_up."""
339
member_opts = self.build_member_opts()
340
member = self._create_member(self.pool_id,
342
member_id = member["id"]
343
self.assertEqual(True, member["admin_state_up"])
344
self.assertEqual(1, member["weight"])
345
member_opts = {"weight": 10}
346
member = self._update_member(self.pool_id, member_id,
348
self.assertEqual(True, member["admin_state_up"])
349
self.assertEqual(10, member["weight"])
350
self._delete_member(self.pool_id, member["id"])
351
members = self.members_client.list_members(self.pool_id)
352
self.assertEmpty(members)
354
@test.attr(type='smoke')
355
def test_update_member_missing_weight(self):
356
"""Test that we can update a member with missing weight."""
357
member_opts = self.build_member_opts()
358
member = self._create_member(self.pool_id,
360
member_id = member["id"]
361
self.assertEqual(True, member["admin_state_up"])
362
self.assertEqual(1, member["weight"])
363
member_opts = {"admin_state_up": False}
364
member = self._update_member(self.pool_id, member_id,
366
self.assertEqual(False, member["admin_state_up"])
367
self.assertEqual(1, member["weight"])
368
self._delete_member(self.pool_id, member["id"])
369
members = self.members_client.list_members(self.pool_id)
370
self.assertEmpty(members)
372
@test.attr(type='negative')
373
def test_update_member_invalid_admin_state_up(self):
374
"""Test that we can update a member with empty admin_state_up."""
375
member_opts = self.build_member_opts()
376
member = self._create_member(self.pool_id,
378
member_id = member["id"]
379
self.assertEqual(True, member["admin_state_up"])
380
self.assertEqual(1, member["weight"])
381
member_opts = {"weight": 10, "admin_state_up": "%^67"}
382
self.assertRaises(ex.BadRequest, self._update_member,
383
self.pool_id, member_id, **member_opts)
384
self._delete_member(self.pool_id, member["id"])
385
members = self.members_client.list_members(self.pool_id)
386
self.assertEmpty(members)
388
@test.attr(type='negative')
389
def test_update_member_invalid_weight(self):
390
"""Test that we can update a member with an empty weight."""
391
member_opts = self.build_member_opts()
392
member = self._create_member(self.pool_id,
394
member_id = member["id"]
395
self.assertEqual(True, member["admin_state_up"])
396
self.assertEqual(1, member["weight"])
397
member_opts = {"admin_state_up": False, "weight": "*^$df"}
398
self.assertRaises(ex.BadRequest, self._update_member,
399
self.pool_id, member_id, **member_opts)
400
self._delete_member(self.pool_id, member["id"])
401
members = self.members_client.list_members(self.pool_id)
402
self.assertEmpty(members)
404
@test.attr(type='negative')
405
def test_update_member_empty_admin_state_up(self):
406
"""Test that we can update a member with empty admin_state_up."""
407
member_opts = self.build_member_opts()
408
member = self._create_member(self.pool_id,
410
member_id = member["id"]
411
self.assertEqual(True, member["admin_state_up"])
412
self.assertEqual(1, member["weight"])
413
member_opts = {"weight": 10, "admin_state_up": ""}
414
self.assertRaises(ex.BadRequest, self._update_member,
415
self.pool_id, member_id, **member_opts)
416
self._delete_member(self.pool_id, member["id"])
417
members = self.members_client.list_members(self.pool_id)
418
self.assertEmpty(members)
420
@test.attr(type='negative')
421
def test_update_member_empty_weight(self):
422
"""Test that we can update a member with an empty weight."""
423
member_opts = self.build_member_opts()
424
member = self._create_member(self.pool_id,
426
member_id = member["id"]
427
self.assertEqual(True, member["admin_state_up"])
428
self.assertEqual(1, member["weight"])
429
member_opts = {"admin_state_up": False, "weight": ""}
430
self.assertRaises(ex.BadRequest, self._update_member,
431
self.pool_id, member_id, **member_opts)
432
self._delete_member(self.pool_id, member["id"])
433
members = self.members_client.list_members(self.pool_id)
434
self.assertEmpty(members)
436
@test.attr(type='negative')
437
def test_raises_immutable_when_updating_immutable_attrs_on_member(self):
438
"""Test failure on immutable attribute on member create."""
439
member_opts = self.build_member_opts()
440
member_id = self._create_member(self.pool_id,
442
member_opts = {"address": "127.0.0.69"}
443
# The following code actually raises a 400 instead of a 422 as expected
444
# Will need to consult with blogan as to what to fix
445
self.assertRaises(ex.BadRequest, self._update_member,
446
self.pool_id, member_id, **member_opts)
447
self._delete_member(self.pool_id, member_id)
448
members = self.members_client.list_members(self.pool_id)
449
self.assertEmpty(members)
451
@test.attr(type='negative')
452
def test_raises_exception_on_invalid_attr_on_create(self):
453
"""Test failure on invalid attribute on member create."""
454
member_opts = self.build_member_opts()
455
member_opts["invalid_op"] = "should_break_request"
456
self.assertRaises(ex.BadRequest, self._create_member,
457
self.pool_id, **member_opts)
459
@test.attr(type='negative')
460
def test_raises_exception_on_invalid_attr_on_update(self):
461
"""Test failure on invalid attribute on member update."""
462
member_opts = self.build_member_opts()
463
member = self._create_member(self.pool_id, **member_opts)
464
member_id = member["id"]
465
member_opts["invalid_op"] = "watch_this_break"
466
self.assertRaises(ex.BadRequest, self._update_member,
467
self.pool_id, member_id, **member_opts)
468
self._delete_member(self.pool_id, member_id)
471
def build_member_opts(cls, **kw):
472
"""Build out default member dictionary """
473
opts = {"address": kw.get("address", "127.0.0.1"),
474
"tenant_id": kw.get("tenant_id", cls.tenant_id),
475
"protocol_port": kw.get("protocol_port", 80),
476
"subnet_id": kw.get("subnet_id", cls.subnet_id)}