CLOUDSTACK-5674: Few new fixes

This commit is contained in:
Girish Shilamkar 2014-02-09 16:02:52 -05:00
parent 286afda5d6
commit 3493f17bad
39 changed files with 248 additions and 249 deletions

View File

@ -226,6 +226,6 @@
}, },
"TestData": "TestData":
{ {
"Path": "config/config.cfg" "Path": ""
} }
} }

View File

@ -44,7 +44,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and Default Built-in template # Get Zone, Domain and Default Built-in template
self.domain = get_domain(self.apiclient) self.domain = get_domain(self.apiclient)
self.zone = get_zone(self.apiclient, self.testdata) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.testdata["mode"] = self.zone.networktype self.testdata["mode"] = self.zone.networktype
self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"])

View File

@ -36,7 +36,7 @@ class TestDeployVmWithUserData(cloudstackTestCase):
cls.apiClient = testClient.getApiClient() cls.apiClient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiClient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiClient, testClient.getZoneForTests())
if cls.zone.localstorageenabled: if cls.zone.localstorageenabled:
#For devcloud since localstroage is enabled #For devcloud since localstroage is enabled
cls.services["service_offerings"]["storagetype"] = "local" cls.services["service_offerings"]["storagetype"] = "local"

View File

@ -34,7 +34,7 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.template = get_template( cls.template = get_template(
cls.apiclient, cls.apiclient,
cls.zone.id, cls.zone.id,

View File

@ -36,7 +36,7 @@ class TestDedicateGuestVlanRange(cloudstackTestCase):
# Get Zone, Domain # Get Zone, Domain
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
# Create Account # Create Account
cls.account = Account.create( cls.account = Account.create(

View File

@ -37,7 +37,7 @@ class TestHosts(cloudstackTestCase):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection() self.dbclient = self.testClient.getDbConnection()
self.services = self.testClient.getParsedTestDataConfig() self.services = self.testClient.getParsedTestDataConfig()
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.pod = get_pod(self.apiclient, self.zone.id) self.pod = get_pod(self.apiclient, self.zone.id)
self.cleanup = [] self.cleanup = []

View File

@ -34,7 +34,7 @@ class TestInternalLb(cloudstackTestCase):
cls.apiclient = testClient.getApiClient() cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.service_offering = ServiceOffering.create( cls.service_offering = ServiceOffering.create(
cls.apiclient, cls.apiclient,

View File

@ -39,7 +39,7 @@ class TestCreateIso(cloudstackTestCase):
self.dbclient = self.testClient.getDbConnection() self.dbclient = self.testClient.getDbConnection()
# Get Zone, Domain and templates # Get Zone, Domain and templates
self.domain = get_domain(self.apiclient) self.domain = get_domain(self.apiclient)
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.services['mode'] = self.zone.networktype self.services['mode'] = self.zone.networktype
self.services["domainid"] = self.domain.id self.services["domainid"] = self.domain.id
self.services["iso_2"]["zoneid"] = self.zone.id self.services["iso_2"]["zoneid"] = self.zone.id

View File

@ -38,7 +38,7 @@ class TestLoadBalance(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
template = get_template( template = get_template(
cls.apiclient, cls.apiclient,
cls.zone.id, cls.zone.id,

View File

@ -48,7 +48,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and Default Built-in template # Get Zone, Domain and Default Built-in template
self.domain = get_domain(self.apiclient) self.domain = get_domain(self.apiclient)
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.testdata["mode"] = self.zone.networktype self.testdata["mode"] = self.zone.networktype
self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"]) self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"])

View File

@ -46,7 +46,7 @@ class TestPublicIP(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
# Create Accounts & networks # Create Accounts & networks
cls.account = Account.create( cls.account = Account.create(
@ -541,7 +541,7 @@ class TestRebootRouter(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
self.domain = get_domain(self.apiclient) self.domain = get_domain(self.apiclient)
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
template = get_template( template = get_template(
self.apiclient, self.apiclient,
self.zone.id, self.zone.id,

View File

@ -32,7 +32,7 @@ class TestNetworkACL(cloudstackTestCase):
cls.apiclient = testClient.getApiClient() cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.service_offering = ServiceOffering.create( cls.service_offering = ServiceOffering.create(
cls.apiclient, cls.apiclient,

View File

@ -48,7 +48,7 @@ class TestNic(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
domain = get_domain(self.apiclient) domain = get_domain(self.apiclient)
zone = get_zone(self.apiclient, self.getZoneForTests()) zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.services['mode'] = zone.networktype self.services['mode'] = zone.networktype
if zone.networktype != 'Advanced': if zone.networktype != 'Advanced':

View File

@ -39,7 +39,7 @@ class TestPortablePublicIPRange(cloudstackTestCase):
# Get Zone, Domain # Get Zone, Domain
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
# Create Account # Create Account
cls.account = Account.create( cls.account = Account.create(

View File

@ -37,7 +37,7 @@ class TestPrimaryStorageServices(cloudstackTestCase):
self.services = self.testClient.getParsedTestDataConfig() self.services = self.testClient.getParsedTestDataConfig()
self.cleanup = [] self.cleanup = []
# Get Zone and pod # Get Zone and pod
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.pod = get_pod(self.apiclient, self.zone.id) self.pod = get_pod(self.apiclient, self.zone.id)
return return

View File

@ -34,7 +34,7 @@ class TestDedicatePublicIPRange(cloudstackTestCase):
cls.services = Services().services cls.services = Services().services
# Get Zone, Domain # Get Zone, Domain
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, cls.getClsTestClient.getZoneForTests())
# Create Account # Create Account
cls.account = Account.create( cls.account = Account.create(

View File

@ -36,7 +36,7 @@ class TestResetVmOnReboot(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
domain = get_domain(cls.apiclient) domain = get_domain(cls.apiclient)
zone = get_zone(cls.apiclient, cls.getZoneForTests()) zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = zone.networktype cls.services['mode'] = zone.networktype
template = get_template( template = get_template(

View File

@ -40,7 +40,7 @@ class TestResourceDetail(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
domain = get_domain(cls.apiclient) domain = get_domain(cls.apiclient)
zone = get_zone(cls.apiclient, cls.getZoneForTests()) zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = zone.networktype cls.services['mode'] = zone.networktype
# Set Zones and disk offerings ?? # Set Zones and disk offerings ??

View File

@ -42,7 +42,7 @@ class TestRouterServices(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
template = get_template( template = get_template(
cls.apiclient, cls.apiclient,

View File

@ -36,7 +36,7 @@ class TestScaleVm(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
domain = get_domain(cls.apiclient) domain = get_domain(cls.apiclient)
zone = get_zone(cls.apiclient, cls.getZoneForTests()) zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = zone.networktype cls.services['mode'] = zone.networktype
template = get_template( template = get_template(

View File

@ -137,7 +137,7 @@ class TestServiceOfferings(cloudstackTestCase):
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
domain = get_domain(cls.apiclient) domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.service_offering_1 = ServiceOffering.create( cls.service_offering_1 = ServiceOffering.create(

View File

@ -32,7 +32,7 @@ class TestSnapshotRootDisk(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
template = get_template( template = get_template(

View File

@ -38,7 +38,7 @@ class TestSSVMs(cloudstackTestCase):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
self.cleanup = [] self.cleanup = []
self.services = Services().services self.services = Services().services
self.zone = get_zone(self.apiclient, self.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
return return
def tearDown(self): def tearDown(self):

View File

@ -59,7 +59,7 @@ class TestCreateTemplate(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.disk_offering = DiskOffering.create( cls.disk_offering = DiskOffering.create(
cls.apiclient, cls.apiclient,

View File

@ -39,7 +39,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
domain = get_domain(cls.apiclient) domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
#If local storage is enabled, alter the offerings to use localstorage #If local storage is enabled, alter the offerings to use localstorage

View File

@ -32,7 +32,7 @@ class TestVmSnapshot(cloudstackTestCase):
cls.services = Services().services cls.services = Services().services
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, cls.getClsTestClient().getZoneForTests())
template = get_template( template = get_template(
cls.apiclient, cls.apiclient,

View File

@ -43,10 +43,10 @@ class TestCreateVolume(cloudstackTestCase):
testClient = super(TestCreateVolume, cls).getClsTestClient() testClient = super(TestCreateVolume, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient() cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
print "\n***************",testClient.getParsedTestDataConfig()
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.disk_offering = DiskOffering.create( cls.disk_offering = DiskOffering.create(
cls.apiclient, cls.apiclient,
@ -224,7 +224,7 @@ class TestVolumes(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.disk_offering = DiskOffering.create( cls.disk_offering = DiskOffering.create(
cls.apiclient, cls.apiclient,

View File

@ -34,7 +34,7 @@ class TestVpcRemoteAccessVpn(cloudstackTestCase):
cls.apiclient = testClient.getApiClient() cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig() cls.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiclient, cls.getZoneForTests()) cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.domain = get_domain(cls.apiclient) cls.domain = get_domain(cls.apiclient)
cls.service_offering = ServiceOffering.create( cls.service_offering = ServiceOffering.create(
cls.apiclient, cls.apiclient,

View File

@ -16,7 +16,7 @@
# under the License. # under the License.
import threading import threading
import cloudstackException from marvin import cloudstackException
import time import time
import Queue import Queue
import copy import copy

View File

@ -38,7 +38,7 @@ from requests import (
Timeout, Timeout,
RequestException RequestException
) )
from cloudstackException import GetDetailExceptionInfo from marvin.cloudstackException import GetDetailExceptionInfo
class CSConnection(object): class CSConnection(object):

View File

@ -26,26 +26,25 @@ from codes import (FAILED, PASS, ADMIN, DOMAIN_ADMIN,
USER, SUCCESS, XEN_SERVER) USER, SUCCESS, XEN_SERVER)
from configGenerator import ConfigManager from configGenerator import ConfigManager
from marvin.lib import utils from marvin.lib import utils
from cloudstackException import GetDetailExceptionInfo from marvin.cloudstackException import GetDetailExceptionInfo
from marvin.lib.utils import (random_gen, validateList) from marvin.lib.utils import (random_gen, validateList)
from marvin.cloudstackAPI.cloudstackAPIClient import CloudStackAPIClient from marvin.cloudstackAPI.cloudstackAPIClient import CloudStackAPIClient
''' class CSTestClient(object):
@Desc : CloudStackTestClient is encapsulated entity for creating and '''
@Desc : CloudStackTestClient is encapsulated entity for creating and
getting various clients viz., apiclient, getting various clients viz., apiclient,
user api client, dbconnection, test Data parsed user api client, dbconnection, test Data parsed
information etc information etc
@Input : mgmtDetails : Management Server Details @Input :
dbSvrDetails: Database Server details of Management \ mgmt_details : Management Server Details
dbsvr_details: Database Server details of Management \
Server. Retrieved from configuration file. Server. Retrieved from configuration file.
asyncTimeout : Timeout for Async queries async_timeout : Timeout for Async queries
defaultWorkerThreads : Number of worker threads default_worker_threads : Number of worker threads
logger : provides logging facilities for this library logger : provides logging facilities for this library
zone : The zone on which test suites using this test client will run zone : The zone on which test suites using this test client will run
''' '''
class CSTestClient(object):
def __init__(self, mgmt_details, def __init__(self, mgmt_details,
dbsvr_details, dbsvr_details,
async_timeout=3600, async_timeout=3600,
@ -133,9 +132,9 @@ class CSTestClient(object):
list_user = listUsers.listUsersCmd() list_user = listUsers.listUsersCmd()
list_user.account = "admin" list_user.account = "admin"
list_user_res = self.__apiClient.listUsers(list_user) list_user_res = self.__apiClient.listUsers(list_user)
if list_user_res is None or\ if list_user_res == FAILED or list_user_res is None or\
(validateList(list_user_res)[0] != PASS): (validateList(list_user_res)[0] != PASS):
self.__logger.debug("__createApiClient: API " self.__logger.error("__createApiClient: API "
"Client Creation Failed") "Client Creation Failed")
return FAILED return FAILED
@ -200,7 +199,6 @@ class CSTestClient(object):
register_user.id = userid register_user.id = userid
register_user_res = \ register_user_res = \
self.__apiClient.registerUserKeys(register_user) self.__apiClient.registerUserKeys(register_user)
if register_user_res == FAILED: if register_user_res == FAILED:
return FAILED return FAILED
return (register_user_res.apikey, register_user_res.secretkey) return (register_user_res.apikey, register_user_res.secretkey)
@ -232,9 +230,11 @@ class CSTestClient(object):
configuration file. They can overwrite it with configuration file. They can overwrite it with
providing their own configuration file as well. providing their own configuration file as well.
''' '''
print "******************PATH*****************",self.__testDataFilePath
self.__configObj = ConfigManager(self.__testDataFilePath) self.__configObj = ConfigManager(self.__testDataFilePath)
if self.__configObj is not None: if self.__configObj:
self.__parsedTestDataConfig = self.__configObj.getConfig() self.__parsedTestDataConfig = self.__configObj.getConfig()
print "\n**************************************HTTTTTT***",self.__parsedTestDataConfig
else: else:
self.__logger.error("createTestClient : Not able to create " self.__logger.error("createTestClient : Not able to create "
"ConfigManager Object") "ConfigManager Object")
@ -246,7 +246,12 @@ class CSTestClient(object):
''' '''
3. Creates API Client 3. Creates API Client
''' '''
return self.__createApiClient() ret = self.__createApiClient()
if ret == FAILED:
self.__logger.error("********Test Client Creation Failed********")
else:
self.__logger.debug("********Test Client Creation Successful********")
return ret
except Exception, e: except Exception, e:
self.__logger.exception("Exception Occurred " self.__logger.exception("Exception Occurred "
"Under createTestClient " "Under createTestClient "
@ -368,7 +373,7 @@ class CSTestClient(object):
return self.__configObj return self.__configObj
def getApiClient(self): def getApiClient(self):
if self.__apiClient is not None: if self.__apiClient:
self.__apiClient.id = self.identifier self.__apiClient.id = self.identifier
return self.__apiClient return self.__apiClient
return None return None

View File

@ -332,10 +332,7 @@ class ConfigManager(object):
"getConfig" API,once configObj is returned. "getConfig" API,once configObj is returned.
''' '''
def __init__(self, cfg_file=None): def __init__(self, cfg_file=None):
if cfg_file is None: self.__filePath = cfg_file
self.__filePath = "config/test_data.cfg"
else:
self.__filePath = cfg_file
self.__parsedCfgDict = None self.__parsedCfgDict = None
''' '''
Set the Configuration Set the Configuration
@ -343,8 +340,11 @@ class ConfigManager(object):
self.__setConfig() self.__setConfig()
def __setConfig(self): def __setConfig(self):
if self.__verifyFile() is not False: if not self.__verifyFile():
self.__parsedCfgDict = self.__parseConfig() dirPath = os.path.dirname(__file__)
self.__filePath = os.path.join(dirPath,"config/test_data.cfg")
self.__parsedCfgDict = self.__parseConfig()
print "*************PATH3***************",self.__filePath,self.__parsedCfgDict
def __parseConfig(self): def __parseConfig(self):
''' '''
@ -382,7 +382,7 @@ class ConfigManager(object):
''' '''
if self.__filePath is None or self.__filePath == '': if self.__filePath is None or self.__filePath == '':
return False return False
return False if os.path.exists(self.__filePath) is False else True return os.path.exists(self.__filePath)
def getSectionData(self, section=None): def getSectionData(self, section=None):
''' '''

View File

@ -20,7 +20,7 @@ import contextlib
from mysql import connector from mysql import connector
from mysql.connector import errors from mysql.connector import errors
from contextlib import closing from contextlib import closing
import cloudstackException from marvin import cloudstackException
import sys import sys
import os import os

View File

@ -686,7 +686,7 @@ if __name__ == "__main__":
log_check = False log_check = False
if log_obj is not None: if log_obj is not None:
log_check = True log_check = True
ret = log_obj.createLogs("DataCenter", ret = log_obj.createLogs("DeployDataCenter",
cfg.logger) cfg.logger)
if ret != FAILED: if ret != FAILED:
log_folder_path = log_obj.getLogFolderPath() log_folder_path = log_obj.getLogFolderPath()

View File

@ -30,7 +30,7 @@ import urlparse
import datetime import datetime
from platform import system from platform import system
from marvin.cloudstackAPI import cloudstackAPIClient, listHosts from marvin.cloudstackAPI import cloudstackAPIClient, listHosts
from cloudstackException import GetDetailExceptionInfo from marvin.cloudstackException import GetDetailExceptionInfo
from marvin.sshClient import SshClient from marvin.sshClient import SshClient
from marvin.codes import ( from marvin.codes import (
SUCCESS, SUCCESS,

View File

@ -15,18 +15,17 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
''' '''
@Desc: Initializes the marvin and does required prerequisites Initializes the marvin and does required prerequisites
for starting it. for starting it.
1. Parses the configuration file passed to marvin and creates a 1. Parses the configuration file passed to marvin and creates a
parsed config parsed config.
2. Initializes the logging required for marvin.All logs are 2. Initializes the logging required for marvin.All logs are
now made available under a single timestamped folder. now made available under a single timestamped folder.
3. Deploys the Data Center based upon input 3. Deploys the Data Center based upon input.
''' '''
from marvin import configGenerator from marvin.configGenerator import getSetupConfig
from marvin import cloudstackException
from marvin.marvinLog import MarvinLog from marvin.marvinLog import MarvinLog
from marvin.deployDataCenter import DeployDataCenters from marvin.deployDataCenter import DeployDataCenters
from marvin.cloudstackTestClient import CSTestClient from marvin.cloudstackTestClient import CSTestClient
@ -49,32 +48,30 @@ from marvin.codegenerator import CodeGenerator
class MarvinInit: class MarvinInit:
def __init__(self, config_file, load_api_flag=None, def __init__(self, config_file,
deploy_dc_flag=None, deploy_dc_flag=None,
test_module_name=None, test_mod_name="deploydc",
zone=None): zone=None):
self.__configFile = config_file self.__configFile = config_file
self.__deployFlag = deploy_dc_flag self.__deployFlag = deploy_dc_flag
self.__loadApiFlag = load_api_flag
self.__parsedConfig = None self.__parsedConfig = None
self.__logFolderPath = None self.__logFolderPath = None
self.__tcRunLogger = None self.__tcRunLogger = None
self.__testModName = test_mod_name
self.__testClient = None self.__testClient = None
self.__tcResultFile = None self.__tcResultFile = None
self.__testModuleName = test_module_name
self.__testDataFilePath = None self.__testDataFilePath = None
self.__zoneForTests = None self.__zoneForTests = None
def __parseConfig(self): def __parseConfig(self):
''' '''
@Name: __parseConfig
@Desc : Parses the configuration file passed and assigns @Desc : Parses the configuration file passed and assigns
the parsed configuration the parsed configuration
@Output : SUCCESS or FAILED
''' '''
try: try:
if self.__configFile is None: self.__parsedConfig = getSetupConfig(self.__configFile)
return FAILED
self.__parsedConfig = configGenerator.\
getSetupConfig(self.__configFile)
return SUCCESS return SUCCESS
except Exception, e: except Exception, e:
print "\nException Occurred Under __parseConfig : " \ print "\nException Occurred Under __parseConfig : " \
@ -93,7 +90,13 @@ class MarvinInit:
def getLogger(self): def getLogger(self):
return self.__tcRunLogger return self.__tcRunLogger
def getDebugFile(self): def getResultFile(self):
'''
@Name : getDebugFile
@Desc : Creates the result file at a given path.
@Output : Returns the Result file to be used for writing
test outputs
'''
if self.__logFolderPath is not None: if self.__logFolderPath is not None:
self.__tcResultFile = open(self.__logFolderPath + self.__tcResultFile = open(self.__logFolderPath +
"/results.txt", "w") "/results.txt", "w")
@ -108,14 +111,14 @@ class MarvinInit:
2. Creates a timestamped log folder and provides all logs 2. Creates a timestamped log folder and provides all logs
to be dumped there to be dumped there
3. Creates the DataCenter based upon configuration provided 3. Creates the DataCenter based upon configuration provided
@Output : SUCCESS or FAILED
''' '''
try: try:
if ((self.__parseConfig() != FAILED) and if ((self.__parseConfig() != FAILED) and
(self.__setTestDataPath() != FAILED) and (self.__setTestDataPath() != FAILED) and
(self.__initLogging() != FAILED) and (self.__initLogging() != FAILED) and
(self.__createTestClient() != FAILED) and (self.__createTestClient() != FAILED) and
(self.__deployDC() != FAILED) and (self.__deployDC() != FAILED)):
(self.__loadNewApiFromXml() != FAILED)):
return SUCCESS return SUCCESS
else: else:
return FAILED return FAILED
@ -125,9 +128,9 @@ class MarvinInit:
return FAILED return FAILED
def __initLogging(self): def __initLogging(self):
try: '''
''' @Name : __initLogging
@Desc : 1. Initializes the logging for marvin and so provides @Desc : 1. Initializes the logging for marvin and so provides
various log features for automation run. various log features for automation run.
2. Initializes all logs to be available under 2. Initializes all logs to be available under
given Folder Path,where all test run logs given Folder Path,where all test run logs
@ -135,18 +138,19 @@ class MarvinInit:
3. All logging like exception log,results, run info etc 3. All logging like exception log,results, run info etc
for a given test run are available under a given for a given test run are available under a given
timestamped folder timestamped folder
''' @Output : SUCCESS or FAILED
'''
try:
log_obj = MarvinLog("CSLog") log_obj = MarvinLog("CSLog")
if log_obj is None: if log_obj:
return FAILED
else:
ret = log_obj.\ ret = log_obj.\
getLogs(self.__testModuleName, createLogs(self.__testModName,
self.__parsedConfig.logger) self.__parsedConfig.logger)
if ret != FAILED: if ret != FAILED:
self.__logFolderPath = log_obj.getLogFolderPath() self.__logFolderPath = log_obj.getLogFolderPath()
self.__tcRunLogger = log_obj.getLogger() self.__tcRunLogger = log_obj.getLogger()
return SUCCESS return SUCCESS
return FAILED
except Exception, e: except Exception, e:
print "\n Exception Occurred Under __initLogging " \ print "\n Exception Occurred Under __initLogging " \
":%s" % GetDetailExceptionInfo(e) ":%s" % GetDetailExceptionInfo(e)
@ -157,6 +161,7 @@ class MarvinInit:
@Name : __createTestClient @Name : __createTestClient
@Desc : Creates the TestClient during init @Desc : Creates the TestClient during init
based upon the parameters provided based upon the parameters provided
@Output: Returns SUCCESS or FAILED
''' '''
try: try:
mgt_details = self.__parsedConfig.mgtSvr[0] mgt_details = self.__parsedConfig.mgtSvr[0]
@ -166,7 +171,7 @@ class MarvinInit:
test_data_filepath= test_data_filepath=
self.__testDataFilePath, self.__testDataFilePath,
zone=self.__zoneForTests) zone=self.__zoneForTests)
if self.__testClient is not None: if self.__testClient:
return self.__testClient.createTestClient() return self.__testClient.createTestClient()
else: else:
return FAILED return FAILED
@ -175,37 +180,12 @@ class MarvinInit:
GetDetailExceptionInfo(e) GetDetailExceptionInfo(e)
return FAILED return FAILED
def __loadNewApiFromXml(self):
try:
if self.__loadApiFlag:
apiLoadCfg = self.__parsedConfig.apiLoadCfg
api_dst_dir = apiLoadCfg.ParsedApiDestFolder + "/cloudstackAPI"
api_spec_file = apiLoadCfg.ApiSpecFile
if not os.path.exists(api_dst_dir):
try:
os.mkdir(api_dst_dir)
except Exception, e:
print "Failed to create folder %s, " \
"due to %s" % (api_dst_dir,
GetDetailExceptionInfo(e))
exit(1)
mgt_details = self.__parsedConfig.mgtSvr[0]
cg = CodeGenerator(api_dst_dir)
if os.path.exists(api_spec_file):
cg.generateCodeFromXML(api_spec_file)
elif mgt_details is not None:
endpoint_url = 'http://%s:8096/client/api?' \
'command=listApis&response=json' \
% mgt_details.mgtSvrIp
cg.generateCodeFromJSON(endpoint_url)
return SUCCESS
except Exception, e:
print "\n Exception Occurred Under __loadNewApiFromXml : %s" \
% GetDetailExceptionInfo(e)
return FAILED
def __setTestDataPath(self): def __setTestDataPath(self):
'''
@Name : __setTestDataPath
@Desc : Sets the TestData Path for tests to run
@Output:Returns SUCCESS or FAILED
'''
try: try:
if ((self.__parsedConfig.TestData is not None) and if ((self.__parsedConfig.TestData is not None) and
(self.__parsedConfig.TestData.Path is not None)): (self.__parsedConfig.TestData.Path is not None)):
@ -217,14 +197,23 @@ class MarvinInit:
return FAILED return FAILED
def __deployDC(self): def __deployDC(self):
'''
@Name : __deployDC
@Desc : Deploy the DataCenter and returns accordingly.
@Output: SUCCESS or FAILED
'''
try: try:
''' ret = SUCCESS
Deploy the DataCenter and retrieves test client. if self.__deployFlag:
''' deploy_obj = DeployDataCenters(self.__testClient,
deploy_obj = DeployDataCenters(self.__testClient,
self.__parsedConfig, self.__parsedConfig,
self.__tcRunLogger) self.__tcRunLogger)
return deploy_obj.deploy() if self.__deployFlag else FAILED ret = deploy_obj.deploy()
if ret == SUCCESS:
print "Deploy DC Successful"
else:
print "Deploy DC Failed"
return ret
except Exception, e: except Exception, e:
print "\n Exception Occurred Under __deployDC : %s" % \ print "\n Exception Occurred Under __deployDC : %s" % \
GetDetailExceptionInfo(e) GetDetailExceptionInfo(e)

View File

@ -65,9 +65,11 @@ class MarvinLog:
self.__logger = logging.getLogger(self.__loggerName) self.__logger = logging.getLogger(self.__loggerName)
self.__logger.setLevel(logging.DEBUG) self.__logger.setLevel(logging.DEBUG)
def __setLogHandler(self, log_file_path, log_format=None, def __setLogHandler(self, log_file_path,
log_format=None,
log_level=logging.DEBUG): log_level=logging.DEBUG):
''' '''
@Name : __setLogHandler
@Desc: Adds the given Log handler to the current logger @Desc: Adds the given Log handler to the current logger
@Input: log_file_path: Log File Path as where to store the logs @Input: log_file_path: Log File Path as where to store the logs
log_format : Format of log messages to be dumped log_format : Format of log messages to be dumped
@ -100,7 +102,8 @@ class MarvinLog:
@Input: logfolder_to_remove: Path of Log to remove @Input: logfolder_to_remove: Path of Log to remove
''' '''
try: try:
os.rmdir(logfolder_to_remove) if os.path.isdir(logfolder_to_remove):
os.rmdir(logfolder_to_remove)
except Exception, e: except Exception, e:
print "\n Exception Occurred Under __cleanPreviousLogs :%s" % \ print "\n Exception Occurred Under __cleanPreviousLogs :%s" % \
GetDetailExceptionInfo(e) GetDetailExceptionInfo(e)
@ -120,7 +123,9 @@ class MarvinLog:
''' '''
return self.__logFolderDir return self.__logFolderDir
def createLogs(self, test_module_name=None, log_cfg=None): def createLogs(self,
test_module_name=None,
log_cfg=None):
''' '''
@Name : createLogs @Name : createLogs
@Desc : Gets the Logger with file paths initialized and created @Desc : Gets the Logger with file paths initialized and created
@ -131,21 +136,15 @@ class MarvinLog:
@Output : SUCCESS\FAILED @Output : SUCCESS\FAILED
''' '''
try: try:
if log_cfg is None: temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S",
print "\nInvalid Log Folder Configuration." \
"Please Check Config File"
return FAILED
if test_module_name is None:
temp_path = time.strftime("%b_%d_%Y_%H_%M_%S",
time.localtime()) time.localtime())
if test_module_name is None:
temp_path = temp_ts
else: else:
temp_path = str(test_module_name.split(".py")[0]) temp_path = str(test_module_name) + "__" + str(temp_ts)
if (('LogFolderPath' in log_cfg.__dict__.keys()) and if ((log_cfg is not None) and ('LogFolderPath' in log_cfg.__dict__.keys()) and
(log_cfg.__dict__.get('LogFolderPath') is not None)): (log_cfg.__dict__.get('LogFolderPath') is not None)):
self.__cleanPreviousLogs(log_cfg.
__dict__.
get('LogFolderPath') + "/MarvinLogs")
temp_dir = \ temp_dir = \
log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs" log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
else: else:

View File

@ -14,10 +14,11 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
import marvin import marvin
import sys import sys
import logging import logging
import time
import os
import nose.core import nose.core
from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.marvinInit import MarvinInit from marvin.marvinInit import MarvinInit
@ -25,9 +26,7 @@ from nose.plugins.base import Plugin
from marvin.codes import (SUCCESS, from marvin.codes import (SUCCESS,
FAILED, FAILED,
EXCEPTION) EXCEPTION)
from marvin.cloudstackException import GetDetailExceptionInfo from marvin.cloudstackException import GetDetailExceptionInfo
import time
import os
class MarvinPlugin(Plugin): class MarvinPlugin(Plugin):
@ -38,32 +37,28 @@ class MarvinPlugin(Plugin):
name = "marvin" name = "marvin"
def __init__(self): def __init__(self):
self.identifier = None self.__identifier = None
self.testClient = None self.__testClient = None
self.parsedConfig = None self.__parsedConfig = None
''' '''
Contains Config File Contains Config File
''' '''
self.__configFile = None self.__configFile = None
''' '''
Signifies the flag whether to load new API Information
'''
self.__loadNewApiFlag = None
'''
Signifies the Zone against which all tests will be Run Signifies the Zone against which all tests will be Run
''' '''
self.__zoneForTests = None self.__zoneForTests = None
''' '''
Signifies the flag whether to deploy the New DC or Not Signifies the flag whether to deploy the New DC or Not
''' '''
self.__deployDcFlag self.__deployDcFlag = None
self.conf = None self.conf = None
self.debugStream = sys.stdout self.__debugStream = sys.stdout
self.testRunner = None self.__testRunner = None
self.testResult = SUCCESS self.__testResult = SUCCESS
self.startTime = None self.__startTime = None
self.testName = None self.__testName = None
self.tcRunLogger = None self.__tcRunLogger = None
Plugin.__init__(self) Plugin.__init__(self)
def configure(self, options, conf): def configure(self, options, conf):
@ -78,12 +73,11 @@ class MarvinPlugin(Plugin):
return return
else: else:
self.enabled = True self.enabled = True
self.__configFile = options.configFile
self.__configFile = options.config_file
self.__loadNewApiFlag = options.loadNewApiFlag
self.__deployDcFlag = options.deployDc self.__deployDcFlag = options.deployDc
self.__zoneForTests = options.zone self.__zoneForTests = options.zone
self.conf = conf self.conf = conf
self.startMarvin()
def options(self, parser, env): def options(self, parser, env):
""" """
@ -92,32 +86,20 @@ class MarvinPlugin(Plugin):
parser.add_option("--marvin-config", action="store", parser.add_option("--marvin-config", action="store",
default=env.get('MARVIN_CONFIG', default=env.get('MARVIN_CONFIG',
'./datacenter.cfg'), './datacenter.cfg'),
dest="config_file", dest="configFile",
help="Marvin's configuration file is required." help="Marvin's configuration file is required."
"The config file containing the datacenter and " "The config file containing the datacenter and "
"other management server " "other management server "
"information is specified") "information is specified")
parser.add_option("--deploy-dc", action="store_true", parser.add_option("--deploy", action="store_true",
default=False, default=False,
dest="deployDc", dest="deployDc",
help="Deploys the DC with Given Configuration." help="Deploys the DC with Given Configuration."
"Requires only when DC needs to be deployed") "Requires only when DC needs to be deployed")
parser.add_option("--zone", action="zone_tests", parser.add_option("--zone", action="store_true",
default=None, default=None,
dest="zone", dest="zone",
help="Runs all tests against this specified zone") help="Runs all tests against this specified zone")
parser.add_option("--load-new-apis", action="store_true",
default=False,
dest="loadNewApiFlag",
help="Loads the New Apis with Given Api Xml File."
"Creates the new Api's from commands.xml File")
'''
Check if the configuration file is not valid,print and exit
'''
(options, args) = parser.parse_args()
if options.config_file is None:
parser.print_usage()
sys.exit(1)
Plugin.options(self, parser, env) Plugin.options(self, parser, env)
def wantClass(self, cls): def wantClass(self, cls):
@ -127,17 +109,9 @@ class MarvinPlugin(Plugin):
return True return True
return None return None
def prepareTest(self, test):
'''
@Desc : Initializes the marvin with required settings
'''
test_module_name = test.__str__()
if self.startMarvin(test_module_name) == FAILED:
print "Starting Marvin FAILED. Please Check Config and " \
"Arguments Supplied"
def __checkImport(self, filename): def __checkImport(self, filename):
''' '''
@Name : __checkImport
@Desc : Verifies to Import the test Module before running and check @Desc : Verifies to Import the test Module before running and check
whether if it is importable. whether if it is importable.
This will check for test modules which has some issues to be This will check for test modules which has some issues to be
@ -145,94 +119,125 @@ class MarvinPlugin(Plugin):
Returns False or True based upon the result. Returns False or True based upon the result.
''' '''
try: try:
__import__(filename) if os.path.isfile(filename):
return True ret = os.path.splitext(filename)
if ret[1] == ".py":
os.system("python "+ filename)
return True
return False
except ImportError, e: except ImportError, e:
self.tcRunLogger.exception("Module : %s Import " print "FileName :%s : Error : %s"%(filename,GetDetailExceptionInfo(e))
"Failed Reason :%s"
% (filename, GetDetailExceptionInfo(e)))
return False return False
def wantFile(self, filename): def wantFile(self, filename):
''' '''
@Desc : Only python files will be used as test modules @Desc : Only python files will be used as test modules
''' '''
if filename is None or filename == '': return self.__checkImport(filename)
return False
parts = filename.split(os.path.sep)
base, ext = os.path.splitext(parts[-1])
if ext != '.py':
return False
else:
return self.__checkImport(filename)
def loadTestsFromTestCase(self, cls): def loadTestsFromTestCase(self, cls):
if cls.__name__ != 'cloudstackTestCase': if cls.__name__ != 'cloudstackTestCase':
self.identifier = cls.__name__ self.__identifier = cls.__name__
self._injectClients(cls) self._injectClients(cls)
def beforeTest(self, test): def beforeTest(self, test):
self.testName = test.__str__().split()[0] self.__testName = test.__str__().split()[0]
self.testClient.identifier = '-'.join([self.identifier, self.testName]) self.__testClient.identifier = '-'.join([self.__identifier, self.__testName])
self.tcRunLogger.name = test.__str__() if self.__tcRunLogger:
self.__tcRunLogger.name = test.__str__()
def prepareTestRunner(self, runner):
return self.testRunner
def startTest(self, test): def startTest(self, test):
""" """
Currently used to record start time for tests Currently used to record start time for tests
Dump Start Msg of TestCase to Log Dump Start Msg of TestCase to Log
""" """
self.tcRunLogger.debug("\n\n::::::::::::STARTED : TC: " + if self.__tcRunLogger:
str(self.testName) + " :::::::::::") self.__tcRunLogger.debug("\n\n::::::::::::STARTED : TC: " +
self.startTime = time.time() str(self.__testName) + " :::::::::::")
self.__startTime = time.time()
def handleError(self, test, err): def handleError(self, test, err):
''' '''
Adds Exception throwing test cases and information to log. Adds Exception throwing test cases and information to log.
''' '''
err_msg = GetDetailExceptionInfo(err) if self.__tcRunLogger:
self.tcRunLogger.fatal("%s: %s: %s" % self.__tcRunLogger.fatal("%s: %s: %s" %
(EXCEPTION, self.testName, err_msg)) (EXCEPTION, self.__testName, GetDetailExceptionInfo(err)))
self.testResult = EXCEPTION self.__testResult = EXCEPTION
def handleFailure(self, test, err): def handleFailure(self, test, err):
''' '''
Adds Failing test cases and information to log. Adds Failing test cases and information to log.
''' '''
err_msg = GetDetailExceptionInfo(err) if self.__tcRunLogger:
self.tcRunLogger.fatal("%s: %s: %s" % self.__tcRunLogger.fatal("%s: %s: %s" %
(FAILED, self.testName, err_msg)) (FAILED, self.__testName, GetDetailExceptionInfo(err)))
self.testResult = FAILED self.__testResult = FAILED
def startMarvin(self, test_module_name): def __getModName(self,inp, type='file'):
''' '''
Initializes the Marvin @Desc : Returns the module name from the path
creates the test Client @Output: trimmed down module name, used for logging
creates the runlogger for logging @Input: type:Whether the type is file or dir
Parses the config and creates a parsedconfig inp:input element
Creates a debugstream for tc debug log '''
if type == 'file':
temp = os.path.splitext(inp)[0]
return os.path.split(temp)[-1]
if type == 'dir':
return os.path.split(inp)[-1]
def __runSuite(self, test_suite=None):
try:
if test_suite:
if self.wantFile(test_suite) == True:
test_mod_name = self.__getModName(test_suite)
temp_obj = MarvinInit(self.__configFile,
None,
test_mod_name,
self.__zoneForTests)
if temp_obj and temp_obj.init() == SUCCESS:
self.__testClient = temp_obj.getTestClient()
self.__tcRunLogger = temp_obj.getLogger()
self.__parsedConfig = temp_obj.getParsedConfig()
self.__debugStream = temp_obj.getResultFile()
self.__testRunner = nose.core.TextTestRunner(stream=self.__debugStream,
descriptions=True,
verbosity=2)
#if self.__testRunner:
# self.__testRunner.run(test_suite)
return SUCCESS
except Exception,e:
print "\n Exception Occurred when running suite :%s Error : %s" % (test_suite, GetDetailExceptionInfo(e))
return FAILED
def __runSuites(self, suites):
for suite in suites:
self.__runSuite(suite)
def startMarvin(self):
'''
@Name : startMarvin
@Desc : Initializes the Marvin
creates the test Client
creates the runlogger for logging
Parses the config and creates a parsedconfig
Creates a debugstream for tc debug log
''' '''
try: try:
obj_marvininit = MarvinInit(self.__configFile, obj_marvininit = MarvinInit(self.__configFile,
self.__loadNewApiFlag,
self.__deployDcFlag, self.__deployDcFlag,
test_module_name, self.__zoneForTests)
self.__zoneForoTests) if obj_marvininit and obj_marvininit.init() == SUCCESS:
if obj_marvininit.init() == SUCCESS: print "\nMarvin Initialization Successful"
self.testClient = obj_marvininit.getTestClient() for suites in self.conf.testNames:
self.tcRunLogger = obj_marvininit.getLogger() if os.path.isdir(suites):
self.parsedConfig = obj_marvininit.getParsedConfig() self.__runSuites(suites)
self.debugStream = obj_marvininit.getDebugFile() if os.path.isfile(suites):
self.testRunner = nose.core.TextTestRunner(stream= self.__runSuite(suites)
self.debugStream,
descriptions=True,
verbosity=2,
config=self.conf)
return SUCCESS return SUCCESS
else: print "\nMarvin Initialization Failed"
return FAILED return FAILED
except Exception, e: except Exception, e:
print "Exception Occurred under startMarvin: %s" % \ print "Exception Occurred under startMarvin: %s" % \
GetDetailExceptionInfo(e) GetDetailExceptionInfo(e)
@ -243,28 +248,29 @@ class MarvinPlugin(Plugin):
Currently used to record end time for tests Currently used to record end time for tests
""" """
endTime = time.time() endTime = time.time()
if self.startTime is not None: if self.__startTime:
totTime = int(endTime - self.startTime) totTime = int(endTime - self.__startTime)
self.tcRunLogger.debug("TestCaseName: %s; Time Taken: " if self.__tcRunLogger:
self.__tcRunLogger.debug("TestCaseName: %s; Time Taken: "
"%s Seconds; " "%s Seconds; "
"StartTime: %s; EndTime: %s; Result: %s" "StartTime: %s; EndTime: %s; Result: %s"
% (self.testName, str(totTime), % (self.__testName, str(totTime),
str(time.ctime(self.startTime)), str(time.ctime(self.__startTime)),
str(time.ctime(endTime)), str(time.ctime(endTime)),
self.testResult)) self.__testResult))
def _injectClients(self, test): def _injectClients(self, test):
setattr(test, "debug", self.tcRunLogger.debug) setattr(test, "debug", self.__tcRunLogger.debug)
setattr(test, "info", self.tcRunLogger.info) setattr(test, "info", self.__tcRunLogger.info)
setattr(test, "warn", self.tcRunLogger.warning) setattr(test, "warn", self.__tcRunLogger.warning)
setattr(test, "error", self.tcRunLogger.error) setattr(test, "error", self.__tcRunLogger.error)
setattr(test, "testClient", self.testClient) setattr(test, "testClient", self.__testClient)
setattr(test, "config", self.parsedConfig) setattr(test, "config", self.__parsedConfig)
if self.testClient.identifier is None: if self.__testClient.identifier is None:
self.testClient.identifier = self.identifier self.__testClient.identifier = self.__identifier
setattr(test, "clstestclient", self.testClient) setattr(test, "clstestclient", self.__testClient)
if hasattr(test, "user"): if hasattr(test, "user"):
# when the class-level attr applied. all test runs as 'user' # when the class-level attr applied. all test runs as 'user'
self.testClient.getUserApiClient(test.UserName, self.__testClient.getUserApiClient(test.UserName,
test.DomainName, test.DomainName,
test.AcctType) test.AcctType)

View File

@ -25,7 +25,7 @@ from paramiko import (BadHostKeyException,
SFTPClient) SFTPClient)
import socket import socket
import time import time
from cloudstackException import ( from marvin.cloudstackException import (
internalError, internalError,
GetDetailExceptionInfo GetDetailExceptionInfo
) )