public void StartStopOrderingTest() { // Run test for a range of scheduler thread counts, including 1. This prevents the // output from appearing in the correct order by fluke due to concurrent scheduling. for (int maxThreads = Environment.ProcessorCount * 2; maxThreads > 0; maxThreads >>= 1) { var cLog = new ConcurrentQueue <string>(); using (var p = Pipeline.Create("P", null, maxThreads)) { var a = new TestSourceComponent(p, "A", cLog); var b = new TestSourceComponent(p, "B", cLog); var c = new TestSourceComponent(p, "C", cLog); a.Emitter.Do(m => cLog.Enqueue(m)); b.Emitter.Do(m => cLog.Enqueue(m)); c.Emitter.Do(m => cLog.Enqueue(m)); Generators.Repeat(p, "PGen", 10, TimeSpan.FromTicks(1)).Do(m => cLog.Enqueue(m)); p.Run(); } var log = cLog.ToList(); log.ForEach(m => Console.WriteLine(m)); // all components should have started Assert.IsTrue(log.Contains("AStart")); Assert.IsTrue(log.Contains("BStart")); Assert.IsTrue(log.Contains("CStart")); // messages should only be delivered after all components have started int latestStartIndex = new[] { log.IndexOf("AStart"), log.IndexOf("BStart"), log.IndexOf("CStart") }.Max(); Assert.IsTrue(latestStartIndex < log.IndexOf("APostFromStart")); Assert.IsTrue(latestStartIndex < log.IndexOf("BPostFromStart")); Assert.IsTrue(latestStartIndex < log.IndexOf("CPostFromStart")); Assert.IsTrue(latestStartIndex < log.IndexOf("PGen")); // all components should be stopped after they were started Assert.IsTrue(log.IndexOf("AStart") < log.IndexOf("AStop")); Assert.IsTrue(log.IndexOf("BStart") < log.IndexOf("BStop")); Assert.IsTrue(log.IndexOf("CStart") < log.IndexOf("CStop")); } }
public void StartStopOrderingTestWithSubpipelines() { // Run test for a range of scheduler thread counts, including 1. This prevents the // output from appearing in the correct order by fluke due to concurrent scheduling. for (int maxThreads = Environment.ProcessorCount * 2; maxThreads > 0; maxThreads >>= 1) { var cLog = new ConcurrentQueue <string>(); using (var p = Pipeline.Create("P", null, maxThreads)) using (var q = Subpipeline.Create(p, "Q")) using (var r = Subpipeline.Create(q, "R")) { var a = new TestSourceComponent(p, "A", cLog); var b = new TestSourceComponent(p, "B", cLog); var c = new TestSourceComponent(p, "C", cLog); var d = new TestSourceComponent(q, "D", cLog); var e = new TestSourceComponent(q, "E", cLog); var f = new TestSourceComponent(q, "F", cLog); var g = new TestSourceComponent(r, "G", cLog); var h = new TestSourceComponent(r, "H", cLog); var i = new TestSourceComponent(r, "I", cLog); a.Emitter.Do(m => cLog.Enqueue(m)); b.Emitter.Do(m => cLog.Enqueue(m)); c.Emitter.Do(m => cLog.Enqueue(m)); d.Emitter.Do(m => cLog.Enqueue(m)); e.Emitter.Do(m => cLog.Enqueue(m)); f.Emitter.Do(m => cLog.Enqueue(m)); g.Emitter.Do(m => cLog.Enqueue(m)); h.Emitter.Do(m => cLog.Enqueue(m)); i.Emitter.Do(m => cLog.Enqueue(m)); Generators.Repeat(p, "PGen", 10, TimeSpan.FromTicks(1)).Do(m => cLog.Enqueue(m)); Generators.Repeat(q, "QGen", 10, TimeSpan.FromTicks(1)).Do(m => cLog.Enqueue(m)); Generators.Repeat(r, "RGen", 10, TimeSpan.FromTicks(1)).Do(m => cLog.Enqueue(m)); p.Run(); } var log = cLog.ToList(); log.ForEach(m => Console.WriteLine(m)); // all components should have started Assert.IsTrue(log.Contains("AStart")); Assert.IsTrue(log.Contains("BStart")); Assert.IsTrue(log.Contains("CStart")); Assert.IsTrue(log.Contains("DStart")); Assert.IsTrue(log.Contains("EStart")); Assert.IsTrue(log.Contains("FStart")); Assert.IsTrue(log.Contains("GStart")); Assert.IsTrue(log.Contains("HStart")); Assert.IsTrue(log.Contains("IStart")); int pLatestStartIndex = new[] { log.IndexOf("AStart"), log.IndexOf("BStart"), log.IndexOf("CStart") }.Max(); int qLatestStartIndex = new[] { log.IndexOf("DStart"), log.IndexOf("EStart"), log.IndexOf("FStart") }.Max(); int rLatestStartIndex = new[] { log.IndexOf("GStart"), log.IndexOf("HStart"), log.IndexOf("IStart") }.Max(); // messages should only be delivered after all components have started within their respective pipelines Assert.IsTrue(pLatestStartIndex < log.IndexOf("APostFromStart")); Assert.IsTrue(pLatestStartIndex < log.IndexOf("BPostFromStart")); Assert.IsTrue(pLatestStartIndex < log.IndexOf("CPostFromStart")); Assert.IsTrue(pLatestStartIndex < log.IndexOf("PGen")); Assert.IsTrue(qLatestStartIndex < log.IndexOf("DPostFromStart")); Assert.IsTrue(qLatestStartIndex < log.IndexOf("EPostFromStart")); Assert.IsTrue(qLatestStartIndex < log.IndexOf("FPostFromStart")); Assert.IsTrue(qLatestStartIndex < log.IndexOf("QGen")); Assert.IsTrue(rLatestStartIndex < log.IndexOf("GPostFromStart")); Assert.IsTrue(rLatestStartIndex < log.IndexOf("HPostFromStart")); Assert.IsTrue(rLatestStartIndex < log.IndexOf("IPostFromStart")); Assert.IsTrue(rLatestStartIndex < log.IndexOf("RGen")); // all components should be stopped after they were started Assert.IsTrue(log.IndexOf("AStart") < log.IndexOf("AStop")); Assert.IsTrue(log.IndexOf("BStart") < log.IndexOf("BStop")); Assert.IsTrue(log.IndexOf("CStart") < log.IndexOf("CStop")); Assert.IsTrue(log.IndexOf("DStart") < log.IndexOf("DStop")); Assert.IsTrue(log.IndexOf("EStart") < log.IndexOf("EStop")); Assert.IsTrue(log.IndexOf("FStart") < log.IndexOf("FStop")); Assert.IsTrue(log.IndexOf("GStart") < log.IndexOf("GStop")); Assert.IsTrue(log.IndexOf("HStart") < log.IndexOf("HStop")); Assert.IsTrue(log.IndexOf("IStart") < log.IndexOf("IStop")); } }