diff options
23 files changed, 925 insertions, 25 deletions
diff --git a/testcases/Controllers/ONOS/Teston/CI/Readme.txt b/testcases/Controllers/ONOS/Teston/CI/Readme.txt index 7648b2a98..7393f59a1 100644 --- a/testcases/Controllers/ONOS/Teston/CI/Readme.txt +++ b/testcases/Controllers/ONOS/Teston/CI/Readme.txt @@ -1,5 +1,5 @@ 1.This is a basic test run about onos,we will make them better and better -2.This test include two suits: +2.This test include two suites: (1)Test northbound(network/subnet/ports create/update/delete) (2)Ovsdb test,default configuration,openflow connection,vm go onlines. 3.Later we will make a framework to do this test
\ No newline at end of file diff --git a/testcases/Controllers/ONOS/Teston/CI/__init__.py b/testcases/Controllers/ONOS/Teston/CI/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testcases/Controllers/ONOS/Teston/CI/__init__.py diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/__init__.py b/testcases/Controllers/ONOS/Teston/CI/adapters/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/__init__.py diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py b/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py new file mode 100644 index 000000000..9890ecfae --- /dev/null +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/connection.py @@ -0,0 +1,146 @@ +""" +Description: + This file is used to make connections + Include ssh & exchange public-key to each other so that + it can run without password + + lanqinglong@huawei.com +""" +import os +import time +import pexpect +import re +import sys +from foundation import foundation + +class connection: + + def __init__( self ): + self.loginfo = foundation() + + def AddKnownHost( self, ipaddr, username, password ): + """ + Add an user to known host,so that onos can login in with onos $ipaddr. + parameters: + ipaddr: ip address + username: login user name + password: login password + """ + print( "Now Adding an user to known hosts " + ipaddr ) + login = pexpect.spawn( "ssh -l %s -p 8101 %s"%( username, ipaddr ) ) + index = 0 + while index != 2: + index = login.expect( ['assword:', 'yes/no', pexpect.EOF, \ + pexpect.TIMEOUT] ) + if index == 0: + login.sendline( password ) + login.sendline( "logout" ) + index = login.expect( ["closed", pexpect.EOF] ) + if index == 0: + self.loginfo.log( "Add SSH Known Host Success!" ) + else: + self.loginfo.log( "Add SSH Known Host Failed! Please Check!" ) + #login.interact() + + if index == 1: + login.sendline('yes') + + def Gensshkey( self ): + """ + 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' ) + 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") + 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: + self.loginfo.log("Generate SSH key failed.") + + self.loginfo.log( "Generate SSH key success." ) + + def GetRootAuth( self, password ): + """ + Get root user + parameters: + password: root login password + """ + print( "Now changing to user root" ) + login = pexpect.spawn( "su - root" ) + index = 0 + while index != 2: + index = login.expect( ['assword:', "failure", \ + pexpect.EOF, pexpect.TIMEOUT] ) + if index == 0: + login.sendline( password ) + if index == 1: + self.loginfo.log("Change user to root failed.") + + login.interact() + + def ReleaseRootAuth( self ): + """ + Exit root user. + """ + print( "Now Release user root" ) + login = pexpect.spawn( "exit" ) + index = login.expect( ['logout', \ + pexpect.EOF, pexpect.TIMEOUT] ) + if index == 0: + self.loginfo.log("Release root user success.") + if index == 1: + self.loginfo.log("Release root user failed.") + + login.interact() + + def AddEnvIntoBashrc( self, envalue ): + """ + Add Env var into /etc/profile. + parameters: + envalue: environment value to add + """ + print "Now Adding bash environment" + fileopen = open( "/etc/profile", 'r' ) + findContext = 1 + while findContext: + findContext = fileopen.readline( ) + result = findContext.find( envalue ) + if result != -1: + break + fileopen.close + if result == -1: + envAdd = open( "/etc/profile", 'a+' ) + envAdd.writelines( "\n" + envalue ) + envAdd.close( ) + self.loginfo.log( "Add env to bashrc success!" ) + + 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" ) + self.AddEnvIntoBashrc("source " + filepath + "\n") + self.AddEnvIntoBashrc("export OCT=" + self.OCT) + self.AddEnvIntoBashrc("export OC1=" + self.OC1) + self.AddEnvIntoBashrc("export OC2=" + self.OC2) + self.AddEnvIntoBashrc("export OC3=" + self.OC3) + self.AddEnvIntoBashrc("export OCN=" + self.OCN) + self.AddEnvIntoBashrc("export OCN2=" + self.OCN2) + self.AddEnvIntoBashrc("export localhost=" + self.localhost) diff --git a/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py b/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py new file mode 100644 index 000000000..2d6b87684 --- /dev/null +++ b/testcases/Controllers/ONOS/Teston/CI/adapters/foundation.py @@ -0,0 +1,32 @@ +""" +Description: + This file include basis functions + lanqinglong@huawei.com +""" + +import logging +import os +import time + +class foundation: + + def __init__(self): + self.dir = os.path.join( os.getcwd(), 'log' ) + + def log (self, loginfo): + """ + Record log in log directory for deploying test environment + parameters: + loginfo(input): record info + """ + filename = time.strftime( '%Y-%m-%d-%H-%M-%S' ) + '.log' + filepath = os.path.join( self.dir, filename ) + logging.basicConfig( level=logging.INFO, + format = '%(asctime)s %(filename)s:%(message)s', + datefmt = '%d %b %Y %H:%M:%S', + filename = filepath, + filemode = 'w') + filelog = logging.FileHandler( filepath ) + logging.getLogger( 'Functest' ).addHandler( filelog ) + print loginfo + logging.info(loginfo)
\ No newline at end of file diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-authenticate.json b/testcases/VIM/OpenStack/CI/suites/opnfv-authenticate.json index 3ded19963..8bb589524 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-authenticate.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-authenticate.json @@ -11,6 +11,9 @@ "tenants": 3, "users_per_tenant": 50 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -29,6 +32,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -47,6 +53,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -65,6 +74,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -83,6 +95,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -101,6 +116,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-cinder.json b/testcases/VIM/OpenStack/CI/suites/opnfv-cinder.json index 4fc3f769b..bada44733 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-cinder.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-cinder.json @@ -20,6 +20,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -41,6 +44,9 @@ "volumes": { "size": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -59,6 +65,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -78,6 +87,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -100,6 +112,9 @@ "volumes": { "size": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -119,6 +134,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -141,6 +159,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -162,6 +183,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -183,6 +207,9 @@ "volumes": { "size": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -217,6 +244,9 @@ }, "servers_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -248,6 +278,9 @@ }, "servers_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -266,6 +299,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -288,6 +324,9 @@ "size": 1, "volumes_per_tenant": 4 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-glance.json b/testcases/VIM/OpenStack/CI/suites/opnfv-glance.json index 68d561345..e905ccaba 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-glance.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-glance.json @@ -17,6 +17,9 @@ "image_container": "bare", "images_per_tenant": 4 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -37,6 +40,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -57,6 +63,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -81,6 +90,9 @@ "tenants": 3, "users_per_tenant": 5 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-heat.json b/testcases/VIM/OpenStack/CI/suites/opnfv-heat.json index 2fbb70fba..a712afefe 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-heat.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-heat.json @@ -11,6 +11,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -29,6 +32,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -47,6 +53,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -62,6 +71,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -80,6 +92,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -98,6 +113,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -117,6 +135,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -136,6 +157,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -155,6 +179,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -174,6 +201,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -193,6 +223,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -212,6 +245,9 @@ "tenants": 2, "users_per_tenant": 3 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -231,6 +267,9 @@ "stacks_per_tenant": 2, "resources_per_stack": 10 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-keystone.json b/testcases/VIM/OpenStack/CI/suites/opnfv-keystone.json index 390a1ae13..f7291ed59 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-keystone.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-keystone.json @@ -8,6 +8,9 @@ "type": "constant", "times": 100, "concurrency": 10 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -20,6 +23,9 @@ "type": "constant", "times": 10, "concurrency": 1 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -32,6 +38,9 @@ "type": "constant", "times": 100, "concurrency": 10 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -44,6 +53,9 @@ "type": "constant", "times": 100, "concurrency": 10 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -56,6 +68,9 @@ "type": "constant", "times": 100, "concurrency": 10 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -69,6 +84,9 @@ "type": "constant", "times": 10, "concurrency": 10 + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-neutron.json b/testcases/VIM/OpenStack/CI/suites/opnfv-neutron.json index 5d176ca0d..9fcdf583d 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-neutron.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-neutron.json @@ -19,6 +19,9 @@ "network": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -45,6 +48,9 @@ "port": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -74,6 +80,9 @@ "router": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -101,6 +110,9 @@ "subnet": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -124,6 +136,9 @@ "network": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -150,6 +165,9 @@ "port": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -179,6 +197,9 @@ "router": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -206,6 +227,9 @@ "subnet": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -233,6 +257,9 @@ "network": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -265,6 +292,9 @@ "port": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -298,6 +328,9 @@ "router": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -329,6 +362,9 @@ "subnet": -1 } } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-nova.json b/testcases/VIM/OpenStack/CI/suites/opnfv-nova.json index 09ca4108a..e32fd57ec 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-nova.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-nova.json @@ -20,6 +20,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -46,6 +49,9 @@ "network": { "start_cidr": "100.1.0.0/26" } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -74,6 +80,9 @@ "network": { "start_cidr": "100.1.0.0/26" } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -98,6 +107,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -122,6 +134,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -145,6 +160,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -175,6 +193,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -200,6 +221,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -224,6 +248,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -247,6 +274,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -272,6 +302,9 @@ "tenants": 2, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -298,6 +331,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -322,6 +358,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -337,6 +376,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -356,6 +398,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -371,6 +416,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -390,6 +438,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -417,6 +468,9 @@ }, "servers_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -445,6 +499,9 @@ "tenants": 1, "users_per_tenant": 1 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-quotas.json b/testcases/VIM/OpenStack/CI/suites/opnfv-quotas.json index 1778a8dd0..1cc1855e7 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-quotas.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-quotas.json @@ -14,6 +14,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -32,6 +35,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -50,6 +56,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -68,6 +77,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -86,6 +98,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json b/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json index ead457dbf..4468d60a3 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json @@ -11,6 +11,9 @@ "type": "constant", "times": 20, "concurrency": 5 + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -26,6 +29,9 @@ "type": "constant", "times": 20, "concurrency": 5 + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-smoke-green.json b/testcases/VIM/OpenStack/CI/suites/opnfv-smoke-green.json index a7eb345b7..b327b53e5 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-smoke-green.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-smoke-green.json @@ -230,6 +230,9 @@ "type": "serial", "times": 1, "concurrency": 1 + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-smoke.json b/testcases/VIM/OpenStack/CI/suites/opnfv-smoke.json index 8c40fab1d..31514d274 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-smoke.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-smoke.json @@ -265,6 +265,9 @@ "type": "serial", "times": 1, "concurrency": 1 + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-tempest.json b/testcases/VIM/OpenStack/CI/suites/opnfv-tempest.json index 0b63070a0..b94de47e4 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-tempest.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-tempest.json @@ -6,6 +6,9 @@ "type": "constant", "times": 1, "concurrency": 1 + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-vm.json b/testcases/VIM/OpenStack/CI/suites/opnfv-vm.json index f50cf2b25..382f40251 100644 --- a/testcases/VIM/OpenStack/CI/suites/opnfv-vm.json +++ b/testcases/VIM/OpenStack/CI/suites/opnfv-vm.json @@ -26,6 +26,9 @@ }, "network": { } + }, + "sla": { + "failure_rate": {"max": 0} } } ], @@ -59,6 +62,9 @@ "tenants": 3, "users_per_tenant": 2 } + }, + "sla": { + "failure_rate": {"max": 0} } } ] diff --git a/testcases/config_functest.yaml b/testcases/config_functest.yaml index c38b46066..e8ee6d9c6 100644 --- a/testcases/config_functest.yaml +++ b/testcases/config_functest.yaml @@ -1,4 +1,3 @@ ---- general: directories: # Relative to the path where the repo is cloned: @@ -6,7 +5,9 @@ general: dir_odl: testcases/Controllers/ODL/CI/ dir_rally: testcases/VIM/OpenStack/CI/libraries/ dir_rally_scn: testcases/VIM/OpenStack/CI/suites/ + dir_vIMS: testcases/vIMS/CI/ # Relative to $HOME: + dir_vIMS_data: functest/vIMS_data/ # $HOME/functest/vIMS_data/ dir_rally_res: functest/results/ # $HOME/functest/results dir_rally_repo: functest/Rally_repo/ # $HOME/Rally_repo/ dir_rally_inst: .rally/ # $HOME/.rally/ usually @@ -38,5 +39,53 @@ vping: ip_1: 192.168.120.30 ip_2: 192.168.120.40 +vIMS: + general: + tenant_name: vIMS + tenant_description: vIMS Functionality Testing + base_image_url: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img + base_image_name: ubuntu_14.04 + cloudify: + blueprint: + url: https://github.com/cloudify-cosmo/cloudify-manager-blueprints.git + branch: "3.2-build" + file_name: "openstack-manager-blueprint.yaml" + inputs: + keystone_username: "" + keystone_password: "" + keystone_tenant_name: "" + keystone_url: "" + manager_public_key_name: 'cloudify-manager' + agent_public_key_name: 'cloudify-agent' + image_id: "" + flavor_id: "2" + external_network_name: "" + use_existing_manager_keypair: false + use_existing_agent_keypair: false + manager_server_name: cloudify-management-server + manager_server_user: ubuntu + manager_security_group_name: cloudify-sg-manager + agents_security_group_name: cloudify-sg-agents + manager_private_key_path: ~/.ssh/cloudify-manager-kp.pem + agent_private_key_path: ~/.ssh/cloudify-agent-kp.pem + agents_user: ubuntu + nova_url: "" + neutron_url: "" + resources_prefix: "" + inputs_path: openstack/inputs.yaml + clearwater: + blueprint: + file_name: 'openstack-blueprint.yaml' + name: "clearwater-opnfv" + destination_folder: "opnfv-cloudify-clearwater" + url: 'https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git' + branch: "master" + deployment-name: 'clearwater-opnfv' + inputs: + image_id: '' + flavor_id: '' + agent_user: 'ubuntu' + external_network_name: '' + public_domain: clearwater.opnfv results: - test_db_url: http://213.77.62.197 + test_db_url: http://213.77.62.197
\ No newline at end of file diff --git a/testcases/functest_utils.py b/testcases/functest_utils.py index 6af55f7a7..6d60fbce3 100644 --- a/testcases/functest_utils.py +++ b/testcases/functest_utils.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # # jose.lausuch@ericsson.com +# valentin.boucher@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 @@ -9,7 +10,7 @@ import re, json, os, urllib2, shutil, subprocess, sys - +############# CREDENTIALS OPENSTACK ############# def check_credentials(): """ Check if the OpenStack credentials (openrc) are sourced @@ -66,7 +67,7 @@ def get_credentials(service): return creds - +################# NOVA ################# def get_instance_status(nova_client,instance): try: instance = nova_client.servers.get(instance.id) @@ -83,7 +84,27 @@ def get_instance_by_name(nova_client, instance_name): return None +def get_flavor_id(nova_client, flavor_name): + flavors = nova_client.flavors.list(detailed=True) + id = '' + for f in flavors: + if f.name == flavor_name: + id = f.id + break + return id + + +def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram): + flavors = nova_client.flavors.list(detailed=True) + id = '' + for f in flavors: + if min_ram <= f.ram and f.ram <= max_ram: + id = f.id + break + return id + +################# NEUTRON ################# def create_neutron_net(neutron_client, name): json_body = {'network': {'name': name, 'admin_state_up': True}} @@ -190,6 +211,34 @@ def check_neutron_net(neutron_client, net_name): return True return False +def get_network_list(neutron_client): + network_list = neutron_client.list_networks()['networks'] + if len(network_list) == 0 : + return None + 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, + "security_group_rule": sg_rule_quota + }} + + try: + quota = neutron_client.update_quota(tenant_id=tenant_id, body=json_body) + return True + except: + print "Error:", sys.exc_info()[0] + return False + +################# GLANCE ################# + def get_image_id(glance_client, image_name): images = glance_client.images.list() id = '' @@ -199,34 +248,17 @@ def get_image_id(glance_client, image_name): break return id -def create_glance_image(glance_client, image_name, file_path): +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=True, disk_format="qcow2", + 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 -def get_flavor_id(nova_client, flavor_name): - flavors = nova_client.flavors.list(detailed=True) - id = '' - for f in flavors: - if f.name == flavor_name: - id = f.id - break - return id - -def get_flavor_id_by_ram_range(nova_client, min_ram, max_ram): - flavors = nova_client.flavors.list(detailed=True) - id = '' - for f in flavors: - if min_ram <= f.ram and f.ram <= max_ram: - id = f.id - break - return id - +################# KEYSTONE ################# def get_tenant_id(keystone_client, tenant_name): tenants = keystone_client.tenants.list() id = '' @@ -270,6 +302,22 @@ 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): + try: + 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) + return True + except: + 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) @@ -279,6 +327,7 @@ def add_role_user(keystone_client, user_id, role_id, tenant_id): return False +################# UTILS ################# def check_internet_connectivity(url='http://www.opnfv.org/'): """ Check if there is access to the internet diff --git a/testcases/vIMS/CI/create_venv.sh b/testcases/vIMS/CI/create_venv.sh new file mode 100755 index 000000000..15294f77b --- /dev/null +++ b/testcases/vIMS/CI/create_venv.sh @@ -0,0 +1,36 @@ +#!/bin/bash -e + +# Script checks that venv exists. If it doesn't it will be created +# It requires python2.7 and virtualenv packages installed + +BASEDIR=`dirname $0` +VENV_PATH=$1 +VENV_NAME="venv_cloudify" +function venv_install() { + if command -v virtualenv-2.7; then + virtualenv-2.7 $1 + elif command -v virtualenv2; then + virtualenv2 $1 + elif command -v virtualenv; then + virtualenv $1 + else + echo Cannot find virtualenv command. + return 1 + fi +} + +# exit when something goes wrong during venv install +set -e +if [ ! -d "$VENV_PATH/$VENV_NAME" ]; then + venv_install $VENV_PATH/$VENV_NAME + echo "Virtualenv" + $VENV_NAME + "created." +fi + +if [ ! -f "$VENV_PATH/$VENV_NAME/updated" -o $BASEDIR/requirements.pip -nt $VENV_PATH/$VENV_NAME/updated ]; then + source $VENV_PATH/$VENV_NAME/bin/activate + pip install -r $BASEDIR/requirements.pip + touch $VENV_PATH/$VENV_NAME/updated + echo "Requirements installed." + deactivate +fi +set +e diff --git a/testcases/vIMS/CI/requirements.pip b/testcases/vIMS/CI/requirements.pip new file mode 100644 index 000000000..5d13172ec --- /dev/null +++ b/testcases/vIMS/CI/requirements.pip @@ -0,0 +1 @@ +cloudify==3.2
\ No newline at end of file diff --git a/testcases/vIMS/CI/vIMS.py b/testcases/vIMS/CI/vIMS.py new file mode 100644 index 000000000..d2d10f345 --- /dev/null +++ b/testcases/vIMS/CI/vIMS.py @@ -0,0 +1,332 @@ +#!/usr/bin/python +# coding: utf8 +####################################################################### +# +# Copyright (c) 2015 Orange +# valentin.boucher@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 +######################################################################## + +import os, time, subprocess, logging, argparse, yaml, pprint, sys, shutil +from git import Repo +import keystoneclient.v2_0.client as ksclient +import glanceclient.client as glclient +import novaclient.client as nvclient +from neutronclient.v2_0 import client as ntclient + +import urllib +pp = pprint.PrettyPrinter(indent=4) + + +parser = argparse.ArgumentParser() +parser.add_argument("repo_path", help="Path to the repository") +parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") +args = parser.parse_args() + +sys.path.append(args.repo_path + "testcases/") + +import functest_utils + +""" logging configuration """ +logger = logging.getLogger('vIMS') +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) + + +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) +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") + +TENANT_NAME = functest_yaml.get("vIMS").get("general").get("tenant_name") +TENANT_DESCRIPTION = functest_yaml.get("vIMS").get("general").get("tenant_description") +BASE_IMAGE_URL = functest_yaml.get("vIMS").get("general").get("base_image_url") +BASE_IMAGE_NAME = functest_yaml.get("vIMS").get("general").get("base_image_name") +GLANCE_IMAGE_NAME = functest_yaml.get("vIMS").get("cloudify").get("inputs").get("image_id") + +CFY_MANAGER_BLUEPRINT = functest_yaml.get("vIMS").get("cloudify").get("blueprint") +CFY_INPUTS = functest_yaml.get("vIMS").get("cloudify").get("inputs") +CFY_INPUTS_PATH = functest_yaml.get("vIMS").get("cloudify").get("inputs_path") + +CW_BLUEPRINT = functest_yaml.get("vIMS").get("clearwater").get("blueprint") +CW_DEPLOYMENT_NAME = functest_yaml.get("vIMS").get("clearwater").get("deployment-name") +CW_INPUTS = functest_yaml.get("vIMS").get("clearwater").get("inputs") +CW_DOMAIN_NAME = functest_yaml.get("vIMS").get("clearwater").get("inputs").get("public_domain") + + +def pMsg(value): + """pretty printing""" + pp.pprint(value) + +def download_and_add_image_on_glance(glance, image_name, image_url): + dest_path = VIMS_DATA_DIR + "tmp/" + 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) + return False + + image = functest_utils.create_glance_image(glance, image_name, dest_path + file_name) + if not image: + logger.error("Failed to upload image on glance") + return False + + return image + +def download_blueprints(blueprint_url, branch, dest_path): + if os.path.exists(dest_path): + shutil.rmtree(dest_path) + try: + Repo.clone_from(blueprint_url, dest_path, branch=branch) + return True + except: + return False + +def initialize_deployments(): + if not os.path.exists(VIMS_DATA_DIR): + os.makedirs(VIMS_DATA_DIR) + + ks_creds = functest_utils.get_credentials("keystone") + nv_creds = functest_utils.get_credentials("nova") + nt_creds = functest_utils.get_credentials("neutron") + + logger.info("Prepare OpenStack plateform (create tenant and user)") + keystone = ksclient.Client(**ks_creds) + + user_id = functest_utils.get_user_id(keystone, ks_creds['username']) + if user_id == '': + logger.error("Error : Failed to get id of %s user" %ks_creds['username']) + exit(-1) + + tenant_id = functest_utils.create_tenant(keystone, TENANT_NAME, TENANT_DESCRIPTION) + if tenant_id == '': + logger.error("Error : Failed to create %s tenant" %TENANT_NAME) + exit(-1) + + role_name = "admin" + role_id = functest_utils.get_role_id(keystone, role_name) + if role_id == '': + logger.error("Error : Failed to get id for %s role" %role_name) + + if not functest_utils.add_role_user(keystone, user_id, role_id, tenant_id): + logger.error("Error : Failed to add %s on tenant" %ks_creds['username']) + + user_id = functest_utils.create_user(keystone, TENANT_NAME, TENANT_NAME, None, tenant_id) + if user_id == '': + logger.error("Error : Failed to create %s user" %TENANT_NAME) + + logger.info("Update OpenStack creds informations") + ks_creds.update({ + "username": TENANT_NAME, + "password": TENANT_NAME, + "tenant_name": TENANT_NAME, + }) + + nt_creds.update({ + "tenant_name": TENANT_NAME, + }) + + nv_creds.update({ + "project_id": TENANT_NAME, + }) + + logger.info("Upload ubuntu image if it doesn't exist") + glance_endpoint = keystone.service_catalog.url_for(service_type='image', + endpoint_type='publicURL') + glance = glclient.Client(1, glance_endpoint, token=keystone.auth_token) + + image_id = functest_utils.get_image_id(glance, BASE_IMAGE_NAME) + if image_id == '': + logger.info("""%s image doesn't exist on glance repository. + Try downloading this image and upload on glance !""" %BASE_IMAGE_NAME) + image_id = download_and_add_image_on_glance(glance, BASE_IMAGE_NAME, BASE_IMAGE_URL) + + if image_id == '': + logger.error("Error : Failed to find or upload required OS image for this deployment" %flavor_name) + exit(-1) + + logger.info("Collect flavor id for cloudify and clearwater VMs") + nova = nvclient.Client("2", **nv_creds) + + flavor_name = "m1.small" + flavor_id = functest_utils.get_flavor_id(nova, flavor_name) + if flavor_id == '': + logger.error("Failed to find %s flavor. Try with ram range requirement !" %flavor_name) + flavor_id = get_flavor_id_by_ram_range(nova, 1792, 2048) + + if flavor_id == '': + logger.error("Failed to find required flavor for this deployment" %flavor_name) + exit(-1) + + logger.info("Update security group quota for this tenant") + neutron = ntclient.Client(**nt_creds) + if not functest_utils.update_sg_quota(neutron, tenant_id, 50, 100): + logger.error("Failed to update security group quota for tenant %s" %TENANT_NAME) + exit(-1) + + ext_net = functest_utils.get_external_net(neutron) + if not ext_net: + logger.error("Failed to get external network") + exit(-1) + + logger.info("Update inputs informations") + CFY_INPUTS['image_id'] = image_id + CFY_INPUTS['flavor_id'] = flavor_id + CFY_INPUTS['external_network_name'] = ext_net + + CW_INPUTS['image_id'] = image_id + CW_INPUTS['flavor_id'] = flavor_id + CW_INPUTS['external_network_name'] = ext_net + + CFY_INPUTS['keystone_username'] = ks_creds['username'] + CFY_INPUTS['keystone_password'] = ks_creds['password'] + CFY_INPUTS['keystone_url'] = ks_creds['auth_url'] + CFY_INPUTS['keystone_tenant_name'] = ks_creds['tenant_name'] + + logger.info("Prepare virtualenv for cloudify-cli") + cmd = "chmod +x " + VIMS_DIR + "create_venv.sh" + functest_utils.execute_command(cmd,logger) + cmd = VIMS_DIR + "create_venv.sh " + VIMS_DATA_DIR + functest_utils.execute_command(cmd,logger) + +def cleanup_deployments(): + ks_creds = functest_utils.get_credentials("keystone") + + keystone = ksclient.Client(**ks_creds) + + logger.info("Removing %s tenant .." %CFY_INPUTS['keystone_tenant_name']) + tenant_id = functest_utils.get_tenant_id(keystone, CFY_INPUTS['keystone_tenant_name']) + if tenant_id == '': + logger.error("Error : Failed to get id of %s tenant" %CFY_INPUTS['keystone_tenant_name']) + else: + if not functest_utils.delete_tenant(keystone, tenant_id): + logger.error("Error : Failed to remove %s tenant" %CFY_INPUTS['keystone_tenant_name']) + + logger.info("Removing %s user .." %CFY_INPUTS['keystone_username']) + user_id = functest_utils.get_user_id(keystone, CFY_INPUTS['keystone_username']) + if user_id == '': + logger.error("Error : Failed to get id of %s user" %CFY_INPUTS['keystone_username']) + else: + if not functest_utils.delete_user(keystone, user_id): + logger.error("Error : Failed to remove %s user" %CFY_INPUTS['keystone_username']) + +def deploy_cloudify_manager(): + + logger.info("Downloading the cloudify manager server blueprint") + download_result = download_blueprints(CFY_MANAGER_BLUEPRINT['url'], + CFY_MANAGER_BLUEPRINT['branch'], + VIMS_DATA_DIR + 'cloudify-manager-blueprint/') + + if not download_result: + logger.error("Failed to download manager blueprint") + exit(-1) + + logger.info("Writing the inputs file") + with open( VIMS_DATA_DIR + 'cloudify-manager-blueprint/' + CFY_INPUTS_PATH, "w") as f: + f.write(yaml.dump(CFY_INPUTS, default_style='"') ) + f.close() + + logger.info("Launching the cloudify-manager deployment") + script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " + script += "cd " + VIMS_DATA_DIR + "; " + script += "cfy init -r; " + script += "cd cloudify-manager-blueprint/openstack; " + script += "cfy local create-requirements -o requirements.txt -p openstack-manager-blueprint.yaml; " + script += "pip install -r requirements.txt; " + script += "cfy bootstrap --install-plugins -p openstack-manager-blueprint.yaml -i inputs.yaml; " + cmd = "/bin/bash -c '" + script + "'" + functest_utils.execute_command(cmd, logger) + + logger.info("Cloudify-manager server is UP !") + +def undeploy_cloudify_manager(): + + logger.info("Launching the cloudify-manager undeployment") + script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " + script += "cd " + VIMS_DATA_DIR + "; " + script += "cfy teardown -f; " + cmd = "/bin/bash -c '" + script + "'" + functest_utils.execute_command(cmd, logger) + + logger.info("Cloudify-manager server has been successfully removed!") + +def deploy_clearwater(): + + logger.info("Downloading the {0} blueprint".format(CW_BLUEPRINT['file_name'])) + download_result = download_blueprints(CW_BLUEPRINT['url'], CW_BLUEPRINT['branch'], + VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder']) + + if not download_result: + logger.error("Failed to download blueprint {0}".format(CW_BLUEPRINT['file_name'])) + exit(-1) + + logger.info("Writing the inputs file") + with open(VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "/inputs.yaml", "w") as f: + f.write(yaml.dump(CW_INPUTS, default_style='"') ) + f.close() + + logger.info("Launching the {0} deployment".format(CW_BLUEPRINT['name'])) + script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " + script += "cd " + VIMS_DATA_DIR + CW_BLUEPRINT['destination_folder'] + "; " + script += "cfy blueprints upload -b " + CW_BLUEPRINT['name'] + " -p openstack-blueprint.yaml; " + script += "cfy deployments create -b " + CW_BLUEPRINT['name'] + " -d " + CW_DEPLOYMENT_NAME + " --inputs inputs.yaml; " + script += "cfy executions start -w install -d " + CW_DEPLOYMENT_NAME + "; " + + cmd = "/bin/bash -c '" + script + "'" + functest_utils.execute_command(cmd, logger) + + logger.info("Clearwater vIMS is UP !") + +def undeploy_clearwater(): + + logger.info("Launching the {0} undeployment".format(CW_BLUEPRINT['name'])) + script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " + script += "cd " + VIMS_DATA_DIR + "; " + script += "cfy executions start -w uninstall -d " + CW_DEPLOYMENT_NAME + "; " + script += "cfy deployments delete -d " + CW_DEPLOYMENT_NAME + "; " + + cmd = "/bin/bash -c '" + script + "'" + functest_utils.execute_command(cmd, logger) + +def test_clearwater(): + + script = "source " + VIMS_DATA_DIR + "venv_cloudify/bin/activate; " + script += "cd " + VIMS_DATA_DIR + "; " + script += "cfy deployments outputs -d clearwater-opnfv | grep Value: | sed \"s/ *Value: //g\";" + cmd = "/bin/bash -c '" + script + "'" + dns_ip = os.popen(cmd).read() + dns_ip = dns_ip.splitlines()[0] + + # Coming soon + +def main(): + initialize_deployments() + deploy_cloudify_manager() + deploy_clearwater() + + #test_clearwater() + + undeploy_clearwater() + undeploy_cloudify_manager() + cleanup_deployments() + +if __name__ == '__main__': + main()
\ No newline at end of file |