public void GatewayListener_OptionsValidation()
        {
            const ushort AnyEphemerealPort = 4323;

            Mock <ILogger> loggerMock = new Mock <ILogger>();
            Mock <ISocketConnectionFactory> connectionFactoryMock = new Mock <ISocketConnectionFactory>();
            Mock <IDoSDefender>             defenderMock          = new Mock <IDoSDefender>();

            GatewayListenerOptions goodGatewayListenerOptions = new GatewayListenerOptions()
            {
                Port = AnyEphemerealPort
            };

            GatewayListenerOptions badGatewayListenerOptions = new GatewayListenerOptions();

            // Initialize with null parameters, should throw.
            ExceptionAssert.Throws <ArgumentNullException>(
                () => new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, null, connectionFactoryMock.Object, defenderMock.Object),
                "Value cannot be null. (Parameter 'options')");

            ExceptionAssert.Throws <ValidationException>(
                () => new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, Options.Create(badGatewayListenerOptions), connectionFactoryMock.Object, defenderMock.Object),
                "A port for the gateway listener must be speficied.");

            // And initialize with all good values.
            new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, Options.Create(goodGatewayListenerOptions), connectionFactoryMock.Object, defenderMock.Object);
        }
        public async Task GatewayListener_CallsNewConnectionEvent()
        {
            const ushort AnyEphemerealPort       = 1234;
            const int    ExpectedConnectionCount = 1;
            const int    NewConnectionsToEmulate = 1;

            TimeSpan waitForConnectionDelay = TimeSpan.FromSeconds(2);

            Mock <ILogger>      loggerMock      = new Mock <ILogger>();
            Mock <IDoSDefender> defenderMock    = new Mock <IDoSDefender>();
            Mock <ITcpListener> tcpListenerMock = this.SetupTcpListenerMock(NewConnectionsToEmulate);

            Mock <ISocketConnectionFactory> connectionFactoryMock = this.SetupSocketConnectionFactory();

            GatewayListenerOptions loginListenerOptions = new GatewayListenerOptions()
            {
                Port = AnyEphemerealPort,
            };

            IListener gatewayListener = new GatewayListener <ISocketConnectionFactory>(
                loggerMock.Object,
                Options.Create(loginListenerOptions),
                connectionFactoryMock.Object,
                defenderMock.Object,
                tcpListenerMock.Object);

            var connectionCount = 0;
            var listenerTask    = gatewayListener.StartAsync(CancellationToken.None);

            gatewayListener.NewConnection += (connection) =>
            {
                connectionCount++;
            };

            // Delay for a second and check that the counter has gone up on connections count.
            await Task.Delay(waitForConnectionDelay).ContinueWith(prev =>
            {
                Assert.AreEqual(ExpectedConnectionCount, connectionCount, $"New connections events counter does not match, expected {ExpectedConnectionCount} but found {connectionCount}.");
            });
        }
        public void GatewayListener_Initialization()
        {
            Mock <ILogger> loggerMock = new Mock <ILogger>();
            Mock <ISocketConnectionFactory> connectionFactoryMock = new Mock <ISocketConnectionFactory>();
            Mock <IDoSDefender>             defenderMock          = new Mock <IDoSDefender>();

            GatewayListenerOptions loginListenerOptions = new GatewayListenerOptions()
            {
                Port = 7171,
            };

            // Initialize with null parameters, should throw.
            ExceptionAssert.Throws <ArgumentNullException>(() => new GatewayListener <ISocketConnectionFactory>(null, Options.Create(loginListenerOptions), connectionFactoryMock.Object, defenderMock.Object), $"Value cannot be null. (Parameter 'logger')");
            ExceptionAssert.Throws <ArgumentNullException>(() => new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, null, connectionFactoryMock.Object, defenderMock.Object), $"Value cannot be null. (Parameter 'options')");
            ExceptionAssert.Throws <ArgumentNullException>(() => new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, Options.Create(loginListenerOptions), null, defenderMock.Object), $"Value cannot be null. (Parameter 'socketConnectionFactory')");

            // A null DoS defender is OK.
            new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, Options.Create(loginListenerOptions), connectionFactoryMock.Object, null);

            // And initialize with all good values.
            new GatewayListener <ISocketConnectionFactory>(loggerMock.Object, Options.Create(loginListenerOptions), connectionFactoryMock.Object, defenderMock.Object);
        }