CLOUDSTACk-5674: Added fix for CLOUDSTACK-5674

This commit is contained in:
Santhosh Edukulla 2014-02-12 17:34:34 +05:30 committed by Girish Shilamkar
parent 7cc9423b8d
commit 3dbb2ae488
35 changed files with 264 additions and 322 deletions

View File

@ -218,14 +218,5 @@
"certCAPath": "NA",
"certPath": "NA"
}
],
"ApiLoadCfg":
{
"ParsedApiDestFolder": ".",
"ApiSpecFile": "/etc/cloud/cli/commands.xml"
},
"TestData":
{
"Path": "config/config.cfg"
}
]
}

View File

@ -44,7 +44,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and Default Built-in template
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.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.services = testClient.getParsedTestDataConfig()
cls.zone = get_zone(cls.apiClient, cls.getZoneForTests())
cls.zone = get_zone(cls.apiClient, testClient.getZoneForTests())
if cls.zone.localstorageenabled:
#For devcloud since localstroage is enabled
cls.services["service_offerings"]["storagetype"] = "local"

View File

@ -34,7 +34,7 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase):
# Get Zone, Domain and templates
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.apiclient,
cls.zone.id,

View File

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

View File

@ -37,7 +37,7 @@ class TestHosts(cloudstackTestCase):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
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.cleanup = []

View File

@ -34,7 +34,7 @@ class TestInternalLb(cloudstackTestCase):
cls.apiclient = testClient.getApiClient()
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.service_offering = ServiceOffering.create(
cls.apiclient,

View File

@ -39,7 +39,7 @@ class TestCreateIso(cloudstackTestCase):
self.dbclient = self.testClient.getDbConnection()
# Get Zone, Domain and templates
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["domainid"] = self.domain.id
self.services["iso_2"]["zoneid"] = self.zone.id

View File

@ -38,7 +38,7 @@ class TestLoadBalance(cloudstackTestCase):
# Get Zone, Domain and templates
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(
cls.apiclient,
cls.zone.id,

View File

@ -48,7 +48,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and Default Built-in template
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.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
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
# Create Accounts & networks
cls.account = Account.create(
@ -541,7 +541,7 @@ class TestRebootRouter(cloudstackTestCase):
# Get Zone, Domain and templates
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(
self.apiclient,
self.zone.id,

View File

@ -32,7 +32,7 @@ class TestNetworkACL(cloudstackTestCase):
cls.apiclient = testClient.getApiClient()
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.service_offering = ServiceOffering.create(
cls.apiclient,

View File

@ -48,7 +48,7 @@ class TestNic(cloudstackTestCase):
# Get Zone, Domain and templates
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
if zone.networktype != 'Advanced':

View File

@ -39,7 +39,7 @@ class TestPortablePublicIPRange(cloudstackTestCase):
# Get Zone, Domain
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
cls.account = Account.create(

View File

@ -37,7 +37,7 @@ class TestPrimaryStorageServices(cloudstackTestCase):
self.services = self.testClient.getParsedTestDataConfig()
self.cleanup = []
# 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)
return

View File

@ -34,7 +34,7 @@ class TestDedicatePublicIPRange(cloudstackTestCase):
cls.services = Services().services
# Get Zone, Domain
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
cls.account = Account.create(

View File

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

View File

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

View File

@ -42,7 +42,7 @@ class TestRouterServices(cloudstackTestCase):
# Get Zone, Domain and templates
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
template = get_template(
cls.apiclient,

View File

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

View File

@ -137,7 +137,7 @@ class TestServiceOfferings(cloudstackTestCase):
cls.services = testClient.getParsedTestDataConfig()
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.service_offering_1 = ServiceOffering.create(

View File

@ -32,7 +32,7 @@ class TestSnapshotRootDisk(cloudstackTestCase):
# Get Zone, Domain and templates
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
template = get_template(

View File

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

View File

@ -59,7 +59,7 @@ class TestCreateTemplate(cloudstackTestCase):
# Get Zone, Domain and templates
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.disk_offering = DiskOffering.create(
cls.apiclient,

View File

@ -39,7 +39,7 @@ class TestDeployVM(cloudstackTestCase):
# Get Zone, Domain and templates
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
#If local storage is enabled, alter the offerings to use localstorage

View File

@ -32,7 +32,7 @@ class TestVmSnapshot(cloudstackTestCase):
cls.services = Services().services
# Get Zone, Domain and templates
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(
cls.apiclient,

View File

@ -17,7 +17,6 @@
""" BVT tests for Volumes
"""
#Import Local Modules
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackException import *
from marvin.cloudstackAPI import *
@ -43,10 +42,9 @@ class TestCreateVolume(cloudstackTestCase):
testClient = super(TestCreateVolume, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
# Get Zone, Domain and templates
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.disk_offering = DiskOffering.create(
cls.apiclient,
@ -224,7 +222,7 @@ class TestVolumes(cloudstackTestCase):
# Get Zone, Domain and templates
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.disk_offering = DiskOffering.create(
cls.apiclient,

View File

@ -34,7 +34,7 @@ class TestVpcRemoteAccessVpn(cloudstackTestCase):
cls.apiclient = testClient.getApiClient()
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.service_offering = ServiceOffering.create(
cls.apiclient,

View File

@ -30,17 +30,19 @@ from marvin.cloudstackException import GetDetailExceptionInfo
from marvin.lib.utils import (random_gen, validateList)
from marvin.cloudstackAPI.cloudstackAPIClient import CloudStackAPIClient
class CSTestClient(object):
'''
@Desc : CloudStackTestClient is encapsulated entity for creating and
getting various clients viz., apiclient,
user api client, dbconnection, test Data parsed
information etc
@Input : mgmtDetails : Management Server Details
dbSvrDetails: Database Server details of Management \
@Input :
mgmt_details : Management Server Details
dbsvr_details: Database Server details of Management \
Server. Retrieved from configuration file.
asyncTimeout : Timeout for Async queries
defaultWorkerThreads : Number of worker threads
async_timeout : Timeout for Async queries
default_worker_threads : Number of worker threads
logger : provides logging facilities for this library
zone : The zone on which test suites using this test client will run
'''
@ -131,9 +133,9 @@ class CSTestClient(object):
list_user = listUsers.listUsersCmd()
list_user.account = "admin"
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):
self.__logger.debug("__createApiClient: API "
self.__logger.error("__createApiClient: API "
"Client Creation Failed")
return FAILED
@ -198,7 +200,6 @@ class CSTestClient(object):
register_user.id = userid
register_user_res = \
self.__apiClient.registerUserKeys(register_user)
if register_user_res == FAILED:
return FAILED
return (register_user_res.apikey, register_user_res.secretkey)
@ -231,8 +232,9 @@ class CSTestClient(object):
providing their own configuration file as well.
'''
self.__configObj = ConfigManager(self.__testDataFilePath)
if self.__configObj is not None:
if self.__configObj:
self.__parsedTestDataConfig = self.__configObj.getConfig()
self.__logger.debug("Parsing Test data successful")
else:
self.__logger.error("createTestClient : Not able to create "
"ConfigManager Object")
@ -244,7 +246,14 @@ class CSTestClient(object):
'''
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:
self.__logger.exception("Exception Occurred "
"Under createTestClient "
@ -366,7 +375,7 @@ class CSTestClient(object):
return self.__configObj
def getApiClient(self):
if self.__apiClient is not None:
if self.__apiClient:
self.__apiClient.id = self.identifier
return self.__apiClient
return None

View File

@ -1,22 +1,3 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Use the common configs added such as account, network_offerings, domain, project,
# or add your own data if required separately for any test case
{
"region": {
"regionid": "2",
@ -39,18 +20,16 @@
"password": "password"
},
"small": {
# Create a small virtual machine instance with disk offering
"displayname": "testserver",
"username": "root", # VM creds for SSH
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
"hypervisor": "XenServer",
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"medium": {
# Create a medium virtual machine instance
"displayname": "testserver",
"username": "root",
"password": "password",
@ -71,8 +50,8 @@
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100, # in MHz
"memory": 128, # In MBs
"cpuspeed": 100,
"memory": 128,
},
"small": {
"name": "Small Instance",
@ -99,7 +78,7 @@
"disk_offering": {
"name": "Disk offering",
"displaytext": "Disk offering",
"disksize": 1 # in GB
"disksize": 1
},
'resized_disk_offering': {
"displaytext": "Resized",
@ -109,7 +88,7 @@
"network": {
"name": "Test Network",
"displaytext": "Test Network",
acltype": "Account",
"acltype": "Account",
},
"network2": {
"name": "Test Network Shared",
@ -178,7 +157,6 @@
"ssh_port": 22,
"hypervisor": 'XenServer',
"privateport": 22,
# For NAT rule creation
"publicport": 22,
"protocol": 'TCP',
},
@ -234,55 +212,40 @@
0: {
"clustername": "Xen Cluster",
"clustertype": "CloudManaged",
# CloudManaged or ExternalManaged"
"hypervisor": "XenServer",
# Hypervisor type
},
1: {
"clustername": "KVM Cluster",
"clustertype": "CloudManaged",
# CloudManaged or ExternalManaged"
"hypervisor": "KVM",
# Hypervisor type
},
2: {
"hypervisor": 'VMware',
# Hypervisor type
"clustertype": 'ExternalManaged',
# CloudManaged or ExternalManaged"
"username": 'administrator',
"password": 'fr3sca',
"url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1',
# Format:http://vCenter Host/Datacenter/Cluster
"clustername": 'VMWare Cluster',
},
},
"hosts": {
"xenserver": {
# Must be name of corresponding Hypervisor type
# in cluster in small letters
"hypervisor": 'XenServer',
# Hypervisor type
"clustertype": 'CloudManaged',
# CloudManaged or ExternalManaged"
"url": 'http://192.168.100.211',
"username": "root",
"password": "fr3sca",
},
"kvm": {
"hypervisor": 'KVM',
# Hypervisor type
"clustertype": 'CloudManaged',
# CloudManaged or ExternalManaged"
"url": 'http://192.168.100.212',
"username": "root",
"password": "fr3sca",
},
"vmware": {
"hypervisor": 'VMware',
# Hypervisor type
"clustertype": 'ExternalManaged',
# CloudManaged or ExternalManaged"
"url": 'http://192.168.100.203',
"username": "administrator",
"password": "fr3sca",
@ -333,18 +296,15 @@
"lbrule": {
"name": "SSH",
"alg": "roundrobin",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"protocol": 'TCP'
},
# ISO related test data
"iso1": {
"displaytext": "Test ISO 1",
"name": "ISO 1",
"url": "http://people.apache.org/~tsp/dummy.iso",
# Source URL where ISO is located
"isextractable": True,
"isfeatured": True,
"ispublic": True,
@ -354,18 +314,16 @@
"displaytext": "Test ISO 2",
"name": "ISO 2",
"url": "http://people.apache.org/~tsp/dummy.iso",
# Source URL where ISO is located
"isextractable": True,
"isfeatured": True,
"ispublic": True,
"ostype": "CentOS 5.3 (64-bit)",
"mode": 'HTTP_DOWNLOAD',
# Used in Extract template, value must be HTTP_DOWNLOAD
},
"isfeatured": True,
"ispublic": True,
"isextractable": True,
"bootable": True, # For edit template
"bootable": True,
"passwordenabled": True,
"template": {
@ -387,7 +345,7 @@
"security_group" : { "name": "custom_Sec_Grp" },
"ingress_rule": {
"protocol": "TCP",
startport": "22",
"startport": "22",
"endport": "22",
"cidrlist": "0.0.0.0/0"
},
@ -408,14 +366,12 @@
"part": ["4090-4091", "4092-4095"],
"full": "4090-4095",
},
nfs": {
"nfs": {
"url": "nfs://10.147.28.7/export/home/talluri/testprimary",
# Format: File_System_Type/Location/Path
"name": "Primary XEN"
},
"iscsi": {
"url": "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1",
# Format : iscsi://IP Address/IQN number/LUN#
"name": "Primary iSCSI"
},
"volume": {"diskname": "Test Volume"},

View File

@ -20,6 +20,8 @@ import os
from optparse import OptionParser
import jsonHelper
from marvin.codes import *
from marvin.cloudstackException import GetDetailExceptionInfo
from marvin.config.test_data import test_data
class managementServer(object):
@ -53,12 +55,6 @@ class logger(object):
self.LogFolderPath = None
class apiLoadCfg(object):
def __init__(self):
self.ParsedApiDestFolder = None
self.ApiSpecFile = None
class cloudstackConfiguration(object):
def __init__(self):
self.zones = []
@ -66,6 +62,7 @@ class cloudstackConfiguration(object):
self.dbSvr = None
self.globalConfig = []
self.logger = []
self.TestData = None
class zone(object):
@ -332,10 +329,7 @@ class ConfigManager(object):
"getConfig" API,once configObj is returned.
'''
def __init__(self, cfg_file=None):
if cfg_file is None:
self.__filePath = "config/test_data.cfg"
else:
self.__filePath = cfg_file
self.__filePath = cfg_file
self.__parsedCfgDict = None
'''
Set the Configuration
@ -343,8 +337,10 @@ class ConfigManager(object):
self.__setConfig()
def __setConfig(self):
if self.__verifyFile() is not False:
self.__parsedCfgDict = self.__parseConfig()
if not self.__verifyFile():
dirPath = os.path.dirname(__file__)
self.__filePath = str(os.path.join(dirPath, "config/test_data.py"))
self.__parsedCfgDict = self.__parseConfig()
def __parseConfig(self):
'''
@ -357,17 +353,21 @@ class ConfigManager(object):
'''
config_dict = None
try:
configlines = []
with open(file, 'r') as fp:
for line in fp:
if len(line) != 0:
if self.__filePath.endswith(".py"):
config_dict = test_data
else:
configLines = []
with open(file, 'r') as fp:
for line in fp:
ws = line.strip()
if ws[0] not in ["#"]:
configlines.append(ws)
config_dict = json.loads("\n".join(configlines))
if not ws.startswith("#"):
configLines.append(ws)
config = json.loads("\n".join(configLines))
config_dict = config
except Exception, e:
#Will replace with log once we have logging done
print "\n Exception occurred under __parseConfig", e
print "\n Exception occurred under ConfigManager:__parseConfig" \
" :%s", GetDetailExceptionInfo(e)
finally:
return config_dict
@ -382,7 +382,7 @@ class ConfigManager(object):
'''
if self.__filePath is None or self.__filePath == '':
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):
'''
@ -894,18 +894,19 @@ def generate_setup_config(config, file=None):
def getSetupConfig(file):
if not os.path.exists(file):
raise IOError("config file %s not found. \
please specify a valid config file" % file)
config = cloudstackConfiguration()
configLines = []
with open(file, 'r') as fp:
for line in fp:
ws = line.strip()
if not ws.startswith("#"):
configLines.append(ws)
config = json.loads("\n".join(configLines))
return jsonHelper.jsonLoader(config)
try:
config = cloudstackConfiguration()
configLines = []
with open(file, 'r') as fp:
for line in fp:
ws = line.strip()
if not ws.startswith("#"):
configLines.append(ws)
config = json.loads("\n".join(configLines))
return jsonHelper.jsonLoader(config)
except Exception, e:
print "\nException Occurred under getSetupConfig %s" % \
GetDetailExceptionInfo(e)
if __name__ == "__main__":
parser = OptionParser()

View File

@ -18,14 +18,14 @@
Initializes the marvin and does required prerequisites
for starting it.
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
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.configGenerator import getSetupConfig
import marvin
from marvin import configGenerator
from marvin.marvinLog import MarvinLog
from marvin.deployDataCenter import DeployDataCenters
from marvin.cloudstackTestClient import CSTestClient
@ -44,37 +44,36 @@ import logging
import string
import random
from sys import exit
from marvin.codegenerator import CodeGenerator
class MarvinInit:
def __init__(self, config_file,
load_api_flag=None,
deploy_dc_flag=None,
test_module_name=None,
test_mod_name="deploydc",
zone=None):
self.__configFile = config_file
self.__deployFlag = deploy_dc_flag
self.__loadApiFlag = load_api_flag
self.__parsedConfig = None
self.__logFolderPath = None
self.__tcRunLogger = None
self.__testModName = test_mod_name
self.__testClient = None
self.__tcResultFile = None
self.__testModuleName = test_module_name
self.__testDataFilePath = None
self.__zoneForTests = None
self.__parsedConfig = None
def __parseConfig(self):
'''
@Name: __parseConfig
@Name: __parseConfig
@Desc : Parses the configuration file passed and assigns
the parsed configuration
@Output : SUCCESS or FAILED
'''
try:
self.__parsedConfig = getSetupConfig(self.__configFile)
if not os.path.isfile(self.__configFile):
return FAILED
self.__parsedConfig = configGenerator.\
getSetupConfig(self.__configFile)
return SUCCESS
except Exception, e:
print "\nException Occurred Under __parseConfig : " \
@ -93,10 +92,11 @@ class MarvinInit:
def getLogger(self):
return self.__tcRunLogger
def getDebugFile(self):
def getResultFile(self):
'''
@Name : getDebugFile
@Desc : Returns the Result file to be used for writing
@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:
@ -120,8 +120,7 @@ class MarvinInit:
(self.__setTestDataPath() != FAILED) and
(self.__initLogging() != FAILED) and
(self.__createTestClient() != FAILED) and
(self.__deployDC() != FAILED) and
(self.__loadNewApiFromXml() != FAILED)):
(self.__deployDC() != FAILED)):
return SUCCESS
else:
return FAILED
@ -145,12 +144,10 @@ class MarvinInit:
'''
try:
log_obj = MarvinLog("CSLog")
if log_obj is None:
return FAILED
else:
if log_obj:
ret = log_obj.\
createLogs(self.__testModuleName,
self.__parsedConfig.logger)
createLogs(self.__testModName,
self.__parsedConfig.logger)
if ret != FAILED:
self.__logFolderPath = log_obj.getLogFolderPath()
self.__tcRunLogger = log_obj.getLogger()
@ -176,7 +173,7 @@ class MarvinInit:
test_data_filepath=
self.__testDataFilePath,
zone=self.__zoneForTests)
if self.__testClient is not None:
if self.__testClient:
return self.__testClient.createTestClient()
else:
return FAILED
@ -185,46 +182,11 @@ class MarvinInit:
GetDetailExceptionInfo(e)
return FAILED
def __loadNewApiFromXml(self):
'''
@Desc: Kept for future usage
Will enhance later.
'''
try:
return SUCCESS
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))
return FAILED
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):
'''
@Name : __setTestDataPath
@Desc: Sets the TestData Path for tests to run
@Output: Returns SUCCESS or FAILED
@Desc : Sets the TestData Path for tests to run
@Output:Returns SUCCESS or FAILED
'''
try:
if ((self.__parsedConfig.TestData is not None) and
@ -240,19 +202,19 @@ class MarvinInit:
'''
@Name : __deployDC
@Desc : Deploy the DataCenter and returns accordingly.
@Output : SUCCESS or FAILED
@Output: SUCCESS or FAILED
'''
try:
ret = SUCCESS
if self.__deployFlag:
deploy_obj = DeployDataCenters(self.__testClient,
self.__parsedConfig,
self.__tcRunLogger)
self.__parsedConfig,
self.__tcRunLogger)
ret = deploy_obj.deploy()
if ret == SUCCESS:
print "Deploy DC Successful"
else:
print "Deploy DC Failed"
if ret == SUCCESS:
print "Deploy DC Successful"
else:
print "Deploy DC Failed"
return ret
except Exception, e:
print "\n Exception Occurred Under __deployDC : %s" % \

View File

@ -65,7 +65,8 @@ class MarvinLog:
self.__logger = logging.getLogger(self.__loggerName)
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):
'''
@Name : __setLogHandler
@ -122,7 +123,9 @@ class MarvinLog:
'''
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
@Desc : Gets the Logger with file paths initialized and created
@ -134,13 +137,14 @@ class MarvinLog:
'''
try:
temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S",
time.localtime())
time.localtime())
if test_module_name is None:
temp_path = temp_ts
else:
temp_path = str(test_module_name) + "__" + str(temp_ts)
if ((log_cfg is not None) and ('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)):
temp_dir = \
log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
@ -151,7 +155,6 @@ class MarvinLog:
print "\n*********Log Folder Path: %s. " \
"All logs will be available here **************" \
% str(self.__logFolderDir)
os.makedirs(self.__logFolderDir)
'''

View File

@ -15,8 +15,10 @@
# specific language governing permissions and limitations
# under the License.
import marvin
import sys
from sys import stdout, exit
import logging
import time
import os
import nose.core
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.marvinInit import MarvinInit
@ -24,9 +26,7 @@ from nose.plugins.base import Plugin
from marvin.codes import (SUCCESS,
FAILED,
EXCEPTION)
from marvin.cloudstackException import GetDetailExceptionInfo
import time
import os
from marvin.cloudstackException import GetDetailExceptionInfo
class MarvinPlugin(Plugin):
@ -37,18 +37,14 @@ class MarvinPlugin(Plugin):
name = "marvin"
def __init__(self):
self.identifier = None
self.testClient = None
self.parsedConfig = None
self.__identifier = None
self.__testClient = None
self.__parsedConfig = None
'''
Contains Config File
'''
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
'''
self.__zoneForTests = None
@ -57,12 +53,12 @@ class MarvinPlugin(Plugin):
'''
self.__deployDcFlag = None
self.conf = None
self.debugStream = sys.stdout
self.testRunner = None
self.testResult = SUCCESS
self.startTime = None
self.testName = None
self.tcRunLogger = None
self.__debugStream = stdout
self.__testRunner = None
self.__testResult = SUCCESS
self.__startTime = None
self.__testName = None
self.__tcRunLogger = None
Plugin.__init__(self)
def configure(self, options, conf):
@ -77,28 +73,14 @@ class MarvinPlugin(Plugin):
return
else:
self.enabled = True
self.__configFile = options.configFile
self.__loadNewApiFlag = options.loadNewApiFlag
self.__deployDcFlag = options.deployDc
self.__zoneForTests = options.zone
self.conf = conf
test_mod_name = None
if self.startMarvin(test_mod_name) == FAILED:
print "\nExiting Marvin"
if self.startMarvin() == FAILED:
print "\nExiting Marvin. Please Check"
exit(1)
def getModName(self):
if len(self.conf.testNames) == 0:
dir_path = getattr(self.conf.options,'where')
if dir_path is not None:
temp = os.path.split(dir_path[0].strip())
return temp
else:
first_entry = self.conf.testNames[0]
temp = os.path.split(first_entry)
return os.path.splitext(temp)[0]
def options(self, parser, env):
"""
Register command line options
@ -111,7 +93,7 @@ class MarvinPlugin(Plugin):
"The config file containing the datacenter and "
"other management server "
"information is specified")
parser.add_option("--deploy-dc", action="store_true",
parser.add_option("--deploy", action="store_true",
default=False,
dest="deployDc",
help="Deploys the DC with Given Configuration."
@ -120,11 +102,6 @@ class MarvinPlugin(Plugin):
default=None,
dest="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")
Plugin.options(self, parser, env)
def wantClass(self, cls):
@ -134,77 +111,125 @@ class MarvinPlugin(Plugin):
return True
return None
def __checkImport(self, filename):
'''
@Name : __checkImport
@Desc : Verifies to Import the test Module before running and check
@Desc : Verifies to run the available test module for any Import
Errors before running and check
whether if it is importable.
This will check for test modules which has some issues to be
getting imported.
Returns False or True based upon the result.
'''
try:
__import__(filename)
print "\n*******************", filename
return True
if os.path.isfile(filename):
ret = os.path.splitext(filename)
if ret[1] == ".py":
os.system("python " + filename)
return True
return False
except ImportError, e:
self.tcRunLogger.exception("Module : %s Import "
"Failed Reason :%s"
% (filename, GetDetailExceptionInfo(e)))
print "FileName :%s : Error : %s" % \
(filename, GetDetailExceptionInfo(e))
return False
def wantFile(self, filename):
'''
@Desc : Only python files will be used as test modules
'''
print "\n*******************", filename
if os.path.isfile(filename):
if os.path.splitext(filename) != ".py":
return False
else:
return self.__checkImport(filename)
return False
return self.__checkImport(filename)
def loadTestsFromTestCase(self, cls):
if cls.__name__ != 'cloudstackTestCase':
self.identifier = cls.__name__
self.__identifier = cls.__name__
self._injectClients(cls)
def beforeTest(self, test):
self.testName = test.__str__().split()[0]
self.testClient.identifier = '-'.join([self.identifier, self.testName])
self.tcRunLogger.name = test.__str__()
def prepareTestRunner(self, runner):
return self.testRunner
self.__testName = test.__str__().split()[0]
self.__testClient.identifier = '-'.\
join([self.__identifier, self.__testName])
if self.__tcRunLogger:
self.__tcRunLogger.name = test.__str__()
def startTest(self, test):
"""
Currently used to record start time for tests
Dump Start Msg of TestCase to Log
"""
self.tcRunLogger.debug("\n\n::::::::::::STARTED : TC: " +
str(self.testName) + " :::::::::::")
self.startTime = time.time()
if self.__tcRunLogger:
self.__tcRunLogger.debug("\n\n::::::::::::STARTED : TC: " +
str(self.__testName) + " :::::::::::")
self.__startTime = time.time()
def handleError(self, test, err):
'''
Adds Exception throwing test cases and information to log.
'''
self.tcRunLogger.fatal("%s: %s: %s" %
(EXCEPTION, self.testName, GetDetailExceptionInfo(err)))
self.testResult = EXCEPTION
if self.__tcRunLogger:
self.__tcRunLogger.\
fatal("%s: %s: %s" % (EXCEPTION,
self.__testName,
GetDetailExceptionInfo(err)))
self.__testResult = EXCEPTION
def prepareTestRunner(self, runner):
if self.__testRunner:
return self.__testRunner
def handleFailure(self, test, err):
'''
Adds Failing test cases and information to log.
'''
self.tcRunLogger.fatal("%s: %s: %s" %
(FAILED, self.testName, GetDetailExceptionInfo(err)))
self.testResult = FAILED
if self.__tcRunLogger:
self.__tcRunLogger.\
fatal("%s: %s: %s" %
(FAILED, self.__testName, GetDetailExceptionInfo(err)))
self.__testResult = FAILED
def startMarvin(self, test_module_name):
def __getModName(self, inp, type='file'):
'''
@Desc : Returns the module name from the path
@Output: trimmed down module name, used for logging
@Input: type:Whether the type is file or dir
inp:input element
'''
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) is 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:
print "\nMarvin Initialization Successful." \
"Test Suite:%s" % str(test_suite)
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)
return SUCCESS
return FAILED
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
@ -214,26 +239,21 @@ class MarvinPlugin(Plugin):
Creates a debugstream for tc debug log
'''
try:
obj_marvininit = MarvinInit(self.__configFile,
self.__loadNewApiFlag,
self.__deployDcFlag,
test_module_name,
self.__zoneForTests)
if obj_marvininit.init() == SUCCESS:
self.testClient = obj_marvininit.getTestClient()
self.tcRunLogger = obj_marvininit.getLogger()
self.parsedConfig = obj_marvininit.getParsedConfig()
self.debugStream = obj_marvininit.getDebugFile()
self.testRunner = nose.core.TextTestRunner(stream=
self.debugStream,
descriptions=True,
verbosity=2,
config=self.conf)
print "\nMarvin Initialization Successful"
return SUCCESS
else:
print "\nMarvin Initialization Failed"
return FAILED
if self.__deployDcFlag:
print "\nStep1 :Deploy Flag is Enabled, will deployDC"
obj_marvininit = MarvinInit(self.__configFile,
self.__deployDcFlag,
"DeployDc",
self.__zoneForTests)
if not obj_marvininit or obj_marvininit.init() != SUCCESS:
return FAILED
print "\nStep2: Now Start Running Test Suites"
for suites in self.conf.testNames:
if os.path.isdir(suites):
self.__runSuites(suites)
if os.path.isfile(suites):
self.__runSuite(suites)
return SUCCESS
except Exception, e:
print "Exception Occurred under startMarvin: %s" % \
GetDetailExceptionInfo(e)
@ -244,28 +264,30 @@ class MarvinPlugin(Plugin):
Currently used to record end time for tests
"""
endTime = time.time()
if self.startTime is not None:
totTime = int(endTime - self.startTime)
self.tcRunLogger.debug("TestCaseName: %s; Time Taken: "
"%s Seconds; "
"StartTime: %s; EndTime: %s; Result: %s"
% (self.testName, str(totTime),
str(time.ctime(self.startTime)),
str(time.ctime(endTime)),
self.testResult))
if self.__startTime:
totTime = int(endTime - self.__startTime)
if self.__tcRunLogger:
self.__tcRunLogger.\
debug("TestCaseName: %s; "
"Time Taken: %s Seconds; StartTime: %s; "
"EndTime: %s; Result: %s" %
(self.__testName, str(totTime),
str(time.ctime(self.__startTime)),
str(time.ctime(endTime)),
self.__testResult))
def _injectClients(self, test):
setattr(test, "debug", self.tcRunLogger.debug)
setattr(test, "info", self.tcRunLogger.info)
setattr(test, "warn", self.tcRunLogger.warning)
setattr(test, "error", self.tcRunLogger.error)
setattr(test, "testClient", self.testClient)
setattr(test, "config", self.parsedConfig)
if self.testClient.identifier is None:
self.testClient.identifier = self.identifier
setattr(test, "clstestclient", self.testClient)
setattr(test, "debug", self.__tcRunLogger.debug)
setattr(test, "info", self.__tcRunLogger.info)
setattr(test, "warn", self.__tcRunLogger.warning)
setattr(test, "error", self.__tcRunLogger.error)
setattr(test, "testClient", self.__testClient)
setattr(test, "config", self.__parsedConfig)
if self.__testClient.identifier is None:
self.__testClient.identifier = self.__identifier
setattr(test, "clstestclient", self.__testClient)
if hasattr(test, "user"):
# when the class-level attr applied. all test runs as 'user'
self.testClient.getUserApiClient(test.UserName,
test.DomainName,
test.AcctType)
self.__testClient.getUserApiClient(test.UserName,
test.DomainName,
test.AcctType)

View File

@ -44,7 +44,7 @@ setup(name="Marvin",
platforms=("Any",),
url="https://builds.apache.org/job/cloudstack-marvin/",
packages=["marvin", "marvin.cloudstackAPI",
"marvin.lib", "marvin.sandbox",
"marvin.lib", "marvin.config","marvin.sandbox",
"marvin.sandbox.advanced", "marvin.sandbox.advancedsg", "marvin.sandbox.basic"],
license="LICENSE.txt",
install_requires=[