public void ProducerConsumer_FastProducer_SlowConsumer() { channel <int> sut = new channel <int>(2); bool producerCalled = false; Task producer = Task.Run(() => { sut.Send(1); sut.Send(2); sut.Send(3); producerCalled = true; }); bool consumerCalled = false; List <int> items = new List <int>(); Task consumer = Task.Run(async() => { await Task.Delay(m_slowActionLatency); items.Add(sut.Receive()); await Task.Delay(m_slowActionLatency); items.Add(sut.Receive()); await Task.Delay(m_slowActionLatency); items.Add(sut.Receive()); consumerCalled = true; }); Task.WaitAll(producer, consumer); Assert.AreEqual(0, sut.Length); Assert.IsTrue(producerCalled); Assert.IsTrue(consumerCalled); CollectionAssert.AreEquivalent(new[] { 1, 2, 3 }, items.ToArray()); }
public void SendMany_ReceiveFew_SendShouldBeBlocked() { channel <int> sut = new channel <int>(2); bool? called = null; Task producer = Task.Run(() => { sut.Send(1); sut.Send(2); sut.Send(3); sut.Send(4); sut.Send(5); called = false; sut.Send(6); called = true; }); List <int> items = new List <int> { sut.Receive(), sut.Receive(), sut.Receive() }; producer.Wait(m_awaitTimeout); Assert.AreEqual(2, sut.Length); Assert.IsFalse(called.GetValueOrDefault()); CollectionAssert.AreEquivalent(new[] { 1, 2, 3 }, items.ToArray()); }
public void Receive_FromNonEmptyChan_ShouldNotBeBlocked() { channel <int> sut = new channel <int>(2); sut.Send(1); sut.Send(2); int item1 = sut.Receive(); int item2 = sut.Receive(); Assert.AreEqual(0, sut.Length); Assert.AreEqual(1, item1); Assert.AreEqual(2, item2); }
public void Receive_RaceCondition_OnlyOneCanGetTheSentItemEachTime() { channel <int> chan = new channel <int>(1); ConcurrentBag <int> items = new ConcurrentBag <int>(); Task receiver1 = Task.Run(() => items.Add(chan.Receive())); Task receiver2 = Task.Run(() => items.Add(chan.Receive())); Task receiver3 = Task.Run(() => items.Add(chan.Receive())); Thread.Sleep(m_slowActionLatency); chan.Send(1); Task.WaitAll(new[] { receiver1, receiver2, receiver3 }, m_awaitTimeout); CollectionAssert.AreEquivalent(new[] { 1 }, items.ToArray()); }
public void ProducerConsumer_MoreThanChanSize() { channel <int> sut = new channel <int>(2); bool producerCalled = false; int totalItemCount = 100; Task producer = Task.Run(() => { for (int i = 1; i <= totalItemCount; i++) { sut.Send(i); } producerCalled = true; }); bool consumerCalled = false; List <int> items = new List <int>(); Task consumer = Task.Run(() => { for (int i = 1; i <= totalItemCount; i++) { items.Add(sut.Receive()); } consumerCalled = true; }); Task.WaitAll(producer, consumer); Assert.AreEqual(0, sut.Length); Assert.IsTrue(producerCalled); Assert.IsTrue(consumerCalled); CollectionAssert.AreEquivalent(Enumerable.Range(1, totalItemCount).ToArray(), items.ToArray()); }
public void Receive_ShouldBeBlocked_IfNoOneSend() { channel <int> chan = new channel <int>(1); bool called = false; Task task = Task.Run(() => { chan.Receive(); called = true; }); task.Wait(m_awaitTimeout); Assert.IsFalse(called); }
public void Receive_NoSend_NoBufferedChan_ShouldBlock() { channel <int> sut = new channel <int>(1); bool called = false; Task receiver = Task.Run(() => { sut.Receive(); called = true; }); receiver.Wait(m_awaitTimeout); Assert.IsFalse(called); }
public void Receive_FromEmptyChan_ReceiveShouldBeBlocked() { channel <int> sut = new channel <int>(2); bool called = false; Task producer = Task.Run(() => { _ = sut.Receive(); called = true; }); producer.Wait(m_awaitTimeout); Assert.AreEqual(0, sut.Length); Assert.IsFalse(called); }
public void SendFew_ReceiveMany_ReceiveShouldBeBlocked() { channel <int> sut = new channel <int>(2); sut.Send(1); sut.Send(2); bool? called = null; List <int> items = new List <int>(); Task consumer = Task.Run(() => { items.Add(sut.Receive()); items.Add(sut.Receive()); called = false; items.Add(sut.Receive()); called = true; }); consumer.Wait(m_awaitTimeout); Assert.AreEqual(0, sut.Length); Assert.IsFalse(called.GetValueOrDefault()); CollectionAssert.AreEquivalent(new[] { 1, 2 }, items.ToArray()); }
public void Receive_ShouldGetTheSameObjectThatSenderSent() { channel <object> chan = new channel <object>(1); object item = new object(); Task receiver = Task.Run(() => { Thread.Sleep(m_slowActionLatency); chan.Send(item); }); object result = chan.Receive(); receiver.Wait(); Assert.AreSame(item, result); }
public void Receive_RaceCondition_OneItemIsReceivedOnlyOnce() { channel <int> chan = new channel <int>(1); ConcurrentBag <int> items = new ConcurrentBag <int>(); int[] samples = Enumerable.Range(0, 3).ToArray(); Task[] receivers = samples.Select(i => { return(Task.Run(() => items.Add(chan.Receive()))); }).ToArray(); Thread.Sleep((int)m_slowActionLatency.TotalMilliseconds); foreach (int i in samples) { chan.Send(i); } Task.WaitAll(receivers); CollectionAssert.AreEquivalent(samples, items.ToArray()); }
public void Receive_ShouldNotBeBlocked_OnceOneSend() { channel <int> chan = new channel <int>(1); bool called = false; int item = 0; Task receiver = Task.Run(() => { item = chan.Receive(); called = true; }); Thread.Sleep(m_slowActionLatency); chan.Send(1); // Make sure Receive() is called before Send() receiver.Wait(); Assert.AreEqual(1, item); Assert.IsTrue(called); }
public void ProducerConsumer_MultipleProducers_MultipleConsumers() { channel <int> sut = new channel <int>(2); bool producer1Called = false; Task producer1 = Task.Run(() => { sut.Send(1); sut.Send(2); sut.Send(3); producer1Called = true; }); bool producer2Called = false; Task producer2 = Task.Run(() => { sut.Send(4); sut.Send(5); sut.Send(6); producer2Called = true; }); ConcurrentBag <int> items = new ConcurrentBag <int>(); bool consumer1Called = false; Task consumer1 = Task.Run(() => { items.Add(sut.Receive()); items.Add(sut.Receive()); items.Add(sut.Receive()); consumer1Called = true; }); bool consumer2Called = false; Task consumer2 = Task.Run(() => { items.Add(sut.Receive()); items.Add(sut.Receive()); items.Add(sut.Receive()); consumer2Called = true; }); Task.WaitAll(producer1, producer2, consumer1, consumer2); Assert.AreEqual(0, sut.Length); Assert.IsTrue(producer1Called); Assert.IsTrue(producer2Called); Assert.IsTrue(consumer1Called); Assert.IsTrue(consumer2Called); CollectionAssert.AreEquivalent(new[] { 1, 2, 3, 4, 5, 6 }, items.ToArray()); }
public void Receive_FromEmptyChanAfterClosed_ShouldThrow() { channel <int> sut = new channel <int>(2); sut.Close(); Exception exception = null; try { sut.Receive(); } catch (Exception ex) { exception = ex; } Assert.AreEqual(0, sut.Length); Assert.IsTrue(sut.IsClosed); Assert.IsInstanceOfType(exception, typeof(PanicException)); }
public void Receive_CancellationToken_ShouldThrow() { channel <int> sut = new channel <int>(2); CancellationTokenSource cts = new CancellationTokenSource(); Exception exception = null; Task consumer = Task.Run(() => { try { sut.Receive(cts.Token); } catch (Exception ex) { exception = ex; } }); consumer.Wait(m_awaitTimeout); cts.Cancel(); consumer.Wait(); // Await the catch block to finish Assert.IsInstanceOfType(exception, typeof(OperationCanceledException)); }