def MakeResult(self, exc_info, result): # Make sure the exception is an object. if not type(exc_info[0]) is types.StringType: result.Fail(qm.message("test raised non-string", exc_type=str(type(exc_info[0])))) # Make sure it's the right string. if exc_info[0] != self.exception_text: result.Fail(qm.message("test raised wrong string", text=exc_info[0]))
def MakeResult(self, exc_info, result): # Make sure the exception is an object. if not type(exc_info[0]) is types.StringType: result.Fail( qm.message("test raised non-string", exc_type=str(type(exc_info[0])))) # Make sure it's the right string. if exc_info[0] != self.exception_text: result.Fail( qm.message("test raised wrong string", text=exc_info[0]))
def MakeResult(self, exc_info, result): # Make sure the exception is an object. if not type(exc_info[0]) is types.ClassType: result.Fail(qm.message("test raised non-object", exc_type=str(type(exc_info[0])))) # Make sure it's an instance of the right class. exception_class_name = exc_info[0].__name__ if exception_class_name != self.exception_class: cause = qm.message("test raised wrong class", class_name=exception_class_name) result.Fail(cause=cause)
def MakeResult(self, exc_info, result): # Make sure the exception is an object. if not type(exc_info[0]) in [types.ClassType, type]: result.Fail( qm.message("test raised non-object", exc_type=str(type(exc_info[0])))) # Make sure it's an instance of the right class. exception_class_name = exc_info[0].__name__ if exception_class_name != self.exception_class: cause = qm.message("test raised wrong class", class_name=exception_class_name) result.Fail(cause=cause)
def _SetUpResource(self, resource_name, context): """Set up the resource given by 'resource_id'. 'resource_name' -- The name of the resource to be set up. 'context' -- The 'Context' in which to run the resource. returns -- A map from strings to strings indicating additional properties added by this resource.""" # Begin setting up the resource. rop = self._BeginResourceSetUp(resource_name) # If it has already been set up, there is no need to do it # again. if rop: return rop # Set up the context. wrapper = Context(context) result = Result(Result.RESOURCE_SETUP, resource_name, Result.PASS) resource = None # Get the resource descriptor. try: resource_desc = self.GetDatabase().GetResource(resource_name) # Set up the resources on which this resource depends. self.__SetUpResources(resource_desc, wrapper) # Make the ID of the resource available. wrapper[Context.ID_CONTEXT_PROPERTY] = resource_name # Set up the resource itself. resource_desc.SetUp(wrapper, result) # Obtain the resource within the try-block so that if it # cannot be obtained the exception is handled below. resource = resource_desc.GetItem() except self.__ResourceSetUpException, e: result.Fail(qm.message("failed resource"), {result.RESOURCE: e.resource})
def CheckArgument(self, exc_info, result): """Check that the exception argument matches expectations. 'result' -- The result object for this test.""" # Was an expected exception argument specified? if self.has_exception_argument: # Yes. Extract the exception argument. argument = exc_info[1] if cmp(argument, self.exception_argument): cause = qm.message("test raised wrong argument") result.Fail( cause, { "BaseExceptionTest.type": str(exc_info[0]), "BaseExceptionTest.argument": repr(argument) })
def CheckArgument(self, exc_info, result): """Check that the exception argument matches expectations. 'result' -- The result object for this test.""" # Was an expected exception argument specified? if self.has_exception_argument: # Yes. Extract the exception argument. argument = exc_info[1] if cmp(argument, self.exception_argument): cause = qm.message("test raised wrong argument") result.Fail(cause, { "BaseExceptionTest.type" : str(exc_info[0]), "BaseExceptionTest.argument" : repr(argument) })
def CheckArgument(self, exc_info, result): """Check that the exception argument matches expectations. 'result' -- The result object for this test.""" # Was an expected argument specified? if self.has_exception_argument: # Extract the actual argument from the exception object. try: argument = exc_info[1].args except: # If the "args" were not available, then the exception # object does not use the documented interface given # for Exception. result.Fail( "Exception object does not provide access " "to arguments provided to 'raise'", {"ExceptionTest.type": str(exc_info[0])}) return # Now the expected argument. expected_argument = self.exception_argument # Python wraps the arguments to class exceptions in strange # ways, so wrap the expected argument similarly. A 'None' # argument is represented by an empty tuple. if expected_argument is None: expected_argument = () # Tuple arguments are unmodified. elif type(expected_argument) is types.TupleType: pass # A non-tuple argument is wrapped in a tuple. else: expected_argument = (expected_argument, ) # Compare the actual argument to the expectation. if cmp(expected_argument, argument) != 0: # We got a different argument. The test fails. cause = qm.message("test raised wrong argument") result.Fail( cause, { "ExceptionTest.type": str(exc_info[0]), "ExceptionTest.argument": repr(argument) })
def CheckArgument(self, exc_info, result): """Check that the exception argument matches expectations. 'result' -- The result object for this test.""" # Was an expected argument specified? if self.has_exception_argument: # Extract the actual argument from the exception object. try: argument = exc_info[1].args except: # If the "args" were not available, then the exception # object does not use the documented interface given # for Exception. result.Fail("Exception object does not provide access " "to arguments provided to 'raise'", { "ExceptionTest.type" : str(exc_info[0]) }) return # Now the expected argument. expected_argument = self.exception_argument # Python wraps the arguments to class exceptions in strange # ways, so wrap the expected argument similarly. A 'None' # argument is represented by an empty tuple. if expected_argument is None: expected_argument = () # Tuple arguments are unmodified. elif type(expected_argument) is types.TupleType: pass # A non-tuple argument is wrapped in a tuple. else: expected_argument = (expected_argument, ) # Compare the actual argument to the expectation. if cmp(expected_argument, argument) != 0: # We got a different argument. The test fails. cause = qm.message("test raised wrong argument") result.Fail(cause, { "ExceptionTest.type" : str(exc_info[0]), "ExceptionTest.argument" : repr(argument) })
def _SetUpResource(self, resource_name, context): """Set up the resource given by 'resource_id'. 'resource_name' -- The name of the resource to be set up. 'context' -- The 'Context' in which to run the resource. returns -- A map from strings to strings indicating additional properties added by this resource.""" # Begin setting up the resource. rop = self._BeginResourceSetUp(resource_name) # If it has already been set up, there is no need to do it # again. if rop: return rop # Set up the context. wrapper = Context(context) result = Result(Result.RESOURCE_SETUP, resource_name, Result.PASS) resource = None # Get the resource descriptor. try: resource_desc = self.GetDatabase().GetResource(resource_name) # Set up the resources on which this resource depends. self.__SetUpResources(resource_desc, wrapper) # Make the ID of the resource available. wrapper[Context.ID_CONTEXT_PROPERTY] = resource_name # Set up the resource itself. try: resource_desc.SetUp(wrapper, result) finally: del wrapper[Context.ID_CONTEXT_PROPERTY] # Obtain the resource within the try-block so that if it # cannot be obtained the exception is handled below. resource = resource_desc.GetItem() except self.__ResourceSetUpException, e: result.Fail(qm.message("failed resource"), { result.RESOURCE : e.resource })
def Run(self, context, result): # Adjust the exception argument. if string.strip(self.exception_argument) != "": self.exception_argument = eval(self.exception_argument, {}, {}) self.has_exception_argument = 1 else: self.has_exception_argument = 0 global_namespace, local_namespace = make_namespaces(context) try: # Execute the test code. exec self.source in global_namespace, local_namespace except: exc_info = sys.exc_info() # Check the exception argument. self.CheckArgument(exc_info, result) if result.GetOutcome() != Result.PASS: return # Check that the exception itself is OK. self.MakeResult(exc_info, result) else: # The test code didn't raise an exception. result.Fail(qm.message("test did not raise"))
qm.rc.Load("test") try: exit_code = main() except qm.cmdline.CommandError, msg: print_error_message(msg) sys.stderr.write( "Run 'qmtest --help' to get instructions about how to use QMTest.\n" ) except qm.common.QMException, msg: print_error_message(msg) except NotImplementedError: exc_info = sys.exc_info() method_name = traceback.extract_tb(exc_info[2])[-1][2] print_error_message( qm.message("not implemented", method_name=method_name)) sys.stderr.write(qm.common.format_traceback(exc_info)) except KeyboardInterrupt: sys.stderr.write("\nqmtest: Interrupted.\n") raise except qm.platform.SignalException, se: # SIGTERM indicates a request to shut down. Other signals # should be handled earlier. if se.GetSignalNumber() != signal.SIGTERM: raise finally: # Collect garbage so that any "__del__" methods with externally # visible side-effects are executed. del qm.test.cmdline._the_qmtest gc.collect()
# Note the exception. result.NoteException(cause = str(e)) # If we get a SIGTERM, propagate it so that QMTest # terminates. if e.GetSignalNumber() == signal.SIGTERM: # Record the result so that the traceback is # available. self._RecordResult(result) # Ask the execution engine to stop running tests. if self.__engine: self.__engine.RequestTermination() # Re-raise the exception. raise except self.__ResourceSetUpException, e: result.SetOutcome(Result.UNTESTED) result[Result.CAUSE] = qm.message("failed resource") result[Result.RESOURCE] = e.resource except: result.NoteException() # Record the result. self._RecordResult(result) def _RecordResult(self, result): """Record the 'result'. 'result' -- A 'Result' of a test or resource execution. Derived classes may override this method, but the overriding method must call this method at some point during its execution."""
# Note the exception. result.NoteException(cause=str(e)) # If we get a SIGTERM, propagate it so that QMTest # terminates. if e.GetSignalNumber() == signal.SIGTERM: # Record the result so that the traceback is # available. self._RecordResult(result) # Ask the execution engine to stop running tests. if self.__engine: self.__engine.RequestTermination() # Re-raise the exception. raise except self.__ResourceSetUpException, e: result.SetOutcome(Result.UNTESTED) result[Result.CAUSE] = qm.message("failed resource") result[Result.RESOURCE] = e.resource except: result.NoteException() # Record the result. self._RecordResult(result) def _RecordResult(self, result): """Record the 'result'. 'result' -- A 'Result' of a test or resource execution. Derived classes may override this method, but the overriding method must call this method at some point during its execution."""
# Load RC options. qm.rc.Load("test") try: exit_code = main() except qm.cmdline.CommandError, msg: print_error_message(msg) sys.stderr.write( "Run 'qmtest --help' to get instructions about how to use QMTest.\n") except qm.common.QMException, msg: print_error_message(msg) except NotImplementedError: exc_info = sys.exc_info() method_name = traceback.extract_tb(exc_info[2])[-1][2] print_error_message(qm.message("not implemented", method_name = method_name)) sys.stderr.write(qm.common.format_traceback(exc_info)) except KeyboardInterrupt: sys.stderr.write("\nqmtest: Interrupted.\n") raise except qm.platform.SignalException, se: # SIGTERM indicates a request to shut down. Other signals # should be handled earlier. if se.GetSignalNumber() != signal.SIGTERM: raise finally: # Collect garbage so that any "__del__" methods with externally # visible side-effects are executed. del qm.test.cmdline._the_qmtest gc.collect()
class Target(qm.extension.Extension): """Base class for target implementations. A 'Target' is an entity that can run tests. QMTest can spread the workload from multiple tests across multiple targets. In addition, a single target can run more that one test at once. 'Target' is an abstract class. You can extend QMTest by providing your own target class implementation. To create your own test class, you must create a Python class derived (directly or indirectly) from 'Target'. The documentation for each method of 'Target' indicates whether you must override it in your test class implementation. Some methods may be overridden, but do not need to be. You might want to override such a method to provide a more efficient implementation, but QMTest will work fine if you just use the default version.""" arguments = [ qm.fields.TextField(name="name", title="Name", description="""The name of this target. The name of the target. The target name will be recorded in any tests executed on that target so that you can see where the test was run.""", default_value=""), qm.fields.TextField( name="group", title="Group", description="""The group associated with this target. Some tests may only be able to run on some targets. A test can specify a pattern indicating the set of targets on which it will run.""", default_value="") ] kind = "target" class __ResourceSetUpException(Exception): """An exception indicating that a resource could not be set up.""" def __init__(self, resource): """Construct a new 'ResourceSetUpException'. 'resource' -- The name of the resoure that could not be set up.""" self.resource = resource def __init__(self, database, properties): """Construct a 'Target'. 'database' -- The 'Database' containing the tests that will be run. 'properties' -- A dictionary mapping strings (property names) to values.""" qm.extension.Extension.__init__(self, properties) self.__database = database #38747 self.log = logging.getLogger('nextestlog') def GetName(self): """Return the name of the target. Derived classes must not override this method.""" return self.name def GetGroup(self): """Return the group of which the target is a member. Derived classes must not override this method.""" return self.group def GetDatabase(self): """Return the 'Database' containing the tests this target will run. returns -- The 'Database' containing the tests this target will run. Derived classes must not override this method.""" return self.__database def IsIdle(self): """Return true if the target is idle. returns -- True if the target is idle. If the target is idle, additional tasks may be assigned to it. Derived classes must override this method.""" raise NotImplementedError def IsInGroup(self, group_pattern): """Returns true if this 'Target' is in a particular group. 'group_pattern' -- A string giving a regular expression. returns -- Returns true if the 'group_pattern' denotes a regular expression that matches the group for this 'Target', false otherwise.""" return re.match(group_pattern, self.GetGroup()) def Start(self, response_queue, engine=None): """Start the target. 'response_queue' -- The 'Queue' in which the results of test executions are placed. 'engine' -- The 'ExecutionEngine' that is starting the target, or 'None' if this target is being started without an 'ExecutionEngine'. Derived classes may override this method, but the overriding method must call this method at some point during its execution.""" self.__response_queue = response_queue self.__engine = engine # There are no resources available on this target yet. self.__resources = {} self.__order_of_resources = [] def Stop(self): """Stop the target. Clean up all resources that have been set up on this target and take whatever other actions are required to stop the target. Derived classes may override this method.""" # Clean up any available resources. self.__order_of_resources.reverse() for name in self.__order_of_resources: rop = self.__resources[name] if rop and rop[1] == Result.PASS: self._CleanUpResource(name, rop[0]) del self.__response_queue del self.__engine del self.__resources del self.__order_of_resources def RunTest(self, descriptor, context): """Run the test given by 'test_id'. 'descriptor' -- The 'TestDescriptor' for the test. 'context' -- The 'Context' in which to run the test. Derived classes may override this method.""" # Create the result. result = Result(Result.TEST, descriptor.GetId()) try: #38747 scm = context['nextest.scm_configuration'] # Augment the context appropriately. context = Context(context) context[context.TMPDIR_CONTEXT_PROPERTY] \ = self._GetTemporaryDirectory() context[context.DB_PATH_CONTEXT_PROPERTY] \ = descriptor.GetDatabase().GetPath() # Set up any required resources. self.__SetUpResources(descriptor, context) # Make the ID of the test available. context[context.ID_CONTEXT_PROPERTY] = descriptor.GetId() # Note the start time. result[Result.START_TIME] = qm.common.format_time_iso() # 38747 If SCM configuration is ON and the swap flag is enabled # continue the remaining tests on the backup by swapping the mysmw and bkupmsw # objects and also in /etc/hosts file. Stop the corewatcher on the master and start the # corewatcher on the backup in order to monitor for core on the backup if scm and self.__engine.swap: if context.has_key('userConfig.to_addr'): toaddr = context['userConfig.to_addr'] toaddrs = string.split(toaddr, ',') if ((toaddr == '') or (string.count(toaddr, '@') == 0)): self.log.info("ERROR : Entered to address %s is wrong,\ " % toaddr) if context.has_key('userConfig.from_addr'): fromaddr = context['userConfig.from_addr'] if ((fromaddr == '') or (string.count(fromaddr, '@') == 0)): self.log.info( "ERROR : Entered from address %s is wrong,\ " % fromaddr) if context.has_key('userConfig.mail_server'): mailserver = context['userConfig.mail_server'] if (mailserver == ''): self.log.info( "ERROR : Entered mailserver name %s is wrong,\ " % mailserver) # Added the code for ticket 34247 if context.has_key('userConfig.login'): login = context['userConfig.login'] if (login == ''): self.log.info( "ERROR : Entered login name %s is wrong,\ " % login) if context.has_key('userConfig.passwd'): passwd = context['userConfig.passwd'] if (passwd == ''): self.log.info( "ERROR : Entered passwd value %s is wrong,\ " % passwd) if ((toaddr == '') or (fromaddr == '') or (mailserver == '') or (login == '') or (passwd == '')): toaddr = None fromaddr = None mailserver = None login = None passwd = None stopOnCore = 'True' if context.has_key('userConfig.stop_on_core'): stopOnCore = context['userConfig.stop_on_core'] #if restartSCM is found in the script, then reverting back the original #/etc/hosts file and stopping the corewatcher on the bkup. Start the #corewatcher on the master to monitor the core on the master tempStr = str(descriptor.GetClass()) if tempStr.__contains__('ExecTest'): contStr = descriptor.GetItem().source else: contStr = descriptor.GetItem().testsource if contStr.__contains__('restartSCM'): self.__engine.swap = False # Restore /etc/hosts if self.__engine.hostsFile: self.__engine.hostsFile = False os.system('sudo cp /etc/hosts_scm /etc/hosts') os.system('sudo rm -rf /etc/hosts_scm') # Modify /etc/hosts only once! # Modified the /etc/hosts file to continue the remaining tests # in bkup until the iserver restart is performed during the presence # of core if self.__engine.swap: if not self.__engine.hostsFile: modifyHostsFile() self.__engine.hostsFile = True #43909 Added code to revert back the original /etc/hosts file #when core is found from active secondary MSX else: if self.__engine.revertBack: self.__engine.swap = False os.system('sudo cp /etc/hosts_scm /etc/hosts') os.system('sudo rm -rf /etc/hosts_scm') self.__engine.hostsFile = False self.__engine.bkupObj = None self.__engine.revertBack = False # Swapping the MSW and MSWInfo object during the presence of core if not self.__engine.bkupObj: self.__engine.bkupCtrl = msw.MSWInfo('mymsw') cont = {'mswinfo': self.__engine.bkupCtrl} self.__engine.bkupObj = SSH(['root@mymsw'], ctxt=cont) context['msw'] = self.__engine.bkupObj context['mswinfo'] = self.__engine.bkupCtrl # Run the test. try: # Pass on the information on whether the previous script restarted MSW or not context['msw_restart'] = self.__engine.msw_restart descriptor.Run(context, result) # 39583 - Check whether the script restarts only if H323 call has been made # msw_restart - Variable used to store previous script information # hValNotChecked - Used to indicate if the first H323 script after the iserver restart has been # executed or not tempStr = str(descriptor.GetClass()) if tempStr.__contains__('call.CallTest'): if context[ 'hValNotChecked'] or not self.__engine.msw_restart: if tempStr.__contains__('ExecTest'): contStr = descriptor.GetItem().source else: contStr = descriptor.GetItem().testsource src = contStr.lower() chk1 = src.__contains__( 'iserver all stop') or src.__contains__( 'ftest') or src.__contains__('checkiserver') chk2 = src.__contains__( 'checkscmstatus') or src.__contains__( 'restartscm') or src.__contains__( '.initialize') if chk1 or chk2: self.__engine.msw_restart = True else: self.__engine.msw_restart = False finally: # Note the end time. result[Result.END_TIME] = qm.common.format_time_iso() except KeyboardInterrupt: result.NoteException(cause="Interrupted by user.") # We received a KeyboardInterrupt, indicating that the # user would like to exit QMTest. Ask the execution # engine to stop. if self.__engine: self.__engine.RequestTermination() except qm.platform.SignalException, e: # Note the exception. result.NoteException(cause=str(e)) # If we get a SIGTERM, propagate it so that QMTest # terminates. if e.GetSignalNumber() == signal.SIGTERM: # Record the result so that the traceback is # available. self._RecordResult(result) # Ask the execution engine to stop running tests. if self.__engine: self.__engine.RequestTermination() # Re-raise the exception. raise except self.__ResourceSetUpException, e: result.SetOutcome(Result.UNTESTED) result[Result.CAUSE] = qm.message("failed resource") result[Result.RESOURCE] = e.resource
def __str__(self): """Return a string describing this exception.""" return qm.message("no such item", kind = self.kind, item_id = self.item_id)