Return a test that is ready to run. 'target' -- The 'Target' on which the test will run. returns -- the 'TestDescriptor' for the next available ready test, or 'None' if no test could be found that will run on 'target'. If a test with unsatisfied prerequisites is encountered, the test will be pushed on the stack and the prerequisites processed recursively.
00439 : """Return a test that is ready to run. 'target' -- The 'Target' on which the test will run. returns -- the 'TestDescriptor' for the next available ready test, or 'None' if no test could be found that will run on 'target'. If a test with unsatisfied prerequisites is encountered, the test will be pushed on the stack and the prerequisites processed recursively.""" while 1: if not self.__test_stack: # We ran out of prerequisite tests, so pull a new one # off the user's list. try: test_id = self.__tests_iterator.next() except StopIteration: # We're entirely out of fresh tests; give up. return None if self.__statuses[test_id].HasBeenQueued(): # This test has already been handled (probably # because it's a prereq of a test already seen). continue # Try to add the new test to the stack. if not self.__AddTestToStack(test_id): # If that failed, look for another test. continue self._Trace("Added new test %s to stack" % test_id) descriptor, prereqs = self.__test_stack[-1] # First look at the listed prereqs. if prereqs: new_test_id = prereqs.pop() # We must filter tests that are already in the process # here; if we were to do it earlier, we would be in # danger of being confused by dependency graphs like # A->B, A->C, B->C, where we can't know ahead of time # that A's dependence on C is unnecessary. if self.__statuses[new_test_id].HasBeenQueued(): # This one is already in process. This might # indicate a dependency cycle, so check for that # now. if new_test_id in self.__ids_on_stack: self._Trace("Cycle detected (%s)" % (new_test_id,)) self.__AddUntestedResult \ (new_test_id, qm.message("dependency cycle")) continue else: self.__AddTestToStack(new_test_id) continue else: # Remove the test from the stack. test_id = descriptor.GetId() del self.__ids_on_stack[test_id] self.__test_stack.pop() # Check to see if the test is already ready to run, or # has completed. The first case occurs when the test # has prerequisites that have completed after it was # placed on the stack; the second occurs when a test # is marked UNTESTED after a cycle is detected. if self.__statuses[test_id].HasBeenReady(): continue # Now check the prerequisites. prereqs = self.__GetPendingPrerequisites(descriptor) # If one of the prerequisites failed, the test will have # been marked UNTESTED. Keep looking for a runnable # test. if prereqs is None: continue # If there are prerequisites, request notification when # they have completed. if prereqs: for p in prereqs: self.__statuses[p].NoteDependant(test_id) # Keep looking for a runnable test. continue # This test is ready to run. See if it can run on # target. if not target.IsInGroup(descriptor.GetTargetGroup()): # This test can't be run on this target, but it can be # run on another target. self.__AddToTargetPatternQueue(descriptor) continue self.__statuses[descriptor.GetId()].NoteReady() return descriptor def __AddTestToStack(self, test_id):