cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gir...@apache.org
Subject [01/32] Marvin + test changes from master Signed-off-by: SrikanteswaraRao Talluri <talluri@apache.org>
Date Tue, 06 May 2014 10:00:35 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/4.4-forward 5e0671376 -> 8546f76b7


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/marvin/marvinPlugin.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py
index df7d7a3..4200a65 100644
--- a/tools/marvin/marvin/marvinPlugin.py
+++ b/tools/marvin/marvin/marvinPlugin.py
@@ -14,25 +14,24 @@
 # KIND, either express or implied.  See the License for the
 # 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
 from nose.plugins.base import Plugin
 from marvin.codes import (SUCCESS,
                           FAILED,
-                          EXCEPTION,
-                          UNKNOWN_ERROR
-                          )
-import traceback
-import time
-import os
+                          EXCEPTION)
+from marvin.lib.utils import random_gen
+from marvin.cloudstackException import GetDetailExceptionInfo
 
 
 class MarvinPlugin(Plugin):
+
     """
     Custom plugin for the cloudstackTestCases to be run using nose
     """
@@ -40,18 +39,35 @@ class MarvinPlugin(Plugin):
     name = "marvin"
 
     def __init__(self):
-        self.identifier = None
-        self.testClient = None
-        self.parsedConfig = None
-        self.configFile = None
-        self.loadFlag = None
+        self.__identifier = None
+        self.__testClient = None
+        self.__logFolderPath = None
+        self.__parsedConfig = None
+        '''
+        Contains Config File
+        '''
+        self.__configFile = None
+        '''
+        Signifies the Zone against which all tests will be Run
+        '''
+        self.__zoneForTests = None
+        '''
+        Signifies the flag whether to deploy the New DC or Not
+        '''
+        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.__resultStream = stdout
+        self.__testRunner = None
+        self.__testResult = SUCCESS
+        self.__startTime = None
+        self.__testName = None
+        self.__tcRunLogger = None
+        self.__testModName = ''
+        self.__hypervisorType = None
+        '''
+        The Log Path provided by user where all logs are routed to
+        '''
+        self.__userLogPath = None
         Plugin.__init__(self)
 
     def configure(self, options, conf):
@@ -60,20 +76,20 @@ 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.config_file
-        self.loadFlag = options.load
-        self.logFolderPath = options.log_folder_path
+        self.__configFile = options.configFile
+        self.__deployDcFlag = options.deployDc
+        self.__zoneForTests = options.zone
+        self.__hypervisorType = options.hypervisor_type
+        self.__userLogPath = options.logFolder
         self.conf = conf
-        '''
-        Initializes the marvin with required settings
-        '''
-        self.startMarvin()
+        if self.startMarvin() == FAILED:
+            print "\nStarting Marvin Failed, exiting. Please Check"
+            exit(1)
 
     def options(self, parser, env):
         """
@@ -82,20 +98,31 @@ class MarvinPlugin(Plugin):
         parser.add_option("--marvin-config", action="store",
                           default=env.get('MARVIN_CONFIG',
                                           './datacenter.cfg'),
-                          dest="config_file",
-                          help="Marvin's configuration file where the " +
-                               "datacenter information is specified" +
-                               " [MARVIN_CONFIG]")
-        parser.add_option("--load", action="store_true",
+                          dest="configFile",
+                          help="Marvin's configuration file is required."
+                               "The config file containing the datacenter and "
+                               "other management server "
+                               "information is specified")
+        parser.add_option("--deploy", action="store_true",
                           default=False,
-                          dest="load",
-                          help="Only load the deployment configuration given")
-        parser.add_option("--log-folder-path",
-                          action="store",
+                          dest="deployDc",
+                          help="Deploys the DC with Given Configuration."
+                               "Requires only when DC needs to be deployed")
+        parser.add_option("--zone", action="store",
+                          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")
+        parser.add_option("--log-folder-path", action="store",
                           default=None,
-                          dest="log_folder_path",
-                          help="Path to the folder "
-                               "where log files will be stored")
+                          dest="logFolder",
+                          help="Collects all logs under the user specified"
+                               "folder"
+                          )
         Plugin.options(self, parser, env)
 
     def wantClass(self, cls):
@@ -105,93 +132,124 @@ class MarvinPlugin(Plugin):
             return True
         return None
 
-    def wantFile(self, filename):
+    def __checkImport(self, filename):
         '''
-        Only python files will be used as test modules
+        @Name : __checkImport
+        @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.
         '''
-        parts = filename.split(os.path.sep)
-        base, ext = os.path.splitext(parts[-1])
-        if ext == '.py':
-            return True
-        else:
+        try:
+            if os.path.isfile(filename):
+                ret = os.path.splitext(filename)
+                if ret[1] == ".py":
+                    os.system("python " + filename)
+                    return True
+            return False
+        except ImportError as 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
+        '''
+        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.__testModName = test.__str__()
+        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("::::::::::::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 printMsg(self, status, tname, err):
+        if status in [FAILED, EXCEPTION] and self.__tcRunLogger:
+            self.__tcRunLogger.\
+                fatal("%s: %s: %s" % (status,
+                                      tname,
+                                      GetDetailExceptionInfo(err)))
+        write_str = "=== TestName: %s | Status : %s ===\n" % (tname, status)
+        self.__resultStream.write(write_str)
+        print write_str
 
-    def getErrorInfo(self, err):
+    def addSuccess(self, test, capt):
         '''
-        Extracts and returns the sanitized error message
+        Adds the Success Messages to logs
         '''
-        if err is not None:
-            return str(traceback.format_exc())
-        else:
-            return UNKNOWN_ERROR
+        self.printMsg(SUCCESS, self.__testName, "Test Case Passed")
+        self.__testresult = SUCCESS
 
     def handleError(self, test, err):
         '''
         Adds Exception throwing test cases and information to log.
         '''
-        err_msg = self.getErrorInfo(err)
-        self.tcRunLogger.fatal("%s: %s: %s" %
-                               (EXCEPTION, self.testName, err_msg))
-        self.testResult = EXCEPTION
+        self.printMsg(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.
         '''
-        err_msg = self.getErrorInfo(err)
-        self.tcRunLogger.fatal("%s: %s: %s" %
-                               (FAILED, self.testName, err_msg))
-        self.testResult = FAILED
+        self.printMsg(FAILED, self.__testName, GetDetailExceptionInfo(err))
+        self.__testResult = FAILED
 
     def startMarvin(self):
         '''
-        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
+        @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:
-            obj_marvininit = MarvinInit(self.configFile,
-                                        self.loadFlag,
-                                        self.logFolderPath)
-            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)
+            obj_marvininit = MarvinInit(self.__configFile,
+                                        self.__deployDcFlag,
+                                        None,
+                                        self.__zoneForTests,
+                                        self.__hypervisorType,
+                                        self.__userLogPath)
+            if obj_marvininit and obj_marvininit.init() == SUCCESS:
+                self.__testClient = obj_marvininit.getTestClient()
+                self.__tcRunLogger = obj_marvininit.getLogger()
+                self.__parsedConfig = obj_marvininit.getParsedConfig()
+                self.__resultStream = obj_marvininit.getResultFile()
+                self.__logFolderPath = obj_marvininit.getLogFolderPath()
+                self.__testRunner = nose.core.\
+                    TextTestRunner(stream=self.__resultStream,
+                                   descriptions=True,
+                                   verbosity=2,
+                                   config=self.conf)
                 return SUCCESS
-            else:
-                return FAILED
-        except Exception, e:
-            print "Exception Occurred under startMarvin: %s" % str(e)
+            return FAILED
+        except Exception as e:
+            print "Exception Occurred under startMarvin: %s" % \
+                  GetDetailExceptionInfo(e)
             return FAILED
 
     def stopTest(self, test):
@@ -199,27 +257,51 @@ 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.createUserApiClient(test.UserName, test.DomainName,
-                                                test.AcctType)
+            self.__testClient.getUserApiClient(test.UserName,
+                                               test.DomainName,
+                                               test.AcctType)
+
+    def finalize(self, result):
+        try:
+            if not self.__userLogPath:
+                src = self.__logFolderPath
+                log_cfg = self.__parsedConfig.logger
+                tmp = log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
+                dst = tmp + "//" + random_gen()
+                mod_name = "test_suite"
+                if self.__testModName:
+                    mod_name = self.__testModName.split(".")
+                    if len(mod_name) > 2:
+                        mod_name = mod_name[-2]
+                if mod_name:
+                    dst = tmp + "/" + mod_name + "_" + random_gen()
+                cmd = "mv " + src + " " + dst
+                os.system(cmd)
+                print "===final results are now copied to: %s===" % str(dst)
+        except Exception, e:
+            print "=== Exception occurred under finalize :%s ===" % \
+                  str(GetDetailExceptionInfo(e))

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/marvin/src/__init__.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/src/__init__.py b/tools/marvin/marvin/src/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/tools/marvin/marvin/src/__init__.py
@@ -0,0 +1,16 @@
+# 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.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/marvin/sshClient.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/sshClient.py b/tools/marvin/marvin/sshClient.py
index fd8726c..611c8b5 100644
--- a/tools/marvin/marvin/sshClient.py
+++ b/tools/marvin/marvin/sshClient.py
@@ -16,29 +16,49 @@
 # under the License.
 
 import paramiko
+from paramiko import (BadHostKeyException,
+                      AuthenticationException,
+                      SSHException,
+                      SSHClient,
+                      AutoAddPolicy,
+                      Transport,
+                      SFTPClient)
+import socket
 import time
-import cloudstackException
+from marvin.cloudstackException import (
+    internalError,
+    GetDetailExceptionInfo
+)
 import contextlib
 import logging
 from marvin.codes import (
-    SUCCESS, FAIL, INVALID_INPUT, EXCEPTION_OCCURRED
-    )
+    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
+    @Desc : SSH Library for Marvin.
+    Facilitates SSH,SCP services to marvin users
+    @Input: host: Host to connect
+            port: port on host to connect
+            user: Username to be used for connecting
+            passwd: Password for connection
+            retries and delay applies for establishing connection
+            timeout : Applies while executing command
     '''
-    def __init__(self, host, port, user, passwd, retries=20, delay=30,
-                 log_lvl=logging.INFO, keyPairFiles=None, timeout=10.0):
+
+    def __init__(self, host, port, user, passwd, retries=60, delay=10,
+                 log_lvl=logging.DEBUG, keyPairFiles=None, timeout=10.0):
         self.host = None
         self.port = 22
         self.user = user
         self.passwd = passwd
         self.keyPairFiles = keyPairFiles
-        self.ssh = paramiko.SSHClient()
-        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        self.ssh = SSHClient()
+        self.ssh.set_missing_host_key_policy(AutoAddPolicy())
         self.logger = logging.getLogger('sshClient')
         self.retryCnt = 0
         self.delay = 0
@@ -47,8 +67,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:
@@ -57,11 +77,10 @@ class SshClient(object):
             self.delay = delay
         if timeout is not None and timeout > 0:
             self.timeout = timeout
-        if port is not None or port >= 0:
+        if port is not None and port >= 0:
             self.port = port
-        if self.createConnection() == FAIL:
-            raise cloudstackException.\
-                internalError("Connection Failed")
+        if self.createConnection() == FAILED:
+            raise internalError("SSH Connection Failed")
 
     def execute(self, command):
         stdin, stdout, stderr = self.ssh.exec_command(command)
@@ -86,15 +105,16 @@ class SshClient(object):
         @Desc: Creates an ssh connection for
                retries mentioned,along with sleep mentioned
         @Output: SUCCESS on successful connection
-                 FAIL If connection through ssh failed
+                 FAILED If connection through ssh failed
         '''
-        ret = FAIL
+        ret = FAILED
+        except_msg = ''
         while self.retryCnt >= 0:
             try:
-                self.logger.debug("SSH Connection: Host:%s User:%s\
-                                   Port:%s" %
-                                  (self.host, self.user, str(self.port)
-                                   ))
+                self.logger.debug("====Trying SSH Connection: Host:%s User:%s\
+                                   Port:%s RetryCnt:%s===" %
+                                  (self.host, self.user, str(self.port),
+                                   str(self.retryCnt)))
                 if self.keyPairFiles is None:
                     self.ssh.connect(hostname=self.host,
                                      port=self.port,
@@ -102,22 +122,39 @@ class SshClient(object):
                                      password=self.passwd,
                                      timeout=self.timeout)
                 else:
+                    self.ssh.load_host_keys(self.keyPairFiles)
                     self.ssh.connect(hostname=self.host,
                                      port=self.port,
                                      username=self.user,
                                      password=self.passwd,
                                      key_filename=self.keyPairFiles,
                                      timeout=self.timeout,
-                                     look_for_keys=False
+                                     look_for_keys=True
                                      )
+                self.logger.debug("===SSH to Host %s port : %s SUCCESSFUL==="
+                                  % (str(self.host), str(self.port)))
                 ret = SUCCESS
                 break
-            except Exception as se:
-                self.retryCnt = self.retryCnt - 1
-                if self.retryCnt == 0:
+            except BadHostKeyException as e:
+                except_msg = GetDetailExceptionInfo(e)
+            except AuthenticationException as e:
+                except_msg = GetDetailExceptionInfo(e)
+            except SSHException as e:
+                except_msg = GetDetailExceptionInfo(e)
+            except socket.error as e:
+                except_msg = GetDetailExceptionInfo(e)
+            except Exception as e:
+                except_msg = GetDetailExceptionInfo(e)
+            finally:
+                if self.retryCnt == 0 or ret == SUCCESS:
                     break
+                if except_msg != '':
+                    self.logger.\
+                        exception("SshClient: Exception under "
+                                  "createConnection: %s" % except_msg)
+                self.retryCnt = self.retryCnt - 1
                 time.sleep(self.delay)
-        return ret
+                return ret
 
     def runCommand(self, command):
         '''
@@ -126,57 +163,54 @@ class SshClient(object):
                returns the result along with status code
         @Input: command to execute
         @Output: 1: status of command executed.
-                 Default to None
                  SUCCESS : If command execution is successful
-                 FAIL    : If command execution has failed
-                 EXCEPTION_OCCURRED: Exception occurred while executing
-                                     command
-                 INVALID_INPUT : If invalid value for command is passed
+                 FAILED    : If command execution has failed
                  2: stdin,stdout,stderr values of command output
         '''
-        excep_msg = ''
-        ret = {"status": None, "stdin": None, "stdout": None, "stderr": None}
+        ret = {"status": FAILED, "stdin": None, "stdout": None,
+               "stderr": INVALID_INPUT}
         if command is None or command == '':
-            ret["status"] = INVALID_INPUT
             return ret
         try:
             status_check = 1
-            stdin, stdout, stderr = self.ssh.exec_command(command)
-            output = stdout.readlines()
-            errors = stderr.readlines()
-            inp = stdin.readlines()
-            ret["stdin"] = inp
-            ret["stdout"] = output
-            ret["stderr"] = errors
+            stdin, stdout, stderr = self.ssh.\
+                exec_command(command, timeout=self.timeout)
             if stdout is not None:
                 status_check = stdout.channel.recv_exit_status()
-            if status_check == 0:
-                ret["status"] = SUCCESS
-            else:
-                ret["status"] = FAIL
+                if status_check == 0:
+                    ret["status"] = SUCCESS
+                ret["stdout"] = stdout.readlines()
+                if stderr is not None:
+                    ret["stderr"] = stderr.readlines()
         except Exception as e:
-            excep_msg = str(e)
-            ret["status"] = EXCEPTION_OCCURRED
+            ret["stderr"] = GetDetailExceptionInfo(e)
+            self.logger.exception("SshClient: Exception under runCommand :%s" %
+                                  GetDetailExceptionInfo(e))
         finally:
-            self.logger.debug(" Host: %s Cmd: %s Output:%s Exception: %s" %
-                              (self.host, command, str(ret), excep_msg))
+            self.logger.debug(" Host: %s Cmd: %s Output:%s" %
+                              (self.host, command, str(ret)))
             return ret
 
     def scp(self, srcFile, destPath):
-        transport = paramiko.Transport((self.host, int(self.port)))
+        transport = Transport((self.host, int(self.port)))
         transport.connect(username=self.user, password=self.passwd)
-        sftp = paramiko.SFTPClient.from_transport(transport)
+        sftp = SFTPClient.from_transport(transport)
         try:
             sftp.put(srcFile, destPath)
-        except IOError, e:
+        except IOError as e:
             raise e
 
+    def __del__(self):
+        self.close()
+
     def close(self):
             if self.ssh is not None:
                 self.ssh.close()
+                self.ssh = None
 
 
 if __name__ == "__main__":
-    with contextlib.closing(SshClient("10.223.75.10", 22, "root",
-                                      "password")) as ssh:
-        print ssh.execute("ls -l")
+    with contextlib.closing(SshClient("127.0.0.1", 22, "root",
+                                      "asdf!@34")) as ssh:
+        ret = ssh.runCommand("ls -l")
+        print ret

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/marvin/tcExecuteEngine.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/tcExecuteEngine.py b/tools/marvin/marvin/tcExecuteEngine.py
index f959e7e..e2f4d11 100644
--- a/tools/marvin/marvin/tcExecuteEngine.py
+++ b/tools/marvin/marvin/tcExecuteEngine.py
@@ -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)
@@ -61,9 +62,10 @@ class TestCaseExecuteEngine(object):
                 setattr(test.__class__, "clstestclient", self.testclient)
                 if hasattr(test, "user"):
                     # attribute when test is entirely executed as user
-                    self.testclient.createUserApiClient(test.UserName,
-                                                        test.DomainName,
-                                                        test.AcctType)
+                    self.testclient.\
+                        getUserApiClient(test.UserName,
+                                         test.DomainName,
+                                         test.AcctType)
 
     def run(self):
         if self.suite:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/marvin/testSetupSuccess.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/testSetupSuccess.py b/tools/marvin/marvin/testSetupSuccess.py
index 1701626..8b000f9 100644
--- a/tools/marvin/marvin/testSetupSuccess.py
+++ b/tools/marvin/marvin/testSetupSuccess.py
@@ -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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/404ac549/tools/marvin/setup.py
----------------------------------------------------------------------
diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py
index 9ce3951..4c775ad 100644
--- a/tools/marvin/setup.py
+++ b/tools/marvin/setup.py
@@ -6,9 +6,9 @@
 # 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
@@ -30,33 +30,37 @@ except ImportError:
 VERSION = '0.1.0'
 
 import os
+
+
 def read(fname):
     return open(os.path.join(os.path.dirname(__file__), fname)).read().strip()
 
 setup(name="Marvin",
-    version=VERSION,
-    description="Marvin - Python client for Apache CloudStack",
-    author="Edison Su",
-    author_email="Edison.Su@citrix.com",
-    maintainer="Prasanna Santhanam",
-    maintainer_email="tsp@apache.org",
-    long_description="Marvin is the Apache CloudStack python client written around the unittest
framework",
-    platforms=("Any",),
-    url="https://builds.apache.org/job/cloudstack-marvin/",
-    packages=["marvin", "marvin.cloudstackAPI", "marvin.integration",
-              "marvin.integration.lib", "marvin.sandbox",
-              "marvin.sandbox.advanced", "marvin.sandbox.advancedsg", "marvin.sandbox.basic"],
-    license="LICENSE.txt",
-    install_requires=[
-        "mysql-connector-python",
-        "requests",
-        "paramiko",
-        "nose",
-        "ddt >= 0.4.0"
-    ],
-    py_modules=['marvin.marvinPlugin'],
-    zip_safe=False,
-    entry_points={
-        'nose.plugins': ['marvinPlugin = marvin.marvinPlugin:MarvinPlugin']
-    },
-)
+      version=VERSION,
+      description="Marvin - Python client for Apache CloudStack",
+      author="Edison Su",
+      author_email="Edison.Su@citrix.com",
+      maintainer="Prasanna Santhanam",
+      maintainer_email="tsp@apache.org",
+      long_description="Marvin is the Apache CloudStack python "
+                       "client written around the unittest framework",
+      platforms=("Any",),
+      url="https://builds.apache.org/job/cloudstack-marvin/",
+      packages=["marvin", "marvin.cloudstackAPI",
+                "marvin.lib", "marvin.config", "marvin.sandbox",
+                "marvin.sandbox.advanced", "marvin.sandbox.advancedsg",
+                "marvin.sandbox.basic"],
+      license="LICENSE.txt",
+      install_requires=[
+          "mysql-connector-python",
+          "requests",
+          "paramiko",
+          "nose",
+          "ddt >= 0.4.0"
+      ],
+      py_modules=['marvin.marvinPlugin'],
+      zip_safe=False,
+      entry_points={
+          'nose.plugins': ['marvinPlugin = marvin.marvinPlugin:MarvinPlugin']
+      },
+      )


Mime
View raw message