Merge "tempest: lbaas l7-switching API tests"

This commit is contained in:
Jenkins 2016-11-16 21:03:30 +00:00 committed by Gerrit Code Review
commit 2cbe06fe18
5 changed files with 353 additions and 16 deletions

View File

@ -38,6 +38,10 @@ from vmware_nsx_tempest.services.lbaas import pools_client
CONF = config.CONF CONF = config.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
NO_ROUTER_TYPE = CONF.nsxv.no_router_type NO_ROUTER_TYPE = CONF.nsxv.no_router_type
L7_POLICY_ACTIONS = ('REJECT', 'REDIRECT_TO_URL', 'REDIRECT_TO_POOL')
L7_RULE_TYPES = ('HOSTNAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE')
L7_RULE_COMPARISON_TYPES = ('REGEXP', 'STARTS_WITH', 'ENDS_WITH',
'CONTAINS', 'EQUAL_TO')
class BaseTestCase(base.BaseNetworkTest): class BaseTestCase(base.BaseNetworkTest):
@ -373,6 +377,75 @@ class BaseTestCase(base.BaseNetworkTest):
member_list = members.get('members', members) member_list = members.get('members', members)
return member_list return member_list
@classmethod
def _create_l7policy(cls, wait=True, **kwargs):
l7policy = cls.l7policies_client.create_l7policy(**kwargs)
l7policy = l7policy.get('l7policy', l7policy)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
return l7policy
@classmethod
def _delete_l7policy(cls, policy_id, wait=True):
cls.l7policies_client.delete_l7policy(policy_id)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
@classmethod
def _update_l7policy(cls, policy_id, wait=True, **kwargs):
l7policy = cls.l7policies_client.update_l7policy(policy_id, **kwargs)
l7policy = l7policy.get('l7policy', l7policy)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
return l7policy
@classmethod
def _show_l7policy(cls, policy_id, **fields):
l7policy = cls.l7policies_client.show_l7policy(policy_id, **fields)
l7policy = l7policy.get('l7policy', l7policy)
return l7policy
@classmethod
def _list_l7policies(cls, **filters):
l7policies = cls.l7policies_client.list_l7policies(**filters)
l7policies = l7policies.get('l7policies', l7policies)
return l7policies
@classmethod
def _create_l7rule(cls, policy_id, wait=True, **kwargs):
l7rule = cls.l7rules_client.create_l7rule(policy_id, **kwargs)
l7rule = l7rule.get('rule', l7rule)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
return l7rule
@classmethod
def _delete_l7rule(cls, policy_id, rule_id, wait=True):
cls.l7rules_client.delete_l7rule(policy_id, rule_id)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
@classmethod
def _update_l7rule(cls, policy_id, rule_id, wait=True, **kwargs):
l7rule = cls.l7rules_client.update_l7rule(policy_id, rule_id,
**kwargs)
l7rule = l7rule.get('rule', l7rule)
if wait:
cls._wait_for_load_balancer_status(cls.load_balancer.get('id'))
return l7rule
@classmethod
def _show_l7rule(cls, policy_id, rule_id, **fields):
l7rule = cls.l7rules_client.show_l7rule(policy_id, rule_id, **fields)
l7rule = l7rule.get('rule', l7rule)
return l7rule
@classmethod
def _list_l7rules(cls, policy_id, **filters):
l7rules = cls.l7rules_client.list_l7rules(policy_id, **filters)
l7rules = l7rules.get('rules', l7rules)
return l7rules
@classmethod @classmethod
def _check_status_tree(cls, load_balancer_id, listener_ids=None, def _check_status_tree(cls, load_balancer_id, listener_ids=None,
pool_ids=None, health_monitor_id=None, pool_ids=None, health_monitor_id=None,

View File

@ -0,0 +1,157 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest import config
from tempest import test
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
PROTOCOL_PORT = 80
class TestL7Policies(base.BaseTestCase):
@classmethod
def skip_checks(cls):
super(TestL7Policies, cls).skip_checks()
if '1739510' in CONF.nsxv.bugs_to_resolve:
msg = ("skip lbaas_l7_switching_ops because bug=1739150"
" -- l7 switching is not supported")
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(TestL7Policies, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'),
wait=True)
cls.loadbalancer_id = cls.load_balancer.get('id')
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
cls.pool7 = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
loadbalancer_id=cls.loadbalancer_id)
cls.pool7_id = cls.pool7.get('id')
@classmethod
def resource_cleanup(cls):
super(TestL7Policies, cls).resource_cleanup()
def remove_all_policies(self):
policies = self._list_l7policies()
for policy in policies:
self._delete_l7policy(policy.get('id'))
policies = self._list_l7policies()
self.assertEmpty(policies)
def create_to_pool_policy(self, to_position=None, name='policy-pool'):
policy_kwargs = dict(
action='REDIRECT_TO_POOL', name=name,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
def create_to_url_policy(self, redirect_url=None, to_position=None,
name='policy-url'):
policy_kwargs = dict(
action='REDIRECT_TO_URL', name=name,
redirect_url=redirect_url,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
def create_reject_policy(self, to_position=1, name='policy-reject'):
policy_kwargs = dict(
action='REJECT', name=name,
redirect_pool_id=self.pool7_id,
listener_id=self.listener_id)
if to_position:
policy_kwargs['position'] = to_position
policy = self._create_l7policy(**policy_kwargs)
self.assertEqual(policy.get('name'), name)
self.assertEqual(policy.get('listener_id'), self.listener_id)
self.assertEqual(policy.get('redirect_pool_id'), self.pool7_id)
return policy
@test.idempotent_id('465c9bea-53de-4a1f-ae00-fa2ee52d250b')
def test_l7policies_crud_ops(self):
policy = self.create_to_pool_policy()
# update
new_policy_name = policy.get('name') + "-update"
policy2 = self._update_l7policy(policy.get('id'),
name=new_policy_name)
self.assertEqual(policy2.get('name'), new_policy_name)
# show
s_policy = self._show_l7policy(policy.get('id'))
self.assertEqual(policy2.get('name'), s_policy.get('name'))
# list
policies = self._list_l7policies()
policy_id_list = [x.get('id') for x in policies]
self.assertIn(policy.get('id'), policy_id_list)
# delete
self._delete_l7policy(policy.get('id'))
policies = self._list_l7policies()
policy_id_list = [x.get('id') for x in policies]
self.assertNotIn(policy.get('id'), policy_id_list)
@test.idempotent_id('726588f4-970a-4f32-8253-95766ddaa7b4')
def test_policy_position(self):
self.remove_all_policies()
policy1 = self.create_to_pool_policy()
self.assertEqual(policy1.get('position'), 1)
# create reject_policy at position=1
policy2 = self.create_reject_policy(to_position=1)
self.assertEqual(policy2.get('position'), 1)
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 2)
# create to_url_policy at position=2
policy3 = self.create_to_url_policy(to_position=2)
self.assertEqual(policy3.get('position'), 2)
policy2A = self._show_l7policy(policy2.get('id'))
self.assertEqual(policy2A.get('position'), 1)
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 3)
# delete policy3, policy1 position==2
self._delete_l7policy(policy3.get('id'))
policy1A = self._show_l7policy(policy1.get('id'))
self.assertEqual(policy1A.get('position'), 2)
policy2A = self._show_l7policy(policy2.get('id'))
self.assertEqual(policy2A.get('position'), 1)
self._delete_l7policy(policy2.get('id'))
policies = self._list_l7policies()
self.assertEqual(len(policies), 1)
self.assertEqual(policy1.get('id'), policies[0].get('id'))
self._delete_l7policy(policy1.get('id'))
policies = self._list_l7policies()
self.assertEmpty(policies)

View File

@ -0,0 +1,89 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest import config
from tempest import test
from vmware_nsx_tempest.tests.nsxv.api.lbaas import base
CONF = config.CONF
PROTOCOL_PORT = 80
class TestL7Rules(base.BaseTestCase):
@classmethod
def skip_checks(cls):
super(TestL7Rules, cls).skip_checks()
if '1739510' in CONF.nsxv.bugs_to_resolve:
msg = ("skip lbaas_l7_switching_ops because bug=1739150"
" -- l7 switching is not supported")
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(TestL7Rules, cls).resource_setup()
cls.load_balancer = cls._create_load_balancer(
tenant_id=cls.subnet.get('tenant_id'),
vip_subnet_id=cls.subnet.get('id'),
wait=True)
cls.loadbalancer_id = cls.load_balancer.get('id')
cls.listener = cls._create_listener(
loadbalancer_id=cls.load_balancer.get('id'),
protocol='HTTP', protocol_port=80)
cls.listener_id = cls.listener.get('id')
cls.pool = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
listener_id=cls.listener_id)
cls.pool_id = cls.pool.get('id')
cls.pool7 = cls._create_pool(protocol='HTTP',
tenant_id=cls.tenant_id,
lb_algorithm='ROUND_ROBIN',
loadbalancer_id=cls.loadbalancer_id)
cls.pool7_id = cls.pool7.get('id')
cls.policy7 = cls._create_l7policy(action='REDIRECT_TO_POOL',
name='policy1',
redirect_pool_id=cls.pool7_id,
listener_id=cls.listener_id)
cls.policy7_id = cls.policy7.get('id')
@classmethod
def resource_cleanup(cls):
super(TestL7Rules, cls).resource_cleanup()
@test.idempotent_id('27e8a3a1-bd3a-40e5-902d-fe9bc79ebf1f')
def test_l7rules_crud_ops(self):
rule = self._create_l7rule(self.policy7_id,
type='PATH',
compare_type='STARTS_WITH',
value='/api')
self.assertEqual(rule.get('compare_type'), 'STARTS_WITH')
self.assertEqual(rule.get('value'), '/api')
self.assertEqual(rule.get('type'), 'PATH')
# update
new_value = '/v2/api'
rule2 = self._update_l7rule(self.policy7_id, rule.get('id'),
value=new_value)
self.assertEqual(rule2.get('value'), new_value)
# show
s_rule = self._show_l7rule(self.policy7_id, rule.get('id'))
self.assertEqual(s_rule.get('value'), new_value)
# list
rules = self._list_l7rules(self.policy7_id)
rule_id_list = [x.get('id') for x in rules]
self.assertIn(rule.get('id'), rule_id_list)
# delete
self._delete_l7rule(self.policy7_id, rule.get('id'))
rules = self._list_l7rules(self.policy7_id)
rule_id_list = [x.get('id') for x in rules]
self.assertNotIn(rule.get('id'), rule_id_list)

View File

@ -11,7 +11,6 @@
# under the License. # under the License.
import time import time
from tempest import config
from tempest import test from tempest import test
from vmware_nsx_tempest.services.lbaas import l7policies_client from vmware_nsx_tempest.services.lbaas import l7policies_client
@ -19,10 +18,9 @@ from vmware_nsx_tempest.services.lbaas import l7rules_client
from vmware_nsx_tempest.tests.nsxv.scenario import ( from vmware_nsx_tempest.tests.nsxv.scenario import (
test_lbaas_round_robin_ops as lbaas_ops) test_lbaas_round_robin_ops as lbaas_ops)
CONF = config.CONF
class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest): class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
"""This test validates lbaas l7 switching with round-robin opertion. """This test validates lbaas l7 switching with round-robin opertion.
Test leverage test_lbaas_round_robin to create the basic round-robin Test leverage test_lbaas_round_robin to create the basic round-robin
@ -32,14 +30,6 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
Manual operation can be found at test proc: https://goo.gl/btDMXy Manual operation can be found at test proc: https://goo.gl/btDMXy
""" """
@classmethod
def skip_checks(cls):
super(TestL7SwitchingOps, cls).skip_checks()
if '1739510' in CONF.nsxv.bugs_to_resolve:
msg = ("skip lbaas_l7_switching_ops because bug=1739150"
" -- l7 switching is not supported")
raise cls.skipException(msg)
@classmethod @classmethod
def resource_setup(cls): def resource_setup(cls):
super(TestL7SwitchingOps, cls).resource_setup() super(TestL7SwitchingOps, cls).resource_setup()
@ -55,19 +45,22 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
super(TestL7SwitchingOps, self).setUp() super(TestL7SwitchingOps, self).setUp()
self.switching_startswith_value1 = "/api" self.switching_startswith_value1 = "/api"
self.switching_startswith_value2 = "/api2" self.switching_startswith_value2 = "/api2"
self.reject_startswith = "/api/v1"
self.pool7 = None self.pool7 = None
self.l7policy1 = None self.l7policy1 = None
self.l7rule1 = None self.l7rule1 = None
self.l7rule_kwargs = dict(type='PATH', self.l7rule_kwargs = dict(type='PATH',
compare_type='STARTS_WITH', compare_type='STARTS_WITH',
value=self.switching_startswith_value1) value=self.switching_startswith_value1)
self.l7policy_reject = None
def tearDown(self): def tearDown(self):
lb_id = self.loadbalancer['id'] lb_id = self.loadbalancer['id']
# teardown lbaas l7 provision # teardown lbaas l7 provision
if self.l7policy1: for policy in [self.l7policy1, self.l7policy_reject]:
self.l7policies_client.delete_l7policy(self.l7policy1.get('id')) if policy:
self.wait_for_load_balancer_status(lb_id) self.l7policies_client.delete_l7policy(policy.get('id'))
self.wait_for_load_balancer_status(lb_id)
if self.pool7: if self.pool7:
self.pools_client.delete_pool(self.pool7.get('id')) self.pools_client.delete_pool(self.pool7.get('id'))
self.wait_for_load_balancer_status(lb_id) self.wait_for_load_balancer_status(lb_id)
@ -122,6 +115,18 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
policy_id = self.l7policy1.get('id') policy_id = self.l7policy1.get('id')
self.l7rule1 = self.l7rules_client.create_l7rule( self.l7rule1 = self.l7rules_client.create_l7rule(
policy_id, **self.l7rule_kwargs)['rule'] policy_id, **self.l7rule_kwargs)['rule']
l7policy_kwargs = dict(action="REJECT", position=1,
redirect_pool_id=pool_id,
listener_id=redirect_to_listener_id,
name='policy-reject')
l7policy1 = self.l7policies_client.create_l7policy(**l7policy_kwargs)
self.l7policy_reject = l7policy1.get(u'l7policy', l7policy1)
self.reject_policy_id = self.l7policy_reject.get('id')
l7rule_kwargs = dict(type='PATH',
compare_type='STARTS_WITH',
value=self.reject_startswith)
self.l7rule_reject = self.l7rules_client.create_l7rule(
self.reject_policy_id, **l7rule_kwargs)['rule']
def check_l7_switching(self, start_path, expected_server_list, def check_l7_switching(self, start_path, expected_server_list,
send_count=6): send_count=6):
@ -133,6 +138,8 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
def validate_l7_switching(self): def validate_l7_switching(self):
l7_sv_name_list = [s['name'] for s in self.l7_server_list] l7_sv_name_list = [s['name'] for s in self.l7_server_list]
rr_sv_name_list = [s['name'] for s in self.rr_server_list] rr_sv_name_list = [s['name'] for s in self.rr_server_list]
reject_name_list = ["403"]
# URL prefix api switching to pool7 # URL prefix api switching to pool7
self.check_l7_switching('api', l7_sv_name_list, 6) self.check_l7_switching('api', l7_sv_name_list, 6)
# URL prefix ap/i switching to pool1 # URL prefix ap/i switching to pool1
@ -140,6 +147,9 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
# URL prefix api2 switching to pool7 # URL prefix api2 switching to pool7
self.check_l7_switching('api2', l7_sv_name_list, 6) self.check_l7_switching('api2', l7_sv_name_list, 6)
# URL /api/v1 should be rejected, status=403
self.check_l7_switching('api/v1', reject_name_list, 6)
# change rule starts_with's value to /api2 # change rule starts_with's value to /api2
# and /api & /api/2 will be swithed to default pool # and /api & /api/2 will be swithed to default pool
policy_id = self.l7policy1.get('id') policy_id = self.l7policy1.get('id')
@ -157,6 +167,9 @@ class TestL7SwitchingOps(lbaas_ops.LBaasRoundRobinBaseTest):
# URL prefix api2 switching to pool # URL prefix api2 switching to pool
self.check_l7_switching('xapi2', rr_sv_name_list, 6) self.check_l7_switching('xapi2', rr_sv_name_list, 6)
# URL /api/v1 should be rejected, status=403
self.check_l7_switching('api/v1', reject_name_list, 6)
@test.idempotent_id('f11e19e4-16b5-41c7-878d-59b9e943e3ce') @test.idempotent_id('f11e19e4-16b5-41c7-878d-59b9e943e3ce')
@test.services('compute', 'network') @test.services('compute', 'network')
def test_lbaas_l7_switching_ops(self): def test_lbaas_l7_switching_ops(self):

View File

@ -125,7 +125,9 @@ class LBaasRoundRobinBaseTest(dmgr.TopoDeployScenarioManager):
lb = statuses.get('loadbalancer') lb = statuses.get('loadbalancer')
for listener in lb.get('listeners', []): for listener in lb.get('listeners', []):
for policy in listener.get('l7policies'): for policy in listener.get('l7policies'):
self.l7policies_client.delete_policy(policy.get('id')) test_utils.call_and_ignore_notfound_exc(
self.l7policies_client.delete_policy,
policy.get('id'))
for pool in listener.get('pools'): for pool in listener.get('pools'):
self.delete_lb_pool_resources(lb_id, pool) self.delete_lb_pool_resources(lb_id, pool)
test_utils.call_and_ignore_notfound_exc( test_utils.call_and_ignore_notfound_exc(
@ -347,7 +349,10 @@ class LBaasRoundRobinBaseTest(dmgr.TopoDeployScenarioManager):
url_path = "http://{0}/{1}".format(self.vip_ip_address, start_path) url_path = "http://{0}/{1}".format(self.vip_ip_address, start_path)
for x in range(send_counts): for x in range(send_counts):
resp = http.request('GET', url_path) resp = http.request('GET', url_path)
self.count_response(resp.data.strip()) if resp.status == 200:
self.count_response(resp.data.strip())
else:
self.count_response(str(resp.status))
return self.http_cnt return self.http_cnt
def check_project_lbaas(self): def check_project_lbaas(self):