public async Task AwaitAlreadyEnqueuedDataTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsBegin, new StrategyOneOnOneUC()) .Register(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsEnd, new StrategyOneOnOneUC()) .Register(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC()) .Register(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC()) ; const int throttle = 3; IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle); sequencer.Run(() => Insert2Items(sequencer, notifier)); sequencer.Run(() => AwaitEnqueuedData(sequencer, notifier)); await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsBegin); //enqueue data await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsEnd); //enqueue completed Assert.AreEqual(2, notifier.Count()); await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncBegin); //begin awaiting enqueued data await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncEnd); //enqueued data should be detected await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task DoNotEnslaveAndDelayMessangerTest() { //The main difference, here as it should be used, but did not exist till .Net 4.5 TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); ISequencerUC sequencer = SequencerUC .Construct() .Register(TCS.ReceiverInitialize, new StrategyOneOnOneUC()) .Register(TCS.ReceiverRecord, new StrategyOneOnOneUC()) .Register(TCS.MessangerSetResult, new StrategyOneOnOneUC()) ; sequencer.Run(seq => Receiver(seq, tcs)); //run Receiver in own thread await sequencer.TestPointAsync(TCS.ReceiverInitialize); //receiver was running and is awaiting tcs now sequencer.Run(seq => Messanger(seq, tcs)); //run Messanger in own thread await sequencer.TestPointAsync(TCS.MessangerSetResult); //messanger SetResult executed var worker = await sequencer.TestPointAsync(TCS.ReceiverRecord); //get info about Receivers thread //Messanger was not executing code inside Receiver synchronously! Assert.AreNotEqual(worker.ProductionArg, nameof(Messanger)); await sequencer.WhenAll(); // wait for all tasks to complete Assert.DoesNotThrow(() => sequencer.TryReThrowException()); }
public async Task Insert3ItemsThrottleTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_Begin, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_A, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_B, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_C_Throttle, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_End, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem, new StrategyOneOnOneUC()) .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC()) ; const int throttle = 3; IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle); sequencer.Run(() => Insert3ItemsThrottle(sequencer, notifier)); sequencer.Run(() => AwaitDequeue3(sequencer, notifier)); IProductionPointUC prodPoint; await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_Begin); await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_A); await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_B); prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_C_Throttle); Assert.IsFalse((prodPoint?.ProductionArg as Task)?.IsCompleted); Assert.AreEqual(3, notifier.Count()); await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncBegin); prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem); Assert.AreEqual("A", prodPoint?.ProductionArg as string); //throttling should be deactivated, resuming await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_End); prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem); Assert.AreEqual("B", prodPoint?.ProductionArg as string); prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem); Assert.AreEqual("C", prodPoint?.ProductionArg as string); await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncEnd); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ThrowTest_ConditionalException_ShouldNotDetect() { ISequencerUC sequencer; await SequencerUC .Construct() .Run(xsequencer => ThrowWorker_ConditionalException(false, xsequencer)) .AssignOut(out sequencer) .WhenAll() ; sequencer.TryReThrowException(); }
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"); }
public async Task ThrowTest_DetectException() { ISequencerUC sequencer; await SequencerUC .Construct() .AssignOut(out sequencer) .Run(xsequencer => ThrowWorker_DetectException(xsequencer)) .WhenAll() ; Assert.Throws <AggregateException>(() => sequencer.TryReThrowException()); }
public async Task MultipleUnRegistrationsTest() { var tickGenerator = new TickGenerator(10); ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) ; Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; Task t = await tickGenerator.RegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); for (int i = 0; i < 10; i++) { await sequencer.TestPointAsync(Steps.Notify); } t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
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(); }
public async Task EnslaveAndDelayMessangerTest() { //The danger is hidden in using the messangers thread to run continuation, //for semaphores in messanger/receiver blocks it can easily create deadlock, //For monitor lock in messanger/receiver blocks it should mostly work well, // recursivness takes care of it. //For UI it is highly dangerous and unpredictable! //If messanger is executed from UI, it will most often execute continuation synchronously on UI. //BUT! //In certain cases TaskCompletionSource can decide to run continuation asynchronously on UI. //Same as if a delegate would not be executed directly but through BeginInvoke scheduled to queue //and executed later. //It is a breaking change to subsequent code, that might expect something will be already done before //subsequent code is executed. TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(); ISequencerUC sequencer = SequencerUC .Construct() .Register(TCS.ReceiverInitialize, new StrategyOneOnOneUC()) .Register(TCS.ReceiverRecord, new StrategyOneOnOneUC()) .Register(TCS.MessangerSetResult, new StrategyOneOnOneUC()) ; sequencer.Run(seq => Receiver(seq, tcs)); //run Receiver in its own thread await sequencer.TestPointAsync(TCS.ReceiverInitialize); //receiver was running and is now awaiting tcs.Task sequencer.Run(seq => Messanger(seq, tcs)); //run Messanger in its own thread await sequencer.TestPointAsync(TCS.MessangerSetResult); //messanger SetResult executed var worker = await sequencer.TestPointAsync(TCS.ReceiverRecord); //receiver was running and is now awaiting tcs.Task //Messanger was executing code inside Receiver synchronously! Assert.AreEqual(worker.ProductionArg, nameof(Messanger)); await sequencer.WhenAll(); // wait for all tasks to complete Assert.DoesNotThrow(() => sequencer.TryReThrowException()); }
public async Task CompletedWithoutTimoutRegisterTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(OrderedExpiryItemsSequencer.TryExpireBegin, new StrategyOneOnOneUC()) ; var timerProcessor = new TimerProcessor(10, new RealTimeSource(), sequencer); var t = await timerProcessor.RegisterAsync <object>(TimeSpan.FromMilliseconds(10000)).WrapIntoTask(); var tcs = t.Result; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); //OrderedExpiryItemsSequencer.TryExpireBegin is Match point, it wont proceed without point setting to Complete() state tcs.SetResult(null); Assert.IsTrue(tcs.Task.IsCompleted); Assert.IsFalse(tcs.Task.IsCanceled); Assert.IsFalse(tcs.Task.IsFaulted); t = await timerProcessor.UnRegisterAsync(tcs).WrapIntoTask(); var tcs2 = t.Result; Assert.AreEqual(tcs, tcs2); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); Assert.IsTrue(tcs2.Task.IsCompleted); Assert.IsFalse(tcs2.Task.IsCanceled); Assert.IsFalse(tcs2.Task.IsFaulted); }
public async Task DisposeBasicTest() { var tickGenerator = new TickGenerator(10); ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) ; Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; tickGenerator.Dispose(); Task t = await tickGenerator.Disposed.WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); Assert.ThrowsAsync <ObjectDisposedException>(async() => t = await tickGenerator.RegisterAsync(action).WrapIntoTask()); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); Assert.ThrowsAsync <ObjectDisposedException>(async() => t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask()); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task Concurrent2RegisterResultTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(TimerProcessorSequencer.RegisterStatus, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.RegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.UnRegisterStatus, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.UnRegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.Processing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ExclusiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.BeginActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.EndActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ActionsProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ActionsProcessingCount, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.TryUpdateTimerBegin, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.TryUpdateTimerEnd, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) ; var timeprocessor = new TimerProcessor(10, new RealTimeSource(), sequencer); var tt = Task.Run(() => timeprocessor.RegisterResultAsync(TimeSpan.FromMilliseconds(10000), new object()).WrapIntoTask()); var rStatus = await sequencer.TestPointAsync(TimerProcessorSequencer.RegisterStatus); Assert.AreEqual(TimerProcessorStatus.Operating, rStatus.ProductionArg); var rActiveProcesing = await sequencer.TestPointAsync(TimerProcessorSequencer.RegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesing.ProductionArg); var processing = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingResult = (TimerProcessor.ProcessingResult)processing.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingResult); var exclusiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessing.Complete(); var beginActiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessing.Complete(); var actionProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessing.Complete(); Assert.AreEqual(false, actionProcessing.ProductionArg); var updateTimerBegin = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBegin.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.None, updateTimerBegin.ProductionArg); var updateTimerEnd = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEnd.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Activate | TimerProcessorTimerStatus.IsActive | TimerProcessorTimerStatus.Changed, updateTimerEnd.ProductionArg); var endActiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessing.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessing.ProductionArg); Task <TaskCompletionSource <object> > t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); TaskCompletionSource <object> tcs = t.Result; for (int i = 0; i < 10; i++) { var callBackProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); //for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) //{ // await sequencer.TestPointAsync(Steps.Notify); //} var updateTimerBeginCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Activate | TimerProcessorTimerStatus.IsActive, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessingCycle.ProductionArg); } for (int i = 0; i < 1; i++) { //var callBackProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.CallBackProcessing); //callBackProcessing.Complete(); //var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); //var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; //Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); //var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); //exclusiveProcessingCycle.Complete(); //var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); //beginActiveProcessingCycle.Complete(); //ActiveProcessing tt = Task.Run(() => timeprocessor.UnRegisterAsync(tcs).WrapIntoTask()); var rStatusCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.UnRegisterStatus); Assert.AreEqual(TimerProcessorStatus.Operating, rStatusCycle.ProductionArg); var rActiveProcesingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.UnRegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesingCycle.ProductionArg); var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(false, actionProcessingCycle.ProductionArg); //var actionProcessingCountCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessingCount); //Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); //for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) //{ // await sequencer.TestPointAsync(Steps.Notify); //} var updateTimerBeginCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Changed, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessingCycle.ProductionArg); } t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ConcurrentSequencing() { StepConcurrentSequencing = 0; ISequencerUC sequencer = SequencerUC .Construct() .Register(ConcurrentSequencingPhase.Begin, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.EnteringSimpleLock, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.Locked, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.LockedNotify, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.End, new StrategyOneOnOneUC()) ; //StrategyOneOnOneUC each production code point(per thread) is matched to unit test point //that is per point and per thread in production code IAsyncLockUC Lock = new AsyncSpinLockUC(); //start first worker sequencer.Run(seq => ConcurrentSequencingWorker(Lock, sequencer)); //await first worker to get to Begin point var Begin1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Begin); //first worker at Begin point //start second worker sequencer.Run(seq => ConcurrentSequencingWorker(Lock, sequencer)); //await second worker to get to Begin point var Begin2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Begin); //second worker at Begin point //allow first worker to continue to Locked point Begin1.Complete(); //Begin1.Fail(new Exception("Hmmmm")); var notify1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.EnteringSimpleLock); //await first worker to get to Locked point var Locked1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Locked); Assert.AreEqual(0, Locked1.ProductionArg); //first worker at Locked point //spinlock is locked, first worker has exclusive access //allow first worker to continue to Locked point it will spin until lock get opened Begin2.Complete(); //this helps us to ensure we do not need thread waiting, //notification are in production code completed awaiters, //immediatelly executiong what is next after the await on notification, //so it is known to be actively running thread! var notify2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.EnteringSimpleLock); //second worker has entered spinlock as is spinning! //let first worker leave spin lock Locked1.Complete(); //first thread is leaving the spinlock, but before leaving step value will be recorderd //second thread is spinning to get inside //LockedNotify can be checked if the recorded step value was 1 => thread 1 inside, thread 2 attempting to get inside var LockedNotify1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.LockedNotify); Assert.AreEqual(1, LockedNotify1.ProductionArg); //this is checking concurrency correctness, as threads were highly probably active during checking //await first worker at End point var End1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.End); //first worker released spinlock End1.Complete(); //first worker done //await second worker at Locked point var Locked2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Locked); //let second worker to continue to End point Locked2.Complete(); var LockedNotify2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.LockedNotify); Assert.AreEqual(0, LockedNotify2.ProductionArg); //await second worker at the End point var End2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.End); //second worker released spinlock End2.Complete(); //second worker done await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ConcurrentTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.RegisterStatus, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.RegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.UnRegisterStatus, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.UnRegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.Processing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ExclusiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.BeginActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.EndActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ActionsProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ActionsProcessingCount, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.TryUpdateTimerBegin, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.TryUpdateTimerEnd, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) ; var tickGenerator = new TickGenerator(10, sequencer); Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; Task <Task> tt = Task.Run(() => tickGenerator.RegisterAsync(action).WrapIntoTask()); var rStatus = await sequencer.TestPointAsync(TickGeneratorSequencer.RegisterStatus); Assert.AreEqual(TickGeneratorStatus.Operating, rStatus.ProductionArg); var rActiveProcesing = await sequencer.TestPointAsync(TickGeneratorSequencer.RegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesing.ProductionArg); var processing = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingResult = (TickGenerator.ProcessingResult)processing.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingResult); var exclusiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessing.Complete(); var beginActiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessing.Complete(); var actionProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessing.Complete(); Assert.AreEqual(false, actionProcessing.ProductionArg); var updateTimerBegin = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBegin.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.None, updateTimerBegin.ProductionArg); var updateTimerEnd = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEnd.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Activate | TickGeneratorTimerStatus.IsActive | TickGeneratorTimerStatus.Changed, updateTimerEnd.ProductionArg); var endActiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessing.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessing.ProductionArg); Task t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); for (int i = 0; i < 10; i++) { var callBackProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingCycleResult = (TickGenerator.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) { await sequencer.TestPointAsync(Steps.Notify); } var updateTimerBeginCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Activate | TickGeneratorTimerStatus.IsActive, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessingCycle.ProductionArg); } for (int i = 0; i < 1; i++) { var callBackProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingCycleResult = (TickGenerator.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); //ActiveProcessing tt = Task.Run(() => tickGenerator.UnRegisterAsync(action).WrapIntoTask()); var rStatusCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.UnRegisterStatus); Assert.AreEqual(TickGeneratorStatus.Operating, rStatusCycle.ProductionArg); var rActiveProcesingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.UnRegisterActiveProcessing); Assert.AreEqual(true, rActiveProcesingCycle.ProductionArg); var actionProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) { await sequencer.TestPointAsync(Steps.Notify); } var updateTimerBeginCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Changed, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessingCycle.ProductionArg); } t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ThreadAbortDuringUnmanagedCall() { object objLock = new object(); ISequencerUC sequencer = SequencerUC .Construct() .Register(Worker.BeforeLock, new StrategyOneOnOneUC()) .Register(Worker.Locked, new StrategyOneOnOneUC()) .Register(Worker.Stuck, new StrategyOneOnOneUC()) ; sequencer.Run(seq => LockedWorker(seq, objLock)); //run 1st thread sequencer.Run(seq => LockedWorker(seq, objLock)); //run 2nd thread sequencer.Run(seq => LockedWorker(seq, objLock)); //run 3rd thread var test1 = await sequencer.TestPointAsync(Worker.BeforeLock); var test2 = await sequencer.TestPointAsync(Worker.BeforeLock); var test3 = await sequencer.TestPointAsync(Worker.BeforeLock); var th1 = test1.ProductionArg as Thread; var th2 = test2.ProductionArg as Thread; var th3 = test3.ProductionArg as Thread; //only one gets inside lock await sequencer.TestPointAsync(Worker.Locked); //and will stuck intentionally var intentionallyStuck = await sequencer.TestPointAsync(Worker.Stuck); await Task.Delay(100); await Task.Delay(100); await Task.Delay(100); await Task.Delay(100); await Task.Delay(100); await Task.Delay(100); try { Thread thread = intentionallyStuck.ProductionArg as Thread; await Task.Delay(100); thread?.Abort(); th1?.Abort(); th2?.Abort(); th3?.Abort(); while (true) { try { await Task.Delay(100); sequencer.TryReThrowException(); } catch (Exception ex) { Assert.Warn(ex.Message); } } } catch (Exception ex) { Assert.Warn(ex.Message); throw; } }