public async Task Cancelling_AllEventsFor() { TimeSpan overheadDelay = TimeSpan.FromMilliseconds(100); TimeSpan oneSecondDelay = TimeSpan.FromSeconds(1); TimeSpan threeSecondsTimeSpan = TimeSpan.FromSeconds(3); const uint anyRequestorId = 100u; const uint anyOtherRequestorId = 200u; const int ExpectedCounterValueBeforeRun = 0; const int ExpectedCounterValueAfterRun = 1; const int ExpectedCounterValueBeforeSecondRun = 1; const int ExpectedCounterValueAfterSecondRun = 2; var scheduledEventFiredCounter = 0; Mock <BaseEvent> bEventMock1 = new Mock <BaseEvent>(anyRequestorId); Mock <BaseEvent> bEventMock2 = new Mock <BaseEvent>(anyRequestorId); Mock <BaseEvent> bEventMock3 = new Mock <BaseEvent>(anyOtherRequestorId); Mock <BaseEvent> bEventMockUncancellable = new Mock <BaseEvent>(anyRequestorId); ConcreteMockedEvent testConcreteEvent = new ConcreteMockedEvent(anyRequestorId, true); bEventMock1.SetupGet(e => e.CanBeCancelled).Returns(true); bEventMock2.SetupGet(e => e.CanBeCancelled).Returns(true); bEventMock3.SetupGet(e => e.CanBeCancelled).Returns(true); bEventMockUncancellable.SetupGet(e => e.CanBeCancelled).Returns(false); Scheduler scheduler = this.SetupSchedulerWithLoggerMock(); using CancellationTokenSource cts = new CancellationTokenSource(); scheduler.EventFired += (sender, eventArgs) => { // test that sender is the same scheduler instance, while we're here. Assert.AreEqual(scheduler, sender, "Test missconfigured, sender is not the the supposed one."); // check that event has a reference. Assert.IsNotNull(eventArgs?.Event, "Expected to have a non-null reference in event."); scheduledEventFiredCounter++; }; // start the scheduler. Task schedulerTask = scheduler.RunAsync(cts.Token); // fire a scheduled event that shall be fired only after one second. scheduler.ScheduleEvent(bEventMock1.Object, oneSecondDelay); scheduler.ScheduleEvent(bEventMock2.Object, oneSecondDelay); scheduler.ScheduleEvent(bEventMock3.Object, oneSecondDelay); // delay for 100 ms (to account for setup overhead and multi threading) and check that the counter has NOT gone up for scheduled await Task.Delay(overheadDelay).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueBeforeRun, scheduledEventFiredCounter, $"Expected scheduler's events counter {scheduledEventFiredCounter} to match {ExpectedCounterValueBeforeRun} before the first run."); }); // cancel this event. scheduler.CancelAllFor(anyRequestorId); // delay for three seconds and check that the counter has NOT gone up for scheduled. await Task.Delay(threeSecondsTimeSpan).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueAfterRun, scheduledEventFiredCounter, $"Expected scheduler's events counter {scheduledEventFiredCounter} to match {ExpectedCounterValueAfterRun} after the first run."); }); scheduler.ScheduleEvent(bEventMockUncancellable.Object, oneSecondDelay); scheduler.ScheduleEvent(testConcreteEvent, oneSecondDelay); // delay for 100 ms (to account for setup overhead and multi threading) and check that the counter has NOT gone up for scheduled await Task.Delay(overheadDelay).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueBeforeSecondRun, scheduledEventFiredCounter, $"Expected scheduler's events counter {scheduledEventFiredCounter} to match {ExpectedCounterValueBeforeSecondRun} before the second run."); }); // cancel only the concrete implementation event. scheduler.CancelAllFor(anyRequestorId, typeof(ConcreteMockedEvent)); // delay for three seconds and check that the time for execution has passed. await Task.Delay(threeSecondsTimeSpan).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueAfterSecondRun, scheduledEventFiredCounter, $"Expected scheduler's events counter {scheduledEventFiredCounter} to match {ExpectedCounterValueAfterSecondRun} after the second run."); }); }
public async Task Event_Expedition_Works() { const uint RequestorId = 1; const int ExpectedCounterValueBeforeRun = 0; const int ExpectedCounterValueAfterRun = 1; const int ExpectedCounterValueAfterWaitingMore = 1; const int ExpectedCounterValueAfterWaitingEvenMore = 2; TimeSpan overheadDelay = TimeSpan.FromMilliseconds(100); TimeSpan twoSecondsTimeSpan = TimeSpan.FromSeconds(2); TimeSpan threeSecondsTimeSpan = TimeSpan.FromSeconds(3); TimeSpan fiveSecondsTimeSpan = TimeSpan.FromSeconds(5); var scheduledEventFiredCounter = 0; Mock <BaseEvent> bEventMockForScheduled = new Mock <BaseEvent>(RequestorId); ConcreteMockedEvent testConcreteEvent = new ConcreteMockedEvent(RequestorId, true); Scheduler scheduler = this.SetupSchedulerWithLoggerMock(); using CancellationTokenSource cts = new CancellationTokenSource(); scheduler.EventFired += (sender, eventArgs) => { // test that sender is the same scheduler instance, while we're here. Assert.AreEqual(scheduler, sender); // check that event has a reference. Assert.IsNotNull(eventArgs?.Event); scheduledEventFiredCounter++; }; // start the scheduler. Task schedulerTask = scheduler.RunAsync(cts.Token); // fire a scheduled event that shall be fired only after some seconds. scheduler.ScheduleEvent(bEventMockForScheduled.Object, fiveSecondsTimeSpan); scheduler.ScheduleEvent(testConcreteEvent, threeSecondsTimeSpan); // delay for 100 ms (to account for setup overhead and multi threading) and check that the counter has NOT gone up for scheduled await Task.Delay(overheadDelay).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueBeforeRun, scheduledEventFiredCounter, $"Expected events counter to be {ExpectedCounterValueBeforeRun} before first run but got {scheduledEventFiredCounter}."); }); // expedite this event. var expedited = testConcreteEvent.Expedite(); Assert.IsTrue(expedited, "Expected event to confirm being expedited."); // delay for two seconds and check that the counter has gone up for scheduled, meaning the event actually got expedited. await Task.Delay(twoSecondsTimeSpan).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueAfterRun, scheduledEventFiredCounter, $"Expected events counter to be {ExpectedCounterValueAfterRun} after first run but got {scheduledEventFiredCounter}."); }); // delay for two more seconds and check that the counter has gone NOT up, meaning the event didn't run again. await Task.Delay(twoSecondsTimeSpan).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueAfterWaitingMore, scheduledEventFiredCounter, $"Expected events counter to be {ExpectedCounterValueAfterRun} after waiting more but got {scheduledEventFiredCounter}."); }); // delay for two more seconds and check that the counter has gone up, since the original 5 second event finally ran. await Task.Delay(twoSecondsTimeSpan).ContinueWith(prev => { Assert.AreEqual(ExpectedCounterValueAfterWaitingEvenMore, scheduledEventFiredCounter, $"Expected events counter to be {ExpectedCounterValueAfterWaitingEvenMore} after waiting even more but got {scheduledEventFiredCounter}."); }); }