def acquire_resources_and_run(self, node, func, func_type=TestFunctionType.TEST):
        """
        Tries to acquire resources for a function and run it, reporting
        appropriately to the TestLogger. Takes care of returning nodes to the work
        provider if resources cannot be locked.

        :param node: The WorkNode containing the function you wish to run.
        :param func: The function you wish to execute
        :param func_type: The TestFunctionType of the function
        :return: True if the function was successfully run, False otherwise
        """
        instance = node.get_test_class_instance()

        # Check for failed execution groups
        if WorkerThread.has_failed_ex_groups(node.test_class, func, node.test_env, self.work_provider):
            self.logger.skippingTestFunction(instance, func, func_type, thread_num=self.thread_num)
            
            #AB - still want to call teardown when threads has failed
            if func_type == TestFunctionType.TEARDOWN:
                func(instance)
                node.test_class_is_torndown = True
            
            return True

        # Try to lock this function's resources
        func_resources = getattr(func, 'resources', [])
        func_resources_locked = self.work_provider.lock_resources(func_resources)
        if not func_resources_locked:
            self.work_provider.release_resources(node.class_resources)
            self.work_provider.add_nodes(node)
            return False

        # Execute the function
        self.logger.runningTestFunction(instance, func, func_type, thread_num=self.thread_num)
        try:
            func(instance)
        except:
            e = sys.exc_info()[0]
            tb = traceback.format_exc()
            self.work_provider.add_failed_ex_groups(
                WorkerThread.get_ex_groups(node.test_class, func),
                node.test_env
            )
            self.logger.foundException(instance, func, e, tb, func_type, thread_num=self.thread_num)

        #AB - additional logging options
        if instance.details != None:
            self.logger.logDetails(instance, func, instance.details, thread_num=self.thread_num)
            instance.clearLog()

        # Cleanup
        if func_type == TestFunctionType.SETUP:
            node.test_class_is_setup = True
        elif func_type == TestFunctionType.TEARDOWN:
            node.test_class_is_torndown = True
        else:
            node.test_funcs.remove(func)
        self.logger.finishedTestFunction(instance, func, func_type, thread_num=self.thread_num)
        self.work_provider.release_resources(func_resources)
        return True
    def run_tests_for_node(self, node):
        """Takes a WorkNode and runs the tests it contains. If some of the node's 
        resources are in use, the node may be returned to the work_provider."""
        # Try to get a lock on the class resources
        resources_locked = self.work_provider.lock_resources(
            node.class_resources)
        if not resources_locked:
            self.work_provider.add_nodes(node)
            return

        cls = node.test_class
        instance = node.get_test_class_instance()

        # if this node contains only one function, check for failed execution groups
        # and don't instatiate the class or call setup
        if len(node.test_funcs) == 1:
            func = node.test_funcs[0]
            if WorkerThread.has_failed_ex_groups(cls, func, node.test_env,
                                                 self.work_provider):
                self.logger.skippingTestFunction(instance,
                                                 func,
                                                 thread_num=self.thread_num)
                self.work_provider.release_resources(node.class_resources)
                return

        # Try to call the class's setup method
        if not node.test_class_is_setup:
            if hasattr(cls, 'setup') and callable(cls.setup):
                success = self.acquire_resources_and_run(
                    node, cls.setup, TestFunctionType.SETUP)
                if not success:
                    return

        # Run all the test functions
        for func in list(
                node.test_funcs
        ):  # copy the list so we don't remove items while iterating
            success = self.acquire_resources_and_run(node, func)
            if not success:
                return

        # Try to call the class's teardown method
        if not node.test_class_is_torndown:
            if hasattr(cls, 'teardown') and callable(cls.teardown):
                success = self.acquire_resources_and_run(
                    node, cls.teardown, TestFunctionType.TEARDOWN)
                if not success:
                    return

        self.work_provider.release_resources(node.class_resources)
示例#3
0
    def test_has_failed_ex_groups(self):
        wp = WorkProvider()
        env = {'env': 'env'}

        # Same class, no failed ex groups
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env,
                                              wp))
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env,
                                              wp))

        # Same class, with failed class ex groups
        wp.add_failed_ex_groups([1], env)

        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env,
                                              wp))
        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env,
                                              wp))

        # Same class, no ex groups, with wp.failed_ex_groups reset
        wp = WorkProvider()

        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env,
                                              wp))
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env,
                                              wp))

        # Same class, with one method having a failed ex_group
        wp.add_failed_ex_groups([2], env)

        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture2, Fixture2.meth1, env,
                                              wp))
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture2, Fixture2.meth2, env,
                                              wp))
示例#4
0
    def test_has_failed_ex_groups(self):
        wp = WorkProvider()
        env = { 'env': 'env' }

        # Same class, no failed ex groups
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env, wp)
        )
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env, wp)
        )

        # Same class, with failed class ex groups
        wp.add_failed_ex_groups([1], env)

        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env, wp)
        )
        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env, wp)
        )

        # Same class, no ex groups, with wp.failed_ex_groups reset
        wp = WorkProvider()

        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth1, env, wp)
        )
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture1, Fixture1.meth2, env, wp)
        )

        # Same class, with one method having a failed ex_group
        wp.add_failed_ex_groups([2], env)

        self.assertTrue(
            WorkerThread.has_failed_ex_groups(Fixture2, Fixture2.meth1, env, wp)
        )
        self.assertFalse(
            WorkerThread.has_failed_ex_groups(Fixture2, Fixture2.meth2, env, wp)
        )
    def run_tests_for_node(self, node):
        """Takes a WorkNode and runs the tests it contains. If some of the node's 
        resources are in use, the node may be returned to the work_provider."""
        # Try to get a lock on the class resources
        resources_locked = self.work_provider.lock_resources(node.class_resources)
        if not resources_locked:
            self.work_provider.add_nodes(node)
            return

        cls = node.test_class
        instance = node.get_test_class_instance()

        # if this node contains only one function, check for failed execution groups
        # and don't instatiate the class or call setup
        if len(node.test_funcs) == 1:
            func = node.test_funcs[0]
            if WorkerThread.has_failed_ex_groups(cls, func, node.test_env, self.work_provider):
                self.logger.skippingTestFunction(instance, func, thread_num=self.thread_num)
                self.work_provider.release_resources(node.class_resources)
                return

        # Try to call the class's setup method
        if not node.test_class_is_setup:
            if hasattr(cls, 'setup') and callable(cls.setup):
                success = self.acquire_resources_and_run(node, cls.setup, TestFunctionType.SETUP)
                if not success:
                    return

        # Run all the test functions
        for func in list(node.test_funcs): # copy the list so we don't remove items while iterating
            success = self.acquire_resources_and_run(node, func)
            if not success:
                return


        # Try to call the class's teardown method
        if not node.test_class_is_torndown:
            if hasattr(cls, 'teardown') and callable(cls.teardown):
                success = self.acquire_resources_and_run(node, cls.teardown, TestFunctionType.TEARDOWN)
                if not success:
                    return

        self.work_provider.release_resources(node.class_resources)
    def acquire_resources_and_run(self,
                                  node,
                                  func,
                                  func_type=TestFunctionType.TEST):
        """
        Tries to acquire resources for a function and run it, reporting
        appropriately to the TestLogger. Takes care of returning nodes to the work
        provider if resources cannot be locked.

        :param node: The WorkNode containing the function you wish to run.
        :param func: The function you wish to execute
        :param func_type: The TestFunctionType of the function
        :return: True if the function was successfully run, False otherwise
        """
        instance = node.get_test_class_instance()

        # Check for failed execution groups
        if WorkerThread.has_failed_ex_groups(node.test_class, func,
                                             node.test_env,
                                             self.work_provider):
            self.logger.skippingTestFunction(instance,
                                             func,
                                             func_type,
                                             thread_num=self.thread_num)

            #AB - still want to call teardown when threads has failed
            if func_type == TestFunctionType.TEARDOWN:
                func(instance)
                node.test_class_is_torndown = True

            return True

        # Try to lock this function's resources
        func_resources = getattr(func, 'resources', [])
        func_resources_locked = self.work_provider.lock_resources(
            func_resources)
        if not func_resources_locked:
            self.work_provider.release_resources(node.class_resources)
            self.work_provider.add_nodes(node)
            return False

        # Execute the function
        self.logger.runningTestFunction(instance,
                                        func,
                                        func_type,
                                        thread_num=self.thread_num)
        try:
            func(instance)
        except:
            e = sys.exc_info()[0]
            tb = traceback.format_exc()
            self.work_provider.add_failed_ex_groups(
                WorkerThread.get_ex_groups(node.test_class, func),
                node.test_env)
            self.logger.foundException(instance,
                                       func,
                                       e,
                                       tb,
                                       func_type,
                                       thread_num=self.thread_num)

        #AB - additional logging options
        if instance.details != None:
            self.logger.logDetails(instance,
                                   func,
                                   instance.details,
                                   thread_num=self.thread_num)
            instance.clearLog()

        # Cleanup
        if func_type == TestFunctionType.SETUP:
            node.test_class_is_setup = True
        elif func_type == TestFunctionType.TEARDOWN:
            node.test_class_is_torndown = True
        else:
            node.test_funcs.remove(func)
        self.logger.finishedTestFunction(instance,
                                         func,
                                         func_type,
                                         thread_num=self.thread_num)
        self.work_provider.release_resources(func_resources)
        return True