aboutsummaryrefslogtreecommitdiffstats
path: root/testcases/VIM/OpenStack/CI/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'testcases/VIM/OpenStack/CI/libraries')
-rwxr-xr-xtestcases/VIM/OpenStack/CI/libraries/check_os.sh91
-rw-r--r--testcases/VIM/OpenStack/CI/libraries/clean_openstack.py399
-rw-r--r--testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml31
-rwxr-xr-xtestcases/VIM/OpenStack/CI/libraries/run_rally-cert.py306
-rw-r--r--testcases/VIM/OpenStack/CI/libraries/run_rally.py273
-rw-r--r--testcases/VIM/OpenStack/CI/libraries/run_tempest.py260
-rwxr-xr-xtestcases/VIM/OpenStack/CI/libraries/test_openstack.sh111
7 files changed, 1348 insertions, 123 deletions
diff --git a/testcases/VIM/OpenStack/CI/libraries/check_os.sh b/testcases/VIM/OpenStack/CI/libraries/check_os.sh
new file mode 100755
index 00000000..56020526
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/check_os.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+#
+# Simple script to check the basic OpenStack clients
+#
+# Author:
+# jose.lausuch@ericsson.com
+#
+
+verify_connectivity() {
+ for i in $(seq 0 10); do
+ if echo "test" | nc -v $1 $2 &>/dev/null; then
+ return 0
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+
+if [ -z $OS_AUTH_URL ];then
+ echo "ERROR: OS_AUTH_URL environment variable missing... Have you sourced the OpenStack credentials?"
+ exit 1
+fi
+
+
+echo "Checking OpenStack endpoints:"
+publicURL=$OS_AUTH_URL
+publicIP=$(echo $publicURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
+publicPort=$(echo $publicURL|sed 's/^.*://'|sed 's/.[^\/]*$//')
+echo ">>Verifying connectivity to the public endpoint $publicIP:$publicPort..."
+verify_connectivity $publicIP $publicPort
+RETVAL=$?
+if [ $RETVAL -ne 0 ]; then
+ echo "ERROR: Cannot talk to the public endpoint publicIP:$publicPort ."
+ echo "OS_AUTH_URL=$OS_AUTH_URL"
+ exit 1
+fi
+echo " ...OK"
+
+adminURL=$(keystone catalog --service identity 2>/dev/null|grep adminURL|awk '{print $4}')
+adminIP=$(echo $adminURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
+adminPort=$(echo $adminURL|sed 's/^.*://'|sed 's/.[^\/]*$//')
+echo ">>Verifying connectivity to the admin endpoint $adminIP:$adminPort..."
+verify_connectivity $adminIP $adminPort
+RETVAL=$?
+if [ $RETVAL -ne 0 ]; then
+ echo "ERROR: Cannot talk to the admin endpoint adminIP:$adminPort ."
+ echo "adminURL"
+ exit 1
+fi
+echo " ...OK"
+
+
+echo "Checking OpenStack basic services:"
+commands=('keystone endpoint-list' 'nova list' 'neutron net-list' \
+ 'glance image-list' 'cinder list')
+for cmd in "${commands[@]}"
+do
+ service=$(echo $cmd | awk '{print $1}')
+ echo ">>Checking $service service..."
+ $cmd &>/dev/null
+ result=$?
+ if [ $result -ne 0 ];
+ then
+
+ echo "ERROR: Failed execution $cmd. The $service does not seem to be working."
+ exit 1
+ else
+ echo " ...OK"
+ fi
+done
+
+echo "OpenStack services are OK."
+
+echo "Checking External network..."
+networks=($(neutron net-list | tail -n +4 | head -n -1 | awk '{print $2}'))
+is_external=False
+for net in "${networks[@]}"
+do
+ is_external=$(neutron net-show $net|grep "router:external"|awk '{print $4}')
+ if [ $is_external == "True" ]; then
+ echo "External network found: $net"
+ break
+ fi
+done
+if [ $is_external == "False" ]; then
+ echo "ERROR: There are no external networks in the deployment."
+ exit 1
+fi
+
+exit 0
diff --git a/testcases/VIM/OpenStack/CI/libraries/clean_openstack.py b/testcases/VIM/OpenStack/CI/libraries/clean_openstack.py
new file mode 100644
index 00000000..96bd172b
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/clean_openstack.py
@@ -0,0 +1,399 @@
+#!/usr/bin/env python
+#
+# Description:
+# Cleans possible leftovers after running functest tests:
+# - Nova instances
+# - Glance images
+# - Cinder volumes
+# - Floating IPs
+# - Neutron networks, subnets and ports
+# - Routers
+# - Users and tenants
+#
+# Author:
+# jose.lausuch@ericsson.com
+#
+
+import argparse
+import logging
+import os
+import re
+import sys
+import time
+import yaml
+
+from novaclient import client as novaclient
+from neutronclient.v2_0 import client as neutronclient
+from keystoneclient.v2_0 import client as keystoneclient
+from cinderclient import client as cinderclient
+
+parser = argparse.ArgumentParser()
+parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
+args = parser.parse_args()
+
+
+""" logging configuration """
+logger = logging.getLogger('clean_openstack')
+logger.setLevel(logging.DEBUG)
+
+ch = logging.StreamHandler()
+if args.debug:
+ ch.setLevel(logging.DEBUG)
+else:
+ ch.setLevel(logging.INFO)
+
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ch.setFormatter(formatter)
+logger.addHandler(ch)
+
+REPO_PATH=os.environ['repos_dir']+'/functest/'
+if not os.path.exists(REPO_PATH):
+ logger.error("Functest repository directory not found '%s'" % REPO_PATH)
+ exit(-1)
+sys.path.append(REPO_PATH + "testcases/")
+import functest_utils
+
+with open(REPO_PATH+"testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml") as f:
+ defaults_yaml = yaml.safe_load(f)
+f.close()
+
+installer = os.environ["INSTALLER_TYPE"]
+
+default_images = defaults_yaml.get(installer).get("images")
+default_networks = defaults_yaml.get(installer).get("networks") +\
+ defaults_yaml.get("common").get("networks")
+default_routers = defaults_yaml.get(installer).get("routers") +\
+ defaults_yaml.get("common").get("routers")
+default_security_groups = defaults_yaml.get(installer).get("security_groups")
+default_users = defaults_yaml.get(installer).get("users")
+default_tenants = defaults_yaml.get(installer).get("tenants")
+
+def separator():
+ logger.info("-------------------------------------------")
+
+def remove_instances(nova_client):
+ logger.info("Removing Nova instances...")
+ instances = functest_utils.get_instances(nova_client)
+ if instances is None or len(instances) == 0:
+ logger.debug("No instances found.")
+ return
+
+ for instance in instances:
+ instance_name = getattr(instance, 'name')
+ instance_id = getattr(instance, 'id')
+ logger.debug("Removing instance '%s', ID=%s ..." % (instance_name,instance_id))
+ if functest_utils.delete_instance(nova_client, instance_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "instance %s..." % instance_id)
+
+ timeout = 50
+ while timeout > 0:
+ instances = functest_utils.get_instances(nova_client)
+ if instances is None or len(instances) == 0:
+ break
+ else:
+ logger.debug("Waiting for instances to be terminated...")
+ timeout -= 1
+ time.sleep(1)
+
+
+def remove_images(nova_client):
+ logger.info("Removing Glance images...")
+ images = functest_utils.get_images(nova_client)
+ if images is None or len(images) == 0:
+ logger.debug("No images found.")
+ return
+
+ for image in images:
+ image_name = getattr(image, 'name')
+ image_id = getattr(image, 'id')
+ logger.debug("'%s', ID=%s " %(image_name,image_id))
+ if image_name not in default_images:
+ logger.debug("Removing image '%s', ID=%s ..." % (image_name,image_id))
+ if functest_utils.delete_glance_image(nova_client, image_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the"
+ "image %s..." % image_id)
+ else:
+ logger.debug(" > this is a default image and will NOT be deleted.")
+
+
+def remove_volumes(cinder_client):
+ logger.info("Removing Cinder volumes...")
+ volumes = functest_utils.get_volumes(cinder_client)
+ if volumes is None or len(volumes) == 0:
+ logger.debug("No volumes found.")
+ return
+
+ for volume in volumes:
+ volume_id = getattr(volume, 'id')
+ logger.debug("Removing cinder volume %s ..." % volume_id)
+ if functest_utils.delete_volume(cinder_client, volume_id):
+ logger.debug(" > Done!")
+ else:
+ logger.debug("Trying forced removal...")
+ if functest_utils.delete_volume(cinder_client,
+ volume_id,
+ forced=True):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "volume %s..." % volume_id)
+
+
+def remove_floatingips(nova_client):
+ logger.info("Removing floating IPs...")
+ floatingips = functest_utils.get_floating_ips(nova_client)
+ if floatingips is None or len(floatingips) == 0:
+ logger.debug("No floating IPs found.")
+ return
+
+ for fip in floatingips:
+ fip_id = getattr(fip, 'id')
+ logger.debug("Removing floating IP %s ..." % fip_id)
+ if functest_utils.delete_floating_ip(nova_client, fip_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "floating IP %s..." % fip_id)
+
+ timeout = 50
+ while timeout > 0:
+ floatingips = functest_utils.get_floating_ips(nova_client)
+ if floatingips is None or len(floatingips) == 0:
+ break
+ else:
+ logger.debug("Waiting for floating ips to be released...")
+ timeout -= 1
+ time.sleep(1)
+
+
+def remove_networks(neutron_client):
+ logger.info("Removing Neutron objects")
+ network_ids = []
+ networks = functest_utils.get_network_list(neutron_client)
+ if networks == None:
+ logger.debug("There are no networks in the deployment. ")
+ else:
+ logger.debug("Existing networks:")
+ for network in networks:
+ net_id = network['id']
+ net_name = network['name']
+ logger.debug(" '%s', ID=%s " %(net_name,net_id))
+ if net_name in default_networks:
+ logger.debug(" > this is a default network and will NOT be deleted.")
+ elif network['router:external'] == True:
+ logger.debug(" > this is an external network and will NOT be deleted.")
+ else:
+ logger.debug(" > this network will be deleted.")
+ network_ids.append(net_id)
+
+ #delete ports
+ ports = functest_utils.get_port_list(neutron_client)
+ if ports is None:
+ logger.debug("There are no ports in the deployment. ")
+ else:
+ remove_ports(neutron_client, ports, network_ids)
+
+ #remove routers
+ routers = functest_utils.get_router_list(neutron_client)
+ if routers is None:
+ logger.debug("There are no routers in the deployment. ")
+ else:
+ remove_routers(neutron_client, routers)
+
+ #remove networks
+ if network_ids != None:
+ for net_id in network_ids:
+ logger.debug("Removing network %s ..." % net_id)
+ if functest_utils.delete_neutron_net(neutron_client, net_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "network %s..." % net_id)
+
+
+def remove_ports(neutron_client, ports, network_ids):
+ for port in ports:
+ if port['network_id'] in network_ids:
+ port_id = port['id']
+ try:
+ subnet_id = port['fixed_ips'][0]['subnet_id']
+ except:
+ logger.info(" > WARNING: Port %s does not contain 'fixed_ips'" % port_id)
+ print port
+ router_id = port['device_id']
+ if len(port['fixed_ips']) == 0 and router_id == '':
+ logger.debug("Removing port %s ..." % port_id)
+ if functest_utils.delete_neutron_port(neutron_client, port_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "port %s ..." %port_id)
+ force_remove_port(neutron_client, port_id)
+
+ elif port['device_owner'] == 'network:router_interface':
+ logger.debug("Detaching port %s (subnet %s) from router %s ..."
+ % (port_id,subnet_id,router_id))
+ if functest_utils.remove_interface_router(neutron_client,
+ router_id, subnet_id):
+ time.sleep(5) # leave 5 seconds to detach before doing anything else
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "interface %s from router %s..." %(subnet_id,router_id))
+ force_remove_port(neutron_client, port_id)
+ else:
+ force_remove_port(neutron_client, port_id)
+
+
+def force_remove_port(neutron_client, port_id):
+ logger.debug("Clearing device_owner for port %s ..." % port_id)
+ functest_utils.update_neutron_port(neutron_client,
+ port_id,
+ device_owner='clear')
+ logger.debug("Removing port %s ..." % port_id)
+ if functest_utils.delete_neutron_port(neutron_client, port_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: Deleting port %s failed" % port_id)
+
+
+def remove_routers(neutron_client, routers):
+ for router in routers:
+ router_id = router['id']
+ router_name = router['name']
+ if router_name not in default_routers:
+ logger.debug("Checking '%s' with ID=(%s) ..." % (router_name,router_id))
+ if router['external_gateway_info'] != None:
+ logger.debug("Router has gateway to external network. Removing link...")
+ if functest_utils.remove_gateway_router(neutron_client, router_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing "
+ "the gateway...")
+ else:
+ logger.debug("Router is not connected to anything. Ready to remove...")
+ logger.debug("Removing router %s(%s) ..." % (router_name, router_id))
+ if functest_utils.delete_neutron_router(neutron_client, router_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "router '%s'(%s)..." % (router_name, router_id))
+
+
+def remove_security_groups(neutron_client):
+ logger.info("Removing Security groups...")
+ secgroups = functest_utils.get_security_groups(neutron_client)
+ if secgroups is None or len(secgroups) == 0:
+ logger.debug("No security groups found.")
+ return
+
+ for secgroup in secgroups:
+ secgroup_name = secgroup['name']
+ secgroup_id = secgroup['id']
+ logger.debug("'%s', ID=%s " %(secgroup_name,secgroup_id))
+ if secgroup_name not in default_security_groups:
+ logger.debug(" Removing '%s'..." % secgroup_name)
+ if functest_utils.delete_security_group(neutron_client, secgroup_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "security group %s..." % secgroup_id)
+ else:
+ logger.debug(" > this is a default security group and will NOT "
+ "be deleted.")
+
+
+def remove_users(keystone_client):
+ logger.info("Removing Users...")
+ users = functest_utils.get_users(keystone_client)
+ if users == None:
+ logger.debug("There are no users in the deployment. ")
+ return
+
+ for user in users:
+ user_name = getattr(user, 'name')
+ user_id = getattr(user, 'id')
+ logger.debug("'%s', ID=%s " %(user_name,user_id))
+ if user_name not in default_users:
+ logger.debug(" Removing '%s'..." % user_name)
+ if functest_utils.delete_user(keystone_client,user_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "user '%s'(%s)..." % (user_name,user_id))
+ else:
+ logger.debug(" > this is a default user and will NOT be deleted.")
+
+
+def remove_tenants(keystone_client):
+ logger.info("Removing Tenants...")
+ tenants = functest_utils.get_tenants(keystone_client)
+ if tenants == None:
+ logger.debug("There are no tenants in the deployment. ")
+ return
+
+ for tenant in tenants:
+ tenant_name=getattr(tenant, 'name')
+ tenant_id = getattr(tenant, 'id')
+ logger.debug("'%s', ID=%s " %(tenant_name,tenant_id))
+ if tenant_name not in default_tenants:
+ logger.debug(" Removing '%s'..." % tenant_name)
+ if functest_utils.delete_tenant(keystone_client,tenant_id):
+ logger.debug(" > Done!")
+ else:
+ logger.info(" > ERROR: There has been a problem removing the "
+ "tenant '%s'(%s)..." % (tenant_name,tenant_id))
+ else:
+ logger.debug(" > this is a default tenant and will NOT be deleted.")
+
+
+
+def main():
+ creds_nova = functest_utils.get_credentials("nova")
+ nova_client = novaclient.Client('2',**creds_nova)
+
+ creds_neutron = functest_utils.get_credentials("neutron")
+ neutron_client = neutronclient.Client(**creds_neutron)
+
+ creds_keystone = functest_utils.get_credentials("keystone")
+ keystone_client = keystoneclient.Client(**creds_keystone)
+
+ creds_cinder = functest_utils.get_credentials("cinder")
+ #cinder_client = cinderclient.Client(**creds_cinder)
+ cinder_client = cinderclient.Client('1',creds_cinder['username'],
+ creds_cinder['api_key'],
+ creds_cinder['project_id'],
+ creds_cinder['auth_url'],
+ service_type="volume")
+
+ if not functest_utils.check_credentials():
+ logger.error("Please source the openrc credentials and run the script again.")
+ exit(-1)
+
+ remove_instances(nova_client)
+ separator()
+ remove_images(nova_client)
+ separator()
+ remove_volumes(cinder_client)
+ separator()
+ remove_floatingips(nova_client)
+ separator()
+ remove_networks(neutron_client)
+ separator()
+ remove_security_groups(neutron_client)
+ separator()
+ remove_users(keystone_client)
+ separator()
+ remove_tenants(keystone_client)
+ separator()
+
+ exit(0)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml b/testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml
new file mode 100644
index 00000000..f792cda5
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/os_defaults.yaml
@@ -0,0 +1,31 @@
+fuel:
+ images: ['TestVM']
+ networks: ['net04', 'net04_ext']
+ routers: ['router04']
+ security_groups: ['default']
+ tenants: ['admin', 'services']
+ users: ['heat', 'heat-cfn', 'cinder', 'nova', 'swift', 'glance', 'neutron', 'admin', 'fuel_stats_user']
+apex:
+ images: []
+ networks: ['internal', 'external']
+ routers: []
+ security_groups: ['default']
+ tenants: ['admin', 'services', 'service']
+ users: ['heat', 'heat-cfn', 'cinder', 'nova', 'swift', 'glance', 'neutron', 'admin', 'ceilometer', 'cinderv2']
+compass:
+ images: []
+ networks: ['ext-net']
+ routers: []
+ security_groups: ['default']
+ tenants: ['admin', 'service', 'demo']
+ users: ['heat', 'cinder', 'nova', 'glance', 'neutron', 'admin', 'ceilometer', 'demo', 'keystone']
+joid:
+ images: []
+ networks: ['ext-net']
+ routers: []
+ security_groups: ['default']
+ tenants: ['admin', 'services']
+ users: ['admin', 'glance', 'nova', 'quantum_nova', 'quantum', 'heat-cfn_heat', 'ceilometer', 'cinder_cinderv2', 'swift']
+common:
+ networks: ['functest-net']
+ routers: ['functest-router']
diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py b/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py
new file mode 100755
index 00000000..b5fcd721
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2015 Orange
+# guyrodrigue.koffi@orange.com
+# morgan.richomme@orange.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# 0.1 (05/2015) initial commit
+# 0.2 (28/09/2015) extract Tempest, format json result, add ceilometer suite
+# 0.3 (19/10/2015) remove Tempest from run_rally
+# and push result into test DB
+#
+
+import re
+import json
+import os
+import argparse
+import logging
+import yaml
+import requests
+import sys
+from novaclient import client as novaclient
+from glanceclient import client as glanceclient
+from keystoneclient.v2_0 import client as keystoneclient
+from neutronclient.v2_0 import client as neutronclient
+
+""" tests configuration """
+tests = ['authenticate', 'glance', 'cinder', 'heat', 'keystone',
+ 'neutron', 'nova', 'quotas', 'requests', 'vm', 'all']
+parser = argparse.ArgumentParser()
+parser.add_argument("test_name",
+ help="Module name to be tested. "
+ "Possible values are : "
+ "[ {d[0]} | {d[1]} | {d[2]} | {d[3]} | {d[4]} | "
+ "{d[5]} | {d[6]} | {d[7]} | {d[8]} | {d[9]} | "
+ "{d[10]} ] "
+ "The 'all' value "
+ "performs all possible test scenarios"
+ .format(d=tests))
+
+parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
+parser.add_argument("-r", "--report",
+ help="Create json result file",
+ action="store_true")
+parser.add_argument("-s", "--smoke",
+ help="Smoke test mode",
+ action="store_true")
+
+args = parser.parse_args()
+
+client_dict = {}
+
+""" logging configuration """
+logger = logging.getLogger("run_rally")
+logger.setLevel(logging.DEBUG)
+
+ch = logging.StreamHandler()
+if args.debug:
+ ch.setLevel(logging.DEBUG)
+else:
+ ch.setLevel(logging.INFO)
+
+formatter = logging.Formatter("%(asctime)s - %(name)s - "
+ "%(levelname)s - %(message)s")
+ch.setFormatter(formatter)
+logger.addHandler(ch)
+
+REPO_PATH=os.environ['repos_dir']+'/functest/'
+if not os.path.exists(REPO_PATH):
+ logger.error("Functest repository directory not found '%s'" % REPO_PATH)
+ exit(-1)
+sys.path.append(REPO_PATH + "testcases/")
+import functest_utils
+
+with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
+ functest_yaml = yaml.safe_load(f)
+f.close()
+
+HOME = os.environ['HOME']+"/"
+####todo:
+#SCENARIOS_DIR = REPO_PATH + functest_yaml.get("general"). \
+# get("directories").get("dir_rally_scn")
+SCENARIOS_DIR = REPO_PATH + "testcases/VIM/OpenStack/CI/rally_cert/"
+###
+TEMPLATE_DIR = SCENARIOS_DIR + "scenario/templates"
+SUPPORT_DIR = SCENARIOS_DIR + "scenario/support"
+###todo:
+FLAVOR_NAME = "m1.tiny"
+USERS_AMOUNT = 2
+TENANTS_AMOUNT = 3
+CONTROLLERS_AMOUNT = 2
+###
+RESULTS_DIR = functest_yaml.get("general").get("directories"). \
+ get("dir_rally_res")
+TEST_DB = functest_yaml.get("results").get("test_db_url")
+FLOATING_NETWORK = functest_yaml.get("general"). \
+ get("openstack").get("neutron_public_net_name")
+FLOATING_SUBNET_CIDR = functest_yaml.get("general"). \
+ get("openstack").get("neutron_public_subnet_cidr")
+PRIVATE_NETWORK = functest_yaml.get("general"). \
+ get("openstack").get("neutron_private_net_name")
+
+GLANCE_IMAGE_NAME = functest_yaml.get("general"). \
+ get("openstack").get("image_name")
+GLANCE_IMAGE_FILENAME = functest_yaml.get("general"). \
+ get("openstack").get("image_file_name")
+GLANCE_IMAGE_FORMAT = functest_yaml.get("general"). \
+ get("openstack").get("image_disk_format")
+GLANCE_IMAGE_PATH = functest_yaml.get("general"). \
+ get("directories").get("dir_functest_data") + "/" + GLANCE_IMAGE_FILENAME
+
+
+def push_results_to_db(payload):
+
+ url = TEST_DB + "/results"
+ installer = functest_utils.get_installer_type(logger)
+ git_version = functest_utils.get_git_branch(REPO_PATH)
+ pod_name = functest_utils.get_pod_name(logger)
+ # TODO pod_name hardcoded, info shall come from Jenkins
+ params = {"project_name": "functest", "case_name": "Rally",
+ "pod_name": pod_name, "installer": installer,
+ "version": git_version, "details": payload}
+
+ headers = {'Content-Type': 'application/json'}
+ r = requests.post(url, data=json.dumps(params), headers=headers)
+ logger.debug(r)
+
+
+def get_task_id(cmd_raw):
+ """
+ get task id from command rally result
+ :param cmd_raw:
+ :return: task_id as string
+ """
+ taskid_re = re.compile('^Task +(.*): started$')
+ for line in cmd_raw.splitlines(True):
+ line = line.strip()
+ match = taskid_re.match(line)
+ if match:
+ return match.group(1)
+ return None
+
+
+def task_succeed(json_raw):
+ """
+ Parse JSON from rally JSON results
+ :param json_raw:
+ :return: Bool
+ """
+ rally_report = json.loads(json_raw)
+ rally_report = rally_report[0]
+ if rally_report is None:
+ return False
+ if rally_report.get('result') is None:
+ return False
+
+ for result in rally_report.get('result'):
+ if len(result.get('error')) > 0:
+ return False
+
+ return True
+
+
+def build_task_args(test_file_name):
+ task_args = {'service_list': [test_file_name]}
+ task_args['smoke'] = args.smoke
+ task_args['image_name'] = GLANCE_IMAGE_NAME
+ task_args['flavor_name'] = FLAVOR_NAME
+ task_args['glance_image_location'] = GLANCE_IMAGE_PATH
+ task_args['floating_network'] = FLOATING_NETWORK
+ task_args['floating_subnet_cidr'] = FLOATING_SUBNET_CIDR
+ task_args['netid'] = functest_utils.get_network_id(client_dict['neutron'],
+ PRIVATE_NETWORK).encode('ascii', 'ignore')
+ task_args['tmpl_dir'] = TEMPLATE_DIR
+ task_args['sup_dir'] = SUPPORT_DIR
+ task_args['users_amount'] = USERS_AMOUNT
+ task_args['tenants_amount'] = TENANTS_AMOUNT
+ task_args['controllers_amount'] = CONTROLLERS_AMOUNT
+
+ return task_args
+
+
+def run_task(test_name):
+ #
+ # the "main" function of the script who launch rally for a task
+ # :param test_name: name for the rally test
+ # :return: void
+ #
+
+ logger.info('starting {} test ...'.format(test_name))
+
+ task_file = '{}task.yaml'.format(SCENARIOS_DIR)
+ if not os.path.exists(task_file):
+ logger.error("Task file '%s' does not exist." % task_file)
+ exit(-1)
+
+ test_file_name = '{}opnfv-{}.yaml'.format(SCENARIOS_DIR + "scenario/", test_name)
+ if not os.path.exists(test_file_name):
+ logger.error("The scenario '%s' does not exist." % test_file_name)
+ exit(-1)
+
+ logger.debug('Scenario fetched from : {}'.format(test_file_name))
+
+ cmd_line = "rally task start --abort-on-sla-failure " + \
+ "--task {} ".format(task_file) + \
+ "--task-args \"{}\" ".format(build_task_args(test_name))
+ logger.debug('running command line : {}'.format(cmd_line))
+ cmd = os.popen(cmd_line)
+ task_id = get_task_id(cmd.read())
+ logger.debug('task_id : {}'.format(task_id))
+
+ if task_id is None:
+ logger.error("failed to retrieve task_id")
+ exit(-1)
+
+ # check for result directory and create it otherwise
+ if not os.path.exists(RESULTS_DIR):
+ logger.debug('does not exists, we create it'.format(RESULTS_DIR))
+ os.makedirs(RESULTS_DIR)
+
+ # write html report file
+ report_file_name = '{}opnfv-{}.html'.format(RESULTS_DIR, test_name)
+ cmd_line = "rally task report {} --out {}".format(task_id,
+ report_file_name)
+
+ logger.debug('running command line : {}'.format(cmd_line))
+ os.popen(cmd_line)
+
+ # get and save rally operation JSON result
+ cmd_line = "rally task results %s" % task_id
+ logger.debug('running command line : {}'.format(cmd_line))
+ cmd = os.popen(cmd_line)
+ json_results = cmd.read()
+ with open('{}opnfv-{}.json'.format(RESULTS_DIR, test_name), 'w') as f:
+ logger.debug('saving json file')
+ f.write(json_results)
+
+ with open('{}opnfv-{}.json'
+ .format(RESULTS_DIR, test_name)) as json_file:
+ json_data = json.load(json_file)
+
+ # Push results in payload of testcase
+ if args.report:
+ logger.debug("Push result into DB")
+ push_results_to_db(json_data)
+
+ """ parse JSON operation result """
+ if task_succeed(json_results):
+ print 'Test OK'
+ else:
+ print 'Test KO'
+
+
+def main():
+ # configure script
+ if not (args.test_name in tests):
+ logger.error('argument not valid')
+ exit(-1)
+
+ creds_nova = functest_utils.get_credentials("nova")
+ nova_client = novaclient.Client('2',**creds_nova)
+ creds_neutron = functest_utils.get_credentials("neutron")
+ neutron_client = neutronclient.Client(**creds_neutron)
+ creds_keystone = functest_utils.get_credentials("keystone")
+ keystone_client = keystoneclient.Client(**creds_keystone)
+ glance_endpoint = keystone_client.service_catalog.url_for(service_type='image',
+ endpoint_type='publicURL')
+ glance_client = glanceclient.Client(1, glance_endpoint,
+ token=keystone_client.auth_token)
+
+ client_dict['neutron'] = neutron_client
+
+ logger.debug("Creating image '%s' from '%s'..." % (GLANCE_IMAGE_NAME, GLANCE_IMAGE_PATH))
+ image_id = functest_utils.create_glance_image(glance_client,
+ GLANCE_IMAGE_NAME,GLANCE_IMAGE_PATH)
+ if not image_id:
+ logger.error("Failed to create a Glance image...")
+ exit(-1)
+ # Check if the given image exists
+ try:
+ nova_client.images.find(name=GLANCE_IMAGE_NAME)
+ logger.info("Glance image found '%s'" % GLANCE_IMAGE_NAME)
+ except:
+ logger.error("ERROR: Glance image '%s' not found." % GLANCE_IMAGE_NAME)
+ logger.info("Available images are: ")
+ exit(-1)
+
+ if args.test_name == "all":
+ for test_name in tests:
+ if not (test_name == 'all' or
+ test_name == 'vm'):
+ print(test_name)
+ run_task(test_name)
+ else:
+ print(args.test_name)
+ run_task(args.test_name)
+
+ logger.debug("Deleting image...")
+ if not functest_utils.delete_glance_image(nova_client, image_id):
+ logger.error("Error deleting the glance image")
+
+if __name__ == '__main__':
+ main()
diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally.py b/testcases/VIM/OpenStack/CI/libraries/run_rally.py
index 2bfb8127..d5796c1b 100644
--- a/testcases/VIM/OpenStack/CI/libraries/run_rally.py
+++ b/testcases/VIM/OpenStack/CI/libraries/run_rally.py
@@ -8,36 +8,48 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
-import re, json, os, urllib2, argparse, logging, yaml
-
-with open('../functest.yaml') as f:
- functest_yaml = yaml.safe_load(f)
-f.close()
+# 0.1 (05/2015) initial commit
+# 0.2 (28/09/2015) extract Tempest, format json result, add ceilometer suite
+# 0.3 (19/10/2015) remove Tempest from run_rally
+# and push result into test DB
+#
-HOME = os.environ['HOME']+"/"
-SCENARIOS_DIR = HOME + functest_yaml.get("general").get("directories").get("dir_rally_scn")
-RESULTS_DIR = HOME + functest_yaml.get("general").get("directories").get("dir_rally_res")
+import re
+import json
+import os
+import argparse
+import logging
+import yaml
+import requests
+import sys
+from novaclient import client as novaclient
+from keystoneclient.v2_0 import client as keystoneclient
+from glanceclient import client as glanceclient
""" tests configuration """
-tests = ['authenticate', 'glance', 'cinder', 'heat', 'keystone', 'neutron', 'nova', 'quotas', 'requests', 'tempest', 'vm', 'all', 'smoke']
+tests = ['authenticate', 'glance', 'cinder', 'ceilometer', 'heat', 'keystone',
+ 'neutron', 'nova', 'quotas', 'requests', 'vm', 'all']
parser = argparse.ArgumentParser()
-parser.add_argument("test_name", help="The name of the test you want to perform with rally. "
- "Possible values are : "
- "[ {d[0]} | {d[1]} | {d[2]} | {d[3]} | {d[4]} | {d[5]} | {d[6]} "
- "| {d[7]} | {d[8]} | {d[9]} | {d[10]} | {d[11]} | {d[12]}]. The 'all' value performs all the tests scenarios "
- "except 'tempest'".format(d=tests))
+parser.add_argument("test_name",
+ help="Module name to be tested"
+ "Possible values are : "
+ "[ {d[0]} | {d[1]} | {d[2]} | {d[3]} | {d[4]} | "
+ "{d[5]} | {d[6]} | {d[7]} | {d[8]} | {d[9]} | "
+ "{d[10]} | {d[11]}]. The 'all' value "
+ "performs all the possible tests scenarios"
+ .format(d=tests))
parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
-parser.add_argument("test_mode", help="Tempest test mode", nargs='?', default="smoke")
+parser.add_argument("-r", "--report",
+ help="Create json result file",
+ action="store_true")
+
args = parser.parse_args()
-test_mode=args.test_mode
-if not args.test_name == "tempest":
- if not args.test_mode == "smoke":
- parser.error("test_mode is only used with tempest")
+
""" logging configuration """
-logger = logging.getLogger('run_rally')
+logger = logging.getLogger("run_rally")
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
@@ -46,25 +58,53 @@ if args.debug:
else:
ch.setLevel(logging.INFO)
-formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+formatter = logging.Formatter("%(asctime)s - %(name)s - "
+ "%(levelname)s - %(message)s")
ch.setFormatter(formatter)
logger.addHandler(ch)
+REPO_PATH=os.environ['repos_dir']+'/functest/'
+if not os.path.exists(REPO_PATH):
+ logger.error("Functest repository directory not found '%s'" % REPO_PATH)
+ exit(-1)
+sys.path.append(REPO_PATH + "testcases/")
+import functest_utils
-def get_tempest_id(cmd_raw):
- """
- get task id from command rally result
- :param cmd_raw:
- :return: task_id as string
- """
- taskid_re = re.compile('^Verification UUID: (.*)$')
- for line in cmd_raw.splitlines(True):
- line = line.strip()
- match = taskid_re.match(line)
+with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
+ functest_yaml = yaml.safe_load(f)
+f.close()
+
+HOME = os.environ['HOME']+"/"
+SCENARIOS_DIR = REPO_PATH + functest_yaml.get("general"). \
+ get("directories").get("dir_rally_scn")
+RESULTS_DIR = functest_yaml.get("general").get("directories"). \
+ get("dir_rally_res")
+TEST_DB = functest_yaml.get("results").get("test_db_url")
+
+GLANCE_IMAGE_NAME = "functest-img-rally"
+GLANCE_IMAGE_FILENAME = functest_yaml.get("general"). \
+ get("openstack").get("image_file_name")
+GLANCE_IMAGE_FORMAT = functest_yaml.get("general"). \
+ get("openstack").get("image_disk_format")
+GLANCE_IMAGE_PATH = functest_yaml.get("general"). \
+ get("directories").get("dir_functest_data") + "/" + GLANCE_IMAGE_FILENAME
+
+
+def push_results_to_db(payload):
+
+ url = TEST_DB + "/results"
+ installer = functest_utils.get_installer_type(logger)
+ git_version = functest_utils.get_git_branch(REPO_PATH)
+ pod_name = functest_utils.get_pod_name(logger)
+ # TODO pod_name hardcoded, info shall come from Jenkins
+ params = {"project_name": "functest", "case_name": "Rally",
+ "pod_name": pod_name, "installer": installer,
+ "version": git_version, "details": payload}
+
+ headers = {'Content-Type': 'application/json'}
+ r = requests.post(url, data=json.dumps(params), headers=headers)
+ logger.debug(r)
- if match:
- return match.group(1)
- return None
def get_task_id(cmd_raw):
"""
@@ -81,6 +121,16 @@ def get_task_id(cmd_raw):
return None
+def create_glance_image(path, name, disk_format):
+ """
+ Create a glance image given the absolute path of the image, its name and the disk format
+ """
+ cmd = ("glance image-create --name " + name + " --visibility public "
+ "--disk-format " + disk_format + " --container-format bare --file " + path)
+ functest_utils.execute_command(cmd, logger)
+ return True
+
+
def task_succeed(json_raw):
"""
Parse JSON from rally JSON results
@@ -95,68 +145,33 @@ def task_succeed(json_raw):
return False
for result in rally_report.get('result'):
- if len(result.get('errors')) > 0:
+ if len(result.get('error')) > 0:
return False
return True
-def run_tempest():
- """
- the function dedicated to Tempest (functional tests for OpenStack)
- :param test_mode: Tempest mode smoke (default), full, ..
- :return: void
- """
- logger.info('starting {} Tempest ...'.format(test_mode))
-
- """ get the date """
- cmd = os.popen("date '+%d%m%Y_%H%M'")
- test_date = cmd.read().rstrip()
-
- cmd_line = "rally verify start {}".format(test_mode)
- logger.debug('running command line : {}'.format(cmd_line))
- cmd = os.popen(cmd_line)
- task_id = get_tempest_id(cmd.read())
- logger.debug('task_id : {}'.format(task_id))
-
- if task_id is None:
- logger.error("failed to retrieve task_id")
- exit(-1)
-
- """ check for result directory and create it otherwise """
- if not os.path.exists(RESULTS_DIR):
- logger.debug('does not exists, we create it'.format(RESULTS_DIR))
- os.makedirs(RESULTS_DIR)
-
- """ write log report file """
- report_file_name = '{}opnfv-tempest-{}.log'.format(RESULTS_DIR, test_date)
- cmd_line = "rally verify detailed {} > {} ".format(task_id, report_file_name)
- logger.debug('running command line : {}'.format(cmd_line))
- os.popen(cmd_line)
-
def run_task(test_name):
- """
- the "main" function of the script who lunch rally for a task
- :param test_name: name for the rally test
- :return: void
- """
- logger.info('starting {} test ...'.format(test_name))
+ #
+ # the "main" function of the script who lunch rally for a task
+ # :param test_name: name for the rally test
+ # :return: void
+ #
- """ get the date """
- cmd = os.popen("date '+%d%m%Y_%H%M'")
- test_date = cmd.read().rstrip()
+ logger.info('starting {} test ...'.format(test_name))
- """ check directory for scenarios test files or retrieve from git otherwise"""
+ # check directory for scenarios test files or retrieve from git otherwise
proceed_test = True
test_file_name = '{}opnfv-{}.json'.format(SCENARIOS_DIR, test_name)
+
if not os.path.exists(test_file_name):
- logger.debug('{} does not exists'.format(test_file_name))
- proceed_test = retrieve_test_cases_file(test_name, SCENARIOS_DIR)
+ logger.error("The scenario '%s' does not exist." % test_file_name)
+ exit(-1)
- """ we do the test only if we have a scenario test file """
+ # we do the test only if we have a scenario test file
if proceed_test:
logger.debug('Scenario fetched from : {}'.format(test_file_name))
- cmd_line = "rally task start --abort-on-sla-failure %s" % test_file_name
+ cmd_line = "rally task start --abort-on-sla-failure {}".format(test_file_name)
logger.debug('running command line : {}'.format(cmd_line))
cmd = os.popen(cmd_line)
task_id = get_task_id(cmd.read())
@@ -166,26 +181,36 @@ def run_task(test_name):
logger.error("failed to retrieve task_id")
exit(-1)
- """ check for result directory and create it otherwise """
+ # check for result directory and create it otherwise
if not os.path.exists(RESULTS_DIR):
logger.debug('does not exists, we create it'.format(RESULTS_DIR))
os.makedirs(RESULTS_DIR)
- """ write html report file """
- report_file_name = '{}opnfv-{}-{}.html'.format(RESULTS_DIR, test_name, test_date)
- cmd_line = "rally task report %s --out %s" % (task_id, report_file_name)
+ # write html report file
+ report_file_name = '{}opnfv-{}.html'.format(RESULTS_DIR, test_name)
+ cmd_line = "rally task report {} --out {}".format(task_id,
+ report_file_name)
+
logger.debug('running command line : {}'.format(cmd_line))
os.popen(cmd_line)
- """ get and save rally operation JSON result """
+ # get and save rally operation JSON result
cmd_line = "rally task results %s" % task_id
logger.debug('running command line : {}'.format(cmd_line))
cmd = os.popen(cmd_line)
json_results = cmd.read()
- with open('{}opnfv-{}-{}.json'.format(RESULTS_DIR, test_name, test_date), 'w') as f:
+ with open('{}opnfv-{}.json'.format(RESULTS_DIR, test_name), 'w') as f:
logger.debug('saving json file')
f.write(json_results)
- logger.debug('saving json file2')
+
+ with open('{}opnfv-{}.json'
+ .format(RESULTS_DIR, test_name)) as json_file:
+ json_data = json.load(json_file)
+
+ # Push results in payload of testcase
+ if args.report:
+ logger.debug("Push result into DB")
+ push_results_to_db(json_data)
""" parse JSON operation result """
if task_succeed(json_results):
@@ -193,53 +218,55 @@ def run_task(test_name):
else:
print 'Test KO'
else:
- logger.error('{} test failed, unable to fetch a scenario test file'.format(test_name))
-
-
-def retrieve_test_cases_file(test_name, tests_path):
- """
- Retrieve from github the sample test files
- :return: Boolean that indicates the retrieval status
- """
-
- """ do not add the "/" at the end """
- url_base = "https://git.opnfv.org/cgit/functest/plain/testcases/VIM/OpenStack/CI/suites"
-
- test_file_name = 'opnfv-{}.json'.format(test_name)
- logger.info('fetching {}/{} ...'.format(url_base, test_file_name))
-
- try:
- response = urllib2.urlopen('{}/{}'.format(url_base, test_file_name))
- except (urllib2.HTTPError, urllib2.URLError):
- return False
- file_raw = response.read()
-
- """ check if the test path exist otherwise we create it """
- if not os.path.exists(tests_path):
- os.makedirs(tests_path)
-
- with open('{}/{}'.format(tests_path, test_file_name), 'w') as f:
- f.write(file_raw)
- return True
+ logger.error('{} test failed, unable to fetch a scenario test file'
+ .format(test_name))
def main():
- """ configure script """
+ # configure script
if not (args.test_name in tests):
logger.error('argument not valid')
exit(-1)
+ creds_nova = functest_utils.get_credentials("nova")
+ nova_client = novaclient.Client('2',**creds_nova)
+ creds_keystone = functest_utils.get_credentials("keystone")
+ keystone_client = keystoneclient.Client(**creds_keystone)
+ glance_endpoint = keystone_client.service_catalog.url_for(service_type='image',
+ endpoint_type='publicURL')
+ glance_client = glanceclient.Client(1, glance_endpoint,
+ token=keystone_client.auth_token)
+
+ logger.debug("Creating image '%s' from '%s'..." % (GLANCE_IMAGE_NAME, GLANCE_IMAGE_PATH))
+ image_id = functest_utils.create_glance_image(glance_client,
+ GLANCE_IMAGE_NAME,GLANCE_IMAGE_PATH)
+ if not image_id:
+ logger.error("Failed to create a Glance image...")
+ exit(-1)
+ # Check if the given image exists
+ try:
+ nova_client.images.find(name=GLANCE_IMAGE_NAME)
+ logger.info("Glance image found '%s'" % GLANCE_IMAGE_NAME)
+ except:
+ logger.error("ERROR: Glance image '%s' not found." % GLANCE_IMAGE_NAME)
+ logger.info("Available images are: ")
+ exit(-1)
+
if args.test_name == "all":
for test_name in tests:
- if not (test_name == 'all' or test_name == 'tempest'):
+ if not (test_name == 'all' or
+ test_name == 'heat' or
+ test_name == 'ceilometer' or
+ test_name == 'smoke' or
+ test_name == 'vm'):
print(test_name)
run_task(test_name)
else:
print(args.test_name)
- if args.test_name == 'tempest':
- run_tempest()
- else:
- run_task(args.test_name)
+ run_task(args.test_name)
+
+ if not functest_utils.delete_glance_image(nova_client, image_id):
+ logger.error("Error deleting the glance image")
if __name__ == '__main__':
main()
diff --git a/testcases/VIM/OpenStack/CI/libraries/run_tempest.py b/testcases/VIM/OpenStack/CI/libraries/run_tempest.py
new file mode 100644
index 00000000..e24697c7
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/run_tempest.py
@@ -0,0 +1,260 @@
+#!/usr/bin/env python
+#
+# Description:
+# Runs tempest and pushes the results to the DB
+#
+# Authors:
+# morgan.richomme@orange.com
+# jose.lausuch@ericsson.com
+#
+
+import argparse
+import json
+import logging
+import os
+import re
+import requests
+import subprocess
+import sys
+import yaml
+import keystoneclient.v2_0.client as ksclient
+from neutronclient.v2_0 import client as neutronclient
+
+modes = ['full', 'smoke', 'baremetal', 'compute', 'data_processing',
+ 'identity', 'image', 'network', 'object_storage', 'orchestration',
+ 'telemetry', 'volume', 'custom']
+
+""" tests configuration """
+parser = argparse.ArgumentParser()
+parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
+parser.add_argument("-m", "--mode", help="Tempest test mode [smoke, all]",
+ default="smoke")
+parser.add_argument("-r", "--report",
+ help="Create json result file",
+ action="store_true")
+
+args = parser.parse_args()
+
+""" logging configuration """
+logger = logging.getLogger('run_tempest')
+logger.setLevel(logging.DEBUG)
+
+ch = logging.StreamHandler()
+if args.debug:
+ ch.setLevel(logging.DEBUG)
+else:
+ ch.setLevel(logging.INFO)
+
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ch.setFormatter(formatter)
+logger.addHandler(ch)
+
+REPO_PATH=os.environ['repos_dir']+'/functest/'
+if not os.path.exists(REPO_PATH):
+ logger.error("Functest repository directory not found '%s'" % REPO_PATH)
+ exit(-1)
+sys.path.append(REPO_PATH + "testcases/")
+import functest_utils
+
+with open("/home/opnfv/functest/conf/config_functest.yaml") as f:
+ functest_yaml = yaml.safe_load(f)
+f.close()
+TEST_DB = functest_yaml.get("results").get("test_db_url")
+
+MODE = "smoke"
+TENANT_NAME = functest_yaml.get("tempest").get("identity").get("tenant_name")
+TENANT_DESCRIPTION = functest_yaml.get("tempest").get("identity").get("tenant_description")
+USER_NAME = functest_yaml.get("tempest").get("identity").get("user_name")
+USER_PASSWORD = functest_yaml.get("tempest").get("identity").get("user_password")
+DEPLOYMENT_MAME = functest_yaml.get("rally").get("deployment_name")
+RALLY_INSTALLATION_DIR = functest_yaml.get("general").get("directories").get("dir_rally_inst")
+
+
+def get_info(file_result):
+ test_run = ""
+ duration = ""
+ test_failed = ""
+
+ p = subprocess.Popen('cat tempest.log',
+ shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ for line in p.stdout.readlines():
+ # print line,
+ if (len(test_run) < 1):
+ test_run = re.findall("[0-9]*\.[0-9]*s", line)
+ if (len(duration) < 1):
+ duration = re.findall("[0-9]*\ tests", line)
+ regexp = r"(failures=[0-9]+)"
+ if (len(test_failed) < 1):
+ test_failed = re.findall(regexp, line)
+
+ retval = p.wait()
+
+ logger.debug("test_run:"+test_run)
+ logger.debug("duration:"+duration)
+
+
+def push_results_to_db(payload, module, pod_name):
+
+ # TODO move DB creds into config file
+ url = TEST_DB + "/results"
+ installer = functest_utils.get_installer_type(logger)
+ git_version = functest_utils.get_git_branch(REPO_PATH)
+ logger.info("Pushing results to DB: '%s'." % url)
+
+ params = {"project_name": "functest", "case_name": "Tempest",
+ "pod_name": str(pod_name), 'installer': installer,
+ "version": git_version, 'details': payload}
+ headers = {'Content-Type': 'application/json'}
+
+ r = requests.post(url, data=json.dumps(params), headers=headers)
+ logger.debug(r)
+
+
+def create_tempest_resources():
+ ks_creds = functest_utils.get_credentials("keystone")
+ logger.info("Creating tenant and user for Tempest suite")
+ keystone = ksclient.Client(**ks_creds)
+ tenant_id = functest_utils.create_tenant(keystone, TENANT_NAME, TENANT_DESCRIPTION)
+ if tenant_id == '':
+ logger.error("Error : Failed to create %s tenant" %TENANT_NAME)
+
+ user_id = functest_utils.create_user(keystone, USER_NAME, USER_PASSWORD, None, tenant_id)
+ if user_id == '':
+ logger.error("Error : Failed to create %s user" %USER_NAME)
+
+
+def free_tempest_resources():
+ ks_creds = functest_utils.get_credentials("keystone")
+ logger.info("Deleting tenant and user for Tempest suite)")
+ keystone = ksclient.Client(**ks_creds)
+
+ user_id = functest_utils.get_user_id(keystone, USER_NAME)
+ if user_id == '':
+ logger.error("Error : Failed to get id of %s user" % USER_NAME)
+ else:
+ if not functest_utils.delete_user(keystone, user_id):
+ logger.error("Error : Failed to delete %s user" % USER_NAME)
+
+ tenant_id = functest_utils.get_tenant_id(keystone, TENANT_NAME)
+ if tenant_id == '':
+ logger.error("Error : Failed to get id of %s tenant" % TENANT_NAME)
+ else:
+ if not functest_utils.delete_tenant(keystone, tenant_id):
+ logger.error("Error : Failed to delete %s tenant" % TENANT_NAME)
+
+
+def configure_tempest():
+ """
+ Add/update needed parameters into tempest.conf file generated by Rally
+ """
+
+ logger.debug("Generating tempest.conf file...")
+ cmd = "rally verify genconfig"
+ functest_utils.execute_command(cmd,logger)
+
+ logger.debug("Resolving deployment UUID...")
+ cmd = "rally deployment list | awk '/"+DEPLOYMENT_MAME+"/ {print $2}'"
+ p = subprocess.Popen(cmd, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT);
+ deployment_uuid = p.stdout.readline().rstrip()
+ if deployment_uuid == "":
+ logger.debug(" Rally deployment NOT found")
+ return False
+
+ logger.debug("Finding tempest.conf file...")
+ tempest_conf_file = RALLY_INSTALLATION_DIR+"/tempest/for-deployment-" \
+ +deployment_uuid+"/tempest.conf"
+ if tempest_conf_file == "":
+ logger.debug(" Tempest configuration file NOT found")
+ return False
+
+ logger.debug(" Updating fixed_network_name...")
+ private_net_name = ""
+ creds_neutron = functest_utils.get_credentials("neutron")
+ neutron_client = neutronclient.Client(**creds_neutron)
+ private_net = functest_utils.get_private_net(neutron_client)
+ if private_net is None:
+ logger.error("No shared private networks found.")
+ else:
+ private_net_name = private_net['name']
+ cmd = "crudini --set "+tempest_conf_file+" compute fixed_network_name " \
+ +private_net_name
+ functest_utils.execute_command(cmd,logger)
+
+ logger.debug(" Updating non-admin credentials...")
+ cmd = "crudini --set "+tempest_conf_file+" identity tenant_name " \
+ +TENANT_NAME
+ functest_utils.execute_command(cmd,logger)
+ cmd = "crudini --set "+tempest_conf_file+" identity username " \
+ +USER_NAME
+ functest_utils.execute_command(cmd,logger)
+ cmd = "crudini --set "+tempest_conf_file+" identity password " \
+ +USER_PASSWORD
+ functest_utils.execute_command(cmd,logger)
+
+ return True
+
+
+def run_tempest(OPTION):
+ #
+ # the "main" function of the script which launches Rally to run Tempest
+ # :param option: tempest option (smoke, ..)
+ # :return: void
+ #
+ logger.info("Starting Tempest test suite: '%s'." % OPTION)
+ cmd_line = "rally verify start "+OPTION
+ logger.debug('Executing command : {}'.format(cmd_line))
+ subprocess.call(cmd_line, shell=True, stderr=subprocess.STDOUT)
+
+ cmd_line = "rally verify list"
+ logger.debug('Executing command : {}'.format(cmd_line))
+ cmd = os.popen(cmd_line)
+ output = (((cmd.read()).splitlines()[3]).replace(" ", "")).split("|")
+ # Format:
+ # | UUID | Deployment UUID | smoke | tests | failures | Created at |
+ # Duration | Status |
+ num_tests = output[4]
+ num_failures = output[5]
+ time_start = output[6]
+ duration = output[7]
+ # Compute duration (lets assume it does not take more than 60 min)
+ dur_min=int(duration.split(':')[1])
+ dur_sec_float=float(duration.split(':')[2])
+ dur_sec_int=int(round(dur_sec_float,0))
+ dur_sec_int = dur_sec_int + 60 * dur_min
+
+ # Generate json results for DB
+ json_results = {"timestart": time_start, "duration": dur_sec_int,
+ "tests": int(num_tests), "failures": int(num_failures)}
+ logger.info("Results: "+str(json_results))
+ pod_name = functest_utils.get_pod_name(logger)
+
+ # Push results in payload of testcase
+ if args.report:
+ logger.debug("Push result into DB")
+ push_results_to_db(json_results, MODE, pod_name)
+
+
+def main():
+ global MODE
+ if not (args.mode):
+ MODE = "smoke"
+ elif not (args.mode in modes):
+ logger.error("Tempest mode not valid. Possible values are:\n"
+ + str(modes))
+ exit(-1)
+ elif (args.mode == 'custom'):
+ MODE = "--tests-file "+REPO_PATH+"testcases/VIM/OpenStack/CI/custom_tests/test_list.txt"
+ else:
+ MODE = "--set "+args.mode
+
+ create_tempest_resources()
+ configure_tempest()
+ run_tempest(MODE)
+ free_tempest_resources()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/testcases/VIM/OpenStack/CI/libraries/test_openstack.sh b/testcases/VIM/OpenStack/CI/libraries/test_openstack.sh
new file mode 100755
index 00000000..7225796c
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/libraries/test_openstack.sh
@@ -0,0 +1,111 @@
+#
+# Script to test clean_openstack.py
+#
+# Author:
+# jose.lausuch@ericsson.com
+#
+
+if [ -z $OS_AUTH_URL ]; then
+ echo "Source credentials first"
+ exit 1
+fi
+
+echo "Using following credentials:"
+env | grep OS
+
+#################################
+echo "Creating keystone stuff.."
+#################################
+keystone tenant-create --name tenant_test1
+keystone tenant-create --name tenant_test2
+tenant1_id=$(keystone tenant-list | grep tenant_test1 | awk '{print $2}')
+tenant2_id=$(keystone tenant-list | grep tenant_test2 | awk '{print $2}')
+keystone user-create --name user_test11 --tenant $tenant1_id
+keystone user-create --name user_test12 --tenant $tenant1_id
+keystone user-create --name user_test13 --tenant $tenant1_id
+keystone user-create --name user_test21 --tenant $tenant2_id
+keystone user-create --name user_test22 --tenant $tenant2_id
+
+
+#################################
+echo "Creating glance stuff.."
+#################################
+wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
+glance image-create --name image_test1 --disk-format qcow2 --container-format bare < cirros-0.3.4-x86_64-disk.img
+glance image-create --name image_test2 --disk-format qcow2 --container-format bare < cirros-0.3.4-x86_64-disk.img
+#glance image-create --name test --visibility public --disk-format qcow2 --container-format bare --file cirros-0.3.4-x86_64-disk.img
+
+
+#################################
+echo "Creating cinder stuff.."
+#################################
+cinder create --display_name volume-test1 1
+cinder create --display_name volume-test2 2
+
+
+#################################
+echo "Creating NEUTRON stuff.."
+#################################
+echo "1. Create Networks."
+neutron net-create net-test1
+neutron net-create net-test2
+
+echo "2. Create subnets."
+neutron subnet-create --name subnet-test11 --allocation-pool start=10.7.0.2,end=10.7.0.253 --gateway 10.7.0.254 net-test1 10.7.0.0/24
+neutron subnet-create --name subnet-test21 --allocation-pool start=10.6.0.2,end=10.6.0.253 --gateway 10.6.0.254 net-test2 10.6.0.0/24
+
+echo "3. Create Ports."
+neutron port-create --name port-test11 --fixed-ip ip_address=10.7.0.10 net-test1
+neutron port-create --name port-test21 --fixed-ip ip_address=10.6.0.60 net-test2
+
+
+echo "4. Create Routers."
+neutron router-create router-test1
+neutron router-create router-test2
+router1_id=$(neutron router-list | grep router-test1 | awk '{print $2}')
+router1_id=$(neutron router-list | grep router-test2 | awk '{print $2}')
+
+neutron router-gateway-set router-test1 net04_ext
+neutron router-gateway-set router-test2 net04_ext
+
+neutron router-interface-add router-test1 subnet-test11
+neutron router-interface-add router-test2 subnet-test21
+
+echo "5. Floating IPs."
+neutron floatingip-create net04_ext
+neutron floatingip-create net04_ext
+neutron floatingip-create net04_ext
+neutron floatingip-create net04_ext
+
+floating_ip1_id=$(neutron floatingip-list | awk 'FNR == 4 {print}' | awk '{print $2}')
+floating_ip2_id=$(neutron floatingip-list | awk 'FNR == 5 {print}' | awk '{print $2}')
+floating_ip3_id=$(neutron floatingip-list | awk 'FNR == 6 {print}' | awk '{print $2}')
+floating_ip4_id=$(neutron floatingip-list | awk 'FNR == 7 {print}' | awk '{print $2}')
+
+floating_ip1=$(neutron floatingip-list | awk 'FNR == 4 {print}' | awk '{print $5}')
+floating_ip2=$(neutron floatingip-list | awk 'FNR == 5 {print}' | awk '{print $5}')
+floating_ip3=$(neutron floatingip-list | awk 'FNR == 6 {print}' | awk '{print $5}')
+floating_ip4=$(neutron floatingip-list | awk 'FNR == 7 {print}' | awk '{print $5}')
+
+#################################
+echo "Creating NOVA stuff.."
+#################################
+net1_id=$(neutron net-list | grep net-test1 | awk '{print $2}')
+net2_id=$(neutron net-list | grep net-test2 | awk '{print $2}')
+
+nova boot --flavor 2 --image image_test1 --nic net-id=$net1_id nova-test11
+nova boot --flavor 2 --image image_test1 --nic net-id=$net1_id nova-test12
+nova boot --flavor 2 --image image_test2 --nic net-id=$net2_id nova-test21
+nova boot --flavor 2 --image image_test2 --nic net-id=$net2_id nova-test22
+
+vm1_id=$(nova list | grep nova-test11 | awk '{print $2}')
+vm2_id=$(nova list | grep nova-test12 | awk '{print $2}')
+vm3_id=$(nova list | grep nova-test21 | awk '{print $2}')
+vm4_id=$(nova list | grep nova-test22 | awk '{print $2}')
+
+nova floating-ip-associate $vm1_id $floating_ip1
+nova floating-ip-associate $vm2_id $floating_ip2
+nova floating-ip-associate $vm3_id $floating_ip3
+nova floating-ip-associate $vm4_id $floating_ip4
+
+#neutron floatingip-associate --fixed-ip-address $floating_ip2 <PORT>