public void NoPredictionIfNotPossible() { // Arrange var workplan = WorkplanDummy.CreateBig(); bool triggered = false; var predictor = Workflow.PathPrediction(workplan); predictor.PathPrediction += (sender, args) => triggered = triggered = true; // Act var engine = Workflow.CreateEngine(workplan, new NullContext()); engine.Completed += (sender, place) => { }; engine.TransitionTriggered += (sender, transition) => { }; predictor.Monitor(engine); engine.Start(); // Assert Assert.IsFalse(triggered, "Path predictor should not have been activiated"); }
public void PredictFailureBeforeCompletion() { // Arrange var stopWatch = new Stopwatch(); var workplan = WorkplanDummy.CreateBig(); var predictor = Workflow.PathPrediction(workplan); long predictionTime = long.MaxValue; NodeClassification prediction = NodeClassification.Intermediate; predictor.PathPrediction += (sender, args) => { prediction = args.PredictedOutcome; predictionTime = stopWatch.ElapsedMilliseconds; }; var engine = Workflow.CreateEngine(workplan, new NullContext()); engine.ExecutedWorkflow.Transitions.OfType <DummyTransition>().ForEach(dt => dt.ResultOutput = -1); // Disable automatic execution // Act long completionTime = 0; var finalResult = NodeClassification.Intermediate; engine.Completed += (sender, place) => { completionTime = stopWatch.ElapsedMilliseconds; finalResult = place.Classification; }; engine.TransitionTriggered += (sender, transition) => ThreadPool.QueueUserWorkItem(ResumeAsync, transition); predictor.Monitor(engine); stopWatch.Start(); engine.Start(); // Assert while (finalResult == NodeClassification.Intermediate) { Thread.Sleep(1); // Await completion } stopWatch.Stop(); Assert.Less(predictionTime, completionTime, "Engine was completed before a prediction was published."); Assert.AreEqual(finalResult, prediction, "Predication was incorrect"); }
public void PublishPredictionAfterInterruption() { // Arrange var workplan = WorkplanDummy.CreateBig(); var predictor = Workflow.PathPrediction(workplan); NodeClassification prediction = NodeClassification.Intermediate; predictor.PathPrediction += (sender, args) => prediction = args.PredictedOutcome; // Start and pause engine in var engine = Workflow.CreateEngine(workplan, new NullContext()); var transitions = engine.ExecutedWorkflow.Transitions.OfType <DummyTransition>(); transitions.ForEach(dt => dt.ResultOutput = -1); // Disable automatic execution transitions.First().ResultOutput = 1; // Except for the first one engine.TransitionTriggered += (sender, transition) => { }; engine.Start(); // Act var snapshot = engine.Pause(); // Snapshot of the engine in a sure failure path engine.Dispose(); engine = Workflow.CreateEngine(workplan, new NullContext()); engine.Restore(snapshot); // Restore new engine from the snapshot var finalResult = NodeClassification.Intermediate; engine.Completed += (sender, place) => finalResult = place.Classification; engine.TransitionTriggered += (sender, transition) => ThreadPool.QueueUserWorkItem(ResumeAsync, transition); predictor.Monitor(engine); engine.Start(); // This should resume the engine in a failure path and directly raise the event // Assert while (finalResult == NodeClassification.Intermediate) { Thread.Sleep(1); // Await completion } Assert.AreEqual(finalResult, prediction, "Predication was incorrect"); }