Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-211 a1809fb83 -> 5772b5498


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientTcpUnreachableMultiNodeSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientTcpUnreachableMultiNodeSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientTcpUnreachableMultiNodeSelfTest.java
new file mode 100644
index 0000000..975a16a
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientTcpUnreachableMultiNodeSelfTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.integration;
+
+import org.apache.ignite.client.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.balancer.*;
+import org.apache.ignite.internal.util.typedef.*;
+
+import java.net.*;
+import java.util.*;
+
+/**
+ * Test for TCP binary rest protocol with unreachable address.
+ */
+public class ClientTcpUnreachableMultiNodeSelfTest extends 
ClientTcpMultiNodeSelfTest {
+    /** {@inheritDoc} */
+    @Override protected GridClientLoadBalancer getBalancer() {
+        final GridClientLoadBalancer b = super.getBalancer();
+
+        return new TestGridClientLoadBalancer(b);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridClientConfiguration clientConfiguration() throws 
GridClientException {
+        GridClientConfiguration cfg = super.clientConfiguration();
+
+        // Setting low connection timeout to allow multiple threads
+        // pass the unavailable address quickly.
+        cfg.setConnectTimeout(100);
+
+        return cfg;
+    }
+
+    /**
+     *
+     */
+    private class TestGridClientLoadBalancer implements 
GridClientLoadBalancer, GridClientTopologyListener {
+        /** */
+        private final GridClientLoadBalancer b;
+
+        /**
+         * @param b Delegating balancer.
+         */
+        TestGridClientLoadBalancer(GridClientLoadBalancer b) {
+            this.b = b;
+        }
+
+        /** {@inheritDoc} */
+        @Override public GridClientNode balancedNode(Collection<? extends 
GridClientNode> nodes)
+            throws GridClientException {
+            final GridClientNode node = b.balancedNode(nodes);
+
+            return new GridClientNode() {
+                @Override public <T> T attribute(String name) {
+                    return node.attribute(name);
+                }
+
+                @Override public Map<String, Object> attributes() {
+                    return node.attributes();
+                }
+
+                @Override public Collection<InetSocketAddress> 
availableAddresses(GridClientProtocol proto,
+                    boolean filterResolved) {
+                    // Fake address first.
+                    return F.asList(new InetSocketAddress("172.22.13.13", 
65432),
+                        F.first(node.availableAddresses(proto, 
filterResolved)));
+                }
+
+                @Override public Map<String, GridClientCacheMode> caches() {
+                    return node.caches();
+                }
+
+                @Override public int replicaCount() {
+                    return node.replicaCount();
+                }
+
+                @Override public List<String> jettyAddresses() {
+                    return node.jettyAddresses();
+                }
+
+                @Override public List<String> jettyHostNames() {
+                    return node.jettyHostNames();
+                }
+
+                @Override public int httpPort() {
+                    return node.httpPort();
+                }
+
+                @Override public List<String> tcpAddresses() {
+                    return node.tcpAddresses();
+                }
+
+                @Override public List<String> tcpHostNames() {
+                    return node.tcpHostNames();
+                }
+
+                @Override public GridClientNodeMetrics metrics() {
+                    return node.metrics();
+                }
+
+                @Override public UUID nodeId() {
+                    return node.nodeId();
+                }
+
+                @Override public Object consistentId() {
+                    return node.consistentId();
+                }
+
+                @Override public int tcpPort() {
+                    return node.tcpPort();
+                }
+
+                @Override public boolean connectable() {
+                    return node.connectable();
+                }
+            };
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onNodeAdded(GridClientNode node) {
+            if (b instanceof GridClientTopologyListener)
+                ((GridClientTopologyListener)b).onNodeAdded(node);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onNodeRemoved(GridClientNode node) {
+            if (b instanceof GridClientTopologyListener)
+                ((GridClientTopologyListener)b).onNodeRemoved(node);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/ClientFailedInitSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/ClientFailedInitSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/ClientFailedInitSelfTest.java
new file mode 100644
index 0000000..7a2d7eb
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/ClientFailedInitSelfTest.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.*;
+import org.apache.ignite.client.*;
+import org.apache.ignite.compute.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.impl.connection.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.util.*;
+
+import static org.apache.ignite.internal.client.GridClientProtocol.*;
+import static 
org.apache.ignite.internal.client.integration.ClientAbstractSelfTest.*;
+import static org.apache.ignite.IgniteSystemProperties.*;
+
+/**
+ *
+ */
+public class ClientFailedInitSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final int RECONN_CNT = 3;
+
+    /** */
+    private static final long TOP_REFRESH_PERIOD = 5000;
+
+    /** */
+    private static final int ROUTER_BINARY_PORT = BINARY_PORT + 1;
+
+    /** */
+    private static final int ROUTER_JETTY_PORT = 8081;
+
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        GridClientFactory.stopAll();
+        GridRouterFactory.stopAllRouters();
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        assert cfg.getClientConnectionConfiguration() == null;
+
+        cfg.setLocalHost(HOST);
+
+        ClientConnectionConfiguration clientCfg = new 
ClientConnectionConfiguration();
+
+        clientCfg.setRestTcpPort(BINARY_PORT);
+        clientCfg.setRestJettyPath(REST_JETTY_CFG);
+
+        cfg.setClientConnectionConfiguration(clientCfg);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(disco);
+
+        return cfg;
+    }
+
+    /**
+     *
+     */
+    public void testEmptyAddresses() {
+        try {
+            GridClientFactory.start(new GridClientConfiguration());
+
+            assert false;
+        }
+        catch (GridClientException e) {
+            info("Caught expected exception: " + e);
+        }
+    }
+
+    /**
+     *
+     */
+    public void testRoutersAndServersAddressesProvided() {
+        try {
+            GridClientConfiguration c = new GridClientConfiguration();
+
+            c.setRouters(Collections.singleton("127.0.0.1:10000"));
+            c.setServers(Collections.singleton("127.0.0.1:10000"));
+
+            GridClientFactory.start(c);
+
+            assert false;
+        }
+        catch (GridClientException e) {
+            info("Caught expected exception: " + e);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTcpClient() throws Exception {
+        doTestClient(TCP);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTcpRouter() throws Exception {
+        doTestRouter(TCP);
+    }
+
+    /**
+     * @param p Protocol.
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("BusyWait")
+    private void doTestClient(GridClientProtocol p) throws Exception {
+        GridClient c = client(p, false);
+
+        for (int i = 0; i < RECONN_CNT; i++) {
+            try {
+                c.compute().nodes();
+            }
+            catch (GridClientDisconnectedException e) {
+                assertTrue(X.hasCause(e,
+                    GridServerUnreachableException.class, 
GridClientConnectionResetException.class));
+            }
+
+            startGrid();
+
+            try {
+                Thread.sleep(TOP_REFRESH_PERIOD * 2);
+
+                c.compute().nodes();
+
+                assertEquals("arg", 
c.compute().execute(TestTask.class.getName(), "arg"));
+            }
+            finally {
+                stopGrid();
+            }
+
+            Thread.sleep(TOP_REFRESH_PERIOD * 2);
+        }
+    }
+
+    /**
+     * @param p Protocol.
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("BusyWait")
+    private void doTestRouter(GridClientProtocol p) throws Exception {
+        startRouters();
+
+        GridClient c = client(p, true);
+
+        for (int i = 0; i < RECONN_CNT; i++) {
+            try {
+                c.compute().nodes();
+
+                fail("Nodes list should fail while grid is stopped.");
+            }
+            catch (GridClientDisconnectedException e) {
+                assertTrue(X.hasCause(e, GridClientException.class));
+            }
+
+            startGrid();
+
+            try {
+                Thread.sleep(TOP_REFRESH_PERIOD * 2);
+
+                c.compute().nodes();
+
+                assertEquals("arg", 
c.compute().execute(TestTask.class.getName(), "arg"));
+            }
+            finally {
+                stopGrid();
+            }
+
+            Thread.sleep(TOP_REFRESH_PERIOD * 2);
+        }
+    }
+
+    /**
+     * @return Grid.
+     * @throws Exception If failed.
+     */
+    @Override protected Ignite startGrid() throws Exception {
+        System.setProperty(IGNITE_JETTY_PORT, Integer.toString(JETTY_PORT));
+
+        try {
+            return super.startGrid();
+        }
+        finally {
+            System.clearProperty(IGNITE_JETTY_PORT);
+        }
+    }
+
+    /**
+     * Starts router.
+     * @throws IgniteCheckedException If failed.
+     */
+    private void startRouters() throws IgniteCheckedException {
+        GridTcpRouterConfiguration tcpCfg = new GridTcpRouterConfiguration();
+
+        tcpCfg.setHost(HOST);
+        tcpCfg.setPort(ROUTER_BINARY_PORT);
+        tcpCfg.setPortRange(0);
+        tcpCfg.setServers(Collections.singleton(HOST + ":" + BINARY_PORT));
+
+        GridRouterFactory.startTcpRouter(tcpCfg);
+    }
+
+    /**
+     * @param p Protocol.
+     * @param useRouter Use router flag.
+     * @return Client instance.
+     * @throws GridClientException If failed.
+     */
+    private GridClient client(GridClientProtocol p, boolean useRouter) throws 
GridClientException {
+        GridClientConfiguration cfg = new GridClientConfiguration();
+
+        int port = p == TCP ?
+            (useRouter ? ROUTER_BINARY_PORT : BINARY_PORT) :
+            (useRouter ? ROUTER_JETTY_PORT : JETTY_PORT);
+
+        cfg.setProtocol(p);
+        cfg.setServers(Arrays.asList(HOST + ":" + port));
+        cfg.setTopologyRefreshFrequency(TOP_REFRESH_PERIOD);
+
+        return GridClientFactory.start(cfg);
+    }
+
+    /**
+     * Test task.
+     */
+    private static class TestTask extends ComputeTaskSplitAdapter<String, 
String> {
+        /** {@inheritDoc} */
+        @Override protected Collection<? extends ComputeJob> split(int 
gridSize, final String arg) throws IgniteCheckedException {
+            return Collections.singleton(new ComputeJobAdapter() {
+                @Override public String execute() {
+                    return arg;
+                }
+            });
+        }
+
+        /** {@inheritDoc} */
+        @Override public String reduce(List<ComputeJobResult> results) throws 
IgniteCheckedException {
+            assertEquals(1, results.size());
+
+            return results.get(0).getData();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/RouterFactorySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/RouterFactorySelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/RouterFactorySelfTest.java
new file mode 100644
index 0000000..6ef5c7b
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/RouterFactorySelfTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.client.router.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.util.*;
+
+import static org.apache.ignite.IgniteSystemProperties.*;
+
+/**
+ * Test routers factory.
+ */
+public class RouterFactorySelfTest extends GridCommonAbstractTest {
+    /** Shared IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final int GRID_HTTP_PORT = 11087;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setDiscoverySpi(discoSpi);
+        cfg.setGridName(gridName);
+
+        return cfg;
+    }
+
+    /**
+     * Test router's start/stop.
+     *
+     * @throws Exception In case of any exception.
+     */
+    public void testRouterFactory() throws Exception {
+        try {
+            System.setProperty(IGNITE_JETTY_PORT, 
String.valueOf(GRID_HTTP_PORT));
+
+            try {
+                startGrid();
+            }
+            finally {
+                System.clearProperty(IGNITE_JETTY_PORT);
+            }
+
+            final int size = 20;
+            final Collection<GridTcpRouter> tcpRouters = new ArrayList<>(size);
+            final GridTcpRouterConfiguration tcpCfg = new 
GridTcpRouterConfiguration();
+
+            tcpCfg.setPortRange(size);
+
+            for (int i = 0; i < size; i++)
+                tcpRouters.add(GridRouterFactory.startTcpRouter(tcpCfg));
+
+            for (GridTcpRouter tcpRouter : tcpRouters) {
+                assertEquals(tcpCfg, tcpRouter.configuration());
+                assertEquals(tcpRouter, 
GridRouterFactory.tcpRouter(tcpRouter.id()));
+            }
+
+            assertEquals("Validate all started tcp routers.", new 
HashSet<>(tcpRouters),
+                new HashSet<>(GridRouterFactory.allTcpRouters()));
+
+            for (Iterator<GridTcpRouter> it = tcpRouters.iterator(); 
it.hasNext(); ) {
+                GridTcpRouter tcpRouter = it.next();
+
+                assertEquals("Validate all started tcp routers.", new 
HashSet<>(tcpRouters),
+                    new HashSet<>(GridRouterFactory.allTcpRouters()));
+
+                it.remove();
+
+                GridRouterFactory.stopTcpRouter(tcpRouter.id());
+
+                assertEquals("Validate all started tcp routers.", new 
HashSet<>(tcpRouters),
+                    new HashSet<>(GridRouterFactory.allTcpRouters()));
+            }
+
+            assertEquals(Collections.<GridTcpRouter>emptyList(), 
GridRouterFactory.allTcpRouters());
+        }
+        finally {
+            GridRouterFactory.stopAllRouters();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterAbstractSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterAbstractSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterAbstractSelfTest.java
new file mode 100644
index 0000000..e31a08d
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterAbstractSelfTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.*;
+import org.apache.ignite.client.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.integration.*;
+import org.apache.ignite.internal.client.router.impl.*;
+import org.apache.ignite.logger.log4j.*;
+import org.apache.ignite.internal.util.typedef.*;
+
+import java.util.*;
+
+/**
+ * Abstract base class for http routing tests.
+ */
+public abstract class TcpRouterAbstractSelfTest extends ClientAbstractSelfTest 
{
+    /** Port number to use by router. */
+    private static final int ROUTER_PORT = BINARY_PORT + 1;
+
+    /** TCP router instance. */
+    private static GridTcpRouterImpl router;
+
+    /** Send count. */
+    private static long sndCnt;
+
+    /** Receive count. */
+    private static long rcvCnt;
+
+    /** {@inheritDoc} */
+    @Override protected GridClientProtocol protocol() {
+        return GridClientProtocol.TCP;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected String serverAddress() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        sndCnt = router.getSendCount();
+        rcvCnt = router.getReceivedCount();
+
+        super.beforeTest();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        assert router.getSendCount() > sndCnt :
+            "Failed to ensure network activity [currCnt=" + 
router.getSendCount() + ", oldCnt=" + sndCnt + ']';
+        assert router.getReceivedCount() > rcvCnt:
+            "Failed to ensure network activity [currCnt=" + 
router.getReceivedCount() + ", oldCnt=" + rcvCnt + ']';
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        router = new GridTcpRouterImpl(routerConfiguration());
+
+        router.start();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        router.stop();
+
+        super.afterTestsStopped();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridClientConfiguration clientConfiguration() throws 
GridClientException {
+        GridClientConfiguration cfg = super.clientConfiguration();
+
+        cfg.setServers(Collections.<String>emptySet());
+        cfg.setRouters(Collections.singleton(HOST + ":" + ROUTER_PORT));
+
+        return cfg;
+    }
+
+    /**
+     * @return Router configuration.
+     * @throws IgniteCheckedException If failed.
+     */
+    public GridTcpRouterConfiguration routerConfiguration() throws 
IgniteCheckedException {
+        GridTcpRouterConfiguration cfg = new GridTcpRouterConfiguration();
+
+        cfg.setHost(HOST);
+        cfg.setPort(ROUTER_PORT);
+        cfg.setPortRange(0);
+        cfg.setServers(Collections.singleton(HOST+":"+BINARY_PORT));
+        cfg.setLogger(new IgniteLog4jLogger(ROUTER_LOG_CFG));
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Override public void testConnectable() throws Exception {
+        GridClient client = client();
+
+        List<GridClientNode> nodes = client.compute().refreshTopology(false, 
false);
+
+        assertFalse(F.first(nodes).connectable());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterMultiNodeSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterMultiNodeSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterMultiNodeSelfTest.java
new file mode 100644
index 0000000..c48cf9a
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterMultiNodeSelfTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.*;
+import org.apache.ignite.client.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.integration.*;
+import org.apache.ignite.internal.client.router.impl.*;
+import org.apache.ignite.logger.log4j.*;
+
+import java.util.*;
+
+import static 
org.apache.ignite.internal.client.integration.ClientAbstractSelfTest.*;
+
+/**
+ *
+ */
+public class TcpRouterMultiNodeSelfTest extends 
ClientAbstractMultiNodeSelfTest {
+    /** Number of routers to start in this test. */
+    private static final int ROUTERS_CNT = 5;
+
+    /** Where to start routers' port numeration. */
+    private static final int ROUTER_TCP_PORT_BASE = REST_TCP_PORT_BASE + 
NODES_CNT;
+
+    /** Collection of routers. */
+    private static Collection<GridTcpRouterImpl> routers = new 
ArrayList<>(ROUTERS_CNT);
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        for (int i = 0; i < ROUTERS_CNT; i++)
+            routers.add(new GridTcpRouterImpl(routerConfiguration(i++)));
+
+        for (GridTcpRouterImpl r : routers)
+            r.start();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        info("Stopping routers...");
+
+        for (GridTcpRouterImpl r : routers)
+            r.stop();
+
+        info("Routers stopped.");
+
+        routers.clear();
+
+        super.afterTestsStopped();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridClientProtocol protocol() {
+        return GridClientProtocol.TCP;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected String serverAddress() {
+        return null;
+    }
+
+    /**
+     * @param i Number of router. Used to avoid configuration conflicts.
+     * @return Router configuration.
+     * @throws IgniteCheckedException If failed.
+     */
+    private GridTcpRouterConfiguration routerConfiguration(int i) throws 
IgniteCheckedException {
+        GridTcpRouterConfiguration cfg = new GridTcpRouterConfiguration();
+
+        cfg.setHost(HOST);
+        cfg.setPort(ROUTER_TCP_PORT_BASE + i);
+        cfg.setPortRange(0);
+        cfg.setServers(Collections.singleton(HOST + ":" + REST_TCP_PORT_BASE));
+        cfg.setLogger(new IgniteLog4jLogger(ROUTER_LOG_CFG));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridClientConfiguration clientConfiguration() throws 
GridClientException {
+        GridClientConfiguration cfg = super.clientConfiguration();
+
+        cfg.setServers(Collections.<String>emptySet());
+
+        Collection<String> rtrs = new ArrayList<>(ROUTERS_CNT);
+
+        for (int i = 0; i < ROUTERS_CNT; i++)
+            rtrs.add(HOST + ':' + (ROUTER_TCP_PORT_BASE + i));
+
+        cfg.setRouters(rtrs);
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterSelfTest.java
new file mode 100644
index 0000000..e848dea
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpRouterSelfTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.internal.client.ssl.*;
+
+/**
+ * Tests the simplest use case for router: singe router proxies connections to 
a single node.
+ */
+public class TcpRouterSelfTest extends TcpRouterAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected boolean useSsl() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridSslContextFactory sslContextFactory() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpSslRouterSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpSslRouterSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpSslRouterSelfTest.java
new file mode 100644
index 0000000..750c246
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/TcpSslRouterSelfTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router;
+
+import org.apache.ignite.*;
+import org.apache.ignite.internal.client.ssl.*;
+import org.apache.ignite.testframework.*;
+
+/**
+ *
+ */
+public class TcpSslRouterSelfTest extends TcpRouterAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected boolean useSsl() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected GridSslContextFactory sslContextFactory() {
+        return GridTestUtils.sslContextFactory();
+    }
+
+    /**
+     * @return Router configuration.
+     */
+    @Override public GridTcpRouterConfiguration routerConfiguration() throws 
IgniteCheckedException {
+        GridTcpRouterConfiguration cfg = super.routerConfiguration();
+
+        cfg.setSslContextFactory(sslContextFactory());
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/router/testsuites/IgniteRouterTestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/router/testsuites/IgniteRouterTestSuite.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/testsuites/IgniteRouterTestSuite.java
new file mode 100644
index 0000000..09609f7
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/router/testsuites/IgniteRouterTestSuite.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.router.testsuites;
+
+import junit.framework.*;
+import org.apache.ignite.internal.client.router.*;
+
+/**
+ * Test suite for router tests.
+ */
+public class IgniteRouterTestSuite extends TestSuite {
+    /**
+     * @return Suite that contains all router tests.
+     */
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite("Ignite Router Test Suite");
+
+        suite.addTest(new TestSuite(RouterFactorySelfTest.class));
+        suite.addTest(new TestSuite(TcpRouterSelfTest.class));
+        suite.addTest(new TestSuite(TcpSslRouterSelfTest.class));
+        suite.addTest(new TestSuite(TcpRouterMultiNodeSelfTest.class));
+//        suite.addTest(new TestSuite(ClientFailedInitSelfTest.class));
+
+        return suite;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
new file mode 100644
index 0000000..d89a960
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.suite;
+
+import junit.framework.*;
+import org.apache.ignite.internal.client.*;
+import org.apache.ignite.internal.client.impl.*;
+import org.apache.ignite.internal.client.integration.*;
+import org.apache.ignite.internal.client.router.*;
+import org.apache.ignite.internal.client.util.*;
+import org.apache.ignite.internal.processors.rest.*;
+import org.apache.ignite.internal.processors.rest.protocols.tcp.*;
+
+/**
+ * Test suite includes all test that concern REST processors.
+ */
+public class IgniteClientTestSuite extends TestSuite {
+    /**
+     * @return Suite that contains all tests for REST.
+     */
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite("Ignite Clients Test Suite");
+
+        suite.addTest(new TestSuite(RouterFactorySelfTest.class));
+
+        // Parser standalone test.
+        suite.addTest(new TestSuite(TcpRestParserSelfTest.class));
+
+        // Test memcache protocol with custom test client.
+        suite.addTest(new TestSuite(RestMemcacheProtocolSelfTest.class));
+
+        // Test custom binary protocol with test client.
+        suite.addTest(new TestSuite(RestBinaryProtocolSelfTest.class));
+
+        // Test jetty rest processor
+        suite.addTest(new TestSuite(JettyRestProcessorSignedSelfTest.class));
+        suite.addTest(new TestSuite(JettyRestProcessorUnsignedSelfTest.class));
+
+        // Test TCP rest processor with original memcache client.
+        suite.addTest(new TestSuite(ClientMemcachedProtocolSelfTest.class));
+
+        suite.addTest(new TestSuite(RestProcessorStartSelfTest.class));
+
+        // Test cache flag conversion.
+        suite.addTest(new TestSuite(ClientCacheFlagsCodecTest.class));
+
+        // Test multi-start.
+        suite.addTest(new TestSuite(RestProcessorMultiStartSelfTest.class));
+
+        // Test clients.
+        suite.addTest(new TestSuite(ClientDataImplSelfTest.class));
+        suite.addTest(new TestSuite(ClientComputeImplSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpDirectSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpSslSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpSslDirectSelfTest.class));
+
+        // Test client with many nodes.
+        suite.addTest(new TestSuite(ClientTcpMultiNodeSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpDirectMultiNodeSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpSslMultiNodeSelfTest.class));
+        suite.addTest(new 
TestSuite(ClientTcpSslDirectMultiNodeSelfTest.class));
+        suite.addTest(new 
TestSuite(ClientTcpUnreachableMultiNodeSelfTest.class));
+        suite.addTest(new TestSuite(ClientPreferDirectSelfTest.class));
+
+        // Test client with many nodes and in multithreaded scenarios
+        suite.addTest(new TestSuite(ClientTcpMultiThreadedSelfTest.class));
+        suite.addTest(new TestSuite(ClientTcpSslMultiThreadedSelfTest.class));
+
+        // Test client authentication.
+        suite.addTest(new TestSuite(ClientTcpSslAuthenticationSelfTest.class));
+
+        suite.addTest(new TestSuite(ClientTcpConnectivitySelfTest.class));
+        suite.addTest(new TestSuite(ClientReconnectionSelfTest.class));
+
+        // Rest task command handler test.
+        suite.addTest(new TestSuite(TaskCommandHandlerSelfTest.class));
+
+        // Default cache only test.
+        suite.addTest(new TestSuite(ClientDefaultCacheSelfTest.class));
+
+        suite.addTestSuite(ClientFutureAdapterSelfTest.class);
+        suite.addTestSuite(ClientPartitionAffinitySelfTest.class);
+        suite.addTestSuite(ClientPropertiesConfigurationSelfTest.class);
+        suite.addTestSuite(ClientConsistentHashSelfTest.class);
+        suite.addTestSuite(ClientJavaHasherSelfTest.class);
+
+        suite.addTestSuite(ClientByteUtilsTest.class);
+
+        suite.addTest(new TestSuite(ClientTopologyCacheSelfTest.class));
+
+        // Router tests.
+        suite.addTest(new TestSuite(TcpRouterSelfTest.class));
+        suite.addTest(new TestSuite(TcpSslRouterSelfTest.class));
+        suite.addTest(new TestSuite(TcpRouterMultiNodeSelfTest.class));
+
+        suite.addTest(new TestSuite(ClientFailedInitSelfTest.class));
+
+        suite.addTest(new 
TestSuite(ClientTcpTaskExecutionAfterTopologyRestartSelfTest.class));
+
+        return suite;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientByteUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientByteUtilsTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientByteUtilsTest.java
new file mode 100644
index 0000000..4f76784
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientByteUtilsTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.util;
+
+import org.apache.ignite.internal.util.*;
+import org.apache.ignite.testframework.junits.common.*;
+import org.junit.*;
+
+import java.util.*;
+
+import static org.apache.ignite.internal.util.GridClientByteUtils.*;
+
+/**
+ * Test case for client's byte convertion utility.
+ */
+public class ClientByteUtilsTest extends GridCommonAbstractTest {
+    /**
+     * Test UUID conversions from string to binary and back.
+     *
+     * @throws Exception On any exception.
+     */
+    public void testUuidConvertions() throws Exception {
+        Map<String, byte[]> map = new LinkedHashMap<>();
+
+        map.put("2ec84557-f7c4-4a2e-aea8-251eb13acff3", new byte[] {
+            46, -56, 69, 87, -9, -60, 74, 46, -82, -88, 37, 30, -79, 58, -49, 
-13
+        });
+        map.put("4e17b7b5-79e7-4db5-ac45-a644ead95b9e", new byte[] {
+            78, 23, -73, -75, 121, -25, 77, -75, -84, 69, -90, 68, -22, -39, 
91, -98
+        });
+        map.put("412daadb-e9e6-443b-8b87-8d7895fc2e53", new byte[] {
+            65, 45, -86, -37, -23, -26, 68, 59, -117, -121, -115, 120, -107, 
-4, 46, 83
+        });
+        map.put("e71aabf4-4aad-4280-b4e9-3c310be0cb88", new byte[] {
+            -25, 26, -85, -12, 74, -83, 66, -128, -76, -23, 60, 49, 11, -32, 
-53, -120
+        });
+        map.put("d4454cda-a81f-490f-9424-9bdfcc9cf610", new byte[] {
+            -44, 69, 76, -38, -88, 31, 73, 15, -108, 36, -101, -33, -52, -100, 
-10, 16
+        });
+        map.put("3a584450-5e85-4b69-9f9d-043d89fef23b", new byte[] {
+            58, 88, 68, 80, 94, -123, 75, 105, -97, -99, 4, 61, -119, -2, -14, 
59
+        });
+        map.put("6c8baaec-f173-4a60-b566-240a87d7f81d", new byte[] {
+            108, -117, -86, -20, -15, 115, 74, 96, -75, 102, 36, 10, -121, 
-41, -8, 29
+        });
+        map.put("d99c7102-79f7-4fb4-a665-d331cf285c20", new byte[] {
+            -39, -100, 113, 2, 121, -9, 79, -76, -90, 101, -45, 49, -49, 40, 
92, 32
+        });
+        map.put("007d56c7-5c8b-4279-a700-7f3f95946dde", new byte[] {
+            0, 125, 86, -57, 92, -117, 66, 121, -89, 0, 127, 63, -107, -108, 
109, -34
+        });
+        map.put("15627963-d8f9-4423-bedc-f6f89f7d3433", new byte[] {
+            21, 98, 121, 99, -40, -7, 68, 35, -66, -36, -10, -8, -97, 125, 52, 
51
+        });
+
+        for (Map.Entry<String, byte[]> e : map.entrySet()) {
+            UUID uuid = UUID.fromString(e.getKey());
+            UUID uuidFromBytes = GridClientByteUtils.bytesToUuid(e.getValue(), 
0);
+
+            assertEquals(uuid, uuidFromBytes);
+            assertEquals(e.getKey(), uuid.toString());
+            assertEquals(e.getKey(), uuidFromBytes.toString());
+
+            byte[] bytes = new byte[16];
+
+            GridClientByteUtils.uuidToBytes(uuid, bytes, 0);
+
+            assertTrue(e.getKey(), Arrays.equals(e.getValue(), bytes));
+        }
+    }
+
+    public void testShortToBytes() throws Exception {
+        Map<String, Short> map = new HashMap<>();
+
+        map.put("00-00", (short)0);
+        map.put("00-0F", (short)0x0F);
+        map.put("FF-F1", (short)-0x0F);
+        map.put("27-10", (short)10000);
+        map.put("D8-F0", (short)-10000);
+        map.put("80-00", Short.MIN_VALUE);
+        map.put("7F-FF", Short.MAX_VALUE);
+
+        for (Map.Entry<String, Short> entry : map.entrySet()) {
+            byte[] b = asByteArray(entry.getKey());
+
+            Assert.assertArrayEquals(b, shortToBytes(entry.getValue()));
+            Assert.assertEquals((short)entry.getValue(), bytesToShort(b, 0));
+
+            byte[] tmp = new byte[2];
+
+            shortToBytes(entry.getValue(), tmp, 0);
+            Assert.assertArrayEquals(b, tmp);
+        }
+    }
+
+    public void testIntToBytes() throws Exception {
+        Map<String, Integer> map = new HashMap<>();
+
+        map.put("00-00-00-00", 0);
+        map.put("00-FF-FF-FF", 0xFFFFFF);
+        map.put("FF-00-00-01", -0xFFFFFF);
+        map.put("3B-9A-CA-00", 1000000000);
+        map.put("C4-65-36-00", -1000000000);
+        map.put("80-00-00-00", Integer.MIN_VALUE);
+        map.put("7F-FF-FF-FF", Integer.MAX_VALUE);
+
+        for (Map.Entry<String, Integer> entry : map.entrySet()) {
+            byte[] b = asByteArray(entry.getKey());
+
+            Assert.assertArrayEquals(b, intToBytes(entry.getValue()));
+            Assert.assertEquals((int)entry.getValue(), bytesToInt(b, 0));
+
+            byte[] tmp = new byte[4];
+
+            intToBytes(entry.getValue(), tmp, 0);
+            Assert.assertArrayEquals(b, tmp);
+        }
+    }
+
+    public void testLongToBytes() throws Exception {
+        Map<String, Long> map = new LinkedHashMap<>();
+
+        map.put("00-00-00-00-00-00-00-00", 0L);
+        map.put("00-00-00-00-00-FF-FF-FF", 0xFFFFFFL);
+        map.put("FF-FF-FF-FF-FF-00-00-01", -0xFFFFFFL);
+        map.put("00-00-00-00-3B-9A-CA-00", 1000000000L);
+        map.put("FF-FF-FF-FF-C4-65-36-00", -1000000000L);
+        map.put("00-00-AA-AA-AA-AA-AA-AA", 0xAAAAAAAAAAAAL);
+        map.put("FF-FF-55-55-55-55-55-56", -0xAAAAAAAAAAAAL);
+        map.put("0D-E0-B6-B3-A7-64-00-00", 1000000000000000000L);
+        map.put("F2-1F-49-4C-58-9C-00-00", -1000000000000000000L);
+        map.put("80-00-00-00-00-00-00-00", Long.MIN_VALUE);
+        map.put("7F-FF-FF-FF-FF-FF-FF-FF", Long.MAX_VALUE);
+
+        for (Map.Entry<String, Long> entry : map.entrySet()) {
+            byte[] b = asByteArray(entry.getKey());
+
+            Assert.assertArrayEquals(b, longToBytes(entry.getValue()));
+            Assert.assertEquals((long)entry.getValue(), bytesToLong(b, 0));
+
+            byte[] tmp = new byte[8];
+
+            longToBytes(entry.getValue(), tmp, 0);
+            Assert.assertArrayEquals(b, tmp);
+        }
+    }
+
+    private byte[] asByteArray(String text) {
+        String[] split = text.split("-");
+        byte[] b = new byte[split.length];
+
+        for (int i = 0; i < split.length; i++)
+            b[i] = (byte)Integer.parseInt(split[i], 16);
+
+        return b;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientConsistentHashSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientConsistentHashSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientConsistentHashSelfTest.java
new file mode 100644
index 0000000..1b67433
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientConsistentHashSelfTest.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.util;
+
+import org.apache.ignite.internal.client.util.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.util.*;
+
+/**
+ * Test for consistent hash management class.
+ */
+public class ClientConsistentHashSelfTest extends GridCommonAbstractTest {
+    /** Replicas count. */
+    private static final int REPLICAS = 512;
+
+    /**
+     * Test hash codes collisions.
+     *
+     * @throws Exception In case of any exception.
+     */
+    public void testCollisions() throws Exception {
+        Map<Integer, Set<UUID>> map = new HashMap<>();
+
+        // Different nodes, but collide hash codes.
+        Collection<UUID> nodes = new LinkedHashSet<>();
+
+        // Generate several nodes with collide hash codes.
+        while (nodes.size() < 10) {
+            UUID uuid = UUID.randomUUID();
+            int hashCode = uuid.hashCode();
+
+            Set<UUID> set = map.get(hashCode);
+
+            if (set == null)
+                map.put(hashCode, set = new LinkedHashSet<>());
+
+            set.add(uuid);
+
+            if (set.size() > 1)
+                nodes.addAll(set);
+        }
+
+        map.clear(); // Clean up.
+
+        GridClientConsistentHash<UUID> hash = new GridClientConsistentHash<>();
+
+        hash.addNodes(nodes, REPLICAS);
+
+        boolean fail = false;
+
+        for (UUID exp : nodes) {
+            UUID act = hash.node(0, Arrays.asList(exp));
+
+            if (exp.equals(act))
+                info("Validation succeed [exp=" + exp + ", act=" + act + ']');
+            else{
+                info("Validation failed  [exp=" + exp + ", act=" + act + ']');
+
+                fail = true;
+            }
+        }
+
+        if (fail)
+            fail("Failed to resolve consistent hash node, when node's hash 
codes collide: " + nodes);
+    }
+
+    /**
+     * Test restrictions from internal {@link TreeSet} usage.
+     *
+     * @throws Exception In case of any exception.
+     */
+    public void testTreeSetRestrictions() throws Exception {
+        // Constructs hash without explicit node's comparator.
+        GridClientConsistentHash<Object> hash = new 
GridClientConsistentHash<>();
+
+        try {
+            // Add several objects with the same hash without neither natural 
ordering nor comparator.
+            hash.addNode(new Object() { public int hashCode() { return 0; } }, 
1);
+            hash.addNode(new Object() { public int hashCode() { return 0; } }, 
1);
+
+            fail("Expects failed due to internal TreeSet requires comparator 
or natural ordering.");
+        }
+        catch (ClassCastException e) {
+            info("Expected fail due to internal TreeSet requires comparator or 
natural ordering: " + e.getMessage());
+        }
+
+        // Constructs hash with explicit node's comparator.
+        hash = new GridClientConsistentHash<>(new Comparator<Object>() {
+            @Override public int compare(Object o1, Object o2) {
+                // Such comparator is invalid for production code, but 
acceptable for current test purposes.
+                return System.identityHashCode(o1) - 
System.identityHashCode(o2);
+            }
+        }, null);
+
+        // Add several objects with the same hash into consistent hash with 
explicit comparator.
+        hash.addNode(new Object() { public int hashCode() { return 0; } }, 1);
+        hash.addNode(new Object() { public int hashCode() { return 0; } }, 1);
+
+        info("Expected pass due to internal TreeSet has explicit comparator.");
+    }
+
+    /**
+     * Validate generated hashes.<p>
+     * Note! This test should be ported into all supported platforms.
+     */
+    public void testHashGeneraton() {
+        // Validate strings.
+        checkHash("", -1484017934);
+        checkHash("1", -80388575);
+        checkHash("a", -873690096);
+        checkHash("Hadoop\u3092\u6bba\u3059", -695300527);
+        checkHash("key1", -2067461682);
+
+        // Validate primitives.
+        checkHash(true, 1669973725);
+        checkHash(false, -1900934144);
+
+        checkHash(3, 386050343);
+        checkHash(1000000000, -547312286);
+        checkHash(0x7fffffff, 473949739);
+        checkHash(0xffffffff, -1399925094);
+        checkHash(0x7fffffffffffffffL, 201097861);
+        checkHash(0xffffffffffffffffL, -1484017934);
+        checkHash(1.4e-45f, 1262722378);
+        checkHash(3.4028235e+38f, 1313755354);
+        checkHash(4.9e-324, 1262722378);
+        checkHash(1.7976931348623157e+308, -783615357);
+
+        // Validate objects.
+        checkHash(UUID.fromString("4d180911-21c9-48f2-a1e6-7bc1daf588a0"), 
-440525148);
+
+        checkUUID("224ea4cd-f449-4dcb-869a-5317c63bd619", 806670090);
+        checkUUID("fdc9ec54-ff53-4fdb-8239-5a3ac1fb31bd", -354375826);
+        checkUUID("0f9c9b94-02ae-45a6-9d5c-a066dbdf2636", -1312538272);
+        checkUUID("d8f1f916-4357-4cfe-a7df-49d4721690bf", -482944041);
+        checkUUID("d67eb652-4e76-47fb-ad4e-cd902d9b868a", -449444069);
+        checkUUID("c77ffeae-78a1-4ee6-a0fd-8d197a794412", -168980875);
+        checkUUID("35de9f21-3c9b-4f4a-a7d5-3e2c6cb01564", -383915637);
+    }
+
+    /**
+     * Test mapping to nodes.
+     */
+    @SuppressWarnings("UnaryPlus")
+    public void testMappingToNodes() {
+        String n1 = "node #1";
+        String n2 = "node #2";
+        String n3 = "node #3";
+        String n4 = "node #4";
+
+        List<String> nodes = Arrays.asList(n1, n2, n3, n4);
+
+        GridClientConsistentHash<String> hash = new 
GridClientConsistentHash<>();
+
+        for (String node : nodes)
+            hash.addNode(node, 5);
+
+        Map<Object, String> data = new LinkedHashMap<>();
+
+        data.put("", n1);
+        data.put("asdf", n3);
+        data.put("224ea4cd-f449-4dcb-869a-5317c63bd619", n2);
+        data.put("fdc9ec54-ff53-4fdb-8239-5a3ac1fb31bd", n4);
+        data.put("0f9c9b94-02ae-45a6-9d5c-a066dbdf2636", n1);
+        data.put("d8f1f916-4357-4cfe-a7df-49d4721690bf", n3);
+        data.put("c77ffeae-78a1-4ee6-a0fd-8d197a794412", n4);
+        data.put("35de9f21-3c9b-4f4a-a7d5-3e2c6cb01564", n4);
+        data.put("d67eb652-4e76-47fb-ad4e-cd902d9b868a", n4);
+
+        data.put(0, n1);
+        data.put(1, n4);
+        data.put(12, n3);
+        data.put(123, n3);
+        data.put(1234, n3);
+        data.put(12345, n4);
+        data.put(123456, n3);
+        data.put(1234567, n4);
+        data.put(12345678, n4);
+        data.put(123456789, n4);
+        data.put(1234567890, n3);
+        data.put(1234567890L, n3);
+        data.put(12345678901L, n4);
+        data.put(123456789012L, n2);
+        data.put(1234567890123L, n4);
+        data.put(12345678901234L, n1);
+        data.put(123456789012345L, n1);
+        data.put(1234567890123456L, n3);
+        data.put(-23456789012345L, n2);
+        data.put(-2345678901234L, n1);
+        data.put(-234567890123L, n4);
+        data.put(-23456789012L, n3);
+        data.put(-2345678901L, n3);
+        data.put(-234567890L, n1);
+        data.put(-234567890, n4);
+        data.put(-23456789, n4);
+        data.put(-2345678, n4);
+        data.put(-234567, n4);
+        data.put(-23456, n4);
+        data.put(-2345, n1);
+        data.put(-234, n4);
+        data.put(-23, n3);
+        data.put(-2, n4);
+
+        data.put(0x80000000, n2);
+        data.put(0x7fffffff, n4);
+        data.put(0x8000000000000000L, n2);
+        data.put(0x7fffffffffffffffL, n2);
+
+        data.put(+1.1, n1);
+        data.put(-10.01, n3);
+        data.put(+100.001, n3);
+        data.put(-1000.0001, n4);
+        data.put(+1.7976931348623157E+308, n4);
+        data.put(-1.7976931348623157E+308, n4);
+        data.put(+4.9E-324, n4);
+        data.put(-4.9E-324, n3);
+
+        for (Map.Entry<Object, String> entry : data.entrySet())
+            assertEquals("Validate key '" + entry.getKey() + "'.", 
entry.getValue(), hash.node(entry.getKey()));
+
+        for (Map.Entry<Object, String> entry : data.entrySet())
+            assertEquals("Validate key '" + entry.getKey() + "'.", 
entry.getValue(), hash.node(entry.getKey(), nodes));
+
+        //
+        // Change order nodes were added.
+        //
+
+        nodes = new ArrayList<>(nodes);
+
+        Collections.reverse(nodes);
+
+        // Reset consistent hash with new nodes order.
+        hash = new GridClientConsistentHash<>();
+
+        for (String node : nodes)
+            hash.addNode(node, 5);
+
+        for (Map.Entry<Object, String> entry : data.entrySet())
+            assertEquals("Validate key '" + entry.getKey() + "'.", 
entry.getValue(), hash.node(entry.getKey()));
+
+        for (Map.Entry<Object, String> entry : data.entrySet())
+            assertEquals("Validate key '" + entry.getKey() + "'.", 
entry.getValue(), hash.node(entry.getKey(), nodes));
+    }
+
+    /**
+     * Check unique id and generated hash code.
+     *
+     * @param uuid String presentation of unique id.
+     * @param code Expected hash code.
+     */
+    private void checkUUID(String uuid, int code) {
+        checkHash(UUID.fromString(uuid), code);
+    }
+
+    /**
+     * Check hash generation for the specified object.
+     *
+     * @param o Object to verify hash generation for.
+     * @param code Expected hash code.
+     */
+    private void checkHash(Object o, int code) {
+        int i = GridClientConsistentHash.hash(o);
+
+        assertEquals("Check affinity for object: " + o, code, i);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientJavaHasherSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientJavaHasherSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientJavaHasherSelfTest.java
new file mode 100644
index 0000000..46d0cca
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/util/ClientJavaHasherSelfTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.util;
+
+import org.apache.ignite.testframework.junits.common.*;
+
+import java.util.*;
+
+/**
+ * Test for Java hash codes calculations - SHOULD BE PORTED to other languages.
+ */
+public class ClientJavaHasherSelfTest extends GridCommonAbstractTest {
+    /**
+     * Validate known Java hash codes.
+     */
+    public void testPredefined() {
+        Map<Object, Integer> map = new LinkedHashMap<>();
+
+        // Primitives.
+        for (long i = 1, max = 1L << 48; i < max; i *= -3) {
+            map.put((byte)i, (int)(byte)i);
+            map.put((char)i, (int)(char)i);
+            map.put((int)i, (int)i);
+            map.put(i, (int)(i ^ (i >>> 32)));
+        }
+
+        // Double.
+        map.put(0.0, 0);
+        map.put(1.0, 1072693248);
+        map.put(-1.0, -1074790400);
+        map.put(3.1415e200, 1130072580);
+        map.put(3.1415e-200, -819810675);
+
+        // Strings
+        map.put("", 0);
+        map.put("asdf", 3003444);
+        map.put("Hadoop\u3092\u6bba\u3059", 2113729932);
+        map.put("224ea4cd-f449-4dcb-869a-5317c63bd619", 258755163);
+        map.put("fdc9ec54-ff53-4fdb-8239-5a3ac1fb31bd", -863611257);
+        map.put("0f9c9b94-02ae-45a6-9d5c-a066dbdf2636", -1499939567);
+        map.put("d8f1f916-4357-4cfe-a7df-49d4721690bf", 2041432124);
+
+        // UUID.
+        map.put(UUID.fromString("224ea4cd-f449-4dcb-869a-5317c63bd619"), 
-1767478264);
+        map.put(UUID.fromString("fdc9ec54-ff53-4fdb-8239-5a3ac1fb31bd"), 
1096337416);
+        map.put(UUID.fromString("0f9c9b94-02ae-45a6-9d5c-a066dbdf2636"), 
1269913698);
+        map.put(UUID.fromString("d8f1f916-4357-4cfe-a7df-49d4721690bf"), 
1315925123);
+
+        boolean ok = true;
+
+        for (Map.Entry<Object, Integer> entry : map.entrySet()) {
+            int act = entry.getKey().hashCode();
+            int exp = entry.getValue();
+
+            if (exp == act)
+                continue;
+
+            ok = false;
+
+            info("Validation of hash code for '" + entry.getKey() + "' failed" 
+
+                " [expected=" + exp + ", actual=" + act + ".");
+        }
+
+        if (ok)
+            return;
+
+        fail("Java hash codes validation fails.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientTcpSslLoadTest.java
----------------------------------------------------------------------
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientTcpSslLoadTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientTcpSslLoadTest.java
index 46145ff..f96113d 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientTcpSslLoadTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientTcpSslLoadTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.ignite.loadtests.client;
 
-import org.apache.ignite.client.*;
+import org.apache.ignite.internal.client.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/resources/spring-cache.xml
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/resources/spring-cache.xml 
b/modules/clients/src/test/resources/spring-cache.xml
index a2e62a9..1896225 100644
--- a/modules/clients/src/test/resources/spring-cache.xml
+++ b/modules/clients/src/test/resources/spring-cache.xml
@@ -233,7 +233,7 @@
                 <property name="typeConfigurations">
                     <list>
                         <bean 
class="org.apache.ignite.portables.PortableTypeConfiguration">
-                            <property name="className" 
value="org.apache.ignite.client.ClientTestPortable"/>
+                            <property name="className" 
value="org.apache.ignite.internal.client.ClientTestPortable"/>
                         </bean>
                     </list>
                 </property>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/resources/spring-server-node.xml
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/resources/spring-server-node.xml 
b/modules/clients/src/test/resources/spring-server-node.xml
index ccfcf0f..1b28fb0 100644
--- a/modules/clients/src/test/resources/spring-server-node.xml
+++ b/modules/clients/src/test/resources/spring-server-node.xml
@@ -80,7 +80,7 @@
                 <property name="typeConfigurations">
                     <list>
                         <bean 
class="org.apache.ignite.portables.PortableTypeConfiguration">
-                            <property name="className" 
value="org.apache.ignite.client.ClientTestPortable"/>
+                            <property name="className" 
value="org.apache.ignite.internal.client.ClientTestPortable"/>
                         </bean>
                         <bean 
class="org.apache.ignite.portables.PortableTypeConfiguration">
                             <property name="className" 
value="org.apache.ignite.client.model.GridPortablePerson"/>
@@ -219,7 +219,7 @@
                     <property name="queryIndexEnabled" value="false"/>
 
                     <property name="store">
-                        <bean class="org.apache.ignite.client.HashMapStore"/>
+                        <bean 
class="org.apache.ignite.internal.client.HashMapStore"/>
                     </property>
                 </bean>
 
@@ -254,7 +254,7 @@
 
                     <!-- Store.-->
                     <property name="store">
-                        <bean class="org.apache.ignite.client.HashMapStore"/>
+                        <bean 
class="org.apache.ignite.internal.client.HashMapStore"/>
                     </property>
                 </bean>
             </list>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/756034f3/modules/clients/src/test/resources/spring-server-ssl-node.xml
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/resources/spring-server-ssl-node.xml 
b/modules/clients/src/test/resources/spring-server-ssl-node.xml
index 76c6fbd..d39925a 100644
--- a/modules/clients/src/test/resources/spring-server-ssl-node.xml
+++ b/modules/clients/src/test/resources/spring-server-ssl-node.xml
@@ -221,7 +221,7 @@
 
                     <!-- Store.-->
                     <property name="store">
-                        <bean class="org.apache.ignite.client.HashMapStore"/>
+                        <bean 
class="org.apache.ignite.internal.client.HashMapStore"/>
                     </property>
                 </bean>
             </list>
@@ -328,7 +328,7 @@
                 <property name="typeConfigurations">
                     <list>
                         <bean 
class="org.apache.ignite.portables.PortableTypeConfiguration">
-                            <property name="className" 
value="org.apache.ignite.client.ClientTestPortable"/>
+                            <property name="className" 
value="org.apache.ignite.internal.client.ClientTestPortable"/>
                         </bean>
                     </list>
                 </property>

Reply via email to