Add trunk smoke test

1. What is the problem
Smoke test engine has been implemented[1] and tests for single
north-south gateway topology and multiple north-south gateway
topology have been added. But we still lack test for trunk.

2. What is the solution for the problem
Define trunk related test using YAML file.

3. What features need to be implemented to the Tricircle to
realize the solution
N/A

[1] https://review.openstack.org/#/c/477500/

Implements: blueprint smoke-test-engine
Change-Id: If9df9983350ea442dab6106cb58d49590c0677b1
This commit is contained in:
zhiyuan_cai 2017-07-05 10:53:01 +08:00
parent 9ce573ef4c
commit eb2662b33e
11 changed files with 364 additions and 2 deletions

View File

@ -113,6 +113,9 @@ function init_local_neutron_variables {
OVS_BRIDGE_MAPPINGS=$vlan_mapping,$ext_mapping OVS_BRIDGE_MAPPINGS=$vlan_mapping,$ext_mapping
fi fi
if [ "$TRICIRCLE_ENABLE_TRUNK" == "True" ]; then
_neutron_service_plugin_class_add trunk
fi
} }
function add_default_bridges { function add_default_bridges {
@ -279,6 +282,10 @@ function start_central_neutron_server {
iniset $NEUTRON_CONF.$server_index client auto_refresh_endpoint True iniset $NEUTRON_CONF.$server_index client auto_refresh_endpoint True
iniset $NEUTRON_CONF.$server_index client top_region_name $CENTRAL_REGION_NAME iniset $NEUTRON_CONF.$server_index client top_region_name $CENTRAL_REGION_NAME
if [ "$TRICIRCLE_ENABLE_TRUNK" == "True" ]; then
iniset $NEUTRON_CONF.$server_index DEFAULT service_plugins "tricircle.network.central_trunk_plugin.TricircleTrunkPlugin"
fi
local type_drivers='' local type_drivers=''
local tenant_network_types='' local tenant_network_types=''
if [ "$Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS" != "" ]; then if [ "$Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS" != "" ]; then

View File

@ -10,6 +10,9 @@ TRICIRCLE_START_SERVICES=${TRICIRCLE_START_SERVICES:-True}
TRICIRCLE_DEPLOY_WITH_WSGI=${TRICIRCLE_DEPLOY_WITH_WSGI:-True} TRICIRCLE_DEPLOY_WITH_WSGI=${TRICIRCLE_DEPLOY_WITH_WSGI:-True}
TRICIRCLE_DEPLOY_WITH_CELL=${TRICIRCLE_DEPLOY_WITH_CELL:-False} TRICIRCLE_DEPLOY_WITH_CELL=${TRICIRCLE_DEPLOY_WITH_CELL:-False}
# extensions working with tricircle
TRICIRCLE_ENABLE_TRUNK=${TRICIRCLE_ENABLE_TRUNK:-False}
# these default settings are used for devstack based gate/check jobs # these default settings are used for devstack based gate/check jobs
TRICIRCLE_DEFAULT_VLAN_BRIDGE=${TRICIRCLE_DEFAULT_VLAN_BRIDGE:-br-vlan} TRICIRCLE_DEFAULT_VLAN_BRIDGE=${TRICIRCLE_DEFAULT_VLAN_BRIDGE:-br-vlan}
TRICIRCLE_DEFAULT_VLAN_RANGE=${TRICIRCLE_DEFAULT_VLAN_RANGE:-101:150} TRICIRCLE_DEFAULT_VLAN_RANGE=${TRICIRCLE_DEFAULT_VLAN_RANGE:-101:150}

View File

@ -43,6 +43,7 @@ function _setup_tricircle_multinode {
# Configure primary node # Configure primary node
export DEVSTACK_LOCAL_CONFIG="$ENABLE_TRICIRCLE" export DEVSTACK_LOCAL_CONFIG="$ENABLE_TRICIRCLE"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=True" export DEVSTACK_LOCAL_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=True"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"TRICIRCLE_ENABLE_TRUNK=True"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"REGION_NAME=RegionOne" export DEVSTACK_LOCAL_CONFIG+=$'\n'"REGION_NAME=RegionOne"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"HOST_IP=$PRIMARY_NODE_IP" export DEVSTACK_LOCAL_CONFIG+=$'\n'"HOST_IP=$PRIMARY_NODE_IP"
@ -59,6 +60,7 @@ function _setup_tricircle_multinode {
# Configure sub-node # Configure sub-node
export DEVSTACK_SUBNODE_CONFIG="$ENABLE_TRICIRCLE" export DEVSTACK_SUBNODE_CONFIG="$ENABLE_TRICIRCLE"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=False" export DEVSTACK_SUBNODE_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=False"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"TRICIRCLE_ENABLE_TRUNK=True"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"REGION_NAME=RegionTwo" export DEVSTACK_SUBNODE_CONFIG+=$'\n'"REGION_NAME=RegionTwo"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"HOST_IP=$SUBNODE_IP" export DEVSTACK_SUBNODE_CONFIG+=$'\n'"HOST_IP=$SUBNODE_IP"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"KEYSTONE_REGION_NAME=RegionOne" export DEVSTACK_SUBNODE_CONFIG+=$'\n'"KEYSTONE_REGION_NAME=RegionOne"

View File

@ -13,3 +13,7 @@ python run_yaml_test.py multi_gw_topology_test.yaml "$OS_AUTH_URL" "$OS_TENANT_N
if [ $? != 0 ]; then if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in multi gateway topology test" die $LINENO "Smoke test fails, error in multi gateway topology test"
fi fi
python run_yaml_test.py trunk_test.yaml "$OS_AUTH_URL" "$OS_TENANT_NAME" "$OS_USERNAME" "$OS_PASSWORD"
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in trunk test"
fi

View File

@ -22,17 +22,23 @@ import yaml
from openstack import connection from openstack import connection
from openstack import profile from openstack import profile
from tricircle.tests.network_sdk import network_service
from tricircle.tests.tricircle_sdk import multiregion_network_service from tricircle.tests.tricircle_sdk import multiregion_network_service
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
SLEEP_INTERVAL = 20
class DummyRunner(object): class DummyRunner(object):
class DummyResource(object): class DummyResource(object):
def __init__(self, _id): def __init__(self, _id):
self.id = _id self.id = _id
def __getattr__(self, item):
return item
def __init__(self): def __init__(self):
self.id_pool = {} self.id_pool = {}
@ -68,7 +74,7 @@ class SDKRunner(object):
'region1': 'RegionOne', 'region1': 'RegionOne',
'region2': 'RegionTwo'} 'region2': 'RegionTwo'}
serv_reslist_map = { serv_reslist_map = {
'network': ['network', 'subnet', 'port', 'router', 'fip'], 'network_sdk': ['network', 'subnet', 'port', 'router', 'fip', 'trunk'],
'compute': ['server'], 'compute': ['server'],
'image': ['image'], 'image': ['image'],
'tricircle_sdk': ['job']} 'tricircle_sdk': ['job']}
@ -94,6 +100,8 @@ class SDKRunner(object):
serv = multiregion_network_service.MultiregionNetworkService( serv = multiregion_network_service.MultiregionNetworkService(
version='v1') version='v1')
prof._add_service(serv) prof._add_service(serv)
net_serv = network_service.NetworkService(version='v2')
prof._add_service(net_serv)
prof.set_region(profile.Profile.ALL, region) prof.set_region(profile.Profile.ALL, region)
param['profile'] = prof param['profile'] = prof
conn = connection.Connection(**param) conn = connection.Connection(**param)
@ -363,7 +371,7 @@ class RunnerEngine(object):
if i == run_time - 1: if i == run_time - 1:
raise raise
else: else:
time.sleep(10) time.sleep(SLEEP_INTERVAL)
LOG.info('Redo failed task %s', task_id) LOG.info('Redo failed task %s', task_id)
def run_tasks(self, task_set_id, depend_task_set_result={}): def run_tasks(self, task_set_id, depend_task_set_result={}):

View File

@ -0,0 +1,229 @@
- task_set_id: preparation
tasks:
- task_id: image1
type: image
region: region1
query:
get_one: true
- task_id: net1
region: central
type: network
params:
name: net1
provider_network_type: vlan
- task_id: subnet1
region: central
type: subnet
depend: [net1]
params:
name: subnet1
ip_version: 4
cidr: 10.0.1.0/24
network_id: net1@id
- task_id: net2
region: central
type: network
params:
name: net2
provider_network_type: vlan
- task_id: subnet2
region: central
type: subnet
depend: [net2]
params:
name: subnet2
ip_version: 4
cidr: 10.0.2.0/24
network_id: net2@id
- task_id: p1
region: central
type: port
depend:
- net1
- subnet1
params:
name: p1
network_id: net1@id
- task_id: p2
region: central
type: port
depend:
- net2
- subnet2
params:
name: p2
network_id: net2@id
- task_id: vm1
region: region1
type: server
depend:
- p1
- image1
- trunk1
params:
flavor_id: 1
image_id: image1@id
name: vm1
networks:
- port: p1@id
- task_id: trunk1
region: central
depend:
- p1
- p2
- net2
type: trunk
params:
name: trunk1
port_id: p1@id
sub_ports:
- port_id: p2@id
segmentation_type: vlan
segmentation_id: net2@provider_segmentation_id
- task_set_id: wait-for-job
tasks:
# ensure server is active and thus sync_trunk job is registered
- task_id: check-servers
region: region1
type: server
validate:
predicate: any
retries: 10
condition:
- status: ACTIVE
name: vm1
- task_id: check-job
region: central
type: job
depend: [check-servers]
validate:
predicate: all
retries: 10
condition:
- status: SUCCESS
- task_set_id: check
depend: [preparation]
tasks:
- task_id: check-ports
region: region1
type: port
validate:
predicate: any
condition:
- name: p1
fixed_ips:
- ip_address: 10.0.1*
- name: p2
fixed_ips:
- ip_address: 10.0.2*
- task_id: check-trunks
region: region1
type: trunk
validate:
predicate: any
condition:
- name: trunk1
port_id: preparation@p1@id
sub_ports:
- port_id: preparation@p2@id
segmentation_type: vlan
segmentation_id: preparation@net2@provider_segmentation_id
- task_set_id: clean
depend: [preparation]
tasks:
- task_id: delete-server
region: region1
type: server
action:
target: preparation@vm1@id
method: delete
- task_id: delete-trunk
region: central
type: trunk
depend: [delete-server]
action:
target: preparation@trunk1@id
method: delete
retries: 3
- task_id: delete-p1
region: central
type: port
depend: [delete-trunk]
action:
target: preparation@p1@id
method: delete
- task_id: delete-p2
region: central
type: port
depend: [delete-trunk]
action:
target: preparation@p2@id
method: delete
- task_id: delete-subnet1
region: central
type: subnet
depend: [delete-p1]
action:
target: preparation@subnet1@id
method: delete
retries: 3
- task_id: delete-subnet2
region: central
type: subnet
depend: [delete-p2]
action:
target: preparation@subnet2@id
method: delete
retries: 3
- task_id: delete-net1
region: central
type: network
depend: [delete-subnet1]
action:
target: preparation@net1@id
method: delete
- task_id: delete-net2
region: central
type: network
depend: [delete-subnet2]
action:
target: preparation@net2@id
method: delete
- task_set_id: clean-check
tasks:
- task_id: check-no-trunks1
region: region1
type: trunk
validate:
predicate: all
condition:
- name: invalid-name
- task_id: check-no-trunks2
region: region2
type: trunk
validate:
predicate: all
condition:
- name: invalid-name
- task_id: check-no-networks1
region: region1
type: network
validate:
predicate: all
condition:
- name: invalid-name
- task_id: check-no-networks2
region: region2
type: network
validate:
predicate: all
condition:
- name: invalid-name
- task_id: check-jobs
region: central
type: job
validate:
predicate: all
retries: 10
condition:
- status: SUCCESS

View File

View File

@ -0,0 +1,24 @@
# 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 openstack import service_filter
class NetworkService(service_filter.ServiceFilter):
"""The network service."""
valid_versions = [service_filter.ValidVersion('v2', 'v2.0')]
def __init__(self, version=None):
"""Create a network service."""
super(NetworkService, self).__init__(service_type='network',
version=version)

View File

@ -0,0 +1,41 @@
# All Rights Reserved
#
# 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 openstack.network.v2 import _proxy
import tricircle.tests.network_sdk.v2.trunk as _trunk
class Proxy(_proxy.Proxy):
def create_trunk(self, **attrs):
return self._create(_trunk.Trunk, **attrs)
def delete_trunk(self, trunk, ignore_missing=True):
self._delete(_trunk.Trunk, trunk, ignore_missing=ignore_missing)
def update_trunk(self, trunk, **attrs):
return self._update(_trunk.Trunk, trunk, **attrs)
def trunks(self, **query):
return self._list(_trunk.Trunk, pagination=False, **query)
def add_subports(self, trunk, subports=[]):
trunk = self._get_resource(_trunk.Trunk, trunk)
body = {'sub_ports': subports}
return trunk.add_subports(self._session, **body)
def remove_subports(self, trunk, subports=[]):
trunk = self._get_resource(_trunk.Trunk, trunk)
body = {'sub_ports': subports}
return trunk.remove_subports(self._session, **body)

View File

@ -0,0 +1,44 @@
# 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 openstack import resource2
from openstack import utils
from tricircle.tests.network_sdk import network_service
class Trunk(resource2.Resource):
resource_key = 'trunk'
resources_key = 'trunks'
base_path = '/trunks'
service = network_service.NetworkService()
allow_create = True
allow_get = True
allow_update = True
allow_delete = True
allow_list = True
status = resource2.Body('status')
name = resource2.Body('name')
port_id = resource2.Body('port_id')
sub_ports = resource2.Body('sub_ports', type=list)
def add_subports(self, session, **body):
url = utils.urljoin(self.base_path, self.id, 'add_subports')
resp = session.put(url, endpoint_filter=self.service, json=body)
return resp.json()
def remove_subports(self, session, **body):
url = utils.urljoin(self.base_path, self.id, 'remove_subports')
resp = session.put(url, endpoint_filter=self.service, json=body)
return resp.json()