/// <summary> /// Called by mediator to perform next action in sequence /// </summary> /// <param name="random"></param> /// <returns> /// True when there are additional sequence actions to perform /// False when performing the last action in sequence /// False in the event of an action state check failure(rollback will be performed automatically) /// </returns> public bool DoNext(DeterministicRandom random) { if (queue.Count == 0) { throw new InvalidOperationException("This sequence does not contain a next action"); } IAction next = queue.Dequeue(); //If Action is in a suitable state, perform action. //Otherwise, engage rollback. if (next.CanPerform()) { Trace.WriteLine("[Sequence] Performing Action:" + next.GetType()); next.Perform(random); } else if (rollbackAction != null && rollbackAction.CanPerform()) { Trace.WriteLine("[Sequence] Rolling Back Sequence"); rollbackAction.Perform(random); queue.Clear(); } return(queue.Count > 0); }
private void DoNextActionSequence(DeterministicRandom random, ExecutionContext currentExecution, int threadId) { currentExecution.GetSequence(random); //Synchronously Execute each action in the sequence on Execution Context. while (currentExecution.DoNext(random)) { //Wait between each action in a sequence Trace.WriteLine("[Scheduler] Pushing Frame onto Dispatcher"); DispatcherHelper.DoEvents((int)idleDuration.TotalMilliseconds, DispatcherPriority.Background); Trace.WriteLine("[Scheduler] Dispatcher queue has been executed."); } //Assess execution state for metrics reset if beyond complexity threshold, or if we've gone through test for a while. //Iteration based mechanism to compensate for memory growth in lieu of metrics if (currentExecution.IsStateBeyondConstraints()) { Trace.WriteLine("[Scheduler] Resetting State"); currentExecution.ResetState(threadId); //After resetting, this is a good time to clean house GC.Collect(); } //De-activate the random object instance for this cycle. Continued use will force-crash the test. random.Dispose(); }
public void DoWork(StabilityTestDefinition metadata, int threadId) { int iteration = 0; DateTime startTime = DateTime.Now; DateTime endTime = startTime.Add(metadata.ExecutionTime); ExecutionContext executionContext = new ExecutionContext(metadata.ExecutionContext); executionContext.ResetState(threadId); //Add a stress trace listener so we can capture traces from test and Fail events Trace.Listeners.Add(new TraceManager(threadId)); //make sure that exceptions are not caught by the dispatcher Dispatcher.CurrentDispatcher.UnhandledExceptionFilter += delegate(object sender, DispatcherUnhandledExceptionFilterEventArgs e) { e.RequestCatch = false; }; while (DateTime.Now < endTime) { Trace.WriteLine("[Scheduler] Starting Iteration:" + iteration); Trace.WriteLine(String.Format("[Scheduler] StartTime: {0}, Current Time: {1} End Time: {2} ", startTime, DateTime.Now, endTime)); //Set up the iteration's randomness DeterministicRandom random = new DeterministicRandom(metadata.RandomSeed, threadId, iteration); DoNextActionSequence(random, executionContext, threadId); Trace.WriteLine("[Scheduler] Pushing Frame onto Dispatcher"); DispatcherHelper.DoEvents((int)idleDuration.TotalMilliseconds, DispatcherPriority.Background); Trace.WriteLine("[Scheduler] Dispatcher queue has been executed."); //Visual Space for Logging readability Trace.WriteLine(""); Trace.WriteLine(""); iteration++; } Trace.WriteLine(String.Format("[Scheduler] Test is ending at {0}, after running for {1}.", endTime, metadata.ExecutionTime)); }
/// <summary> /// Attempts to generate a new sequence from ActionSequencer when no sequence is on hand. /// Will throw in presence of existing Sequence. /// </summary> /// <param name="random"></param> /// <returns>Returns true if a new sequence could be prepared. Returns false in event of failure to create sequence.</returns> public void GetSequence(DeterministicRandom random) { if (currentSequence != null) { throw new InvalidOperationException("Attempted to create a new sequence in presence of existing sequence."); } currentSequence = actionSequencer.GetNext(state, random); if (currentSequence == null) { throw new InvalidOperationException("Attempted to create a new sequence in presence of existing sequence."); } }
/// <summary> /// Performs next action in Sequence. Discards reference to sequence when end is reached. /// </summary> /// <param name="random"></param> /// <returns>Returns true if sequence has more actions to perform</returns> public bool DoNext(DeterministicRandom random) { bool hasMoreActions = false; //if current sequence is not null, do next action. if (currentSequence == null) { throw new InvalidOperationException("Attempting to execute on a null sequence."); } else { hasMoreActions = currentSequence.DoNext(random); //discard sequence reference at end of sequence if (hasMoreActions == false) { currentSequence = null; } } return(hasMoreActions); }