TestPointFailAsync <TEnum>(this ISequencerUC sequencer, TEnum registration, Exception ex = null) where TEnum : struct { IProductionPointUC prodPoint = await sequencer.TestPointAsync(registration); prodPoint?.Fail(ex); return(prodPoint); }
TestPointCompleteAsync <TEnum>(this ISequencerUC sequencer, TEnum registration, object testArg = null, SeqContinuationUC context = SeqContinuationUC.OnCapturedContext) where TEnum : struct { IProductionPointUC prodPoint = await sequencer.TestPointAsync(registration); prodPoint?.Complete(testArg, context); return(prodPoint); }
public void Complete(IProductionPointUC productionPoint = null) { if (Interlocked.CompareExchange(ref _completed, 1, 0) == 0) //allow completion only once { SetCompletion(productionPoint); return; } Exception ex = new InvalidOperationException($"{nameof(TestPointUC)}: Calling {nameof(Complete)} or {nameof(Fail)} multiple times!"); ExceptionRegister?.RegisterException(ex); throw ex; }
public async Task TestAB() { //create sequencer ISequencerUC sequencer = SequencerUC.Construct(); //create production code ProductionCode worker = new ProductionCode(sequencer); //register production code sequencer event spots //strategy, one production code event is translated to one unit test code event sequencer .Register(ProductionCode.SequencingEnumTest.SpotBegin, new StrategyOneOnOneUC()) .Register(ProductionCode.SequencingEnumTest.SpotEnd, new StrategyOneOnOneUC()) ; //start concurrent tasks Task.Run(() => { worker.Worker("A"); }); Task.Run(() => { worker.Worker("B"); }); //await two production code events IProductionPointUC taskWorkerBegin1 = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotBegin); IProductionPointUC taskWorkerBegin2 = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotBegin); IProductionPointUC taskWorkerBeginA; IProductionPointUC taskWorkerBeginB; //detect which event is which taskWorkerBeginA = (string)taskWorkerBegin1.ProductionArg == "A" ? taskWorkerBegin1 : null; taskWorkerBeginA = (string)taskWorkerBegin2.ProductionArg == "A" ? taskWorkerBegin2 : taskWorkerBeginA; //detect which event is which taskWorkerBeginB = (string)taskWorkerBegin1.ProductionArg == "B" ? taskWorkerBegin1 : null; taskWorkerBeginB = (string)taskWorkerBegin2.ProductionArg == "B" ? taskWorkerBegin2 : taskWorkerBeginB; //decide about the order of execution taskWorkerBeginA.Complete("A runs first"); //await A to run to SpotB IProductionPointUC taskWorkerEndA = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotEnd); //decide about the order of execution taskWorkerBeginB.Complete("B runs second"); IProductionPointUC taskWorkerEndB = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotEnd); taskWorkerEndA.Complete("A continue"); taskWorkerEndB.Complete("B continue"); }
TestPoint(ISequencerTaskRegister taskRegister, ISequencerExceptionRegister exceptionRegister) { TestPointUC testPoint = new TestPointUC(taskRegister, exceptionRegister); IProductionPointUC productionMatch = null; ITestPointUC testMatch = null; using (Lock.Enter()) { TestPointQueue.Enqueue(testPoint); if (ProductionPointQueue.Count > 0 && TestPointQueue.Count > 0) { productionMatch = ProductionPointQueue.Dequeue(); testMatch = TestPointQueue.Dequeue(); } } testMatch?.Complete(productionMatch); return(testPoint); }
public async Task AwaitAheadOfDataTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(AwaitAheadOfDataEnum.Enqueue2ItemsBegin, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.Enqueue2ItemsA, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.Enqueue2ItemsEnd, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncAwaiting, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC()) ; const int throttle = 3; IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle); sequencer.Run(() => Enque2Items(sequencer, notifier)); sequencer.Run(() => AwaitAhedOfData(sequencer, notifier)); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncBegin); IProductionPointUC point = await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncAwaiting); Task t = point.ProductionArg as Task; Assert.IsFalse(t?.IsCompleted); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsBegin); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsA); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncEnd); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsEnd); Assert.AreEqual(1, notifier.Count()); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
ProductionPoint(ISequencerTaskRegister taskRegister, ISequencerExceptionRegister exceptionRegister, SeqPointTypeUC seqPointTypeUC, object arg = null, Action <object> injectContinuation = null) { ProductionPointUC productionPoint = new ProductionPointUC(taskRegister, exceptionRegister, seqPointTypeUC, arg, injectContinuation); IProductionPointUC productionMatch = null; ITestPointUC testMatch = null; using (Lock.Enter()) { ProductionPointQueue.Enqueue(productionPoint); if (ProductionPointQueue.Count > 0 && TestPointQueue.Count > 0) { productionMatch = ProductionPointQueue.Dequeue(); testMatch = TestPointQueue.Dequeue(); } } testMatch?.Complete(productionMatch); return(productionPoint); }