public void ShouldHandleBlockingAtTheEndOfGrantedInterval() { var indicator = false; using (var master = new MasterTimeSource { Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true }) using (var timeSlave = new SlaveTimeSource(null) { Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true }) using (var timeSink = new MoreComplicatedTimeSink("A")) { // tester thread new Thread(() => { this.Trace(); timeSink.ExecuteOnDispatcherThread((ts, ti) => { this.Trace(); Assert.AreEqual(10, ti.Ticks); ts.TimeHandle.ReportBackAndBreak(TimeInterval.Empty); }); this.Trace(); // here we sleep to make sure that master won't go further Thread.Sleep(5000); this.Trace(); Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks); indicator = true; this.Trace(); timeSink.ExecuteOnDispatcherThread((ts, ti) => { this.Trace(); Assert.AreEqual(0, ti.Ticks); ts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty); }); timeSink.ExecuteOnDispatcherThread((ts, ti) => { this.Trace(); Assert.AreEqual(10, ti.Ticks); ts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty); }); }) { Name = "tester thread" }.Start(); master.RegisterSink(timeSlave); timeSlave.RegisterSink(timeSink); // just to pass the first syncpoint master.Run(1); this.Trace(); master.Run(1); this.Trace(); Assert.IsTrue(indicator); Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks); master.Run(1); Assert.AreEqual(20, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(20, timeSlave.ElapsedVirtualTime.Ticks); } }
public void ShouldHandleTwoBlockingSinks() { var indicator = false; using (var master = new MasterTimeSource { Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true }) using (var timeSlave = new SlaveTimeSource(null) { Quantum = TimeInterval.FromTicks(10), AdvanceImmediately = true }) using (var timeSinkA2 = new MoreComplicatedTimeSink("A")) using (var timeSinkB2 = new MoreComplicatedTimeSink("B")) { var ttt = new Thread(() => { Parallel( () => { timeSinkA2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(10, ti.Ticks); var timeUsed = TimeInterval.FromTicks(4); var timeLeft = ti - timeUsed; sts.TimeHandle.ReportBackAndBreak(timeLeft); }); }, () => { timeSinkB2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(10, ti.Ticks); var timeUsed = TimeInterval.FromTicks(6); var timeLeft = ti - timeUsed; sts.TimeHandle.ReportBackAndBreak(timeLeft); }); } ); // here we sleep to make sure that master won't go further this.Trace(); Thread.Sleep(5000); this.Trace(); Assert.AreEqual(4, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(4, timeSlave.ElapsedVirtualTime.Ticks); Parallel( () => { timeSinkA2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(6, ti.Ticks); var timeUsed = TimeInterval.FromTicks(4); var timeLeft = ti - timeUsed; sts.TimeHandle.ReportBackAndBreak(timeLeft); }); }, () => { timeSinkB2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(4, ti.Ticks); sts.TimeHandle.ReportBackAndBreak(ti); }); } ); // here we sleep to make sure that master won't go further this.Trace(); Thread.Sleep(5000); this.Trace(); Assert.AreEqual(6, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(6, timeSlave.ElapsedVirtualTime.Ticks); Parallel( () => { timeSinkA2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(2, ti.Ticks); sts.TimeHandle.ReportBackAndBreak(ti); }); }, () => { timeSinkB2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(4, ti.Ticks); sts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty); }); } ); // here we sleep to make sure that master won't go further this.Trace(); Thread.Sleep(5000); this.Trace(); Assert.AreEqual(8, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(8, timeSlave.ElapsedVirtualTime.Ticks); Parallel( () => { timeSinkA2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.AreEqual(2, ti.Ticks); indicator = true; sts.TimeHandle.ReportBackAndContinue(TimeInterval.Empty); }); }, () => { timeSinkB2.ExecuteOnDispatcherThread((sts, ti) => { this.Trace(); Assert.Fail(); }, false); // do not wait for finish Thread.Sleep(10000); // wait for 10s and check if Fail() is called } ); }) { Name = "tester thread" }; ttt.Start(); master.RegisterSink(timeSlave); timeSlave.RegisterSink(timeSinkA2); timeSlave.RegisterSink(timeSinkB2); // just to pass the first syncpoint master.Run(1); master.Run(1); Assert.IsTrue(indicator); this.Trace(); Assert.AreEqual(10, master.ElapsedVirtualTime.Ticks); Assert.AreEqual(10, timeSlave.ElapsedVirtualTime.Ticks); ttt.Join(); } }