public void ExerciserMethodsAreCalledInCorrectOrder() { const int expectedUnitsOfWork = 10; const int countThreads = 5; ConcurrentBag <DateTime> setupTimes = null; ConcurrentBag <DateTime> beforeUOWTimes = null; ConcurrentBag <DateTime> uowTimes = null; ConcurrentBag <DateTime> afterUowTimes = null; ConcurrentBag <DateTime> teardownTimes = null; var iterativeExerciser = IterativeExerciser.Create() .UsingThreads(countThreads) .PerformUnitOfWorkNTimes(expectedUnitsOfWork) .DoThisToSetup(() => { setupTimes.Add(DateTime.Now); Thread.Sleep(50); }) .DoThisBeforeEachUnitOfWork(() => { beforeUOWTimes.Add(DateTime.Now); Thread.Sleep(10); }) .DoThisUnitOfWork(() => uowTimes.Add(DateTime.Now)) .DoThisAfterEachUnitOfWork(() => { Thread.Sleep(10); afterUowTimes.Add(DateTime.Now); }) .DoThisToTearDown(() => { Thread.Sleep(50); teardownTimes.Add(DateTime.Now); }); var workQueueExerciser = WorkQueueExerciser.Create() .UsingThreads(countThreads) .WithWorkQueueSize(expectedUnitsOfWork) .DoThisToSetup(() => { setupTimes.Add(DateTime.Now); Thread.Sleep(50); }) .DoThisBeforeEachUnitOfWork(() => { beforeUOWTimes.Add(DateTime.Now); Thread.Sleep(10); }) .DoThisUnitOfWork(() => uowTimes.Add(DateTime.Now)) .DoThisAfterEachUnitOfWork(() => { Thread.Sleep(10); afterUowTimes.Add(DateTime.Now); }) .DoThisToTearDown(() => { Thread.Sleep(50); teardownTimes.Add(DateTime.Now); }); var throughputExerciser = ThroughputExerciser.Create() .UsingThreads(countThreads) .ForDuration(100) .DoThisToSetup(() => { setupTimes.Add(DateTime.Now); Thread.Sleep(50); }) .DoThisBeforeEachUnitOfWork(() => { beforeUOWTimes.Add(DateTime.Now); Thread.Sleep(10); }) .DoThisUnitOfWork(() => uowTimes.Add(DateTime.Now)) .DoThisAfterEachUnitOfWork(() => { Thread.Sleep(10); afterUowTimes.Add(DateTime.Now); }) .DoThisToTearDown(() => { Thread.Sleep(50); teardownTimes.Add(DateTime.Now); }); foreach (var exerciser in new Exerciser[] { iterativeExerciser, workQueueExerciser, throughputExerciser }) { setupTimes = new ConcurrentBag <DateTime>(); beforeUOWTimes = new ConcurrentBag <DateTime>(); uowTimes = new ConcurrentBag <DateTime>(); afterUowTimes = new ConcurrentBag <DateTime>(); teardownTimes = new ConcurrentBag <DateTime>(); var exerciserResult = exerciser.ExecAll(); NrAssert.Multiple( () => Assert.Greater(beforeUOWTimes.Min(), setupTimes.Max(), $"{exerciser.GetType().FullName} BeforeUOW detected before end of Setup"), () => Assert.Greater(uowTimes.Min(), beforeUOWTimes.Min(), $"{exerciser.GetType().FullName} UOW detected before end of BeforeUOW"), () => Assert.Greater(afterUowTimes.Max(), uowTimes.Max(), $"{exerciser.GetType().FullName} AfterUOW detected before end of UOW"), () => Assert.Greater(teardownTimes.Min(), afterUowTimes.Max(), $"{exerciser.GetType().FullName} Terdown detected before end of AfterUOW")); } }
public void UnitOfWorkVariablesAreBeingCapturedCorrectly() { const int expectedUnitsOfWork = 100; const int countThreads = 5; //Update counters based on the global or local counter //later we will check to make sure that they are all set to 1 ConcurrentDictionary <int, ConcurrentDictionary <int, int[]> > localCounters = null; ConcurrentDictionary <int, int[]> globalResultCounters = null; var iterativeExerciser = IterativeExerciser.Create() .UsingThreads(countThreads) .PerformUnitOfWorkNTimes(expectedUnitsOfWork) .DoThisBeforeEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[0]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[0]); }) .DoThisUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[1]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[1]); }) .DoThisAfterEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[2]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[2]); }); var workQueueExerciser = WorkQueueExerciser.Create() .UsingThreads(countThreads) .WithWorkQueueSize(expectedUnitsOfWork) .DoThisBeforeEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[0]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[0]); }) .DoThisUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[1]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[1]); }) .DoThisAfterEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[2]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[2]); }); var throughputExerciser = ThroughputExerciser.Create() .UsingThreads(countThreads) .ForDuration(100) .DoThisBeforeEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[0]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[0]); }) .DoThisUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[1]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[1]); }) .DoThisAfterEachUnitOfWork((threadId, uowIdLocal, uowIdGlobal) => { Interlocked.Increment(ref localCounters[threadId].GetOrAdd(uowIdLocal, new int[3])[2]); Interlocked.Increment(ref globalResultCounters.GetOrAdd(uowIdGlobal, new int[3])[2]); }); foreach (var exerciser in new Exerciser[] { iterativeExerciser, workQueueExerciser, throughputExerciser }) { localCounters = new ConcurrentDictionary <int, ConcurrentDictionary <int, int[]> >(); globalResultCounters = new ConcurrentDictionary <int, int[]>(); foreach (var thread in localCounters) { foreach (var uow in thread.Value) { NrAssert.Multiple( () => Assert.AreEqual(1, uow.Value[0], $"{exerciser.GetType().FullName}, threadID: {thread.Key}, uowIdLocal: {uow.Key}, BeforeUOW"), () => Assert.AreEqual(1, uow.Value[1], $"{exerciser.GetType().FullName}, threadID: {thread.Key}, uowIdLocal: {uow.Key}, TheUOW"), () => Assert.AreEqual(1, uow.Value[2], $"{exerciser.GetType().FullName}, threadID: {thread.Key}, uowIdLocal: {uow.Key}, AfterUOW")); } } foreach (var uow in globalResultCounters) { NrAssert.Multiple( () => Assert.AreEqual(1, uow.Value[0], $"{exerciser.GetType().FullName}, uowIdGlobal {uow.Key}, BeforeUOW"), () => Assert.AreEqual(1, uow.Value[1], $"{exerciser.GetType().FullName}, uowIdGlobal {uow.Key}, TheUOW"), () => Assert.AreEqual(1, uow.Value[2], $"{exerciser.GetType().FullName}, uowIdGlobal {uow.Key}, AfterUOW")); } } }