public async Task StartAsync_MultipleListeners_CallStart()
        {
            // Arrange
            var transportListener1 = new Mock <ITransportListener>();
            var transportListener2 = new Mock <ITransportListener>();
            var transportListener3 = new Mock <ITransportListener>();
            var transportListeners = new List <ITransportListener>
            {
                transportListener1.Object,
                transportListener2.Object,
                transportListener3.Object
            };
            var capacity = -1;
            var target   = new AggregateTransportListener(transportListeners, capacity);

            // Act
            await target.StartAsync(CancellationToken);

            // Assert
            transportListener1
            .Verify(t
                    => t.StartAsync(It.IsAny <CancellationToken>()), Times.Once);
            transportListener2
            .Verify(t
                    => t.StartAsync(It.IsAny <CancellationToken>()), Times.Once);
            transportListener3
            .Verify(t
                    => t.StartAsync(It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task AcceptTransportAsync_MultipleListeners_ReceivesFromAll()
        {
            // Arrange
            var transportListener1 = new FakeTransportListener();
            var transportListener2 = new FakeTransportListener();
            var transportListener3 = new FakeTransportListener();
            var transportListeners = new List <ITransportListener>
            {
                transportListener1,
                transportListener2,
                transportListener3
            };
            var capacity = -1;
            var count    = 100;

            var transports = Enumerable
                             .Range(0, count)
                             .Select(i => new FakeTransport(i))
                             .ToList();

            for (int i = 0; i < transports.Count; i++)
            {
                var transport = transports[i];
                if (i % 3 == 0)
                {
                    await transportListener1.ChannelWriter.WriteAsync(transport, CancellationToken);
                }
                else if (i % 3 == 1)
                {
                    await transportListener2.ChannelWriter.WriteAsync(transport, CancellationToken);
                }
                else if (i % 3 == 2)
                {
                    await transportListener3.ChannelWriter.WriteAsync(transport, CancellationToken);
                }
            }
            var target = new AggregateTransportListener(transportListeners, capacity);
            await target.StartAsync(CancellationToken);

            // Act
            var actuals = new List <ITransport>();

            for (int i = 0; i < count; i++)
            {
                actuals.Add(
                    await target.AcceptTransportAsync(CancellationToken));
            }

            // Assert
            actuals.Count.ShouldBe(transports.Count);
            foreach (var expected in transports)
            {
                actuals.ShouldContain(expected);
            }
        }
        public async Task StartAsync_ListenerThrowsException_PropagateException()
        {
            // Arrange
            var transportListener1 = new Mock <ITransportListener>();
            var transportListener2 = new Mock <ITransportListener>();

            transportListener2
            .Setup(t => t.StartAsync(It.IsAny <CancellationToken>()))
            .ThrowsAsync(new ApplicationException());
            var transportListener3 = new Mock <ITransportListener>();
            var transportListeners = new List <ITransportListener>
            {
                transportListener1.Object,
                transportListener2.Object,
                transportListener3.Object
            };
            var capacity = -1;
            var target   = new AggregateTransportListener(transportListeners, capacity);

            // Act
            await target.StartAsync(CancellationToken).ShouldThrowAsync <ApplicationException>();
        }