public void IdleTimeoutBidi_must_be_able_to_signal_timeout_once_no_traffic_on_either_sides()
{
this.AssertAllStagesStopped(() =>
{
var upWrite = TestPublisher.CreateProbe<string>(this);
var upRead = TestSubscriber.CreateProbe<int>(this);
var downWrite = TestPublisher.CreateProbe<int>(this);
var downRead = TestSubscriber.CreateProbe<string>(this);
RunnableGraph.FromGraph(GraphDsl.Create(b =>
{
var timeoutStage = b.Add(BidiFlow.BidirectionalIdleTimeout<string, int>(TimeSpan.FromSeconds(2)));
b.From(Source.FromPublisher<string>(upWrite)).To(timeoutStage.Inlet1);
b.From(timeoutStage.Outlet1).To(Sink.FromSubscriber(downRead));
b.From(timeoutStage.Outlet2).To(Sink.FromSubscriber(upRead));
b.From(Source.FromPublisher<int>(downWrite)).To(timeoutStage.Inlet2);
return ClosedShape.Instance;
})).Run(Materializer);
// Request enough for the whole test
upRead.Request(100);
downRead.Request(100);
upWrite.SendNext("DATA1");
downRead.ExpectNext("DATA1");
Thread.Sleep(1500);
downWrite.SendNext(1);
upRead.ExpectNext(1);
Thread.Sleep(1500);
upWrite.SendNext("DATA2");
downRead.ExpectNext("DATA2");
Thread.Sleep(1000);
downWrite.SendNext(2);
upRead.ExpectNext(2);
upRead.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
var error1 = upRead.ExpectError();
var error2 = downRead.ExpectError();
error1.Should().BeOfType<TimeoutException>();
error1.Message.Should().Be($"No elements passed in the last {TimeSpan.FromSeconds(2)}.");
error2.ShouldBeEquivalentTo(error1);
upWrite.ExpectCancellation();
downWrite.ExpectCancellation();
}, Materializer);
}