public void CreateStreamAsync_should_connect_to_a_running_server_and_return_a_non_null_stream()
        {
            var subject = new TcpStreamFactory();

            var stream = subject.CreateStreamAsync(new DnsEndPoint("localhost", 27017), Timeout.InfiniteTimeSpan, CancellationToken.None);
            stream.Should().NotBeNull();
        }
        // methods
        public ICluster BuildCluster()
        {
            IStreamFactory streamFactory = new TcpStreamFactory(_tcpStreamSettings);
            // TODO: SSL gets handled here specifically...

            streamFactory = _streamFactoryWrapper(streamFactory);

            var connectionFactory = new BinaryConnectionFactory(
                _connectionSettings,
                streamFactory,
                _connectionListener);

            var connectionPoolFactory = new ExclusiveConnectionPoolFactory(
                _connectionPoolSettings,
                connectionFactory,
                _connectionPoolListener);

            var serverFactory = new ServerFactory(
                _serverSettings,
                connectionPoolFactory,
                connectionFactory,
                _serverListener);

            var clusterFactory = new ClusterFactory(
                _clusterSettings,
                serverFactory,
                _clusterListener);

            return clusterFactory.CreateCluster();
        }
        public void CreateStreamAsync_should_throw_a_SocketException_when_the_endpoint_could_not_be_resolved()
        {
            var subject = new TcpStreamFactory();

            Action act = () => subject.CreateStreamAsync(new DnsEndPoint("not-gonna-exist-i-hope", 27017), CancellationToken.None).Wait();

            act.ShouldThrow<SocketException>();
        }
        public async Task CreateStreamAsync_should_connect_to_a_running_server_and_return_a_non_null_stream()
        {
            var subject = new TcpStreamFactory();
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            var stream = await subject.CreateStreamAsync(endPoint, CancellationToken.None);

            stream.Should().NotBeNull();
        }
        public async Task CreateStreamAsync_should_call_the_socketConfigurator()
        {
            var socketConfiguratorWasCalled = false;
            Action<Socket> socketConfigurator = s => socketConfiguratorWasCalled = true;
            var settings = new TcpStreamSettings(socketConfigurator: socketConfigurator);
            var subject = new TcpStreamFactory(settings);
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            await subject.CreateStreamAsync(endPoint, CancellationToken.None);

            socketConfiguratorWasCalled.Should().BeTrue();
        }
        public async Task SocketConfigurator_can_be_used_to_set_keepAlive()
        {
            Action<Socket> socketConfigurator = s => s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            var settings = new TcpStreamSettings(socketConfigurator: socketConfigurator);
            var subject = new TcpStreamFactory(settings);
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            var stream = await subject.CreateStreamAsync(endPoint, CancellationToken.None);

            var socketProperty = typeof(NetworkStream).GetProperty("Socket", BindingFlags.NonPublic | BindingFlags.Instance);
            var socket = (Socket)socketProperty.GetValue(stream);
            var keepAlive = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive);
            keepAlive.Should().NotBe(0); // .NET returns 1 but Mono returns 8
        }
        public void CreateStream_should_throw_a_SocketException_when_the_endpoint_could_not_be_resolved(
            [Values(false, true)]
            bool async)
        {
            var subject = new TcpStreamFactory();

            Action act;
            if (async)
            {
                act = () => subject.CreateStreamAsync(new DnsEndPoint("not-gonna-exist-i-hope", 27017), CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                act = () => subject.CreateStream(new DnsEndPoint("not-gonna-exist-i-hope", 27017), CancellationToken.None);
            }

            act.ShouldThrow<SocketException>();
        }
        public void CreateStream_should_throw_when_cancellation_is_requested(
            [Values(false, true)]
            bool async)
        {
            var subject = new TcpStreamFactory();
            var endPoint = new IPEndPoint(new IPAddress(0x01010101), 12345); // a non-existent host and port
            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(20));

            Action action;
            if (async)
            {
                action = () => subject.CreateStreamAsync(endPoint, cancellationTokenSource.Token).GetAwaiter().GetResult();
            }
            else
            {
                action = () => subject.CreateStream(endPoint, cancellationTokenSource.Token);
            }

            action.ShouldThrow<OperationCanceledException>();
        }
        public void CreateStream_should_throw_when_cancellation_is_requested(
            [Values(false, true)]
            bool async)
        {
            var subject  = new TcpStreamFactory();
            var endPoint = new IPEndPoint(new IPAddress(0x01010101), 12345); // a non-existent host and port
            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(20));

            Action action;

            if (async)
            {
                action = () => subject.CreateStreamAsync(endPoint, cancellationTokenSource.Token).GetAwaiter().GetResult();
            }
            else
            {
                action = () => subject.CreateStream(endPoint, cancellationTokenSource.Token);
            }

            action.ShouldThrow <OperationCanceledException>();
        }
        public void CreateStream_should_throw_when_connect_timeout_has_expired(
            [Values(false, true)]
            bool async)
        {
            var settings = new TcpStreamSettings(connectTimeout: TimeSpan.FromMilliseconds(20));
            var subject  = new TcpStreamFactory(settings);
            var endPoint = new IPEndPoint(new IPAddress(0x01010101), 12345); // a non-existent host and port

            Action action;

            if (async)
            {
                action = () => subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();;
            }
            else
            {
                action = () => subject.CreateStream(endPoint, CancellationToken.None);
            }

            action.ShouldThrow <TimeoutException>();
        }
        public void CreateStream_should_connect_to_a_running_server_and_return_a_non_null_stream(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check();
            var subject  = new TcpStreamFactory();
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            Stream stream;

            if (async)
            {
                stream = subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                stream = subject.CreateStream(endPoint, CancellationToken.None);
            }

            stream.Should().NotBeNull();
        }
        public void CreateStream_should_call_the_socketConfigurator(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Check();
            var             socketConfiguratorWasCalled = false;
            Action <Socket> socketConfigurator          = s => socketConfiguratorWasCalled = true;
            var             settings = new TcpStreamSettings(socketConfigurator: socketConfigurator);
            var             subject  = new TcpStreamFactory(settings);
            var             endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            if (async)
            {
                subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                subject.CreateStream(endPoint, CancellationToken.None);
            }

            socketConfiguratorWasCalled.Should().BeTrue();
        }
        public void CreateStream_should_call_the_socketConfigurator(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Any();
            var socketConfiguratorWasCalled = false;
            Action<Socket> socketConfigurator = s => socketConfiguratorWasCalled = true;
            var settings = new TcpStreamSettings(socketConfigurator: socketConfigurator);
            var subject = new TcpStreamFactory(settings);
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            if (async)
            {
                 subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                subject.CreateStream(endPoint, CancellationToken.None);
            }

            socketConfiguratorWasCalled.Should().BeTrue();
        }
 internal static Task ConnectAsync(this TcpStreamFactory obj, Socket socket, EndPoint endPoint, CancellationToken cancellationToken)
 {
     return((Task)Reflector.Invoke(obj, nameof(ConnectAsync), socket, endPoint, cancellationToken));
 }
 internal static void Connect(this TcpStreamFactory obj, Socket socket, EndPoint endPoint, CancellationToken cancellationToken)
 {
     Reflector.Invoke(obj, nameof(Connect), socket, endPoint, cancellationToken);
 }
 internal static TcpStreamSettings _settings(this TcpStreamFactory obj) => (TcpStreamSettings)Reflector.GetFieldValue(obj, nameof(_settings));
        public void CreateStream_should_throw_when_connect_timeout_has_expired(
            [Values(false, true)]
            bool async)
        {
            var settings = new TcpStreamSettings(connectTimeout: TimeSpan.FromMilliseconds(20));
            var subject = new TcpStreamFactory(settings);
            var endPoint = new IPEndPoint(new IPAddress(0x01010101), 12345); // a non-existent host and port

            Action action;
            if (async)
            {
                action = () => subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult(); ;
            }
            else
            {
                action = () => subject.CreateStream(endPoint, CancellationToken.None);
            }

            action.ShouldThrow<TimeoutException>();
        }
        public void SocketConfigurator_can_be_used_to_set_keepAlive(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Any();
            Action<Socket> socketConfigurator = s => s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            var settings = new TcpStreamSettings(socketConfigurator: socketConfigurator);
            var subject = new TcpStreamFactory(settings);
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            Stream stream;
            if (async)
            {
                stream = subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                stream = subject.CreateStream(endPoint, CancellationToken.None);
            }

            var socketProperty = typeof(NetworkStream).GetProperty("Socket", BindingFlags.NonPublic | BindingFlags.Instance);
            var socket = (Socket)socketProperty.GetValue(stream);
            var keepAlive = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive);
            keepAlive.Should().NotBe(0); // .NET returns 1 but Mono returns 8
        }
        public void CreateStream_should_connect_to_a_running_server_and_return_a_non_null_stream(
            [Values(false, true)]
            bool async)
        {
            RequireServer.Any();
            var subject = new TcpStreamFactory();
            var endPoint = CoreTestConfiguration.ConnectionString.Hosts[0];

            Stream stream;
            if (async)
            {
                stream = subject.CreateStreamAsync(endPoint, CancellationToken.None).GetAwaiter().GetResult();
            }
            else
            {
                stream = subject.CreateStream(endPoint, CancellationToken.None);
            }

            stream.Should().NotBeNull();
        }