Merge "Basic smoke test script"

This commit is contained in:
Jenkins 2017-04-28 03:43:32 +00:00 committed by Gerrit Code Review
commit ef1bc23899
9 changed files with 257 additions and 17 deletions

View File

@ -30,6 +30,7 @@ Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS=(network_vlan_ranges=bridge:2001:3000,extern:3001
Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS=(vni_ranges=1001:2000)
Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS=(flat_networks=bridge,extern)
OVS_BRIDGE_MAPPINGS=bridge:br-vlan
ML2_L3_PLUGIN=tricircle.network.local_l3_plugin.TricircleL3Plugin
# Specify Central Region name
# CENTRAL_REGION_NAME=CentralRegion

View File

@ -34,6 +34,7 @@ Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS=(network_vlan_ranges=bridge:2001:3000,extern:3001
Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS=(vni_ranges=1001:2000)
Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS=(flat_networks=bridge,extern)
OVS_BRIDGE_MAPPINGS=bridge:br-vlan,extern:br-ext
ML2_L3_PLUGIN=tricircle.network.local_l3_plugin.TricircleL3Plugin
# Specify Central Region name
# CENTRAL_REGION_NAME=CentralRegion

View File

@ -64,10 +64,9 @@ function init_common_tricircle_conf {
function init_local_neutron_conf {
iniset $NEUTRON_CONF DEFAULT core_plugin tricircle.network.local_plugin.TricirclePlugin
iniset $NEUTRON_CONF DEFAULT service_plugins tricircle.network.local_l3_plugin.TricircleL3Plugin
iniset $NEUTRON_CONF client auth_url http://$KEYSTONE_SERVICE_HOST:5000/v3
iniset $NEUTRON_CONF client identity_url http://$KEYSTONE_SERVICE_HOST:35357/v3
iniset $NEUTRON_CONF client auth_url http://$KEYSTONE_SERVICE_HOST/identity/v3
iniset $NEUTRON_CONF client identity_url http://$KEYSTONE_SERVICE_HOST/identity_admin/v3
iniset $NEUTRON_CONF client admin_username admin
iniset $NEUTRON_CONF client admin_password $ADMIN_PASSWORD
iniset $NEUTRON_CONF client admin_tenant demo
@ -162,6 +161,7 @@ function configure_tricircle_api_wsgi {
sudo cp $TRICIRCLE_API_APACHE_TEMPLATE $tricircle_api_apache_conf
sudo sed -e "
s|%TRICIRCLE_BIN%|$tricircle_bin_dir|g;
s|%PUBLICPORT%|$TRICIRCLE_API_PORT|g;
s|%APACHE_NAME%|$APACHE_NAME|g;
s|%PUBLICWSGI%|$tricircle_bin_dir/tricircle-api-wsgi|g;

View File

@ -35,10 +35,10 @@ from tricircle.db import models
client_opts = [
cfg.StrOpt('auth_url',
default='http://127.0.0.1:5000/v3',
default='http://127.0.0.1/identity/v3',
help='keystone authorization url'),
cfg.StrOpt('identity_url',
default='http://127.0.0.1:35357/v3',
default='http://127.0.0.1/identity_admin/v3',
help='keystone service url'),
cfg.BoolOpt('auto_refresh_endpoint',
default=False,

View File

@ -28,9 +28,9 @@ from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
import neutron.common.exceptions as ml2_exceptions
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as q_db_api
from neutron.db.availability_zone import router as router_az
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_v2
from neutron.db import external_net_db
from neutron.db import extradhcpopt_db
@ -218,13 +218,11 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
availability_zone=diff.pop())
@staticmethod
@resource_extend.extends([attributes.NETWORKS])
def _extend_availability_zone(net_res, net_db):
net_res[az_ext.AZ_HINTS] = az_ext.convert_az_string_to_list(
net_db[az_ext.AZ_HINTS])
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
attributes.NETWORKS, ['_extend_availability_zone'])
@staticmethod
def _ensure_az_set_for_external_network(context, req_data):
external = req_data.get(external_net.EXTERNAL)

View File

@ -40,11 +40,23 @@ function _setup_tricircle_multinode {
ENABLE_TRICIRCLE="enable_plugin tricircle https://git.openstack.org/openstack/tricircle/"
# Configure primary node
export DEVSTACK_LOCAL_CONFIG="$ENABLE_TRICIRCLE"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=True"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"REGION_NAME=RegionOne"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"HOST_IP=$PRIMARY_NODE_IP"
ML2_CONFIG=$'\n'"ML2_L3_PLUGIN=tricircle.network.local_l3_plugin.TricircleL3Plugin"
ML2_CONFIG+=$'\n'"[[post-config|/"'$Q_PLUGIN_CONF_FILE]]'
ML2_CONFIG+=$'\n'"[ml2]"
ML2_CONFIG+=$'\n'"mechanism_drivers = openvswitch,linuxbridge,l2population"
ML2_CONFIG+=$'\n'"[agent]"
ML2_CONFIG+=$'\n'"tunnel_types=vxlan"
ML2_CONFIG+=$'\n'"l2_population=True"
export DEVSTACK_LOCAL_CONFIG+=$ML2_CONFIG
# Configure sub-node
export DEVSTACK_SUBNODE_CONFIG="$ENABLE_TRICIRCLE"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"TRICIRCLE_START_SERVICES=False"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"REGION_NAME=RegionTwo"
@ -59,6 +71,8 @@ function _setup_tricircle_multinode {
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"DATABASE_HOST=$SUBNODE_IP"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"GLANCE_HOSTPORT=$SUBNODE_IP:9292"
export DEVSTACK_SUBNODE_CONFIG+=$'\n'"Q_HOST=$SUBNODE_IP"
export DEVSTACK_SUBNODE_CONFIG+=$ML2_CONFIG
}
if [ "$DEVSTACK_GATE_TOPOLOGY" == "multinode" ]; then

View File

@ -94,11 +94,7 @@ iniset $TEMPEST_CONF volume-feature-enabled api_v1 false
iniset $TEMPEST_CONF validation connect_method fixed
# Run the Network Tempest tests
cd $TRICIRCLE_TEMPEST_PLUGIN_DIR
sudo BASE=$BASE ./tempest_network.sh
# Run the Scenario Tempest tests
# cd $TRICIRCLE_TEMPEST_PLUGIN_DIR
# sudo BASE=$BASE ./tempest_scenario.sh
if [ "$DEVSTACK_GATE_TOPOLOGY" == "multinode" ]; then
cd $TRICIRCLE_TEMPEST_PLUGIN_DIR
sudo BASE=$BASE bash smoke_test.sh
fi

View File

@ -0,0 +1,155 @@
#!/bin/bash -xe
DEST=$BASE/new
DEVSTACK_DIR=$DEST/devstack
source $DEVSTACK_DIR/openrc admin demo
unset OS_REGION_NAME
openstacktop="openstack --os-region-name CentralRegion"
openstackpod1="openstack --os-region-name RegionOne"
openstackpod2="openstack --os-region-name RegionTwo"
echo list networks before running
$openstacktop network list
echo create external network
$openstacktop network create --external --provider-network-type vlan \
--provider-physical-network extern --availability-zone-hint RegionTwo ext-net
echo show networks after running
for id in $($openstacktop network list -c ID -f value)
do $openstacktop network show $id
done
echo create external subnet
$openstacktop subnet create --subnet-range 163.3.124.0/24 --network ext-net \
--no-dhcp ext-subnet
echo create router
router_id=$($openstacktop router create router -c id -f value)
echo attach router to external network
$openstacktop router set --external-gateway ext-net router
echo create network1
$openstacktop network create net1
echo create subnet1
$openstacktop subnet create --subnet-range 10.0.1.0/24 --network net1 subnet1
echo create port1
port1_id=$($openstacktop port create --network net1 port1 -c id -f value)
echo attach subnet1 to router
$openstacktop router add subnet router subnet1
echo associate floating ip to port1
$openstacktop floating ip create --port $port1_id ext-net -c id -f value
image1_id=$($openstackpod1 image list -c ID -f value)
echo create server1
$openstackpod1 server create --flavor 1 --image $image1_id --nic port-id=$port1_id vm1
echo create network2
net2_id=$($openstacktop network create net2 -c id -f value)
echo create subnet2
$openstacktop subnet create --subnet-range 10.0.2.0/24 --network net2 subnet2
image2_id=$($openstackpod2 image list -c ID -f value)
echo create server2
$openstackpod2 server create --flavor 1 --image $image2_id --nic net-id=$net2_id vm2
echo attach subnet2 to router
$openstacktop router add subnet router subnet2
sleep 20
TOP_DIR=$DEVSTACK_DIR
source $DEVSTACK_DIR/stackrc
source $DEVSTACK_DIR/inc/meta-config
extract_localrc_section $TOP_DIR/local.conf $TOP_DIR/localrc $TOP_DIR/.localrc.auto
source $DEVSTACK_DIR/functions-common
source $DEVSTACK_DIR/lib/database
initialize_database_backends
if [ "$DATABASE_TYPE" == "mysql" ]; then
for i in $(seq 1 11); do
if [ $i == 11 ]; then
# we check fail job at the end to give fail job a chance to redo
fail_result=$(mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -h$DATABASE_HOST -Dtricircle -e 'SELECT COUNT(*) FROM async_jobs WHERE status = "0_Fail"')
fail_count=$(echo $fail_result | grep -o "[0-9]\{1,\}")
if [ $fail_count -ne 0 ]; then
echo "Listing fail job"
mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -h$DATABASE_HOST -Dtricircle -e 'SELECT * FROM async_jobs WHERE status = "0_Fail";'
die $LINENO "Smoke test fails, $fail_count job fail"
fi
die $LINENO "Smoke test fails, exceed max wait time for job"
fi
full_result=$(mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -h$DATABASE_HOST -Dtricircle -e 'SELECT COUNT(*) FROM async_jobs;')
full_count=$(echo $full_result | grep -o "[0-9]\{1,\}")
if [ $full_count -ne 0 ]; then
echo "Wait for job to finish"
sleep 5
else
break
fi
done
else
for i in $(seq 1 11); do
if [ $i == 11 ]; then
# we check fail job at the end to give fail job a chance to redo
fail_result=$(psql -h$DATABASE_HOST -U$DATABASE_USER -dtricircle -c 'SELECT COUNT(*) FROM async_jobs WHERE status = "0_Fail"')
fail_count=$(echo $fail_result | grep -o "[0-9]\{1,\}")
if [ $fail_count -ne 0 ]; then
echo "Listing fail job"
psql -h$DATABASE_HOST -U$DATABASE_USER -dtricircle -c 'SELECT * FROM async_jobs WHERE status = "0_Fail";'
die $LINENO "Smoke test fails, $fail_count job fail"
fi
die $LINENO "Smoke test fails, exceed max wait time for job"
fi
full_result=$(psql -h$DATABASE_HOST -U$DATABASE_USER -dtricircle -c 'SELECT COUNT(*) FROM async_jobs;')
full_count=$(echo $full_result | grep -o "[0-9]\{1,\}")
if [ $full_count -ne 0 ]; then
echo "Wait for job to finish"
sleep 5
else
break
fi
done
fi
$openstackpod1 server list -f json | python smoke_test_validation.py server 1
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in server of RegionOne"
fi
$openstackpod2 server list -f json | python smoke_test_validation.py server 2
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in server of RegionTwo"
fi
$openstackpod1 subnet list -f json | python smoke_test_validation.py subnet 1
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in subnet of RegionOne"
fi
$openstackpod2 subnet list -f json | python smoke_test_validation.py subnet 2
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in subnet of RegionTwo"
fi
$openstackpod1 port list --router $router_id -f json | python smoke_test_validation.py router_port 1
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in router port of RegionOne"
fi
$openstackpod2 port list --router $router_id -f json | python smoke_test_validation.py router_port 2
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in router port of RegionTwo"
fi
$openstackpod1 router show $router_id -c routes -f json | python smoke_test_validation.py router 1
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in router of RegionOne"
fi
$openstackpod2 router show $router_id -c routes -f json | python smoke_test_validation.py router 2
if [ $? != 0 ]; then
die $LINENO "Smoke test fails, error in router of RegionTwo"
fi

View File

@ -0,0 +1,75 @@
# Copyright 2017 Huawei Technologies Co., Ltd.
# 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.
import json
import sys
class ContainedString(object):
def __init__(self, txt):
self.content = txt
def __eq__(self, other):
return other.find(self.content) != -1
def __ne__(self, other):
return other.find(self.content) == -1
CONDITIONS = {
'1': {'server': [{'Name': 'vm1', 'Status': 'ACTIVE'}],
'subnet': [{'Subnet': '100.0.0.0/24'}, {'Subnet': '10.0.1.0/24'}],
'router_port': [{'Fixed IP Addresses': ContainedString('10.0.1')},
{'Fixed IP Addresses': ContainedString('100.0.0')}],
'router': [
{'routes': ContainedString(
"destination='0.0.0.0/0', gateway='100.0.0.1'")},
{'routes': ContainedString("destination='10.0.2")}]},
'2': {'server': [{'Name': 'vm2', 'Status': 'ACTIVE'}],
'subnet': [{'Subnet': '100.0.0.0/24'}, {'Subnet': '10.0.1.0/24'},
{'Subnet': '10.0.2.0/24'}, {'Subnet': '163.3.124.0/24'}],
'router_port': [{'Fixed IP Addresses': ContainedString('10.0.2')},
{'Fixed IP Addresses': ContainedString('100.0.0')}],
'router': [
{'routes': ContainedString(
"destination='0.0.0.0/0', gateway='100.0.0.1'")},
{'routes': ContainedString("destination='10.0.1")}]}
}
def validate_condition(result, condition):
if not isinstance(result, list):
result = [result]
for res in result:
if all(res[key] == value for (key, value) in condition.items()):
return True
return False
def validate_result(result, region, res_type):
for condition in CONDITIONS[region][res_type]:
if not validate_condition(result, condition):
return False
return True
if __name__ == '__main__':
res_type, region = sys.argv[1:]
raw_result = ''.join([line for line in sys.stdin])
result = json.loads(raw_result)
passed = validate_result(result, region, res_type)
# True is casted to 1, but 1 indicates error in shell
sys.exit(1 - int(passed))