mirror of https://github.com/apache/cloudstack.git
Added fix for CLOUDSTACK-6316
Added changes for CLOUDSTACK-6316. More details in the bug Signed-off-by: Santhosh Edukulla <Santhosh.Edukulla@citrix.com>
This commit is contained in:
parent
70e104021c
commit
63d3688360
|
|
@ -24,6 +24,7 @@ from marvin.cloudstackAPI import *
|
|||
from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import *
|
||||
import time
|
||||
|
||||
|
||||
class Services:
|
||||
|
|
@ -619,11 +620,7 @@ class TestHostHighAvailability(cloudstackTestCase):
|
|||
|
||||
#verify the VM live migration happened to another running host
|
||||
self.debug("Waiting for VM to come up")
|
||||
wait_for_vm(
|
||||
self.apiclient,
|
||||
virtualmachineid=vm_with_ha_enabled.id,
|
||||
interval=timeout
|
||||
)
|
||||
time.sleep(timeout)
|
||||
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
|
|
@ -751,11 +748,7 @@ class TestHostHighAvailability(cloudstackTestCase):
|
|||
|
||||
#verify the VM live migration happened to another running host
|
||||
self.debug("Waiting for VM to come up")
|
||||
wait_for_vm(
|
||||
self.apiclient,
|
||||
virtualmachineid=vm_with_ha_disabled.id,
|
||||
interval=timeout
|
||||
)
|
||||
time.sleep(timeout)
|
||||
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
#Marvin - The cloudstack test client
|
||||
# Marvin - The cloudstack test client
|
||||
|
|
|
|||
|
|
@ -26,12 +26,14 @@ import datetime
|
|||
|
||||
|
||||
class job(object):
|
||||
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.cmd = None
|
||||
|
||||
|
||||
class jobStatus(object):
|
||||
|
||||
def __init__(self):
|
||||
self.result = None
|
||||
self.status = None
|
||||
|
|
@ -47,6 +49,7 @@ class jobStatus(object):
|
|||
|
||||
|
||||
class workThread(threading.Thread):
|
||||
|
||||
def __init__(self, in_queue, outqueue, apiClient, db=None, lock=None):
|
||||
threading.Thread.__init__(self)
|
||||
self.inqueue = in_queue
|
||||
|
|
@ -62,7 +65,7 @@ class workThread(threading.Thread):
|
|||
try:
|
||||
self.lock.acquire()
|
||||
result = self.connection.poll(job.jobId, job.responsecls).jobresult
|
||||
except cloudstackException.CloudstackAPIException, e:
|
||||
except cloudstackException.CloudstackAPIException as e:
|
||||
result = str(e)
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
|
@ -102,7 +105,7 @@ class workThread(threading.Thread):
|
|||
except:
|
||||
pass
|
||||
jobstatus.status = True
|
||||
except cloudstackException.CloudstackAPIException, e:
|
||||
except cloudstackException.CloudstackAPIException as e:
|
||||
jobstatus.result = str(e)
|
||||
jobstatus.status = False
|
||||
except:
|
||||
|
|
@ -129,6 +132,7 @@ class workThread(threading.Thread):
|
|||
|
||||
|
||||
class jobThread(threading.Thread):
|
||||
|
||||
def __init__(self, inqueue, interval):
|
||||
threading.Thread.__init__(self)
|
||||
self.inqueue = inqueue
|
||||
|
|
@ -149,12 +153,14 @@ class jobThread(threading.Thread):
|
|||
|
||||
|
||||
class outputDict(object):
|
||||
|
||||
def __init__(self):
|
||||
self.lock = threading.Condition()
|
||||
self.dict = {}
|
||||
|
||||
|
||||
class asyncJobMgr(object):
|
||||
|
||||
def __init__(self, apiClient, db):
|
||||
self.inqueue = Queue.Queue()
|
||||
self.output = outputDict()
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import base64
|
|||
import hmac
|
||||
import hashlib
|
||||
import time
|
||||
from cloudstackAPI import *
|
||||
import jsonHelper
|
||||
from codes import (
|
||||
from .cloudstackAPI import *
|
||||
from . import jsonHelper
|
||||
from .codes import (
|
||||
FAILED,
|
||||
INVALID_RESPONSE,
|
||||
INVALID_INPUT,
|
||||
|
|
@ -42,12 +42,14 @@ from marvin.cloudstackException import GetDetailExceptionInfo
|
|||
|
||||
|
||||
class CSConnection(object):
|
||||
|
||||
'''
|
||||
@Desc: Connection Class to make API\Command calls to the
|
||||
CloudStack Management Server
|
||||
Sends the GET\POST requests to CS based upon the
|
||||
information provided and retrieves the parsed response.
|
||||
'''
|
||||
|
||||
def __init__(self, mgmtDet, asyncTimeout=3600, logger=None,
|
||||
path='client/api'):
|
||||
self.apiKey = mgmtDet.apiKey
|
||||
|
|
@ -56,10 +58,9 @@ class CSConnection(object):
|
|||
self.port = mgmtDet.port
|
||||
self.user = mgmtDet.user
|
||||
self.passwd = mgmtDet.passwd
|
||||
self.certPath = ()
|
||||
if mgmtDet.certCAPath != "NA" and mgmtDet.certPath != "NA":
|
||||
self.certPath = (mgmtDet.certCAPath, mgmtDet.certPath)
|
||||
else:
|
||||
self.certPath = ()
|
||||
self.logger = logger
|
||||
self.path = path
|
||||
self.retries = 5
|
||||
|
|
@ -94,28 +95,33 @@ class CSConnection(object):
|
|||
cmd = queryAsyncJobResult.queryAsyncJobResultCmd()
|
||||
cmd.jobid = jobid
|
||||
timeout = self.asyncTimeout
|
||||
|
||||
start_time = time.time()
|
||||
end_time = time.time()
|
||||
async_response = FAILED
|
||||
self.logger.debug("=== Jobid: %s Started ===" % (str(jobid)))
|
||||
while timeout > 0:
|
||||
async_response = self.\
|
||||
marvinRequest(cmd, response_type=response_cmd)
|
||||
if async_response != FAILED:
|
||||
job_status = async_response.jobstatus
|
||||
if job_status in [JOB_FAILED, JOB_CANCELLED]:
|
||||
self.logger.debug("=====JobId:%s Either "
|
||||
"got Cancelled or Failed======"
|
||||
% (str(jobid)))
|
||||
return FAILED
|
||||
if job_status == JOB_SUCCEEDED:
|
||||
self.logger.debug("======JobId:%s Succeeded====="
|
||||
% (str(jobid)))
|
||||
return async_response
|
||||
if job_status in [JOB_FAILED,
|
||||
JOB_CANCELLED,
|
||||
JOB_SUCCEEDED]:
|
||||
break
|
||||
time.sleep(5)
|
||||
timeout -= 5
|
||||
self.logger.debug("JobId:%s is Still Processing, "
|
||||
"Will TimeOut in:%s" % (str(jobid),
|
||||
str(timeout)))
|
||||
return FAILED
|
||||
except Exception, e:
|
||||
end_time = time.time()
|
||||
tot_time = int(start_time - end_time)
|
||||
self.logger.debug(
|
||||
"===Jobid:%s ; StartTime:%s ; EndTime:%s ; "
|
||||
"TotalTime:%s===" %
|
||||
(str(jobid), str(time.ctime(start_time)),
|
||||
str(time.ctime(end_time)), str(tot_time)))
|
||||
return async_response
|
||||
except Exception as e:
|
||||
self.__lastError = GetDetailExceptionInfo(e)
|
||||
self.logger.exception("__poll: Exception Occurred :%s" %
|
||||
self.__lastError)
|
||||
|
|
@ -165,11 +171,11 @@ class CSConnection(object):
|
|||
cert=self.certPath,
|
||||
verify=self.httpsFlag)
|
||||
return response
|
||||
except Exception, e:
|
||||
self.__lastError = GetDetailExceptionInfo(e)
|
||||
except Exception as e:
|
||||
self.__lastError = e
|
||||
self.logger.\
|
||||
exception("__sendPostReqToCS : Exception "
|
||||
"Occurred: %s" % self.__lastError)
|
||||
"Occurred: %s" % str(self.__lastError))
|
||||
return FAILED
|
||||
|
||||
def __sendGetReqToCS(self, url, payload):
|
||||
|
|
@ -187,10 +193,10 @@ class CSConnection(object):
|
|||
cert=self.certPath,
|
||||
verify=self.httpsFlag)
|
||||
return response
|
||||
except Exception, e:
|
||||
self.__lastError = GetDetailExceptionInfo(e)
|
||||
except Exception as e:
|
||||
self.__lastError = e
|
||||
self.logger.exception("__sendGetReqToCS : Exception Occurred: %s" %
|
||||
self.__lastError)
|
||||
str(self.__lastError))
|
||||
return FAILED
|
||||
|
||||
def __sendCmdToCS(self, command, auth=True, payload={}, method='GET'):
|
||||
|
|
@ -213,8 +219,9 @@ class CSConnection(object):
|
|||
payload["apiKey"] = self.apiKey
|
||||
payload["signature"] = self.__sign(payload)
|
||||
|
||||
#Verify whether protocol is "http", then call the request over http
|
||||
if self.protocol == "http" or self.protocol == "https":
|
||||
# Verify whether protocol is "http" or "https", then send the
|
||||
# request
|
||||
if self.protocol in ["http", "https"]:
|
||||
self.logger.debug("Payload: %s" % str(payload))
|
||||
if method == 'POST':
|
||||
self.logger.debug("=======Sending POST Cmd : %s======="
|
||||
|
|
@ -227,7 +234,7 @@ class CSConnection(object):
|
|||
else:
|
||||
self.logger.exception("__sendCmdToCS: Invalid Protocol")
|
||||
return FAILED
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.logger.exception("__sendCmdToCS: Exception:%s" %
|
||||
GetDetailExceptionInfo(e))
|
||||
return FAILED
|
||||
|
|
@ -276,7 +283,7 @@ class CSConnection(object):
|
|||
payload["%s[%d].%s" % (param, i, k)] = v
|
||||
i += 1
|
||||
return cmd_name.strip(), isAsync, payload
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.logger.\
|
||||
exception("__sanitizeCmd: CmdName : "
|
||||
"%s : Exception:%s" % (cmd_name,
|
||||
|
|
@ -352,10 +359,13 @@ class CSConnection(object):
|
|||
4. Check if the Command Response received above is valid or Not.
|
||||
If not return Invalid Response
|
||||
'''
|
||||
return self.__parseAndGetResponse(cmd_response,
|
||||
response_type,
|
||||
is_async)
|
||||
except Exception, e:
|
||||
ret = self.__parseAndGetResponse(cmd_response,
|
||||
response_type,
|
||||
is_async)
|
||||
if ret == FAILED:
|
||||
raise self.__lastError
|
||||
return ret
|
||||
except Exception as e:
|
||||
self.logger.exception("marvinRequest : CmdName: %s Exception: %s" %
|
||||
(str(cmd), GetDetailExceptionInfo(e)))
|
||||
return FAILED
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from marvin.codes import (INVALID_INPUT, EXCEPTION_OCCURRED)
|
|||
|
||||
|
||||
class CloudstackAPIException(Exception):
|
||||
|
||||
def __init__(self, cmd="", result=""):
|
||||
self.errorMsg = "Execute cmd: %s failed, due to: %s" % (cmd, result)
|
||||
|
||||
|
|
@ -29,6 +30,7 @@ class CloudstackAPIException(Exception):
|
|||
|
||||
|
||||
class InvalidParameterException(Exception):
|
||||
|
||||
def __init__(self, msg=''):
|
||||
self.errorMsg = msg
|
||||
|
||||
|
|
@ -37,6 +39,7 @@ class InvalidParameterException(Exception):
|
|||
|
||||
|
||||
class dbException(Exception):
|
||||
|
||||
def __init__(self, msg=''):
|
||||
self.errorMsg = msg
|
||||
|
||||
|
|
@ -45,6 +48,7 @@ class dbException(Exception):
|
|||
|
||||
|
||||
class internalError(Exception):
|
||||
|
||||
def __init__(self, msg=''):
|
||||
self.errorMsg = msg
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ def user(Name, DomainName, AcctType):
|
|||
class cloudstackTestCase(unittest.case.TestCase):
|
||||
clstestclient = None
|
||||
|
||||
def assertElementInList(inp, toverify, responsevar=None, pos=0,
|
||||
def assertElementInList(inp, toverify, responsevar=None, pos=0,
|
||||
assertmsg="TC Failed for reason"):
|
||||
'''
|
||||
@Name: assertElementInList
|
||||
|
|
@ -46,7 +46,7 @@ class cloudstackTestCase(unittest.case.TestCase):
|
|||
Takes one additional argument of what message to assert with
|
||||
when failed
|
||||
'''
|
||||
out = verifyElementInList(inp, toverify, responsevar, pos)
|
||||
out = verifyElementInList(inp, toverify, responsevar, pos)
|
||||
unittest.TestCase.assertEquals(out[0], PASS, "msg:%s" % out[1])
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -15,23 +15,20 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from cloudstackConnection import CSConnection
|
||||
import asyncJobMgr
|
||||
from dbConnection import DbConnection
|
||||
from cloudstackAPI import *
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
from codes import (FAILED, PASS, ADMIN, DOMAIN_ADMIN,
|
||||
USER, SUCCESS, XEN_SERVER)
|
||||
from configGenerator import ConfigManager
|
||||
from marvin.lib import utils
|
||||
from marvin.cloudstackConnection import CSConnection
|
||||
from marvin.asyncJobMgr import asyncJobMgr
|
||||
from marvin.dbConnection import DbConnection
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.codes import (FAILED, PASS, ADMIN, DOMAIN_ADMIN,
|
||||
USER, SUCCESS, XEN_SERVER)
|
||||
from marvin.configGenerator import ConfigManager
|
||||
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,
|
||||
|
|
@ -46,13 +43,14 @@ class CSTestClient(object):
|
|||
logger : provides logging facilities for this library
|
||||
zone : The zone on which test suites using this test client will run
|
||||
'''
|
||||
|
||||
def __init__(self, mgmt_details,
|
||||
dbsvr_details,
|
||||
async_timeout=3600,
|
||||
default_worker_threads=10,
|
||||
logger=None,
|
||||
test_data_filepath=None,
|
||||
zone=None):
|
||||
zone=None,
|
||||
hypervisor_type=None):
|
||||
self.__mgmtDetails = mgmt_details
|
||||
self.__dbSvrDetails = dbsvr_details
|
||||
self.__csConnection = None
|
||||
|
|
@ -60,15 +58,15 @@ class CSTestClient(object):
|
|||
self.__testClient = None
|
||||
self.__asyncTimeOut = async_timeout
|
||||
self.__logger = logger
|
||||
self.__defaultWorkerThreads = default_worker_threads
|
||||
self.__apiClient = None
|
||||
self.__userApiClient = None
|
||||
self.__asyncJobMgr = None
|
||||
self.__id = None
|
||||
self.__hypervisor = None
|
||||
self.__hypervisor = hypervisor_type
|
||||
self.__testDataFilePath = test_data_filepath
|
||||
self.__parsedTestDataConfig = None
|
||||
self.__zone = zone
|
||||
self.__setHypervisorInfo()
|
||||
|
||||
@property
|
||||
def identifier(self):
|
||||
|
|
@ -96,36 +94,30 @@ class CSTestClient(object):
|
|||
Even, if it is not available, return None
|
||||
@Output : Returns the Zone Name
|
||||
'''
|
||||
if self.__zone is None:
|
||||
if self.__parsedTestDataConfig:
|
||||
ret = self.__parsedTestDataConfig.get("zone")
|
||||
if ret != "NA":
|
||||
self.__zone = ret
|
||||
return self.__zone
|
||||
|
||||
def getHypervisorInfo(self):
|
||||
'''
|
||||
@Name : getHypervisorInfo
|
||||
@Desc : Provides the hypervisor Information to test users
|
||||
@Output : Return Hypervisor Information
|
||||
'''
|
||||
if not self.__hypervisor:
|
||||
if self.__mgmtDetails.hypervisor:
|
||||
self.__hypervisor = self.__mgmtDetails.hypervisor
|
||||
else:
|
||||
self.__hypervisor = XEN_SERVER
|
||||
return self.__hypervisor
|
||||
|
||||
|
||||
def __setHypervisorToClient(self):
|
||||
def __setHypervisorInfo(self):
|
||||
'''
|
||||
@Name : ___setHypervisorToClient
|
||||
@Desc: Set the HyperVisor Details under API Client;
|
||||
default to Xen
|
||||
@Name : __setHypervisorInfo
|
||||
@Desc: Set the HyperVisor details;
|
||||
default to XenServer
|
||||
'''
|
||||
if self.__mgmtDetails.hypervisor:
|
||||
self.__apiClient.hypervisor = self.__mgmtDetails.hypervisor
|
||||
else:
|
||||
self.__apiClient.hypervisor = XEN_SERVER
|
||||
try:
|
||||
if not self.__hypervisor:
|
||||
self.__hypervisor = XEN_SERVER
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "\n Exception Occurred Under __setHypervisorInfo " \
|
||||
"%s" % GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
||||
def __createApiClient(self):
|
||||
try:
|
||||
|
|
@ -178,12 +170,8 @@ class CSTestClient(object):
|
|||
self.__asyncTimeOut,
|
||||
self.__logger)
|
||||
self.__apiClient = CloudStackAPIClient(self.__csConnection)
|
||||
'''
|
||||
Set the HyperVisor Details to Client default to Xen
|
||||
'''
|
||||
self.__setHypervisorToClient()
|
||||
return SUCCESS
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.__logger.exception(" Exception Occurred Under "
|
||||
"__createApiClient: %s" %
|
||||
GetDetailExceptionInfo(e))
|
||||
|
|
@ -210,16 +198,18 @@ class CSTestClient(object):
|
|||
'''
|
||||
@Name : ___getKeys
|
||||
@Desc : Retrieves the API and Secret Key for the provided Userid
|
||||
@Input: userid: Userid to register
|
||||
@Output: FAILED or tuple with apikey and secretkey
|
||||
'''
|
||||
try:
|
||||
register_user = registerUserKeys.registerUserKeysCmd()
|
||||
register_user.id = userid
|
||||
register_user_res = \
|
||||
self.__apiClient.registerUserKeys(register_user)
|
||||
if register_user_res == FAILED:
|
||||
if not register_user_res:
|
||||
return FAILED
|
||||
return (register_user_res.apikey, register_user_res.secretkey)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.__logger.exception("Exception Occurred Under __geKeys : "
|
||||
"%s" % GetDetailExceptionInfo(e))
|
||||
return FAILED
|
||||
|
|
@ -247,14 +237,21 @@ class CSTestClient(object):
|
|||
configuration file. They can overwrite it with
|
||||
providing their own configuration file as well.
|
||||
'''
|
||||
'''
|
||||
1. Check Config,Zone,Hypervisor Information
|
||||
'''
|
||||
self.__configObj = ConfigManager(self.__testDataFilePath)
|
||||
if self.__configObj:
|
||||
self.__parsedTestDataConfig = self.__configObj.getConfig()
|
||||
self.__logger.debug("Parsing Test data successful")
|
||||
else:
|
||||
self.__logger.error("createTestClient : Not able to create "
|
||||
|
||||
if not self.__configObj or not self.__hypervisor:
|
||||
self.__logger.error("createTestClient : "
|
||||
"Either Hypervisor is None or "
|
||||
"Not able to create "
|
||||
"ConfigManager Object")
|
||||
return FAILED
|
||||
|
||||
self.__parsedTestDataConfig = self.__configObj.getConfig()
|
||||
self.__logger.debug("Parsing Test data successful")
|
||||
|
||||
'''
|
||||
2. Create DB Connection
|
||||
'''
|
||||
|
|
@ -265,12 +262,12 @@ class CSTestClient(object):
|
|||
ret = self.__createApiClient()
|
||||
if ret == FAILED:
|
||||
self.__logger.\
|
||||
error("********Test Client Creation Failed********")
|
||||
error("==== Test Client Creation Failed ====")
|
||||
else:
|
||||
self.__logger.\
|
||||
debug("********Test Client Creation Successful********")
|
||||
debug("==== Test Client Creation Successful ====")
|
||||
return ret
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.__logger.exception("Exception Occurred "
|
||||
"Under createTestClient "
|
||||
": %s" % GetDetailExceptionInfo(e))
|
||||
|
|
@ -302,6 +299,10 @@ class CSTestClient(object):
|
|||
@Name : ___createUserApiClient
|
||||
@Desc : Creates a User API Client with given
|
||||
UserName\DomainName Parameters
|
||||
@Input: UserName: Username to be created in cloudstack
|
||||
DomainName: Domain under which the above account be created
|
||||
accType: Type of Account EX: Root,Non Root etc
|
||||
@Output: Return the API client for the user
|
||||
'''
|
||||
try:
|
||||
if not self.isAdminContext():
|
||||
|
|
@ -364,9 +365,9 @@ class CSTestClient(object):
|
|||
self.__csConnection.logger)
|
||||
self.__userApiClient = CloudStackAPIClient(newUserConnection)
|
||||
self.__userApiClient.connection = newUserConnection
|
||||
self.__userApiClient.hypervisor = self.__apiClient.hypervisor
|
||||
self.__userApiClient.hypervisor = self.__hypervisor
|
||||
return self.__userApiClient
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
self.__logger.exception("Exception Occurred "
|
||||
"Under getUserApiClient : %s" %
|
||||
GetDetailExceptionInfo(e))
|
||||
|
|
@ -399,16 +400,12 @@ class CSTestClient(object):
|
|||
def getUserApiClient(self, account, domain, type=0):
|
||||
"""
|
||||
@Name : getUserApiClient
|
||||
@Desc : Provides the User API Client to Users
|
||||
@Desc : Provides the User API Client to test Users
|
||||
0 - user ; 1 - admin;2 - domain admin
|
||||
@OutPut : FAILED In case of an issue
|
||||
else User API Client
|
||||
"""
|
||||
return FAILED if (self.__createUserApiClient(account,
|
||||
domain,
|
||||
type)
|
||||
== FAILED) \
|
||||
else self.__userApiClient
|
||||
return self.__createUserApiClient(account, domain, type)
|
||||
|
||||
def submitCmdsAndWait(self, cmds, workers=1):
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import urllib2
|
|||
|
||||
|
||||
class cmdParameterProperty(object):
|
||||
|
||||
def __init__(self):
|
||||
self.name = None
|
||||
self.required = False
|
||||
|
|
@ -34,6 +35,7 @@ class cmdParameterProperty(object):
|
|||
|
||||
|
||||
class cloudStackCmd(object):
|
||||
|
||||
def __init__(self):
|
||||
self.name = ""
|
||||
self.desc = ""
|
||||
|
|
@ -43,6 +45,7 @@ class cloudStackCmd(object):
|
|||
|
||||
|
||||
class CodeGenerator(object):
|
||||
|
||||
"""
|
||||
Apache CloudStack- marvin python classes can be generated from the json
|
||||
returned by API discovery or from the xml spec of commands generated by
|
||||
|
|
@ -208,12 +211,12 @@ class CodeGenerator(object):
|
|||
|
||||
body += self.space + '@property' + self.newline
|
||||
body += self.space + 'def id(self):' + self.newline
|
||||
body += self.space*2 + 'return self._id' + self.newline
|
||||
body += self.space * 2 + 'return self._id' + self.newline
|
||||
body += self.newline
|
||||
|
||||
body += self.space + '@id.setter' + self.newline
|
||||
body += self.space + 'def id(self, identifier):' + self.newline
|
||||
body += self.space*2 + 'self._id = identifier' + self.newline
|
||||
body += self.space * 2 + 'self._id = identifier' + self.newline
|
||||
body += self.newline
|
||||
|
||||
for cmdName in self.cmdsName:
|
||||
|
|
@ -340,7 +343,7 @@ class CodeGenerator(object):
|
|||
paramProperty.desc = response['description']
|
||||
if 'type' in response:
|
||||
if response['type'] in ['list', 'map', 'set']:
|
||||
#Here list becomes a subproperty
|
||||
# Here list becomes a subproperty
|
||||
if 'response' in response:
|
||||
for innerResponse in response['response']:
|
||||
subProperty =\
|
||||
|
|
@ -394,7 +397,7 @@ class CodeGenerator(object):
|
|||
csCmd.request.append(paramProperty)
|
||||
|
||||
for response in cmd['response']:
|
||||
#FIXME: ExtractImage related APIs return empty dicts in response
|
||||
# FIXME: ExtractImage related APIs return empty dicts in response
|
||||
if len(response) > 0:
|
||||
paramProperty = self.constructResponseFromJSON(response)
|
||||
csCmd.response.append(paramProperty)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ test_data = {
|
|||
"regionendpoint": "http://region2:8080/client"
|
||||
},
|
||||
"zone": "NA",
|
||||
"domain": { "name": "domain" },
|
||||
"hypervisor": "XenServer",
|
||||
"vdomain": { "name": "domain" },
|
||||
"email" : "test@test.com",
|
||||
"gateway" : "172.1.1.1",
|
||||
"netmask" : "255.255.255.0",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from marvin.config.test_data import test_data
|
|||
|
||||
|
||||
class managementServer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.mgtSvrIp = None
|
||||
self.port = 8096
|
||||
|
|
@ -36,6 +37,7 @@ class managementServer(object):
|
|||
|
||||
|
||||
class dbServer(object):
|
||||
|
||||
def __init__(self):
|
||||
self.dbSvr = None
|
||||
self.port = 3306
|
||||
|
|
@ -85,6 +87,7 @@ class zone(object):
|
|||
|
||||
|
||||
class trafficType(object):
|
||||
|
||||
def __init__(self, typ, labeldict=None):
|
||||
self.typ = typ # Guest/Management/Public
|
||||
if labeldict:
|
||||
|
|
@ -97,6 +100,7 @@ class trafficType(object):
|
|||
|
||||
|
||||
class pod(object):
|
||||
|
||||
def __init__(self):
|
||||
self.gateway = None
|
||||
self.name = None
|
||||
|
|
@ -111,6 +115,7 @@ class pod(object):
|
|||
|
||||
|
||||
class VmwareDc(object):
|
||||
|
||||
def __init__(self):
|
||||
self.zoneid = None
|
||||
self.name = None
|
||||
|
|
@ -120,6 +125,7 @@ class VmwareDc(object):
|
|||
|
||||
|
||||
class cluster(object):
|
||||
|
||||
def __init__(self):
|
||||
self.clustername = None
|
||||
self.clustertype = None
|
||||
|
|
@ -134,6 +140,7 @@ class cluster(object):
|
|||
|
||||
|
||||
class host(object):
|
||||
|
||||
def __init__(self):
|
||||
self.hypervisor = None
|
||||
self.password = None
|
||||
|
|
@ -151,6 +158,7 @@ class host(object):
|
|||
|
||||
|
||||
class physicalNetwork(object):
|
||||
|
||||
def __init__(self):
|
||||
self.name = None
|
||||
self.tags = []
|
||||
|
|
@ -165,6 +173,7 @@ class physicalNetwork(object):
|
|||
|
||||
|
||||
class provider(object):
|
||||
|
||||
def __init__(self, name=None):
|
||||
self.name = name
|
||||
self.state = None
|
||||
|
|
@ -175,6 +184,7 @@ class provider(object):
|
|||
|
||||
|
||||
class network(object):
|
||||
|
||||
def __init__(self):
|
||||
self.displaytext = None
|
||||
self.name = None
|
||||
|
|
@ -187,6 +197,7 @@ class network(object):
|
|||
|
||||
|
||||
class iprange(object):
|
||||
|
||||
def __init__(self):
|
||||
'''tagged/untagged'''
|
||||
self.gateway = None
|
||||
|
|
@ -200,12 +211,14 @@ class iprange(object):
|
|||
|
||||
|
||||
class primaryStorage(object):
|
||||
|
||||
def __init__(self):
|
||||
self.name = None
|
||||
self.url = None
|
||||
|
||||
|
||||
class secondaryStorage(object):
|
||||
|
||||
def __init__(self):
|
||||
self.url = None
|
||||
self.provider = None
|
||||
|
|
@ -213,6 +226,7 @@ class secondaryStorage(object):
|
|||
|
||||
|
||||
class cacheStorage(object):
|
||||
|
||||
def __init__(self):
|
||||
self.url = None
|
||||
self.provider = None
|
||||
|
|
@ -220,6 +234,7 @@ class cacheStorage(object):
|
|||
|
||||
|
||||
class s3(object):
|
||||
|
||||
def __init__(self):
|
||||
self.accesskey = None
|
||||
self.secretkey = None
|
||||
|
|
@ -232,6 +247,7 @@ class s3(object):
|
|||
|
||||
|
||||
class netscaler(object):
|
||||
|
||||
def __init__(self, hostname=None, username='nsroot', password='nsroot'):
|
||||
self.hostname = hostname
|
||||
self.username = username
|
||||
|
|
@ -248,11 +264,12 @@ class netscaler(object):
|
|||
|
||||
def __repr__(self):
|
||||
req = zip(self.__dict__.keys(), self.__dict__.values())
|
||||
return self.hostname+"?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
return self.hostname + "?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
|
||||
|
||||
class srx(object):
|
||||
|
||||
def __init__(self, hostname=None, username='root', password='admin'):
|
||||
self.hostname = hostname
|
||||
self.username = username
|
||||
|
|
@ -271,11 +288,12 @@ class srx(object):
|
|||
|
||||
def __repr__(self):
|
||||
req = zip(self.__dict__.keys(), self.__dict__.values())
|
||||
return self.hostname+"?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
return self.hostname + "?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
|
||||
|
||||
class bigip(object):
|
||||
|
||||
def __init__(self, hostname=None, username='root', password='default'):
|
||||
self.hostname = hostname
|
||||
self.username = username
|
||||
|
|
@ -292,11 +310,12 @@ class bigip(object):
|
|||
|
||||
def __repr__(self):
|
||||
req = zip(self.__dict__.keys(), self.__dict__.values())
|
||||
return self.hostname+"?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
return self.hostname + "?" + "&".join(["=".join([r[0], r[1]])
|
||||
for r in req])
|
||||
|
||||
|
||||
class ConfigManager(object):
|
||||
|
||||
'''
|
||||
@Name: ConfigManager
|
||||
@Desc: 1. It provides the basic configuration facilities to marvin.
|
||||
|
|
@ -328,6 +347,7 @@ class ConfigManager(object):
|
|||
8. Users can use their own configuration file passed to
|
||||
"getConfig" API,once configObj is returned.
|
||||
'''
|
||||
|
||||
def __init__(self, cfg_file=None):
|
||||
self.__filePath = cfg_file
|
||||
self.__parsedCfgDict = None
|
||||
|
|
@ -364,8 +384,8 @@ class ConfigManager(object):
|
|||
configLines.append(ws)
|
||||
config = json.loads("\n".join(configLines))
|
||||
config_dict = config
|
||||
except Exception, e:
|
||||
#Will replace with log once we have logging done
|
||||
except Exception as e:
|
||||
# Will replace with log once we have logging done
|
||||
print "\n Exception occurred under ConfigManager:__parseConfig" \
|
||||
" :%s", GetDetailExceptionInfo(e)
|
||||
finally:
|
||||
|
|
@ -413,9 +433,9 @@ class ConfigManager(object):
|
|||
def getDeviceUrl(obj):
|
||||
req = zip(obj.__dict__.keys(), obj.__dict__.values())
|
||||
if obj.hostname:
|
||||
return "http://" + obj.hostname+"?" + "&".join(["=".join([r[0],
|
||||
r[1]])
|
||||
for r in req])
|
||||
return "http://" + obj.hostname + "?" + "&".join(["=".join([r[0],
|
||||
r[1]])
|
||||
for r in req])
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -430,11 +450,11 @@ def descSetupInBasicMode():
|
|||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
z.name = "test" + str(l)
|
||||
z.networktype = 'Basic'
|
||||
z.securitygroupenabled = 'True'
|
||||
|
||||
#If security groups are reqd
|
||||
# If security groups are reqd
|
||||
sgprovider = provider()
|
||||
sgprovider.broadcastdomainrange = 'Pod'
|
||||
sgprovider.name = 'SecurityGroupProvider'
|
||||
|
|
@ -460,15 +480,15 @@ def descSetupInBasicMode():
|
|||
ip = iprange()
|
||||
ip.gateway = p.gateway
|
||||
ip.netmask = p.netmask
|
||||
ip.startip = "192.168.%d.%d" % (i, j*20)
|
||||
ip.endip = "192.168.%d.%d" % (i, j*20+10)
|
||||
ip.startip = "192.168.%d.%d" % (i, j * 20)
|
||||
ip.endip = "192.168.%d.%d" % (i, j * 20 + 10)
|
||||
|
||||
p.guestIpRanges.append(ip)
|
||||
|
||||
'''add 10 clusters'''
|
||||
for j in range(2):
|
||||
c = cluster()
|
||||
c.clustername = "test"+str(l)+str(i) + str(j)
|
||||
c.clustername = "test" + str(l) + str(i) + str(j)
|
||||
c.clustertype = "CloudManaged"
|
||||
c.hypervisor = "Simulator"
|
||||
|
||||
|
|
@ -477,15 +497,16 @@ def descSetupInBasicMode():
|
|||
h = host()
|
||||
h.username = "root"
|
||||
h.password = "password"
|
||||
memory = 8*1024*1024*1024
|
||||
localstorage = 1*1024*1024*1024*1024
|
||||
memory = 8 * 1024 * 1024 * 1024
|
||||
localstorage = 1 * 1024 * 1024 * 1024 * 1024
|
||||
h.url = "http://sim/%d%d%d%d" % (l, i, j, k)
|
||||
c.hosts.append(h)
|
||||
|
||||
'''add 2 primary storages'''
|
||||
for m in range(2):
|
||||
primary = primaryStorage()
|
||||
primary.name = "primary"+str(l) + str(i) + str(j) + str(m)
|
||||
primary.name = "primary" + \
|
||||
str(l) + str(i) + str(j) + str(m)
|
||||
primary.url = "nfs://localhost/path%s" % (str(l) + str(i) +
|
||||
str(j) + str(m))
|
||||
c.primaryStorages.append(primary)
|
||||
|
|
@ -497,7 +518,7 @@ def descSetupInBasicMode():
|
|||
'''add two secondary'''
|
||||
for i in range(5):
|
||||
secondary = secondaryStorage()
|
||||
secondary.url = "nfs://localhost/path"+str(l) + str(i)
|
||||
secondary.url = "nfs://localhost/path" + str(l) + str(i)
|
||||
z.secondaryStorages.append(secondary)
|
||||
|
||||
zs.zones.append(z)
|
||||
|
|
@ -539,7 +560,7 @@ def descSetupInEipMode():
|
|||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
z.name = "test" + str(l)
|
||||
z.networktype = 'Basic'
|
||||
|
||||
ips = iprange()
|
||||
|
|
@ -550,7 +571,7 @@ def descSetupInEipMode():
|
|||
ips.netmask = "255.255.255.0"
|
||||
z.ipranges.append(ips)
|
||||
|
||||
#If security groups are reqd
|
||||
# If security groups are reqd
|
||||
sgprovider = provider()
|
||||
sgprovider.broadcastdomainrange = 'Pod'
|
||||
sgprovider.name = 'SecurityGroupProvider'
|
||||
|
|
@ -584,15 +605,15 @@ def descSetupInEipMode():
|
|||
ip = iprange()
|
||||
ip.gateway = p.gateway
|
||||
ip.netmask = p.netmask
|
||||
ip.startip = "192.168.%d.%d" % (i, j*20)
|
||||
ip.endip = "192.168.%d.%d" % (i, j*20+10)
|
||||
ip.startip = "192.168.%d.%d" % (i, j * 20)
|
||||
ip.endip = "192.168.%d.%d" % (i, j * 20 + 10)
|
||||
|
||||
p.guestIpRanges.append(ip)
|
||||
|
||||
'''add 10 clusters'''
|
||||
for j in range(2):
|
||||
c = cluster()
|
||||
c.clustername = "test"+str(l)+str(i) + str(j)
|
||||
c.clustername = "test" + str(l) + str(i) + str(j)
|
||||
c.clustertype = "CloudManaged"
|
||||
c.hypervisor = "Simulator"
|
||||
|
||||
|
|
@ -607,7 +628,8 @@ def descSetupInEipMode():
|
|||
'''add 2 primary storages'''
|
||||
for m in range(2):
|
||||
primary = primaryStorage()
|
||||
primary.name = "primary"+str(l) + str(i) + str(j) + str(m)
|
||||
primary.name = "primary" + \
|
||||
str(l) + str(i) + str(j) + str(m)
|
||||
primary.url = "nfs://localhost/path%s" % (str(l) + str(i)
|
||||
+ str(j)
|
||||
+ str(m))
|
||||
|
|
@ -620,7 +642,7 @@ def descSetupInEipMode():
|
|||
'''add two secondary'''
|
||||
for i in range(5):
|
||||
secondary = secondaryStorage()
|
||||
secondary.url = "nfs://localhost/path"+str(l) + str(i)
|
||||
secondary.url = "nfs://localhost/path" + str(l) + str(i)
|
||||
z.secondaryStorages.append(secondary)
|
||||
|
||||
zs.zones.append(z)
|
||||
|
|
@ -660,7 +682,7 @@ def descSetupInAdvancedMode():
|
|||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
z.name = "test" + str(l)
|
||||
z.networktype = 'Advanced'
|
||||
z.guestcidraddress = "10.1.1.0/24"
|
||||
z.vlan = "100-2000"
|
||||
|
|
@ -696,7 +718,7 @@ def descSetupInAdvancedMode():
|
|||
'''add 10 clusters'''
|
||||
for j in range(2):
|
||||
c = cluster()
|
||||
c.clustername = "test"+str(l)+str(i) + str(j)
|
||||
c.clustername = "test" + str(l) + str(i) + str(j)
|
||||
c.clustertype = "CloudManaged"
|
||||
c.hypervisor = "Simulator"
|
||||
|
||||
|
|
@ -707,7 +729,7 @@ def descSetupInAdvancedMode():
|
|||
h.password = "password"
|
||||
memory = 8 * 1024 * 1024 * 1024
|
||||
localstorage = 1 * 1024 * 1024 * 1024 * 1024
|
||||
#h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\
|
||||
# h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\
|
||||
# memory=%d&localstorage=%d"%(l, i, j, k, memory,
|
||||
# localstorage)
|
||||
h.url = "http://sim/%d%d%d%d" % (l, i, j, k)
|
||||
|
|
@ -716,8 +738,9 @@ def descSetupInAdvancedMode():
|
|||
'''add 2 primary storages'''
|
||||
for m in range(2):
|
||||
primary = primaryStorage()
|
||||
primary.name = "primary"+str(l) + str(i) + str(j) + str(m)
|
||||
#primary.url = "nfs://localhost/path%s/size=%d" %
|
||||
primary.name = "primary" + \
|
||||
str(l) + str(i) + str(j) + str(m)
|
||||
# primary.url = "nfs://localhost/path%s/size=%d" %
|
||||
# (str(l) + str(i) + str(j) + str(m), size)
|
||||
primary.url = "nfs://localhost/path%s" % (str(l) + str(i)
|
||||
+ str(j)
|
||||
|
|
@ -731,7 +754,7 @@ def descSetupInAdvancedMode():
|
|||
'''add two secondary'''
|
||||
for i in range(5):
|
||||
secondary = secondaryStorage()
|
||||
secondary.url = "nfs://localhost/path"+str(l) + str(i)
|
||||
secondary.url = "nfs://localhost/path" + str(l) + str(i)
|
||||
z.secondaryStorages.append(secondary)
|
||||
|
||||
'''add default public network'''
|
||||
|
|
@ -781,7 +804,7 @@ def descSetupInAdvancedsgMode():
|
|||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
z.name = "test" + str(l)
|
||||
z.networktype = 'Advanced'
|
||||
z.vlan = "100-2000"
|
||||
z.securitygroupenabled = "true"
|
||||
|
|
@ -790,7 +813,7 @@ def descSetupInAdvancedsgMode():
|
|||
pn.name = "test-network"
|
||||
pn.traffictypes = [trafficType("Guest"), trafficType("Management")]
|
||||
|
||||
#If security groups are reqd
|
||||
# If security groups are reqd
|
||||
sgprovider = provider()
|
||||
sgprovider.broadcastdomainrange = 'ZONE'
|
||||
sgprovider.name = 'SecurityGroupProvider'
|
||||
|
|
@ -810,7 +833,7 @@ def descSetupInAdvancedsgMode():
|
|||
'''add 10 clusters'''
|
||||
for j in range(2):
|
||||
c = cluster()
|
||||
c.clustername = "test"+str(l)+str(i) + str(j)
|
||||
c.clustername = "test" + str(l) + str(i) + str(j)
|
||||
c.clustertype = "CloudManaged"
|
||||
c.hypervisor = "Simulator"
|
||||
|
||||
|
|
@ -821,17 +844,18 @@ def descSetupInAdvancedsgMode():
|
|||
h.password = "password"
|
||||
memory = 8 * 1024 * 1024 * 1024
|
||||
localstorage = 1 * 1024 * 1024 * 1024 * 1024
|
||||
#h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\
|
||||
#memory=%d&localstorage=%d" % (l, i, j, k, memory,
|
||||
#localstorage)
|
||||
# h.url = "http://sim/%d%d%d%d/cpucore=1&cpuspeed=8000&\
|
||||
# memory=%d&localstorage=%d" % (l, i, j, k, memory,
|
||||
# localstorage)
|
||||
h.url = "http://sim/%d%d%d%d" % (l, i, j, k)
|
||||
c.hosts.append(h)
|
||||
|
||||
'''add 2 primary storages'''
|
||||
for m in range(2):
|
||||
primary = primaryStorage()
|
||||
primary.name = "primary"+str(l) + str(i) + str(j) + str(m)
|
||||
#primary.url = "nfs://localhost/path%s/size=%d" % \
|
||||
primary.name = "primary" + \
|
||||
str(l) + str(i) + str(j) + str(m)
|
||||
# primary.url = "nfs://localhost/path%s/size=%d" % \
|
||||
#(str(l) + str(i) + str(j) + str(m), size)
|
||||
primary.url = "nfs://localhost/path%s" % \
|
||||
(str(l) + str(i) + str(j) + str(m))
|
||||
|
|
@ -844,7 +868,7 @@ def descSetupInAdvancedsgMode():
|
|||
'''add two secondary'''
|
||||
for i in range(5):
|
||||
secondary = secondaryStorage()
|
||||
secondary.url = "nfs://localhost/path"+str(l) + str(i)
|
||||
secondary.url = "nfs://localhost/path" + str(l) + str(i)
|
||||
z.secondaryStorages.append(secondary)
|
||||
|
||||
'''add default guest network'''
|
||||
|
|
@ -904,7 +928,7 @@ def getSetupConfig(file):
|
|||
configLines.append(ws)
|
||||
config = json.loads("\n".join(configLines))
|
||||
return jsonHelper.jsonLoader(config)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "\nException Occurred under getSetupConfig %s" % \
|
||||
GetDetailExceptionInfo(e)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import os
|
|||
|
||||
|
||||
class DbConnection(object):
|
||||
|
||||
def __init__(self, host="localhost", port=3306, user='cloud',
|
||||
passwd='cloud', db='cloud'):
|
||||
self.host = host
|
||||
|
|
@ -51,7 +52,7 @@ class DbConnection(object):
|
|||
try:
|
||||
resultRow = cursor.fetchall()
|
||||
except errors.InterfaceError:
|
||||
#Raised on empty result - DML
|
||||
# Raised on empty result - DML
|
||||
resultRow = []
|
||||
return resultRow
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tcExecuteEngine import TestCaseExecuteEngine
|
||||
from .tcExecuteEngine import TestCaseExecuteEngine
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
import time
|
||||
from argparse import ArgumentParser
|
||||
from marvinInit import MarvinInit
|
||||
from .marvinInit import MarvinInit
|
||||
from marvin.codes import (SUCCESS,
|
||||
FAILED,
|
||||
EXCEPTION,
|
||||
|
|
@ -96,7 +96,7 @@ def startMarvin(cfg_file, load_flag):
|
|||
else:
|
||||
print "\nMarvin Initialization Failed"
|
||||
exit(1)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "\n Exception occurred while starting Marvin %s" % str(e)
|
||||
exit(1)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -18,11 +18,13 @@
|
|||
import cloudstackException
|
||||
import json
|
||||
import inspect
|
||||
from cloudstackAPI import *
|
||||
from marvin.cloudstackAPI import *
|
||||
|
||||
|
||||
class jsonLoader(object):
|
||||
|
||||
'''The recursive class for building and representing objects with.'''
|
||||
|
||||
def __init__(self, obj):
|
||||
for k in obj:
|
||||
v = obj[k]
|
||||
|
|
@ -52,6 +54,7 @@ class jsonLoader(object):
|
|||
|
||||
|
||||
class jsonDump(object):
|
||||
|
||||
@staticmethod
|
||||
def __serialize(obj):
|
||||
"""Recursively walk object's hierarchy."""
|
||||
|
|
@ -247,7 +250,7 @@ due to missing parameter jobid"
|
|||
}'''
|
||||
try:
|
||||
asynJob = getResultObj(result)
|
||||
except cloudstackException.CloudstackAPIException, e:
|
||||
except cloudstackException.CloudstackAPIException as e:
|
||||
print e
|
||||
|
||||
result = '{ "queryasyncjobresultresponse" : {} }'
|
||||
|
|
|
|||
|
|
@ -24,26 +24,17 @@ for starting it.
|
|||
3. Deploys the Data Center based upon input.
|
||||
|
||||
'''
|
||||
import marvin
|
||||
from marvin import configGenerator
|
||||
from marvin.configGenerator import getSetupConfig
|
||||
from marvin.marvinLog import MarvinLog
|
||||
from marvin.deployDataCenter import DeployDataCenters
|
||||
from marvin.cloudstackTestClient import CSTestClient
|
||||
from marvin.cloudstackException import GetDetailExceptionInfo
|
||||
from marvin.codes import(
|
||||
PASS,
|
||||
YES,
|
||||
NO,
|
||||
XEN_SERVER,
|
||||
SUCCESS,
|
||||
FAILED
|
||||
)
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import logging
|
||||
import string
|
||||
import random
|
||||
from sys import exit
|
||||
|
||||
|
||||
class MarvinInit:
|
||||
|
|
@ -51,7 +42,8 @@ class MarvinInit:
|
|||
def __init__(self, config_file,
|
||||
deploy_dc_flag=None,
|
||||
test_mod_name="deploydc",
|
||||
zone=None):
|
||||
zone=None,
|
||||
hypervisor_type=None):
|
||||
self.__configFile = config_file
|
||||
self.__deployFlag = deploy_dc_flag
|
||||
self.__logFolderPath = None
|
||||
|
|
@ -62,6 +54,7 @@ class MarvinInit:
|
|||
self.__testDataFilePath = None
|
||||
self.__zoneForTests = zone
|
||||
self.__parsedConfig = None
|
||||
self.__hypervisorType = hypervisor_type
|
||||
|
||||
def __parseConfig(self):
|
||||
'''
|
||||
|
|
@ -74,8 +67,7 @@ class MarvinInit:
|
|||
if not os.path.isfile(self.__configFile):
|
||||
print "\n=== Marvin Parse Config Init Failed ==="
|
||||
return FAILED
|
||||
self.__parsedConfig = configGenerator.\
|
||||
getSetupConfig(self.__configFile)
|
||||
self.__parsedConfig = getSetupConfig(self.__configFile)
|
||||
print "\n=== Marvin Parse Config Successful ==="
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
|
|
@ -107,6 +99,26 @@ class MarvinInit:
|
|||
"/results.txt", "w")
|
||||
return self.__tcResultFile
|
||||
|
||||
def __setHypervisorAndZoneInfo(self):
|
||||
'''
|
||||
@Name : __setHypervisorAndZoneInfo
|
||||
@Desc: Set the HyperVisor and Zone details;
|
||||
default to XenServer
|
||||
'''
|
||||
try:
|
||||
if not self.__hypervisorType:
|
||||
self.__hypervisorType = XEN_SERVER
|
||||
if not self.__zoneForTests:
|
||||
if self.__parsedConfig:
|
||||
for zone in self.__parsedConfig.zones:
|
||||
self.__zoneForTests = zone.name
|
||||
break
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "\n Exception Occurred Under init " \
|
||||
"%s" % GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
||||
def init(self):
|
||||
'''
|
||||
@Name : init
|
||||
|
|
@ -120,6 +132,7 @@ class MarvinInit:
|
|||
'''
|
||||
try:
|
||||
if ((self.__parseConfig() != FAILED) and
|
||||
(self.__setHypervisorAndZoneInfo())and
|
||||
(self.__setTestDataPath() != FAILED) and
|
||||
(self.__initLogging() != FAILED) and
|
||||
(self.__createTestClient() != FAILED) and
|
||||
|
|
@ -153,7 +166,7 @@ class MarvinInit:
|
|||
if ret != FAILED:
|
||||
self.__logFolderPath = log_obj.getLogFolderPath()
|
||||
self.__tcRunLogger = log_obj.getLogger()
|
||||
print "\n=== Marvin Init Logging Sccessful==="
|
||||
print "\n=== Marvin Init Logging Successful==="
|
||||
return SUCCESS
|
||||
return FAILED
|
||||
except Exception as e:
|
||||
|
|
@ -175,11 +188,12 @@ class MarvinInit:
|
|||
logger=self.__tcRunLogger,
|
||||
test_data_filepath=
|
||||
self.__testDataFilePath,
|
||||
zone=self.__zoneForTests)
|
||||
zone=self.__zoneForTests,
|
||||
hypervisor_type=
|
||||
self.__hypervisorType)
|
||||
if self.__testClient:
|
||||
return self.__testClient.createTestClient()
|
||||
else:
|
||||
return FAILED
|
||||
return FAILED
|
||||
except Exception as e:
|
||||
print "\n Exception Occurred Under __createTestClient : %s" % \
|
||||
GetDetailExceptionInfo(e)
|
||||
|
|
@ -195,7 +209,7 @@ class MarvinInit:
|
|||
if ((self.__parsedConfig.TestData is not None) and
|
||||
(self.__parsedConfig.TestData.Path is not None)):
|
||||
self.__testDataFilePath = self.__parsedConfig.TestData.Path
|
||||
print "\n=== Marvin TestData Successful==="
|
||||
print "\n=== Marvin Setting TestData Successful==="
|
||||
return SUCCESS
|
||||
except Exception as e:
|
||||
print "\nException Occurred Under __setTestDataPath : %s" % \
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ from marvin.cloudstackException import GetDetailExceptionInfo
|
|||
|
||||
|
||||
class MarvinLog:
|
||||
|
||||
'''
|
||||
@Name : MarvinLog
|
||||
@Desc : provides interface for logging to marvin
|
||||
|
|
@ -89,7 +90,7 @@ class MarvinLog:
|
|||
stream.setLevel(log_level)
|
||||
self.__logger.addHandler(stream)
|
||||
return SUCCESS
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "\nException Occurred Under " \
|
||||
"__setLogHandler %s" % GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
|
@ -104,7 +105,7 @@ class MarvinLog:
|
|||
try:
|
||||
if os.path.isdir(logfolder_to_remove):
|
||||
os.rmdir(logfolder_to_remove)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "\n Exception Occurred Under __cleanPreviousLogs :%s" % \
|
||||
GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
|
@ -151,8 +152,8 @@ class MarvinLog:
|
|||
log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
|
||||
|
||||
self.__logFolderDir = temp_dir + "//" + temp_path
|
||||
print "\n*********Log Folder Path: %s. " \
|
||||
"All logs will be available here **************" \
|
||||
print "\n==== Log Folder Path: %s. " \
|
||||
"All logs will be available here ====" \
|
||||
% str(self.__logFolderDir)
|
||||
os.makedirs(self.__logFolderDir)
|
||||
|
||||
|
|
@ -171,7 +172,7 @@ class MarvinLog:
|
|||
log_level=logging.FATAL)
|
||||
return SUCCESS
|
||||
return FAILED
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "\n Exception Occurred Under createLogs :%s" % \
|
||||
GetDetailExceptionInfo(e)
|
||||
return FAILED
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ class MarvinPlugin(Plugin):
|
|||
self.__startTime = None
|
||||
self.__testName = None
|
||||
self.__tcRunLogger = None
|
||||
self.__testModName = None
|
||||
self.__testModName = ''
|
||||
self.__hypervisorType = None
|
||||
Plugin.__init__(self)
|
||||
|
||||
def configure(self, options, conf):
|
||||
|
|
@ -70,15 +71,15 @@ class MarvinPlugin(Plugin):
|
|||
self.enabled (True|False) determines whether marvin's tests will run.
|
||||
By default non-default plugins like marvin will be disabled
|
||||
"""
|
||||
self.enabled = True
|
||||
if hasattr(options, self.enableOpt):
|
||||
if not getattr(options, self.enableOpt):
|
||||
self.enabled = False
|
||||
return
|
||||
else:
|
||||
self.enabled = True
|
||||
self.__configFile = options.configFile
|
||||
self.__deployDcFlag = options.deployDc
|
||||
self.__zoneForTests = options.zone
|
||||
self.__hypervisorType = options.hypervisor_type
|
||||
self.conf = conf
|
||||
if self.startMarvin() == FAILED:
|
||||
print "\nStarting Marvin Failed, exiting. Please Check"
|
||||
|
|
@ -105,6 +106,11 @@ class MarvinPlugin(Plugin):
|
|||
default=None,
|
||||
dest="zone",
|
||||
help="Runs all tests against this specified zone")
|
||||
parser.add_option("--hypervisor", action="store",
|
||||
default=None,
|
||||
dest="hypervisor_type",
|
||||
help="Runs all tests against the specified "
|
||||
"zone and hypervisor Type")
|
||||
Plugin.options(self, parser, env)
|
||||
|
||||
def wantClass(self, cls):
|
||||
|
|
@ -148,9 +154,10 @@ class MarvinPlugin(Plugin):
|
|||
self._injectClients(cls)
|
||||
|
||||
def beforeTest(self, test):
|
||||
#self.__testModName = test.__str__()
|
||||
self.__testModName = test.__str__()
|
||||
self.__testName = test.__str__().split()[0]
|
||||
self.__testClient.identifier = '-'.join([self.__identifier, self.__testName])
|
||||
self.__testClient.identifier = '-'.\
|
||||
join([self.__identifier, self.__testName])
|
||||
if self.__tcRunLogger:
|
||||
self.__tcRunLogger.name = test.__str__()
|
||||
|
||||
|
|
@ -199,19 +206,6 @@ class MarvinPlugin(Plugin):
|
|||
self.printMsg(FAILED, self.__testName, GetDetailExceptionInfo(err))
|
||||
self.__testResult = FAILED
|
||||
|
||||
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 startMarvin(self):
|
||||
'''
|
||||
@Name : startMarvin
|
||||
|
|
@ -225,7 +219,8 @@ class MarvinPlugin(Plugin):
|
|||
obj_marvininit = MarvinInit(self.__configFile,
|
||||
self.__deployDcFlag,
|
||||
None,
|
||||
self.__zoneForTests)
|
||||
self.__zoneForTests,
|
||||
self.__hypervisorType)
|
||||
if obj_marvininit and obj_marvininit.init() == SUCCESS:
|
||||
self.__testClient = obj_marvininit.getTestClient()
|
||||
self.__tcRunLogger = obj_marvininit.getLogger()
|
||||
|
|
|
|||
|
|
@ -28,19 +28,21 @@ import time
|
|||
from marvin.cloudstackException import (
|
||||
internalError,
|
||||
GetDetailExceptionInfo
|
||||
)
|
||||
)
|
||||
import contextlib
|
||||
import logging
|
||||
from marvin.codes import (
|
||||
SUCCESS, FAILED, INVALID_INPUT, EXCEPTION_OCCURRED
|
||||
)
|
||||
)
|
||||
from contextlib import closing
|
||||
|
||||
|
||||
class SshClient(object):
|
||||
|
||||
'''
|
||||
Added timeout flag for ssh connect calls.Default to 3.0 seconds
|
||||
'''
|
||||
|
||||
def __init__(self, host, port, user, passwd, retries=20, delay=30,
|
||||
log_lvl=logging.DEBUG, keyPairFiles=None, timeout=10.0):
|
||||
self.host = None
|
||||
|
|
@ -58,8 +60,8 @@ class SshClient(object):
|
|||
ch.setLevel(log_lvl)
|
||||
self.logger.addHandler(ch)
|
||||
|
||||
#Check invalid host value and raise exception
|
||||
#Atleast host is required for connection
|
||||
# Check invalid host value and raise exception
|
||||
# Atleast host is required for connection
|
||||
if host is not None and host != '':
|
||||
self.host = host
|
||||
if retries is not None and retries > 0:
|
||||
|
|
@ -126,15 +128,15 @@ class SshClient(object):
|
|||
% (str(self.host), str(self.port)))
|
||||
ret = SUCCESS
|
||||
break
|
||||
except BadHostKeyException, e:
|
||||
except BadHostKeyException as e:
|
||||
except_msg = GetDetailExceptionInfo(e)
|
||||
except AuthenticationException, e:
|
||||
except AuthenticationException as e:
|
||||
except_msg = GetDetailExceptionInfo(e)
|
||||
except SSHException, e:
|
||||
except SSHException as e:
|
||||
except_msg = GetDetailExceptionInfo(e)
|
||||
except socket.error, e:
|
||||
except socket.error as e:
|
||||
except_msg = GetDetailExceptionInfo(e)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
except_msg = GetDetailExceptionInfo(e)
|
||||
finally:
|
||||
if self.retryCnt == 0 or ret == SUCCESS:
|
||||
|
|
@ -188,7 +190,7 @@ class SshClient(object):
|
|||
sftp = SFTPClient.from_transport(transport)
|
||||
try:
|
||||
sftp.put(srcFile, destPath)
|
||||
except IOError, e:
|
||||
except IOError as e:
|
||||
raise e
|
||||
|
||||
def __del__(self):
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from functools import partial
|
|||
|
||||
|
||||
class TestCaseExecuteEngine(object):
|
||||
|
||||
def __init__(self, testclient, config, tc_logger=None, debug_stream=None):
|
||||
"""
|
||||
Initialize the testcase execution engine, just the basics here
|
||||
|
|
@ -53,7 +54,7 @@ class TestCaseExecuteEngine(object):
|
|||
if isinstance(test, unittest.BaseTestSuite):
|
||||
self.injectTestCase(test)
|
||||
else:
|
||||
#inject testclient and logger into each unittest
|
||||
# inject testclient and logger into each unittest
|
||||
self.tcRunLogger.name = test.__str__()
|
||||
setattr(test, "testClient", self.testclient)
|
||||
setattr(test, "config", self.config)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from time import sleep as delay
|
|||
|
||||
|
||||
class TestSetupSuccess(cloudstackTestCase):
|
||||
|
||||
"""
|
||||
Test to verify if the cloudstack is ready to launch tests upon
|
||||
1. Verify that system VMs are up and running in all zones
|
||||
|
|
|
|||
Loading…
Reference in New Issue