diff options
-rw-r--r-- | INFO | 13 | ||||
-rw-r--r-- | docker/demo.sh | 143 | ||||
-rw-r--r-- | docker/start.sh | 12 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/adapters/client.py | 69 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/adapters/connection.py | 79 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/adapters/environment.py | 48 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py | 38 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/onosfunctest.py | 198 | ||||
-rw-r--r-- | testcases/Dashboard/dashboard_utils.py | 86 | ||||
-rw-r--r-- | testcases/Dashboard/vPing2Dashboard.py | 1 | ||||
-rw-r--r-- | testcases/VIM/OpenStack/CI/libraries/run_rally.py | 164 | ||||
-rw-r--r-- | testcases/VIM/OpenStack/CI/libraries/run_tempest.py | 144 | ||||
-rw-r--r-- | testcases/config_functest.yaml | 17 | ||||
-rw-r--r-- | testcases/functest_utils.py | 137 | ||||
-rw-r--r-- | testcases/vIMS/CI/vIMS.py | 6 | ||||
-rw-r--r-- | testcases/vPing/CI/libraries/vPing.py | 10 |
16 files changed, 763 insertions, 402 deletions
@@ -3,7 +3,7 @@ Project Creation Date: January 20, 2015 Project Category: Integration & Testing Lifecycle State: Incubation Primary Contact: Morgan Richomme (morgan.richomme@orange.com) -Project Lead: Morgan Richomme (morgan.richomme@orange.comtrevor.cooper@inte) +Project Lead: Morgan Richomme (morgan.richomme@orange.com) Jira Project Name: Base System Functionality Testing Project Jira Project Prefix: FUNCTEST Mailing list tag: [functest] @@ -19,17 +19,22 @@ morgan.richomme@orange.com trevor.cooper@intel.com Prabu.Kuppuswamy@spirent.com fuqiao@chinamobile.com -chitti.nimmagadda@ericsson.com raja.karthik@hp.com vivekanandan.p@hp.com koffirodrigue@gmail.com dk068x@att.com meimei@huawei.com valentin.boucher@orange.com +lanqinglong@huawei.com +viktor.tikkanen@nokia.com +juha.kosonen@nokia.com +zhanghaoyu7@huawei.com Link to TSC approval of the project: http://meetbot.opnfv.org/meetings/opnfv-meeting/2015/opnfv-meeting.2015-01-20-14.57.html -Link(s) to approval of additional committers: http://lists.opnfv.org/pipermail/opnfv-tech-discuss/2015-April/001971.html +Link(s) to approval of additional committers: +http://lists.opnfv.org/pipermail/opnfv-tech-discuss/2015-April/001971.html +http://ircbot.wl.linuxfoundation.org/meetings/opnfv-testperf/2015/opnfv-testperf.2015-09-29-13.00.html -* Addition of the following committers was approved by majority vote of exisitng committers: pbandzi@cisco.com, sama@docomolab-euro.com, jose.lausuch@ericsson.com ,Andrew.Caldwell@metaswitch.com, morgan.richomme@orange.com, iben.rodriguez@spirent.com +* Addition of the following committers was approved by majority vote of exisitng committers: pbandzi@cisco.com, sama@docomolab-euro.com, jose.lausuch@ericsson.com ,Andrew.Caldwell@metaswitch.com, morgan.richomme@orange.com, iben.rodriguez@spirent.com, koffirodrigue@gmail.com, dk068x@att.com, meimei@huawei.com, valentin.boucher@orange.com, lanqinglong@huawei.com, viktor.tikkanen@nokia.com, juha.kosonen@nokia.com, zhanghaoyu7@huawei.com diff --git a/docker/demo.sh b/docker/demo.sh new file mode 100644 index 000000000..4207810eb --- /dev/null +++ b/docker/demo.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +# +# Author: Jose Lausuch (jose.lausuch@ericsson.com) +# +# Installs the Functest framework within the Docker container +# and run the tests automatically +# +# DO NOT USE FOR PRODUCTION. +# Changes: +# It runs only 1 Rally bench scenario +# + + +config_file=$(find / -name config_functest.yaml) + +REPOS_DIR=$(cat $config_file | grep -w dir_repos | awk 'END {print $NF}') +FUNCTEST_REPO_DIR=$(cat $config_file | grep -w dir_repo_functest | awk 'END {print $NF}') +RALLY_REPO_DIR=$(cat $config_file | grep -w dir_repo_rally | awk 'END {print $NF}') +RELENG_REPO_DIR=$(cat $config_file | grep -w dir_repo_releng | awk 'END {print $NF}') + +FUNCTEST_DIR=$(cat $config_file | grep -w dir_functest | awk 'END {print $NF}') +FUNCTEST_RESULTS_DIR=$(cat $config_file | grep -w dir_results | awk 'END {print $NF}') +FUNCTEST_CONF_DIR=$(cat $config_file | grep -w dir_functest_conf | awk 'END {print $NF}') +FUNCTEST_DATA_DIR=$(cat $config_file | grep -w dir_functest_data | awk 'END {print $NF}') +RALLY_VENV=$(cat $config_file | grep -w dir_rally_inst | awk 'END {print $NF}') +RALLY_COMMIT=$(cat $config_file | grep -w rally_stable_commit | awk 'END {print $NF}') + + +info () { + logger -s -t "start.info" "$*" +} + + +error () { + logger -s -t "start.error" "$*" + exit 1 +} + +# Check if environment variables are set +if [ -z ${INSTALLER_TYPE} ]; then + error "Environment variable 'INSTALLER_TYPE' is not defined." +elif [ "${INSTALLER_TYPE}" != "fuel" ] && [ "${INSTALLER_TYPE}" != "foreman" ]; then + error "Invalid environment variable INSTALLER_TYPE=${INSTALLER_TYPE}" +fi + +if [ -z ${INSTALLER_IP} ]; then + error "Environment variable 'INSTALLER_IP' is not defined." +fi + +echo "#############################################" +echo "############### FUNCTEST DEMO ###############" +echo "#############################################" + +# Update repos +echo "---------- Updating repositories ----------" +cd ${FUNCTEST_REPO_DIR} +git pull +echo "Functest repository updated." +cd ${RELENG_REPO_DIR} +git pull +echo "Releng repository updated." +cd ${RALLY_REPO_DIR} +git reset --hard ${RALLY_COMMIT} +echo "Rally repository reset to commit ${RALLY_COMMIT}." + + +# Create directories +echo "---------- Creating directories ----------" +mkdir -p ${FUNCTEST_CONF_DIR} +echo "${FUNCTEST_CONF_DIR} created." +mkdir -p ${FUNCTEST_DATA_DIR} +echo "${FUNCTEST_DATA_DIR} created." +mkdir -p ${FUNCTEST_RESULTS_DIR}/ODL +echo "${FUNCTEST_RESULTS_DIR}/ODL created." + + + +# Create Openstack credentials file +echo "---------- Retrieving Credentials from Fuel ----------" +${REPOS_DIR}/releng/utils/fetch_os_creds.sh -d ${FUNCTEST_CONF_DIR}/openstack.creds \ + -i ${INSTALLER_TYPE} -a ${INSTALLER_IP} +retval=$? +if [ $retval != 0 ]; then + echo "Cannot retrieve credentials file from installation. Check logs." + exit $retval +fi +echo "Credentials succesfully stored in ${FUNCTEST_CONF_DIR}/openstack.creds" + +# Source credentials +echo "---------- Sourcing Openstack Credentials ----------" +source ${FUNCTEST_CONF_DIR}/openstack.creds + + +# Prepare Functest Environment +echo "---------- Preparing Functest environment ----------" +python ${FUNCTEST_REPO_DIR}/testcases/config_functest.py --debug ${FUNCTEST_REPO_DIR}/ start +retval=$? +if [ $retval != 0 ]; then + echo "Error when configuring Functest environment" + exit $retval +fi + +# vPing +echo "----------------------------------------------" +echo "---------- Running vPING test case ----------" +echo "----------------------------------------------" +python ${FUNCTEST_REPO_DIR}/testcases/vPing/CI/libraries/vPing.py --debug ${FUNCTEST_REPO_DIR}/ -r + +# ODL +echo "----------------------------------------------" +echo "---------- Running ODL test case ----------" +echo "----------------------------------------------" +if [ $INSTALLER_TYPE == "fuel" ]; then + odl_ip=$(keystone catalog --service network | grep publicURL | cut -f3 -d"/" | cut -f1 -d":") + neutron_ip=$(keystone catalog --service identity | grep publicURL | cut -f3 -d"/" | cut -f1 -d":") + usr_name=$(env | grep OS | grep OS_USERNAME | cut -f2 -d'=') + pass=$(env | grep OS | grep OS_PASSWORD | cut -f2 -d'=') + odl_port=8181 + ODL_PORT=$odl_port ODL_IP=$odl_ip NEUTRON_IP=$neutron_ip USR_NAME=$usr_name PASS=$pass \ + ${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/start_tests.sh +elif [ $INSTALLER_TYPE == "foreman" ]; then + #odl_port=8081 + ${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/start_tests.sh +else + echo "INSTALLER_TYPE not valid." + exit 1 +fi + +# rally +echo "----------------------------------------------" +echo "------- Running Rally bench test case -------" +echo "----------------------------------------------" +echo "Functest: run Functest Rally Bench suites" +python ${FUNCTEST_REPO_DIR}/testcases/VIM/OpenStack/CI/libraries/run_rally.py --debug ${FUNCTEST_REPO_DIR}/ glance + +# tempest +echo "----------------------------------------------" +echo "-------- Running Tempest smoke tests --------" +echo "----------------------------------------------" +echo "Functest: run Tempest suite" +rally verify start smoke +rally verify list diff --git a/docker/start.sh b/docker/start.sh index bd2308caf..60a21d1f6 100644 --- a/docker/start.sh +++ b/docker/start.sh @@ -134,9 +134,13 @@ rally verify list echo "Functest: copy results and clean Functest environment" # save ODL results -cp -Rf ${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/logs ${FUNCTEST_RESULTS_DIR}/ODL +odl_logs="${FUNCTEST_REPO_DIR}/testcases/Controllers/ODL/CI/logs" +if [ -d ${tempest_conf} ]; then + cp -Rf ${odl_logs} ${FUNCTEST_CONF_DIR}/ODL/ +fi # save tempest.conf for further troubleshooting -cp $RALLY_VENV/tempest/for-deployment-*/tempest.conf ${FUNCTEST_CONF_DIR} - - +tempest_conf="${RALLY_VENV}/tempest/for-deployment-*/tempest.conf" +if [ -f ${tempest_conf} ]; then + cp $tempest_conf ${FUNCTEST_CONF_DIR} +fi
\ No newline at end of file diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/client.py b/testcases/Controllers/ONOS/Teston/CI/adapters/client.py new file mode 100644 index 000000000..32e3749f0 --- /dev/null +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/client.py @@ -0,0 +1,69 @@ +""" +Description: + This file is used to run testcase + lanqinglong@huawei.com +""" +from environment import environment +import os +import time +import pexpect +import re + +class client( environment ): + + def __init__( self ): + environment.__init__( self ) + self.loginfo = environment() + self.testcase = '' + + def RunScript( self, handle, testname, timeout=300 ): + """ + Run ONOS Test Script + Parameters: + testname: ONOS Testcase Name + masterusername: The server username of running ONOS + masterpassword: The server password of running ONOS + """ + self.testcase = testname + self.ChangeTestCasePara( testname, self.masterusername, self.masterpassword ) + runhandle = handle + runtest = self.home + "/OnosSystemTest/TestON/bin/cli.py run " + testname + runhandle.sendline(runtest) + circletime = 0 + lastshowscreeninfo = '' + while True: + Result = runhandle.expect(["PEXPECT]#", pexpect.EOF, pexpect.TIMEOUT]) + curshowscreeninfo = runhandle.before + if (len(lastshowscreeninfo) != len(curshowscreeninfo)): + print str(curshowscreeninfo)[len(lastshowscreeninfo)::] + lastshowscreeninfo = curshowscreeninfo + if Result == 0: + print "Done!" + return + time.sleep(1) + circletime += 1 + if circletime > timeout: + break + self.loginfo.log( "Timeout when running the test, please check!" ) + + def onosstart( self ): + #This is the compass run machine user&pass,you need to modify + + print "Test Begin....." + self.OnosConnectionSet() + masterhandle = self.SSHlogin(self.localhost, self.masterusername, + self.masterpassword) + self.OnosEnvSetup( masterhandle ) + return masterhandle + + def onosclean( self, handle ): + self.SSHRelease( handle ) + self.loginfo.log('Release onos handle Successful') + + def push_results_to_db( self, payload, pushornot = 1): + url = self.Result_DB + "/results" + params = {"project_name": "functest", "case_name": "ONOS-" + self.testcase, + "pod_name": 'huawei-build-2', "details": payload} + headers = {'Content-Type': 'application/json'} + r = requests.post(url, data=json.dumps(params), headers=headers) + self.loginfo.log('Pushing result via Northbound, info:' + r ) diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py b/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py index 9890ecfae..f7f283ed0 100644 --- a/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py @@ -13,12 +13,13 @@ import re import sys from foundation import foundation -class connection: +class connection( foundation ): def __init__( self ): + foundation.__init__( self ) self.loginfo = foundation() - def AddKnownHost( self, ipaddr, username, password ): + def AddKnownHost( self, handle, ipaddr, username, password ): """ Add an user to known host,so that onos can login in with onos $ipaddr. parameters: @@ -27,7 +28,8 @@ class connection: password: login password """ print( "Now Adding an user to known hosts " + ipaddr ) - login = pexpect.spawn( "ssh -l %s -p 8101 %s"%( username, ipaddr ) ) + login = handle + login.sendline( "ssh -l %s -p 8101 %s"%( username, ipaddr ) ) index = 0 while index != 2: index = login.expect( ['assword:', 'yes/no', pexpect.EOF, \ @@ -38,38 +40,64 @@ class connection: index = login.expect( ["closed", pexpect.EOF] ) if index == 0: self.loginfo.log( "Add SSH Known Host Success!" ) + break else: self.loginfo.log( "Add SSH Known Host Failed! Please Check!" ) - #login.interact() + break + login.prompt( ) if index == 1: login.sendline('yes') - def Gensshkey( self ): + def GetEnvValue( self, handle, envname): + """ + os.getenv only returns current user value + GetEnvValue returns a environment value of + current handle + eg: GetEnvValue(handle,'HOME') + """ + envhandle = handle + envhandle.sendline( 'echo $' + envname ) + envhandle.prompt( ) + reg = envname + '\r\n(.*)\r' + envaluereg = re.compile( reg ) + envalue = envaluereg.search( envhandle.before ) + if envalue: + return envalue.groups()[0] + else: + return None + + def Gensshkey( self, handle ): """ Generate ssh keys, used for some server have no sshkey. """ print "Now Generating SSH keys..." #Here file name may be id_rsa or id_ecdsa or others #So here will have a judgement - filelist = os.listdir( '~/.ssh' ) + keysub = handle + filepath = self.GetEnvValue( keysub, 'HOME' ) + '/.ssh' + filelist = os.listdir( filepath ) for item in filelist: if 'id' in item: self.loginfo.log("SSH keys are exsit in ssh directory.") return True - keysub = pexpect.spawn("ssh-keygen -t rsa") + keysub.sendline("ssh-keygen -t rsa") Result = 0 while Result != 2: Result = keysub.expect( ["Overwrite", "Enter", pexpect.EOF, \ - pexpect.TIMEOUT]) + 'PEXPECT]#', pexpect.TIMEOUT]) if Result == 0: keysub.sendline("y") - if Result == 1: + if Result == 1 or Result == 2: keysub.sendline("\n") if Result == 3: + self.loginfo.log( "Generate SSH key success." ) + keysub.prompt() + break + if Result == 4: self.loginfo.log("Generate SSH key failed.") - - self.loginfo.log( "Generate SSH key success." ) + keysub.prompt() + break def GetRootAuth( self, password ): """ @@ -126,16 +154,33 @@ class connection: envAdd.close( ) self.loginfo.log( "Add env to bashrc success!" ) + def OnosRootPathChange( self, onospath ): + """ + Change ONOS root path in file:bash_profile + onospath: path of onos root + """ + print "Now Changing ONOS Root Path" + filepath = onospath + '/onos/tools/dev/bash_profile' + line = open(filepath, 'r').readlines() + lenall = len(line) - 1 + for i in range(lenall): + if "export ONOS_ROOT" in line[i]: + line[i] = 'export ONOS_ROOT=' + onospath + 'onos\n' + NewFile = open(filepath, 'w') + NewFile.writelines(line) + NewFile.close + print "Done!" + def OnosConnectionSet (self): """ Intergrate for ONOS connection setup """ - self.Gensshkey() - self.AddKnownHost( self.OC1, "karaf", "karaf" ) - self.AddKnownHost( self.OC2, "karaf", "karaf" ) - self.AddKnownHost( self.OC3, "karaf", "karaf" ) - currentpath = os.getcwd() - filepath = os.path.join( currentpath, "onos/tools/dev/bash_profile" ) + if self.masterusername == 'root': + filepath = '/root/' + else : + filepath = '/home/' + self.masterusername + '/' + self.OnosRootPathChange( filepath ) + filepath = os.path.join( filepath, "onos/tools/dev/bash_profile" ) self.AddEnvIntoBashrc("source " + filepath + "\n") self.AddEnvIntoBashrc("export OCT=" + self.OCT) self.AddEnvIntoBashrc("export OC1=" + self.OC1) diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/environment.py b/testcases/Controllers/ONOS/Teston/CI/adapters/environment.py index 0578d62f5..bdd0e122e 100644 --- a/testcases/Controllers/ONOS/Teston/CI/adapters/environment.py +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/environment.py @@ -14,13 +14,15 @@ import pexpect import re import sys import pxssh -from foundation import foundation +from connection import connection -class environment: +class environment( connection ): def __init__( self ): - self.loginfo = foundation( ) + connection.__init__( self ) + self.loginfo = connection( ) self.masterhandle = '' + self.home = '' def DownLoadCode( self, handle, codeurl ): """ @@ -30,7 +32,7 @@ class environment: codeurl: clone code url """ print "Now loading test codes! Please wait in patient..." - originalfolder = os.getcwd() + originalfolder = self.home gitclone = handle gitclone.sendline( "git clone " + codeurl ) index = 0 @@ -92,16 +94,19 @@ class environment: Pushkeys.sendline( cmd ) Result = 0 while Result != 2: - Result = Pushkeys.expect( ["yes", "password", "#|$", pexpect.EOF, \ - pexpect.TIMEOUT]) + Result = Pushkeys.expect( ["(yes/no)", "assword:", "PEXPECT]#", \ + pexpect.EOF, pexpect.TIMEOUT]) if ( Result == 0 ): Pushkeys.sendline( "yes" ) if ( Result == 1 ): Pushkeys.sendline( password ) if ( Result == 2 ): self.loginfo.log( "ONOS Push keys Success!" ) + break if ( Result == 3 ): self.loginfo.log( "ONOS Push keys Error!" ) + break + time.sleep(2) Pushkeys.prompt( ) print "Done!" @@ -130,12 +135,9 @@ class environment: password: onos&compute node password """ print "Now Changing ONOS name&password" - if masterusername is 'root': - filepath = '/root/' - else : - filepath = '/home/' +masterusername + '/' - line = open(filepath + "onos/tools/build/envDefaults", 'r').readlines() - lenall = len(line)-1 + filepath = self.home + '/onos/tools/build/envDefaults' + line = open(filepath, 'r').readlines() + lenall = len(line) - 1 for i in range(lenall): if "ONOS_USER=" in line[i]: line[i]=line[i].replace("sdn",user) @@ -143,12 +145,12 @@ class environment: line[i]=line[i].replace("sdn",user) if "ONOS_PWD" in line[i]: line[i]=line[i].replace("rocks",password) - NewFile = open("onos/tools/build/envDefaults",'w') + NewFile = open(filepath, 'w') NewFile.writelines(line) NewFile.close print "Done!" - def ChangeTestCasePara(testcase,user,password): + def ChangeTestCasePara(self, testcase, user, password): """ When running test script, there's something need \ to change in every test folder's *.param & *.topo files @@ -156,10 +158,10 @@ class environment: password: onos&compute node password """ print "Now Changing " + testcase + " name&password" - if masterusername is 'root': + if self.masterusername == 'root': filepath = '/root/' else : - filepath = '/home/' + masterusername + '/' + filepath = '/home/' + self.masterusername + '/' filepath = filepath +"OnosSystemTest/TestON/tests/" + testcase + "/" + \ testcase + ".topo" line = open(filepath,'r').readlines() @@ -201,12 +203,24 @@ class environment: #Release ssh handle.logout() + def CopyOnostoTestbin( self ): + sourcefile = os.curdir + '/dependencies/onos' + destifile = self.home + '/onos/tools/test/bin/' + runcommand = 'cp ' + sourcefile + ' ' + destifile + os.system( runcommand ) + def OnosEnvSetup( self, handle ): """ Onos Environment Setup function """ + self.Gensshkey( handle ) + self.home = self.GetEnvValue( handle, 'HOME' ) + self.AddKnownHost( handle, self.OC1, "karaf", "karaf" ) + self.AddKnownHost( handle, self.OC2, "karaf", "karaf" ) + self.AddKnownHost( handle, self.OC3, "karaf", "karaf" ) self.DownLoadCode( handle, 'https://github.com/sunyulin/OnosSystemTest.git' ) self.DownLoadCode( handle, 'https://gerrit.onosproject.org/onos' ) + self.CopyOnostoTestbin() self.ChangeOnosName(self.agentusername,self.agentpassword) self.InstallDefaultSoftware( handle ) - self.SetOnosEnvVar(handle, self.masterpassword,self.agentpassword)
\ No newline at end of file + self.SetOnosEnvVar(handle, self.masterpassword,self.agentpassword) diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py b/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py index 2d6b87684..c909d36be 100644 --- a/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py @@ -7,11 +7,16 @@ Description: import logging import os import time +import yaml class foundation: def __init__(self): - self.dir = os.path.join( os.getcwd(), 'log' ) + + currentpath = os.getcwd() + self.logdir = os.path.join( currentpath, 'log' ) + self.workhome = currentpath[0:currentpath.rfind('testcases')-1] + self.Result_DB = '' def log (self, loginfo): """ @@ -20,7 +25,7 @@ class foundation: loginfo(input): record info """ filename = time.strftime( '%Y-%m-%d-%H-%M-%S' ) + '.log' - filepath = os.path.join( self.dir, filename ) + filepath = os.path.join( self.logdir, filename ) logging.basicConfig( level=logging.INFO, format = '%(asctime)s %(filename)s:%(message)s', datefmt = '%d %b %Y %H:%M:%S', @@ -29,4 +34,31 @@ class foundation: filelog = logging.FileHandler( filepath ) logging.getLogger( 'Functest' ).addHandler( filelog ) print loginfo - logging.info(loginfo)
\ No newline at end of file + logging.info(loginfo) + + def getdefaultpara( self ): + """ + Get Default Parameters value + """ + with open(self.workhome + "testcases/config_functest.yaml") as f: + functest_yaml = yaml.safe_load(f) + f.close() + + self.Result_DB = str(functest_yaml.get("results").get("test_db_url")) + self.masterusername = str(functest_yaml.get("ONOS").get("general").\ + get('onosbench_username')) + self.masterpassword = str(functest_yaml.get("ONOS").get("general").\ + get("onosbench_password")) + self.agentusername = str(functest_yaml.get("ONOS").get("general").\ + get("onoscli_username")) + self.agentpassword = str(functest_yaml.get("ONOS").get("general").\ + get("onoscli_password")) + self.runtimeout = functest_yaml.get("ONOS").get("general").get("runtimeout") + self.OCT = str(functest_yaml.get("ONOS").get("environment").get("OCT")) + self.OC1 = str(functest_yaml.get("ONOS").get("environment").get("OC1")) + self.OC2 = str(functest_yaml.get("ONOS").get("environment").get("OC2")) + self.OC3 = str(functest_yaml.get("ONOS").get("environment").get("OC3")) + self.OCN = str(functest_yaml.get("ONOS").get("environment").get("OCN")) + self.OCN2 = str(functest_yaml.get("ONOS").get("environment").get("OCN2")) + self.localhost = self.OCT + return True
\ No newline at end of file diff --git a/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py b/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py index 72fa4ae1f..e8524430f 100644 --- a/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py +++ b/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py @@ -7,197 +7,15 @@ CASE2 - Ovsdb test&Default configuration&Vm go online lanqinglong@huawei.com """ -import os -import os.path -import time -import pexpect -import re -import sys - -def SSHlogin(ipaddr,username,password): - login = pexpect.spawn('ssh %s@%s'%(username,ipaddr)) - index = 0 - while index != 2: - index = login.expect(['assword:','yes/no','#|$',pexpect.EOF]) - if index == 0: - login.sendline(password) - login.interact() - if index == 1: - login.sendline('yes') - print "Login Success!" - -def AddKarafUser(ipaddr,username,password): - print '\033[1;31;40m' - print "Now Adding karaf user to OC1..." - print "\033[0m" - login = pexpect.spawn("ssh -l %s -p 8101 %s"%(username,ipaddr)) - index = 0 - while index != 2: - index = login.expect(['assword:','yes/no',pexpect.EOF]) - if index == 0: - login.sendline(password) - login.sendline("logout") - index = login.expect(["closed",pexpect.EOF]) - if index == 0: - print "Add SSH Known Host Success!" - else: - print "Add SSH Known Host Failed! Please Check!" - login.interact() - if index == 1: - login.sendline('yes') - -def DownLoadCode(): - print '\033[1;31;40m' - print "Now loading test codes!Please wait in patient..." - print "\033[0m" - os.system("git clone https://github.com/sunyulin/OnosSystemTest.git") - time.sleep(1) - os.system("git clone https://gerrit.onosproject.org/onos") - time.sleep(1) - print "Done!" - -def CleanEnv(): - print '\033[1;31;40m' - print "Now Cleaning test environment" - print "\033[0m" - os.system("sudo apt-get install -y mininet") - os.system("OnosSystemTest/TestON/bin/cleanup.sh") - time.sleep(5) - print "Done!" - -def OnosPushKeys(cmd,password): - print '\033[1;31;40m' - print "Now Pushing Onos Keys:"+cmd - print "\033[0m" - Pushkeys = pexpect.spawn(cmd) - Result = 0 - while Result != 2: - Result = Pushkeys.expect(["yes","password",pexpect.EOF,pexpect.TIMEOUT]) - if (Result == 0): - Pushkeys.sendline("yes") - if (Result == 1): - Pushkeys.sendline(password) - if (Result == 3): - print("Push keys Error!") - print "Done!" - -def AddEnvIntoBashrc(name): - print '\033[1;31;40m' - print "Now Adding bash environment" - print "\033[0m" - fileopen = open("/etc/profile",'r') - findContext = 1 - while findContext: - findContext = fileopen.readline() - result = findContext.find('dev/bash_profile') - if result != -1: - break - fileopen.close - if result == -1: - envAdd = open("/etc/profile",'a+') - envAdd.writelines("\nsource /root/onos/tools/dev/bash_profile") - envAdd.close() - -def SetEnvVar(masterpass,agentpass): - print '\033[1;31;40m' - print "Now Setting test environment" - print "\033[0m" - os.environ["OCT"] = "10.1.0.1" - os.environ["OC1"] = "10.1.0.50" - os.environ["OC2"] = "10.1.0.51" - os.environ["OC3"] = "10.1.0.52" - os.environ["OCN"] = "10.1.0.53" - os.environ["OCN2"] = "10.1.0.54" - os.environ["localhost"] = "10.1.0.1" - os.system("sudo pip install configobj") - os.system("sudo apt-get install -y sshpass") - OnosPushKeys("onos-push-keys 10.1.0.1",masterpass) - OnosPushKeys("onos-push-keys 10.1.0.50",agentpass) - OnosPushKeys("onos-push-keys 10.1.0.53",agentpass) - OnosPushKeys("onos-push-keys 10.1.0.54",agentpass) - -def Gensshkey(): - print '\033[1;31;40m' - print "Now Generating SSH keys..." - print "\033[0m" - os.system("rm -rf ~/.ssh/*") - keysub = pexpect.spawn("ssh-keygen -t rsa") - Result = 0 - while Result != 2: - Result = keysub.expect(["Overwrite","Enter",pexpect.EOF,pexpect.TIMEOUT]) - if Result == 0: - keysub.sendline("y") - if Result == 1: - keysub.sendline("\n") - if Result == 3: - printf("Generate SSH key failed.") - print "Done!" - -def ChangeOnosName(user,password): - print '\033[1;31;40m' - print "Now Changing ONOS name&password" - print "\033[0m" - line = open("onos/tools/build/envDefaults",'r').readlines() - lenall = len(line)-1 - for i in range(lenall): - if "ONOS_USER=" in line[i]: - line[i]=line[i].replace("sdn",user) - if "ONOS_GROUP" in line[i]: - line[i]=line[i].replace("sdn",user) - if "ONOS_PWD" in line[i]: - line[i]=line[i].replace("rocks",password) - NewFile = open("onos/tools/build/envDefaults",'w') - NewFile.writelines(line) - NewFile.close - print "Done!" - -def ChangeTestCasePara(testcase,user,password): - print '\033[1;31;40m' - print "Now Changing " + testcase + " name&password" - print "\033[0m" - filepath = "OnosSystemTest/TestON/tests/" + testcase + "/" + testcase + ".topo" - line = open(filepath,'r').readlines() - lenall = len(line)-1 - for i in range(lenall-2): - if ("localhost" in line[i]) or ("OCT" in line[i]): - line[i+1]=re.sub(">\w+",">"+user,line[i+1]) - line[i+2]=re.sub(">\w+",">"+password,line[i+2]) - if "OC1" in line [i] \ - or "OC2" in line [i] \ - or "OC3" in line [i] \ - or "OCN" in line [i] \ - or "OCN2" in line[i]: - line[i+1]=re.sub(">\w+",">root",line[i+1]) - line[i+2]=re.sub(">\w+",">root",line[i+2]) - NewFile = open(filepath,'w') - NewFile.writelines(line) - NewFile.close - print "Done!" - -def RunScript(testname,masterusername,masterpassword): - ChangeTestCasePara(testname,masterusername,masterpassword) - runtest = "OnosSystemTest/TestON/bin/cli.py run " + testname - os.system(runtest) - print "Done!" +from adapters.client import client if __name__=="__main__": - #This is the compass run machine user&pass,you need to modify - masterusername = "root" - masterpassword = "root" - - #The config below you don't need to care - agentusername = "root" - agentpassword = "root" + main = client() + main.getdefaultpara() - print "Test Begin....." - Gensshkey() - AddKarafUser("10.1.0.50","karaf","karaf") - AddEnvIntoBashrc("source onos/tools/dev/bash_profile") - SSHlogin("10.1.0.1",masterusername,masterpassword) - ChangeOnosName(agentusername,agentpassword) - DownLoadCode() - CleanEnv() - SetEnvVar(masterpassword,agentpassword) - RunScript("FUNCvirNetNB",masterusername,masterpassword) - RunScript("FUNCovsdbtest",masterusername,masterpassword) + #scripts to run + runhandle = main.onosstart() + main.RunScript(runhandle, "FUNCvirNetNB") + main.RunScript(runhandle, "FUNCovsdbtest") + main.onosclean( runhandle ) diff --git a/testcases/Dashboard/dashboard_utils.py b/testcases/Dashboard/dashboard_utils.py index 90562855a..0af383f3b 100644 --- a/testcases/Dashboard/dashboard_utils.py +++ b/testcases/Dashboard/dashboard_utils.py @@ -1,6 +1,5 @@ -#!/usr/bin/python -# -# Copyright (c) 2015 Orange +# copyrighi (c) 2015 Orange + # morgan.richomme@orange.com # # This program and the accompanying materials @@ -25,16 +24,16 @@ class TestCriteria: def __init__(self): self.project = '' self.testcase = '' - self.pod_id = -1 + self.pod_name = 'all' self.duration = 'all' self.version = 'all' self.installer = 'all' - def setCriteria(self, project, testcase, pod_id, + def setCriteria(self, project, testcase, pod_name, duration, version, installer): self.project = project self.testcase = testcase - self.pod_id = pod_id + self.pod_name = pod_name self.duration = duration self.version = version self.installer = installer @@ -44,17 +43,17 @@ class TestCriteria: return "" else: if(type(name) == int): - return "-" + str(name) + return "_" + str(name) else: - return "-" + name + return "_" + name def format(self): - pod_name = self.format_criteria(self.pod_id) + pod_name = self.format_criteria(self.pod_name) version_name = self.format_criteria(self.version) installer_name = self.format_criteria(self.installer) duration_name = self.format_criteria(self.duration) try: - fileName = "result-" + self.project + "-" + self.testcase + \ + fileName = "result_" + self.project + "_" + self.testcase + \ pod_name + version_name + installer_name + \ duration_name + ".json" except: @@ -78,9 +77,9 @@ def get_pods(db_url): for pod in pods: # cast int becase otherwise API retrieve 1.0 # TODO check format with API - pods_table.append(int(pod['_id'])) + pods_table.append(pod['name']) - pods_table.append(0) # 0 means all the pods here + pods_table.append('all') return pods_table except: print "Error retrieving the list of PODs" @@ -90,7 +89,7 @@ def get_pods(db_url): def get_versions(db_url): # retrieve the list of versions # TODO not supported in API yet - url = db_url + "/versions" + url = db_url + "/results" # Build headers headers = {'Content-Type': 'application/json'} @@ -99,14 +98,14 @@ def get_versions(db_url): # Get result as a json object versions_data = json.loads(db_data.text) # Get results - versions = versions_data['versions'] - + versions = versions_data['test_results'] versions_table = [] for version in versions: - versions_table.append(version['version']) + if (version['version'] is not None): + versions_table.append(version['version']) versions_table.append('all') - + versions_table = sorted(set(versions_table)) return versions_table except: print "Error retrieving the list of OPNFV versions" @@ -116,7 +115,7 @@ def get_versions(db_url): def get_installers(db_url): # retrieve the list of installers # TODO not supported in API yet - url = db_url + "/installers" + url = db_url + "/results" # Build headers headers = {'Content-Type': 'application/json'} @@ -125,15 +124,16 @@ def get_installers(db_url): # Get result as a json object installers_data = json.loads(db_data.text) # Get results - installers = installers_data['installers'] + installers = installers_data['test_results'] installers_table = [] for installer in installers: - installers_table.append(installer['installer']) + if (installer['installer'] is not None): + installers_table.append(installer['installer']) installers_table.append('all') - - return installers + installers_table = sorted(set(installers_table)) + return installers_table except: print "Error retrieving the list of OPNFV installers" return None @@ -180,33 +180,40 @@ def get_results(db_url, test_criteria): # - yardstick tests on any POD since 30 days # - Qtip tests on dell-test1 POD # - # params = {"pod_id":pod_id, "testcase":testcase} + # params = {"pod_name":pod, "testcase":testcase} # filter_date = days # data from now - days - # test_project = test_criteria.project + test_project = test_criteria.project testcase = test_criteria.testcase - # duration_frame = test_criteria.duration - # version = test_criteria.version - # installer_type = test_criteria.installer - pod_id = test_criteria.pod_id - - pod_criteria = "" - if (pod_id > 0): - pod_criteria = "&pod=" + str(pod_id) + period = test_criteria.duration + version = test_criteria.version + installer = test_criteria.installer + pod = test_criteria.pod_name # TODO complete params (installer type, testcase, version ) # need API to be up to date # we assume that criteria could be used at the API level # no need to processing on date for instance - params = {"pod_id": pod_id} + # params = {"pod_name": pod_name} # Build headers headers = {'Content-Type': 'application/json'} - url = db_url + "/results?case=" + testcase + pod_criteria + # build the request + # if criteria is all => remove criteria + url = db_url + "/results?project=" + test_project + "&case=" + testcase + + if (pod != "all"): + url += "&pod=" + pod + if (installer != "all"): + url += "&installer=" + installer + if (version != "all"): + url += "&version=" + version + url += "&period=" + str(period) # Send Request to Test DB - myData = requests.get(url, data=json.dumps(params), headers=headers) + myData = requests.get(url, headers=headers) + # Get result as a json object myNewData = json.loads(myData.text) @@ -217,15 +224,16 @@ def get_results(db_url, test_criteria): def generateJson(test_name, test_case, db_url): - # pod_id = 1 + # pod_id = "opnfv-jump-1' # test_version = 'Arno master' # test_installer = 'fuel' # test_retention = 30 pods = get_pods(db_url) - versions = ['ArnoR1', 'ArnoSR1', 'all'] # not available in the API yet - installers = ['fuel', 'foreman', 'all'] # not available in the API yet - test_durations = [90, 365, 'all'] # not available through the API yet + versions = get_versions(db_url) + installers = get_installers(db_url) + + test_durations = [90, 365, 0] # 0 means since the beginning # For all the PoDs for pod in pods: diff --git a/testcases/Dashboard/vPing2Dashboard.py b/testcases/Dashboard/vPing2Dashboard.py index f799e280f..43008a620 100644 --- a/testcases/Dashboard/vPing2Dashboard.py +++ b/testcases/Dashboard/vPing2Dashboard.py @@ -49,7 +49,6 @@ TEST_DB = functest_yaml.get("results").get("test_db_url") def format_vPing_for_dashboard(criteria): - # Get results myDataResults = dashboard_utils.get_results(TEST_DB, criteria) diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally.py b/testcases/VIM/OpenStack/CI/libraries/run_rally.py index 61bbaaeb7..42ad1f5e4 100644 --- a/testcases/VIM/OpenStack/CI/libraries/run_rally.py +++ b/testcases/VIM/OpenStack/CI/libraries/run_rally.py @@ -8,31 +8,47 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 # -import re, json, os, urllib2, argparse, logging, yaml - +# 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 """ tests configuration """ -tests = ['authenticate', 'glance', 'cinder', 'heat', 'keystone', 'neutron', 'nova', 'quotas', 'requests', 'vm', 'tempest', 'all', 'smoke'] +tests = ['authenticate', 'glance', 'cinder', 'ceilometer', 'heat', 'keystone', + 'neutron', 'nova', 'quotas', 'requests', 'vm', 'all'] parser = argparse.ArgumentParser() parser.add_argument("repo_path", help="Path to the repository") -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 possible 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("-r", "--report", + help="Create json result file", + action="store_true") -parser.add_argument("test_mode", help="Tempest test mode", nargs='?', default="smoke") 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") +sys.path.append(args.repo_path + "testcases/") +import functest_utils """ logging configuration """ -logger = logging.getLogger('run_rally') +logger = logging.getLogger("run_rally") logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() @@ -41,7 +57,8 @@ 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) @@ -51,26 +68,27 @@ f.close() HOME = os.environ['HOME']+"/" REPO_PATH = args.repo_path -SCENARIOS_DIR = REPO_PATH + functest_yaml.get("general").get("directories").get("dir_rally_scn") -RESULTS_DIR = HOME + functest_yaml.get("general").get("directories").get("dir_rally_res") + "/rally/" +SCENARIOS_DIR = REPO_PATH + functest_yaml.get("general"). \ + get("directories").get("dir_rally_scn") +RESULTS_DIR = HOME + functest_yaml.get("general").get("directories"). \ + get("dir_rally_res") + "/rally/" +TEST_DB = functest_yaml.get("results").get("test_db_url") +def push_results_to_db(payload, module): + url = TEST_DB + "/results" + installer = functest_utils.get_installer_type(logger) + git_version = functest_utils.get_git_branch(args.repo_path) + # TODO pod_name hardcoded, info shall come from Jenkins + params = {"project_name": "functest", "case_name": "Rally-"+module, + "pod_name": "opnfv-jump-2", "installer": installer, + "version": git_version, "details": payload} -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) + 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): """ @@ -106,55 +124,28 @@ def task_succeed(json_raw): 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)) - - 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) - 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 - """ + # + # 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)) - """ 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.error("The scenario '%s' does not exist." %test_file_name) + 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()) @@ -164,18 +155,20 @@ 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 """ + # write html report file report_file_name = '{}opnfv-{}.html'.format(RESULTS_DIR, test_name) - cmd_line = "rally task report %s --out %s" % (task_id, report_file_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) @@ -183,7 +176,15 @@ def run_task(test_name): 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, test_name) """ parse JSON operation result """ if task_succeed(json_results): @@ -191,27 +192,28 @@ def run_task(test_name): else: print 'Test KO' else: - logger.error('{} test failed, unable to fetch a scenario test file'.format(test_name)) - + 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) if args.test_name == "all": for test_name in tests: - if not (test_name == 'all' or test_name == 'tempest' or test_name == 'heat' or test_name == 'smoke' or test_name == 'vm' ): + 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 __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 000000000..d673b5300 --- /dev/null +++ b/testcases/VIM/OpenStack/CI/libraries/run_tempest.py @@ -0,0 +1,144 @@ +#!/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 + +modes = ['full', 'smoke', 'baremetal', 'compute', 'data_processing', 'identity', + 'image', 'network', 'object_storage', 'orchestration', 'telemetry', 'volume'] + +""" tests configuration """ +parser = argparse.ArgumentParser() +parser.add_argument("repo_path", help="Path to the Functest repository") +parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") +parser.add_argument("-m", "--mode", help="Tempest test mode [smoke, all]" + , default="smoke") + +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) + +with open(args.repo_path+"/testcases/config_functest.yaml") as f: + functest_yaml = yaml.safe_load(f) +f.close() + +REPO_PATH = args.repo_path +TEST_DB = functest_yaml.get("results").get("test_db_url") +sys.path.append(args.repo_path + "/testcases/") +import functest_utils + +MODE="smoke" + +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() + + print "test_run:" + print test_run + print "duration:" + print 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'} + + print url + print " ----- " + print params + print " ----- " + + r = requests.post(url, data=json.dumps(params), headers=headers) + logger.debug(r) + + +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] + + # Generate json results for DB + json_results={'timestart': time_start, 'duration': duration, + 'tests': num_tests, 'failures': num_failures} + logger.info("Results: "+str(json_results)) + push_results_to_db(json_results, MODE, "opnfv-jump-2") + + +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) + else: + MODE = args.mode + + run_tempest(MODE) + + + +if __name__ == '__main__': + main() diff --git a/testcases/config_functest.yaml b/testcases/config_functest.yaml index dcbac0927..46fae91ed 100644 --- a/testcases/config_functest.yaml +++ b/testcases/config_functest.yaml @@ -6,6 +6,7 @@ general: dir_rally: testcases/VIM/OpenStack/CI/libraries/ dir_rally_scn: testcases/VIM/OpenStack/CI/suites/ dir_vIMS: testcases/vIMS/CI/ + dir_onos: testcases/Controllers/ONOS/Teston/CI/ # Absolute path dir_repos: /home/opnfv/repos @@ -56,7 +57,7 @@ vIMS: base_image_name: ubuntu_14.04 cloudify: blueprint: - url: https://github.com/cloudify-cosmo/cloudify-manager-blueprints.git + url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git branch: "3.2-build" file_name: "openstack-manager-blueprint.yaml" inputs: @@ -96,5 +97,19 @@ vIMS: agent_user: 'ubuntu' external_network_name: '' public_domain: clearwater.opnfv +ONOS: + general: + onosbench_username: 'root' + onosbench_password: 'root' + onoscli_username: 'root' + onoscli_password: 'root' + runtimeout: 300 + environment: + OCT: '189.42.8.99' + OC1: '189.42.8.101' + OC2: '189.42.8.102' + OC3: '189.42.8.103' + OCN: '189.42.8.104' + OCN2: '189.42.8.105' results: test_db_url: http://213.77.62.197 diff --git a/testcases/functest_utils.py b/testcases/functest_utils.py index c2e4bc6d5..59e89a5af 100644 --- a/testcases/functest_utils.py +++ b/testcases/functest_utils.py @@ -8,28 +8,35 @@ # http://www.apache.org/licenses/LICENSE-2.0 # -import re, json, os, urllib2, shutil, subprocess, sys -############# CREDENTIALS OPENSTACK ############# +import os +import urllib2 +import subprocess +import sys +from git import Repo + + +# ############ CREDENTIALS OPENSTACK ############# def check_credentials(): """ Check if the OpenStack credentials (openrc) are sourced """ - #TODO: there must be a short way to do this, doing if os.environ["something"] == "" throws an error + # TODO: there must be a short way to do this + # doing if os.environ["something"] == "" throws an error try: - os.environ['OS_AUTH_URL'] + os.environ['OS_AUTH_URL'] except KeyError: return False try: - os.environ['OS_USERNAME'] + os.environ['OS_USERNAME'] except KeyError: return False try: - os.environ['OS_PASSWORD'] + os.environ['OS_PASSWORD'] except KeyError: return False try: - os.environ['OS_TENANT_NAME'] + os.environ['OS_TENANT_NAME'] except KeyError: return False return True @@ -44,7 +51,6 @@ def get_credentials(service): :param service: a string indicating the name of the service requesting the credentials. """ - #TODO: get credentials from the openrc file creds = {} # Unfortunately, each of the OpenStack client will request slightly # different entries in their credentials dict. @@ -58,17 +64,18 @@ def get_credentials(service): # The most common way to pass these info to the script is to do it through # environment variables. creds.update({ - "username": os.environ.get('OS_USERNAME', "admin"), # add your cloud username details - password: os.environ.get("OS_PASSWORD", 'admin'), # add password - "auth_url": os.environ.get("OS_AUTH_URL","http://192.168.20.71:5000/v2.0"), # Auth URL + "username": os.environ.get('OS_USERNAME', "admin"), + password: os.environ.get("OS_PASSWORD", 'admin'), + "auth_url": os.environ.get("OS_AUTH_URL", + "http://192.168.20.71:5000/v2.0"), tenant: os.environ.get("OS_TENANT_NAME", "admin"), }) return creds -################# NOVA ################# -def get_instance_status(nova_client,instance): +# ################ NOVA ################# +def get_instance_status(nova_client, instance): try: instance = nova_client.servers.get(instance.id) return instance.status @@ -104,10 +111,10 @@ def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram): return id -################# NEUTRON ################# +# ################ NEUTRON ################# def create_neutron_net(neutron_client, name): json_body = {'network': {'name': name, - 'admin_state_up': True}} + 'admin_state_up': True}} try: network = neutron_client.create_network(body=json_body) network_dict = network['network'] @@ -116,6 +123,7 @@ def create_neutron_net(neutron_client, name): print "Error:", sys.exc_info()[0] return False + def delete_neutron_net(neutron_client, network_id): try: neutron_client.delete_network(network_id) @@ -124,9 +132,10 @@ def delete_neutron_net(neutron_client, network_id): print "Error:", sys.exc_info()[0] return False + def create_neutron_subnet(neutron_client, name, cidr, net_id): json_body = {'subnets': [{'name': name, 'cidr': cidr, - 'ip_version': 4, 'network_id': net_id}]} + 'ip_version': 4, 'network_id': net_id}]} try: subnet = neutron_client.create_subnet(body=json_body) return subnet['subnets'][0]['id'] @@ -134,6 +143,7 @@ def create_neutron_subnet(neutron_client, name, cidr, net_id): print "Error:", sys.exc_info()[0] return False + def delete_neutron_subnet(neutron_client, subnet_id): try: neutron_client.delete_subnet(subnet_id) @@ -142,6 +152,7 @@ def delete_neutron_subnet(neutron_client, subnet_id): print "Error:", sys.exc_info()[0] return False + def create_neutron_router(neutron_client, name): json_body = {'router': {'name': name, 'admin_state_up': True}} try: @@ -151,6 +162,7 @@ def create_neutron_router(neutron_client, name): print "Error:", sys.exc_info()[0] return False + def delete_neutron_router(neutron_client, router_id): json_body = {'router': {'id': router_id}} try: @@ -174,19 +186,21 @@ def add_interface_router(neutron_client, router_id, subnet_id): def remove_interface_router(neutron_client, router_id, subnet_id): json_body = {"subnet_id": subnet_id} try: - neutron_client.remove_interface_router(router=router_id, body=json_body) + neutron_client.remove_interface_router(router=router_id, + body=json_body) return True except: print "Error:", sys.exc_info()[0] return False + def create_neutron_port(neutron_client, name, network_id, ip): json_body = {'port': { - 'admin_state_up': True, - 'name': name, - 'network_id': network_id, - 'fixed_ips': [{"ip_address": ip}] - }} + 'admin_state_up': True, + 'name': name, + 'network_id': network_id, + 'fixed_ips': [{"ip_address": ip}] + }} try: port = neutron_client.create_port(body=json_body) return port['port']['id'] @@ -197,33 +211,37 @@ def create_neutron_port(neutron_client, name, network_id, ip): def get_network_id(neutron_client, network_name): networks = neutron_client.list_networks()['networks'] - id = '' + id = '' for n in networks: if n['name'] == network_name: id = n['id'] break return id + def check_neutron_net(neutron_client, net_name): for network in neutron_client.list_networks()['networks']: - if network['name'] == net_name : + if network['name'] == net_name: for subnet in network['subnets']: return True return False + def get_network_list(neutron_client): network_list = neutron_client.list_networks()['networks'] - if len(network_list) == 0 : + if len(network_list) == 0: return None - else : + else: return network_list + def get_external_net(neutron_client): for network in neutron_client.list_networks()['networks']: if network['router:external']: return network['name'] return False + def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota): json_body = {"quota": { "security_group": sg_quota, @@ -231,13 +249,15 @@ def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota): }} try: - quota = neutron_client.update_quota(tenant_id=tenant_id, body=json_body) + quota = neutron_client.update_quota(tenant_id=tenant_id, + body=json_body) return True except: print "Error:", sys.exc_info()[0] return False -################# GLANCE ################# +# ################ GLANCE ################# + def get_image_id(glance_client, image_name): images = glance_client.images.list() @@ -248,17 +268,21 @@ def get_image_id(glance_client, image_name): break return id + def create_glance_image(glance_client, image_name, file_path, is_public=True): try: with open(file_path) as fimage: - image = glance_client.images.create(name=image_name, is_public=is_public, disk_format="qcow2", - container_format="bare", data=fimage) + image = glance_client.images.create(name=image_name, + is_public=is_public, + disk_format="qcow2", + container_format="bare", + data=fimage) return image.id except: return False -################# KEYSTONE ################# +# ################ KEYSTONE ################# def get_tenant_id(keystone_client, tenant_name): tenants = keystone_client.tenants.list() id = '' @@ -268,6 +292,7 @@ def get_tenant_id(keystone_client, tenant_name): break return id + def get_role_id(keystone_client, role_name): roles = keystone_client.roles.list() id = '' @@ -277,6 +302,7 @@ def get_role_id(keystone_client, role_name): break return id + def get_user_id(keystone_client, user_name): users = keystone_client.users.list() id = '' @@ -286,14 +312,18 @@ def get_user_id(keystone_client, user_name): break return id + def create_tenant(keystone_client, tenant_name, tenant_description): try: - tenant = keystone_client.tenants.create(tenant_name, tenant_description, enabled=True) + tenant = keystone_client.tenants.create(tenant_name, + tenant_description, + enabled=True) return tenant.id except: print "Error:", sys.exc_info()[0] return False + def delete_tenant(keystone_client, tenant_id): try: tenant = keystone_client.tenants.delete(tenant_id) @@ -302,14 +332,19 @@ def delete_tenant(keystone_client, tenant_id): print "Error:", sys.exc_info()[0] return False -def create_user(keystone_client, user_name, user_password, user_email, tenant_id): + +def create_user(keystone_client, user_name, user_password, + user_email, tenant_id): try: - user = keystone_client.users.create(user_name, user_password, user_email, tenant_id, enabled=True) + user = keystone_client.users.create(user_name, user_password, + user_email, tenant_id, + enabled=True) return user.id except: print "Error:", sys.exc_info()[0] return False + def delete_user(keystone_client, user_id): try: tenant = keystone_client.users.delete(user_id) @@ -318,6 +353,7 @@ def delete_user(keystone_client, user_id): print "Error:", sys.exc_info()[0] return False + def add_role_user(keystone_client, user_id, role_id, tenant_id): try: keystone_client.roles.add_user_role(user_id, role_id, tenant_id) @@ -327,7 +363,7 @@ def add_role_user(keystone_client, user_id, role_id, tenant_id): return False -################# UTILS ################# +# ################ UTILS ################# def check_internet_connectivity(url='http://www.opnfv.org/'): """ Check if there is access to the internet @@ -335,7 +371,7 @@ def check_internet_connectivity(url='http://www.opnfv.org/'): try: urllib2.urlopen(url, timeout=5) return True - except urllib.URLError: + except urllib2.URLError: return False @@ -363,15 +399,38 @@ def execute_command(cmd, logger=None): logger.debug('Executing command : {}'.format(cmd)) output_file = "output.txt" f = open(output_file, 'w+') - p = subprocess.call(cmd,shell=True, stdout=f, stderr=subprocess.STDOUT) + p = subprocess.call(cmd, shell=True, stdout=f, stderr=subprocess.STDOUT) f.close() f = open(output_file, 'r') result = f.read() if result != "" and logger: logger.debug(result) - if p == 0 : + if p == 0: return True else: if logger: - logger.error("Error when executing command %s" %cmd) + logger.error("Error when executing command %s" % cmd) exit(-1) + + +def get_git_branch(repo_path): + """ + Get git branch name + """ + repo = Repo(repo_path) + branch = repo.active_branch + return branch.name + + +def get_installer_type(logger=None): + """ + Get installer type (fuel, foreman, apex, joid, compass) + """ + try: + installer = os.environ['INSTALLER_TYPE'] + except KeyError: + if logger: + logger.error("Impossible to retrieve the installer type") + installer = "Unkown" + + return installer diff --git a/testcases/vIMS/CI/vIMS.py b/testcases/vIMS/CI/vIMS.py index d2d10f345..07241c14e 100644 --- a/testcases/vIMS/CI/vIMS.py +++ b/testcases/vIMS/CI/vIMS.py @@ -45,7 +45,6 @@ ch.setFormatter(formatter) logger.addHandler(ch) -HOME = os.environ['HOME']+"/" # with open(args.repo_path+"config_functest.yaml") as f: with open(args.repo_path + "testcases/config_functest.yaml") as f: functest_yaml = yaml.safe_load(f) @@ -53,9 +52,8 @@ f.close() # Cloudify parameters REPO_PATH = args.repo_path -HOME = os.environ['HOME']+"/" VIMS_DIR = REPO_PATH + functest_yaml.get("general").get("directories").get("dir_vIMS") -VIMS_DATA_DIR = HOME + functest_yaml.get("general").get("directories").get("dir_vIMS_data") +VIMS_DATA_DIR = functest_yaml.get("general").get("directories").get("dir_vIMS_data")+"/" TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name") TENANT_DESCRIPTION = functest_yaml.get("vIMS").get("general").get("tenant_description") @@ -79,6 +77,8 @@ def pMsg(value): def download_and_add_image_on_glance(glance, image_name, image_url): dest_path = VIMS_DATA_DIR + "tmp/" + if not os.path.exists(dest_path): + os.makedirs(dest_path) file_name = image_url.rsplit('/')[-1] if not functest_utils.download_url(image_url, dest_path): logger.error("Failed to download image %s" %file_name) diff --git a/testcases/vPing/CI/libraries/vPing.py b/testcases/vPing/CI/libraries/vPing.py index 5d68f2229..b51bb6287 100644 --- a/testcases/vPing/CI/libraries/vPing.py +++ b/testcases/vPing/CI/libraries/vPing.py @@ -245,10 +245,14 @@ def cleanup(nova, neutron, network_dic): def push_results_to_db(payload): - # TODO move DB creds into config file url = TEST_DB + "/results" - params = {"project_name": "functest", "case_name": "vPing", "pod_id": 1, - "details": payload} + installer = functest_utils.get_installer_type(logger) + git_version = functest_utils.get_git_branch(args.repo_path) + # TODO pod_name hardcoded, info shall come from Jenkins + params = {"project_name": "functest", "case_name": "vPing", + "pod_name": "opnfv-jump-2", "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) |