Browse Source

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
changes/76/480976/11
zhiyuan_cai 5 years ago
parent
commit
eb2662b33e
  1. 7
      devstack/plugin.sh
  2. 3
      devstack/settings
  3. 2
      tricircle/tempestplugin/gate_hook.sh
  4. 4
      tricircle/tempestplugin/smoke_test.sh
  5. 12
      tricircle/tempestplugin/task_runner.py
  6. 229
      tricircle/tempestplugin/trunk_test.yaml
  7. 0
      tricircle/tests/network_sdk/__init__.py
  8. 24
      tricircle/tests/network_sdk/network_service.py
  9. 0
      tricircle/tests/network_sdk/v2/__init__.py
  10. 41
      tricircle/tests/network_sdk/v2/_proxy.py
  11. 44
      tricircle/tests/network_sdk/v2/trunk.py

7
devstack/plugin.sh

@ -113,6 +113,9 @@ function init_local_neutron_variables {
OVS_BRIDGE_MAPPINGS=$vlan_mapping,$ext_mapping
fi
if [ "$TRICIRCLE_ENABLE_TRUNK" == "True" ]; then
_neutron_service_plugin_class_add trunk
fi
}
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 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 tenant_network_types=''
if [ "$Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS" != "" ]; then

3
devstack/settings

@ -10,6 +10,9 @@ TRICIRCLE_START_SERVICES=${TRICIRCLE_START_SERVICES:-True}
TRICIRCLE_DEPLOY_WITH_WSGI=${TRICIRCLE_DEPLOY_WITH_WSGI:-True}
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
TRICIRCLE_DEFAULT_VLAN_BRIDGE=${TRICIRCLE_DEFAULT_VLAN_BRIDGE:-br-vlan}
TRICIRCLE_DEFAULT_VLAN_RANGE=${TRICIRCLE_DEFAULT_VLAN_RANGE:-101:150}

2
tricircle/tempestplugin/gate_hook.sh

@ -43,6 +43,7 @@ function _setup_tricircle_multinode {
# Configure primary node
export DEVSTACK_LOCAL_CONFIG="$ENABLE_TRICIRCLE"
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'"HOST_IP=$PRIMARY_NODE_IP"
@ -59,6 +60,7 @@ function _setup_tricircle_multinode {
# Configure sub-node
export DEVSTACK_SUBNODE_CONFIG="$ENABLE_TRICIRCLE"
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'"HOST_IP=$SUBNODE_IP"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"KEYSTONE_REGION_NAME=RegionOne"

4
tricircle/tempestplugin/smoke_test.sh

@ -13,3 +13,7 @@ python run_yaml_test.py multi_gw_topology_test.yaml "$OS_AUTH_URL" "$OS_TENANT_N
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in multi gateway topology test"
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

12
tricircle/tempestplugin/task_runner.py

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

229
tricircle/tempestplugin/trunk_test.yaml

@ -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

0
tricircle/tests/network_sdk/__init__.py

24
tricircle/tests/network_sdk/network_service.py

@ -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)

0
tricircle/tests/network_sdk/v2/__init__.py

41
tricircle/tests/network_sdk/v2/_proxy.py

@ -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)

44
tricircle/tests/network_sdk/v2/trunk.py

@ -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()
Loading…
Cancel
Save