package com.lambdaworks.redis;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import java.net.NoRouteToHostException;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

import io.netty.channel.ConnectTimeoutException;

/**
 * @author Mark Paluch
 */
public class SocketOptionsTest extends AbstractRedisClientTest {

    @Test
    public void testNew() throws Exception {
        checkAssertions(SocketOptions.create());
    }

    @Test
    public void testBuilder() throws Exception {

        SocketOptions sut = SocketOptions.builder().connectTimeout(1, TimeUnit.MINUTES).keepAlive(true).tcpNoDelay(true)
                .build();

        assertThat(sut.isKeepAlive()).isEqualTo(true);
        assertThat(sut.isTcpNoDelay()).isEqualTo(true);
        assertThat(sut.getConnectTimeout()).isEqualTo(1);
        assertThat(sut.getConnectTimeoutUnit()).isEqualTo(TimeUnit.MINUTES);
    }

    @Test
    public void testCopy() throws Exception {
        checkAssertions(SocketOptions.copyOf(SocketOptions.builder().build()));
    }

    protected void checkAssertions(SocketOptions sut) {
        assertThat(sut.isKeepAlive()).isEqualTo(false);
        assertThat(sut.isTcpNoDelay()).isEqualTo(false);
        assertThat(sut.getConnectTimeout()).isEqualTo(10);
        assertThat(sut.getConnectTimeoutUnit()).isEqualTo(TimeUnit.SECONDS);
    }

    @Test(timeout = 1000)
    public void testConnectTimeout() {

        SocketOptions socketOptions = SocketOptions.builder().connectTimeout(100, TimeUnit.MILLISECONDS).build();
        client.setOptions(ClientOptions.builder().socketOptions(socketOptions).build());

        try {
            client.connect(RedisURI.create("2:4:5:5::1", 60000));
            fail("Missing RedisConnectionException");
        } catch (RedisConnectionException e) {

            if (e.getCause() instanceof NoRouteToHostException) {
                assertThat(e).hasRootCauseInstanceOf(NoRouteToHostException.class);
                assertThat(e.getCause()).hasMessageContaining("No route to host");
                return;
            }

            assertThat(e).hasRootCauseInstanceOf(ConnectTimeoutException.class);
            assertThat(e.getCause()).hasMessageContaining("connection timed out");
        }
    }
}
@@ -152,28 +152,21 @@
 ava.net.
-NoRouteToHos
+Socke
 tExcepti
@@ -1898,28 +1898,29 @@
 tanceof 
-NoRouteToHos
+ConnectTimeou
 tExcepti
@@ -1982,20 +1982,21 @@
 eOf(
-NoRouteToHos
+ConnectTimeou
 tExc
@@ -2077,23 +2077,27 @@
 ng(%22
-No route to hos
+connection timed ou
 t%22);
@@ -2152,58 +2152,41 @@
     
-assertThat(e).hasRoo
+if (e.ge
 tCause
-I
+() i
 nstance
-Of(ConnectTimeou
+of Socke
 tExc
@@ -2187,32 +2187,27 @@
 ketException
-.class);
+) %7B
 %0A           
@@ -2211,78 +2211,111 @@
     
-assertThat(e.getCause()).hasMessageContaining(%22connection timed out%22);
+    // Network is unreachable or No route to host are OK as well.%0A                return;%0A            %7D
 %0A   

Allow SocketOptionsTest to run on non-IPv6 machines