http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/load/cache-benchmark.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/load/cache-benchmark.xml 
b/modules/core/src/test/config/load/cache-benchmark.xml
index c6608c5..01e0637 100644
--- a/modules/core/src/test/config/load/cache-benchmark.xml
+++ b/modules/core/src/test/config/load/cache-benchmark.xml
@@ -66,9 +66,9 @@
         <property name="includeProperties"><list/></property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/load/cache-client-benchmark.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/load/cache-client-benchmark.xml 
b/modules/core/src/test/config/load/cache-client-benchmark.xml
index 668c315..749b065 100644
--- a/modules/core/src/test/config/load/cache-client-benchmark.xml
+++ b/modules/core/src/test/config/load/cache-client-benchmark.xml
@@ -66,9 +66,9 @@
         <property name="includeProperties"><list/></property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/load/dsi-load-base.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/load/dsi-load-base.xml 
b/modules/core/src/test/config/load/dsi-load-base.xml
index 8476ba8..20548b2 100644
--- a/modules/core/src/test/config/load/dsi-load-base.xml
+++ b/modules/core/src/test/config/load/dsi-load-base.xml
@@ -43,10 +43,10 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
                     <bean
-                            
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                            
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/load/merge-sort-base.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/load/merge-sort-base.xml 
b/modules/core/src/test/config/load/merge-sort-base.xml
index 3bb3645..11a3166 100644
--- a/modules/core/src/test/config/load/merge-sort-base.xml
+++ b/modules/core/src/test/config/load/merge-sort-base.xml
@@ -97,7 +97,7 @@
 
         <!-- Discovery SPI configuration. -->
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="networkTimeout" value="20000"/>
                 <property name="socketTimeout" value="5000"/>
                 <property name="ackTimeout" value="5000"/>
@@ -108,7 +108,7 @@
                 <property name="statisticsPrintFrequency" value="60000"/>
 
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/load/mongo-multinode-foster.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/load/mongo-multinode-foster.xml 
b/modules/core/src/test/config/load/mongo-multinode-foster.xml
index d8a6587..87f1b29 100644
--- a/modules/core/src/test/config/load/mongo-multinode-foster.xml
+++ b/modules/core/src/test/config/load/mongo-multinode-foster.xml
@@ -131,10 +131,10 @@
             TCP discovery SPI (uses VM-shared IP-finder).
         -->
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <!-- Override default IP-finder.-->
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>10.1.10.212:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/loaders/grid-cfg-2-grids.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/loaders/grid-cfg-2-grids.xml 
b/modules/core/src/test/config/loaders/grid-cfg-2-grids.xml
index 7e1f68b..4361ac5 100644
--- a/modules/core/src/test/config/loaders/grid-cfg-2-grids.xml
+++ b/modules/core/src/test/config/loaders/grid-cfg-2-grids.xml
@@ -24,9 +24,9 @@
         <property name="restEnabled" value="false" />
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                         <property name="multicastGroup" 
value="228.111.111.111"/>
                         <property name="multicastPort" value="54535"/>
                     </bean>
@@ -41,9 +41,9 @@
         <property name="restEnabled" value="false" />
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                         <property name="multicastGroup" 
value="228.111.111.111"/>
                         <property name="multicastPort" value="54535"/>
                     </bean>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/loaders/grid-cfg.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/loaders/grid-cfg.xml 
b/modules/core/src/test/config/loaders/grid-cfg.xml
index c414c48..86b5009 100644
--- a/modules/core/src/test/config/loaders/grid-cfg.xml
+++ b/modules/core/src/test/config/loaders/grid-cfg.xml
@@ -24,9 +24,9 @@
         <property name="restEnabled" value="false" />
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                         <property name="multicastGroup" 
value="228.111.111.222"/>
                         <property name="multicastPort" value="54522"/>
                     </bean>
@@ -41,9 +41,9 @@
         <property name="restEnabled" value="false" />
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                         <property name="multicastGroup" 
value="228.111.111.222"/>
                         <property name="multicastPort" value="54522"/>
                     </bean>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-cache-load.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-cache-load.xml 
b/modules/core/src/test/config/spring-cache-load.xml
index 550ef79..78ff871 100644
--- a/modules/core/src/test/config/spring-cache-load.xml
+++ b/modules/core/src/test/config/spring-cache-load.xml
@@ -57,9 +57,9 @@
             (at least one address must be provided).
         -->
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <!--

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-cache-put-remove-load.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-cache-put-remove-load.xml 
b/modules/core/src/test/config/spring-cache-put-remove-load.xml
index 513e300..103f519 100644
--- a/modules/core/src/test/config/spring-cache-put-remove-load.xml
+++ b/modules/core/src/test/config/spring-cache-put-remove-load.xml
@@ -54,9 +54,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-cache-swap.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-cache-swap.xml 
b/modules/core/src/test/config/spring-cache-swap.xml
index 5873e95..3b2bf6f 100644
--- a/modules/core/src/test/config/spring-cache-swap.xml
+++ b/modules/core/src/test/config/spring-cache-swap.xml
@@ -47,9 +47,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-cache-teststore.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-cache-teststore.xml 
b/modules/core/src/test/config/spring-cache-teststore.xml
index bd139e6..a8127b7 100644
--- a/modules/core/src/test/config/spring-cache-teststore.xml
+++ b/modules/core/src/test/config/spring-cache-teststore.xml
@@ -43,9 +43,9 @@
         <property name="networkTimeout" value="10000"/>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-multicache.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-multicache.xml 
b/modules/core/src/test/config/spring-multicache.xml
index fc3e030..af55077 100644
--- a/modules/core/src/test/config/spring-multicache.xml
+++ b/modules/core/src/test/config/spring-multicache.xml
@@ -255,9 +255,9 @@
             (at least one address must be provided).
         -->
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <!--

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-start-nodes-attr.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-start-nodes-attr.xml 
b/modules/core/src/test/config/spring-start-nodes-attr.xml
index b7aa38e..e72665c 100644
--- a/modules/core/src/test/config/spring-start-nodes-attr.xml
+++ b/modules/core/src/test/config/spring-start-nodes-attr.xml
@@ -37,9 +37,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/spring-start-nodes.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/spring-start-nodes.xml 
b/modules/core/src/test/config/spring-start-nodes.xml
index e4246cb..d5e31e4 100644
--- a/modules/core/src/test/config/spring-start-nodes.xml
+++ b/modules/core/src/test/config/spring-start-nodes.xml
@@ -31,9 +31,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/streamer/spring-streamer-base.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/streamer/spring-streamer-base.xml 
b/modules/core/src/test/config/streamer/spring-streamer-base.xml
index b241f8e..ba404e3 100644
--- a/modules/core/src/test/config/streamer/spring-streamer-base.xml
+++ b/modules/core/src/test/config/streamer/spring-streamer-base.xml
@@ -60,7 +60,7 @@
             <constructor-arg value="127.0.0.1"/>
         </bean>
 
-        <bean id="discoSpi" 
class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+        <bean id="discoSpi" 
class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
             <property name="ackTimeout" value="5000"/>
             <property name="socketTimeout" value="5000"/>
             <property name="reconnectCount" value="5"/>
@@ -68,7 +68,7 @@
             <property name="maxMissedHeartbeats" value="3"/>
 
             <property name="ipFinder">
-                <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                     <property name="addresses">
                         <list>
                             <value>127.0.0.1:47500</value>
@@ -82,9 +82,9 @@
         <!-- Empty local host value. -->
         <bean id="localHost" class="java.lang.String"/>
 
-        <bean id="discoSpi" 
class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+        <bean id="discoSpi" 
class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
             <property name="ipFinder">
-                <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                     <property name="addresses">
                         <list>
                             <value>10.1.10.210</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/websession/spring-cache-1.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/websession/spring-cache-1.xml 
b/modules/core/src/test/config/websession/spring-cache-1.xml
index 31b75da..9a3c89b 100644
--- a/modules/core/src/test/config/websession/spring-cache-1.xml
+++ b/modules/core/src/test/config/websession/spring-cache-1.xml
@@ -78,9 +78,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/websession/spring-cache-2.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/websession/spring-cache-2.xml 
b/modules/core/src/test/config/websession/spring-cache-2.xml
index 35f8f41..ff09e40 100644
--- a/modules/core/src/test/config/websession/spring-cache-2.xml
+++ b/modules/core/src/test/config/websession/spring-cache-2.xml
@@ -78,9 +78,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/config/websession/spring-cache-3.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/websession/spring-cache-3.xml 
b/modules/core/src/test/config/websession/spring-cache-3.xml
index bc24f47..3d7fb88 100644
--- a/modules/core/src/test/config/websession/spring-cache-3.xml
+++ b/modules/core/src/test/config/websession/spring-cache-3.xml
@@ -78,9 +78,9 @@
         </property>
 
         <property name="discoverySpi">
-            <bean class="org.gridgain.grid.spi.discovery.tcp.TcpDiscoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                 <property name="ipFinder">
-                    <bean 
class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                    <bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                         <property name="addresses">
                             <list>
                                 <value>127.0.0.1:47500</value>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerTest.java
 
b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerTest.java
index 0a1797a..dce41dd 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerTest.java
@@ -5,8 +5,8 @@ import org.apache.ignite.compute.*;
 import org.apache.ignite.marshaller.*;
 import org.gridgain.grid.*;
 import org.gridgain.grid.marshaller.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
 import org.gridgain.grid.util.typedef.internal.*;
 import org.gridgain.testframework.junits.common.*;
 import org.jetbrains.annotations.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridTestTcpDiscoveryIpFinderAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridTestTcpDiscoveryIpFinderAdapter.java
 
b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridTestTcpDiscoveryIpFinderAdapter.java
index 26f0fc7..38fbac7 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridTestTcpDiscoveryIpFinderAdapter.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/GridTestTcpDiscoveryIpFinderAdapter.java
@@ -10,7 +10,7 @@
 package org.apache.ignite.marshaller.optimized;
 
 import org.apache.ignite.spi.IgniteSpiException;
-import 
org.gridgain.grid.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter;
+import 
org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter;
 
 import java.net.InetSocketAddress;
 import java.util.Collection;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/checkpoint/cache/GridCacheCheckpointSpiSecondCacheSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/checkpoint/cache/GridCacheCheckpointSpiSecondCacheSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/checkpoint/cache/GridCacheCheckpointSpiSecondCacheSelfTest.java
index 4dcdd7e..04ae6c8 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/checkpoint/cache/GridCacheCheckpointSpiSecondCacheSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/checkpoint/cache/GridCacheCheckpointSpiSecondCacheSelfTest.java
@@ -11,9 +11,9 @@ package org.apache.ignite.spi.checkpoint.cache;
 
 import org.apache.ignite.configuration.*;
 import org.gridgain.grid.cache.*;
-import org.gridgain.grid.spi.discovery.tcp.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.*;
+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.gridgain.testframework.junits.common.*;
 
 import static org.gridgain.grid.cache.GridCacheMode.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiAttributesSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiAttributesSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiAttributesSelfTest.java
index 1246b40..fa73c02 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiAttributesSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiAttributesSelfTest.java
@@ -11,7 +11,7 @@ package org.apache.ignite.spi.collision.jobstealing;
 
 import org.apache.ignite.cluster.*;
 import org.apache.ignite.spi.collision.*;
-import org.gridgain.grid.spi.discovery.*;
+import org.apache.ignite.spi.discovery.*;
 import org.gridgain.grid.spi.failover.jobstealing.*;
 import org.gridgain.grid.util.typedef.*;
 import org.gridgain.grid.util.typedef.internal.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiCustomTopologySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiCustomTopologySelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiCustomTopologySelfTest.java
index 9d56adc..ff49b08 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiCustomTopologySelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiCustomTopologySelfTest.java
@@ -13,7 +13,7 @@ import org.apache.ignite.cluster.*;
 import org.apache.ignite.lang.*;
 import org.gridgain.grid.*;
 import org.apache.ignite.spi.collision.*;
-import org.gridgain.grid.spi.discovery.*;
+import org.apache.ignite.spi.discovery.*;
 import org.gridgain.grid.spi.failover.jobstealing.*;
 import org.gridgain.grid.util.typedef.internal.*;
 import org.gridgain.testframework.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiSelfTest.java
index 443a620..5d7c0f1 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/collision/jobstealing/GridJobStealingCollisionSpiSelfTest.java
@@ -13,7 +13,7 @@ import org.apache.ignite.cluster.*;
 import org.apache.ignite.lang.*;
 import org.gridgain.grid.*;
 import org.apache.ignite.spi.collision.*;
-import org.gridgain.grid.spi.discovery.*;
+import org.apache.ignite.spi.discovery.*;
 import org.gridgain.grid.spi.failover.jobstealing.*;
 import org.gridgain.grid.util.typedef.*;
 import org.gridgain.grid.util.typedef.internal.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridCacheDhtLockBackupSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridCacheDhtLockBackupSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridCacheDhtLockBackupSelfTest.java
index 936f71b..703c5d8 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridCacheDhtLockBackupSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridCacheDhtLockBackupSelfTest.java
@@ -20,9 +20,9 @@ import org.gridgain.grid.cache.*;
 import org.gridgain.grid.kernal.managers.communication.*;
 import org.gridgain.grid.kernal.processors.cache.distributed.near.*;
 import org.apache.ignite.spi.communication.*;
-import org.gridgain.grid.spi.discovery.tcp.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.*;
+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.gridgain.grid.util.direct.*;
 import org.gridgain.grid.util.typedef.internal.*;
 import org.gridgain.testframework.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
index 6d753c1..ca76a8a 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
@@ -20,9 +20,9 @@ import org.gridgain.grid.cache.query.*;
 import org.gridgain.grid.kernal.*;
 import org.gridgain.grid.kernal.managers.communication.*;
 import org.gridgain.grid.kernal.processors.cache.query.*;
-import org.gridgain.grid.spi.discovery.tcp.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.*;
-import org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.*;
+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.gridgain.grid.util.direct.*;
 import org.gridgain.grid.util.typedef.internal.*;
 import org.gridgain.testframework.junits.common.*;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryRandomStartStopTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryRandomStartStopTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryRandomStartStopTest.java
new file mode 100644
index 0000000..47496a5
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryRandomStartStopTest.java
@@ -0,0 +1,205 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.spi.discovery;
+
+import org.apache.ignite.cluster.*;
+import org.apache.ignite.events.*;
+import org.gridgain.grid.kernal.managers.eventstorage.*;
+import org.gridgain.testframework.junits.spi.*;
+
+import javax.swing.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Base discovery random start-stop test class.
+ * @param <T> Discovery spi type.
+ */
+public abstract class GridAbstractDiscoveryRandomStartStopTest<T extends 
DiscoverySpi> extends GridSpiAbstractTest<T> {
+    /** */
+    private static final int DFLT_MAX_INTERVAL = 10;
+
+    /** */
+    private volatile boolean semaphore = true;
+
+    /** */
+    private boolean isRunning;
+
+    /** */
+    private Pinger pinger;
+
+    /** */
+    private class Pinger extends Thread {
+        /** */
+        private final Object mux = new Object();
+
+        /** */
+        private volatile boolean canceled;
+
+        /** {@inheritDoc} */
+        @SuppressWarnings({"UnusedCatchParameter"})
+        @Override public void run() {
+            while (!canceled) {
+                try {
+                    if (getSpi() != null) {
+                        Collection<ClusterNode> nodes = 
getSpi().getRemoteNodes();
+
+                        for (ClusterNode item : nodes) {
+                            boolean flag = getSpi().pingNode(item.id());
+
+                            if (flag) {
+                                info("Ping node [nodeId=" + 
item.id().toString().toUpperCase() +
+                                    ", pingResult=" + flag + ']');
+                            }
+                            else {
+                                info("***Error*** Ping node fail [nodeId=" + 
item.id().toString().toUpperCase() +
+                                    ", pingResult=" + flag + ']');
+                            }
+                        }
+                    }
+                }
+                catch (Exception e) {
+                    error("Can't get remote nodes list.", e);
+                }
+
+                synchronized (mux) {
+                    if (!canceled) {
+                        try {
+                            mux.wait(2000);
+                        }
+                        catch (InterruptedException e) {
+                            //No-op.
+                        }
+                    }
+                }
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public void interrupt() {
+            synchronized (mux) {
+                canceled = true;
+
+                mux.notifyAll();
+            }
+
+            super.interrupt();
+        }
+    }
+
+    /** */
+    private class DiscoveryListener implements GridLocalEventListener {
+        /** {@inheritDoc} */
+        @Override public void onEvent(IgniteEvent evt) {
+            info("Discovery event [event=" + evt + ']');
+        }
+    }
+
+    /** */
+    protected GridAbstractDiscoveryRandomStartStopTest() {
+        super(false);
+    }
+
+    /**
+     * @return Max interval.
+     */
+    protected int getMaxInterval() {
+        return DFLT_MAX_INTERVAL;
+    }
+
+    /**
+     *
+     */
+    private class Waiter extends Thread {
+        /** {@inheritDoc} */
+        @Override public void run() {
+            // Wait until Ok is pressed.
+            JOptionPane.showMessageDialog(
+                null,
+                new JComponent[] {
+                    new JLabel("Test started."),
+                    new JLabel("Press OK to stop test.")
+                },
+                "GridGain",
+                JOptionPane.INFORMATION_MESSAGE
+            );
+
+            semaphore = false;
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings({"BusyWait"})
+    public void testDiscovery() throws Exception {
+        Random rand = new Random();
+
+        new Waiter().start();
+
+        while (semaphore) {
+            int interval = rand.nextInt(getMaxInterval() - 1) + 1;
+
+            toggleState();
+
+            if (isRunning)
+                info("Spi stopped for the interval of " + interval + " 
seconds...");
+            else
+                info("Spi started for the interval of " + interval + " 
seconds...");
+
+            try {
+                Thread.sleep(interval * 1000);
+            }
+            catch (InterruptedException e) {
+                error("Got interrupted", e);
+
+                break;
+            }
+        }
+
+        info("Spi stopped...");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void toggleState() throws Exception {
+        if (isRunning)
+            spiStop();
+        else
+            spiStart();
+
+        isRunning = !isRunning;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        if (getSpiContext() != null)
+            getSpiContext().addLocalEventListener(new DiscoveryListener());
+
+        pinger = new Pinger();
+
+        pinger.start();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        pinger.interrupt();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Map<String, Serializable> getNodeAttributes() {
+        Map<String, Serializable> attrs = new HashMap<>(1);
+
+        attrs.put("testDiscoveryAttribute", new Date());
+
+        return attrs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoverySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoverySelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoverySelfTest.java
new file mode 100644
index 0000000..338ce9e
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoverySelfTest.java
@@ -0,0 +1,488 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.spi.discovery;
+
+import mx4j.tools.adaptor.http.*;
+import org.apache.ignite.cluster.*;
+import org.apache.ignite.marshaller.*;
+import org.apache.ignite.spi.*;
+import org.gridgain.grid.kernal.managers.security.*;
+import org.gridgain.grid.security.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import org.gridgain.testframework.config.*;
+import org.gridgain.testframework.junits.*;
+import org.gridgain.testframework.junits.spi.*;
+
+import javax.management.*;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+import static org.apache.ignite.events.IgniteEventType.*;
+import static org.apache.ignite.product.IgniteProductVersion.*;
+
+/**
+ * Base discovery self-test class.
+ * @param <T> SPI implementation class.
+ */
+@SuppressWarnings({"JUnitAbstractTestClassNamingConvention"})
+public abstract class GridAbstractDiscoverySelfTest<T extends IgniteSpi> 
extends GridSpiAbstractTest<T> {
+    /** */
+    private static final List<DiscoverySpi> spis = new ArrayList<>();
+
+    /** */
+    private static final Collection<GridTestResources> spiRsrcs = new 
ArrayList<>();
+
+    /** */
+    private static long spiStartTime;
+
+    /** */
+    private static final Object mux = new Object();
+
+    /** */
+    private static final String TEST_ATTRIBUTE_NAME = "test.node.prop";
+
+    /** */
+    protected GridAbstractDiscoverySelfTest() {
+        super(false);
+    }
+
+    /**
+     * Checks that each started discovery spi found all other SPI's.
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings({"UnconditionalWait"})
+    public void testDiscovery() throws Exception {
+        assert spis.size() > 1;
+        assert spiStartTime > 0;
+        assert spiRsrcs.size() == getSpiCount();
+
+        boolean isAllDiscovered = false;
+
+        while (!isAllDiscovered) {
+            for (DiscoverySpi spi : spis) {
+                if (spi.getRemoteNodes().size() < (getSpiCount() - 1)) {
+                    isAllDiscovered = false;
+
+                    break;
+                }
+
+                isAllDiscovered = true;
+
+                for (GridTestResources rscrs : spiRsrcs) {
+                    UUID nodeId = rscrs.getNodeId();
+
+                    if (!nodeId.equals(spi.getLocalNode().id())) {
+                        if (!isContainsNodeId(spi.getRemoteNodes(), nodeId)) {
+                            isAllDiscovered = false;
+
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (isAllDiscovered)
+                info("All nodes discovered.");
+            else {
+                if (System.currentTimeMillis() > spiStartTime + 
getMaxDiscoveryTime()) {
+                    for (int i = 0; i < getSpiCount(); i++) {
+                        DiscoverySpi spi = spis.get(i);
+
+                        info("Remote nodes [spiIdx=" + i + ", nodes=" + 
spi.getRemoteNodes() + ']');
+                    }
+
+                    fail("Nodes were not discovered.");
+                }
+                else {
+                    synchronized (mux) {
+                        mux.wait(getMaxDiscoveryTime());
+                    }
+                }
+            }
+        }
+    }
+
+    /** */
+    private static class DiscoveryListener implements DiscoverySpiListener {
+        /** * */
+        private boolean isMetricsUpdate;
+
+        /**
+         *
+         *
+         * @return Metrics updates.
+         */
+        public boolean isMetricsUpdated() {
+            return isMetricsUpdate;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onDiscovery(int type, long topVer, ClusterNode 
node, Collection<ClusterNode> topSnapshot,
+            Map<Long, Collection<ClusterNode>> topHist) {
+            if (type == EVT_NODE_METRICS_UPDATED)
+                isMetricsUpdate = true;
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings({"UnconditionalWait"})
+    public void testMetrics() throws Exception {
+        Collection<DiscoveryListener> listeners = new ArrayList<>();
+
+        long metricsStartTime = System.currentTimeMillis();
+
+        for (DiscoverySpi spi : spis) {
+            DiscoveryListener metricsUpdateLsnr = new DiscoveryListener();
+
+            spi.setListener(metricsUpdateLsnr);
+
+            listeners.add(metricsUpdateLsnr);
+        }
+
+        boolean isAllSpiMetricUpdated = false;
+
+        while (!isAllSpiMetricUpdated) {
+            isAllSpiMetricUpdated = true;
+
+            for (DiscoveryListener lsnr : listeners) {
+                if (!lsnr.isMetricsUpdated()) {
+                    isAllSpiMetricUpdated = false;
+
+                    break;
+                }
+            }
+
+            if (isAllSpiMetricUpdated)
+                info("All SPI metrics updated.");
+            else {
+                if (System.currentTimeMillis() > metricsStartTime + 
getMaxMetricsWaitTime()) {
+                    for (int i = 0; i < getSpiCount(); i++) {
+                        DiscoverySpi spi = spis.get(i);
+
+                        info("Remote nodes [spiIdx=" + i + ", nodes=" + 
spi.getRemoteNodes() + ']');
+                    }
+
+                    fail("SPI Metrics not updated.");
+                }
+                else {
+                    synchronized (mux) {
+                        mux.wait(getMaxMetricsWaitTime());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests whether local node heartbeats cause METRICS_UPDATE event.
+     *
+     * @throws Exception If test failed.
+     */
+    public void testLocalHeartbeat() throws Exception {
+        AtomicInteger[] locUpdCnts = new AtomicInteger[getSpiCount()];
+
+        int i = 0;
+
+        for (final DiscoverySpi spi : spis) {
+            final AtomicInteger spiCnt = new AtomicInteger(0);
+
+            DiscoverySpiListener locHeartbeatLsnr = new DiscoverySpiListener() 
{
+                @Override public void onDiscovery(int type, long topVer, 
ClusterNode node,
+                    Collection<ClusterNode> topSnapshot, Map<Long, 
Collection<ClusterNode>> topHist) {
+                    // If METRICS_UPDATED came from local node
+                    if (type == EVT_NODE_METRICS_UPDATED
+                        && node.id().equals(spi.getLocalNode().id()))
+                        spiCnt.addAndGet(1);
+                }
+            };
+
+            locUpdCnts[i] = spiCnt;
+
+            spi.setListener(locHeartbeatLsnr);
+
+            i++;
+        }
+
+        // Sleep fro 3 Heartbeats.
+        Thread.sleep(getMaxDiscoveryTime() * 3);
+
+        for (AtomicInteger cnt : locUpdCnts) {
+            assert cnt.get() > 1 : "One of the SPIs did not get at least 2 
METRICS_UPDATE events from local node";
+        }
+    }
+
+    /**
+     * @param nodes Nodes iterator.
+     * @param nodeId Node UUID.
+     * @return {@code true} if provided iterator contains node with provided 
UUID.
+     */
+    private boolean isContainsNodeId(Iterable<ClusterNode> nodes, UUID nodeId) 
{
+        for (ClusterNode node : nodes) {
+            assert node.id() != null;
+
+            if (node.id().equals(nodeId))
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks that physical address of local node is equal to local.ip 
property.
+     */
+    public void testLocalNode() {
+        for (DiscoverySpi spi : spis) {
+            ClusterNode loc = spi.getLocalNode();
+
+            Collection<ClusterNode> rmt = spi.getRemoteNodes();
+
+            assert !rmt.contains(loc);
+        }
+    }
+
+    /**
+     * Check that "test.node.prop" is present on all nodes.
+     */
+    public void testNodeAttributes() {
+        for (DiscoverySpi spi : spis) {
+            assert !spi.getRemoteNodes().isEmpty() : "No remote nodes found in 
Spi.";
+
+            Collection<UUID> nodeIds = new HashSet<>();
+
+            for (GridTestResources rsrc : spiRsrcs) {
+                nodeIds.add(rsrc.getNodeId());
+            }
+
+            for (ClusterNode node : spi.getRemoteNodes()) {
+                if (nodeIds.contains(node.id())) {
+                    Serializable attr = node.attribute(TEST_ATTRIBUTE_NAME);
+
+                    if (attr == null || !(attr instanceof String)) {
+                        fail("Node does not contains attribute [attr=" + 
TEST_ATTRIBUTE_NAME + ", nodeId=" +
+                            node.id() + ", spiIdx=" + spis.indexOf(spi) + ']');
+                    }
+                    else if (!"true".equals(attr)) {
+                        fail("Attribute value is wrong [attr=" + 
TEST_ATTRIBUTE_NAME + ", value=" + attr + ", nodeId=" +
+                            node.id() + ", spiIdx=" + spis.indexOf(spi) + ']');
+                    }
+                    else {
+                        info("Node contains attribute [attr=" + 
TEST_ATTRIBUTE_NAME + ", value=" + attr + ", nodeId=" +
+                            node.id() + ", spiIdx=" + spis.indexOf(spi) + ']');
+                    }
+                }
+                else
+                    error("Discovered unknown node [node=" + node + ", 
spiIdx=" + spis.indexOf(spi) + ']');
+            }
+        }
+    }
+
+    /**
+     * Checks that each spi can pings all other.
+     */
+    public void testPing() {
+        for (DiscoverySpi spi : spis) {
+            for (GridTestResources rscrs : spiRsrcs) {
+                UUID nodeId = rscrs.getNodeId();
+
+                if (spi.pingNode(nodeId))
+                    info("Ping node success [nodeId=" + nodeId + ", spiIdx=" + 
spis.indexOf(spi) + ']');
+                else
+                    fail("Ping node error [nodeId=" + nodeId + ", spiIdx=" + 
spis.indexOf(spi) + ']');
+            }
+        }
+    }
+
+    /**
+     * Checks that node serializable.
+     *
+     * @throws Exception If failed.
+     */
+    public void testNodeSerialize() throws Exception {
+        for (DiscoverySpi spi : spis) {
+            ClusterNode node = spi.getLocalNode();
+
+            assert node != null;
+
+            writeObject(node);
+
+            info("Serialize node success [nodeId=" + node.id() + ", spiIdx=" + 
spis.indexOf(spi) + ']');
+        }
+    }
+
+    /**
+     * @param idx Index.
+     * @return Discovery SPI.
+     */
+    protected abstract DiscoverySpi getSpi(int idx);
+
+    /**
+     * @return SPI count.
+     */
+    protected int getSpiCount() {
+        return 2;
+    }
+
+    /**
+     * @return Maximum discovery time.
+     */
+    protected long getMaxDiscoveryTime() {
+        return 10000;
+    }
+
+    /**
+     * @return Maximum metrics wait time.
+     */
+    protected long getMaxMetricsWaitTime() {
+        return getMaxDiscoveryTime();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        try {
+            for (int i = 0; i < getSpiCount(); i++) {
+                DiscoverySpi spi = getSpi(i);
+
+                GridTestResources rsrcMgr = new 
GridTestResources(getMBeanServer(i));
+
+                rsrcMgr.inject(spi);
+
+                spi.setNodeAttributes(Collections.<String, 
Object>singletonMap(TEST_ATTRIBUTE_NAME, "true"),
+                    fromString("99.99.99"));
+
+                spi.setListener(new DiscoverySpiListener() {
+                    @SuppressWarnings({"NakedNotify"})
+                    @Override public void onDiscovery(int type, long topVer, 
ClusterNode node,
+                        Collection<ClusterNode> topSnapshot, Map<Long, 
Collection<ClusterNode>> topHist) {
+                        info("Discovery event [type=" + type + ", node=" + 
node + ']');
+
+                        synchronized (mux) {
+                            mux.notifyAll();
+                        }
+                    }
+                });
+
+                spi.setDataExchange(new DiscoverySpiDataExchange() {
+                    @Override public List<Object> collect(UUID nodeId) {
+                        return new LinkedList<>();
+                    }
+
+                    @Override public void onExchange(List<Object> data) {
+                        // No-op.
+                    }
+                });
+
+                spi.setAuthenticator(new DiscoverySpiNodeAuthenticator() {
+                    @Override public GridSecurityContext 
authenticateNode(ClusterNode n, GridSecurityCredentials cred) {
+                        GridSecuritySubjectAdapter subj = new 
GridSecuritySubjectAdapter(
+                            GridSecuritySubjectType.REMOTE_NODE, n.id());
+
+                        subj.permissions(new GridAllowAllPermissionSet());
+
+                        return new GridSecurityContext(subj);
+                    }
+
+                    @Override public boolean isGlobalNodeAuthentication() {
+                        return false;
+                    }
+                });
+
+
+                spi.spiStart(getTestGridName() + i);
+
+                spis.add(spi);
+
+                spiRsrcs.add(rsrcMgr);
+
+                // Force to use test context instead of default dummy context.
+                spi.onContextInitialized(initSpiContext());
+            }
+        }
+        catch (Throwable e) {
+            e.printStackTrace();
+        }
+
+        spiStartTime = System.currentTimeMillis();
+    }
+
+    /**
+     * @param idx Index.
+     * @return MBean server.
+     * @throws Exception If failed.
+     */
+    private MBeanServer getMBeanServer(int idx) throws Exception {
+        HttpAdaptor adaptor = new HttpAdaptor();
+
+        MBeanServer srv = MBeanServerFactory.createMBeanServer();
+
+        
adaptor.setPort(Integer.valueOf(GridTestProperties.getProperty("discovery.mbeanserver.selftest.baseport"))
 +
+            idx);
+
+        srv.registerMBean(adaptor, new 
ObjectName("mbeanAdaptor:protocol=HTTP"));
+
+        adaptor.start();
+
+        return srv;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        assert spis.size() > 1;
+        assert spis.size() == spiRsrcs.size();
+
+        for (DiscoverySpi spi : spis) {
+            spi.setListener(null);
+
+            spi.spiStop();
+        }
+
+        for (GridTestResources rscrs : spiRsrcs) {
+            rscrs.stopThreads();
+        }
+
+        // Clear.
+        spis.clear();
+        spiRsrcs.clear();
+
+        spiStartTime = 0;
+
+        tearDown();
+    }
+
+    /**
+     * @param node Grid node.
+     * @throws IOException If write failed.
+     */
+    private void writeObject(ClusterNode node) throws Exception {
+
+        IgniteMarshaller marshaller = getTestResources().getMarshaller();
+
+        OutputStream out = new NullOutputStream();
+
+        try {
+            marshaller.marshal(node, out);
+        }
+        finally {
+            U.close(out, null);
+        }
+    }
+
+    /**
+     *
+     */
+    private static class NullOutputStream extends OutputStream {
+        /** {@inheritDoc} */
+        @Override public void write(int b) throws IOException {
+            // No-op
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryTest.java
new file mode 100644
index 0000000..a6ee6e5
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridAbstractDiscoveryTest.java
@@ -0,0 +1,145 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.spi.discovery;
+
+import org.apache.ignite.cluster.*;
+import org.apache.ignite.events.*;
+import org.gridgain.grid.kernal.managers.eventstorage.*;
+import org.gridgain.testframework.junits.spi.*;
+
+import javax.swing.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Base discovery test class.
+ * @param <T> SPI implementation class.
+ */
+@SuppressWarnings({"JUnitAbstractTestClassNamingConvention"})
+public abstract class GridAbstractDiscoveryTest<T extends DiscoverySpi> 
extends GridSpiAbstractTest<T> {
+    /** */
+    @SuppressWarnings({"ClassExplicitlyExtendsThread"})
+    private class Pinger extends Thread {
+        /** */
+        private final Object mux = new Object();
+
+        /** */
+        @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
+        private boolean isCanceled;
+
+        /** {@inheritDoc} */
+        @SuppressWarnings({"UnusedCatchParameter"})
+        @Override public void run() {
+            Random rnd = new Random();
+
+            while (isCanceled) {
+                try {
+                    Collection<ClusterNode> nodes = getSpi().getRemoteNodes();
+
+                    pingNode(UUID.randomUUID(), false);
+
+                    for (ClusterNode item : nodes) {
+                        pingNode(item.id(), true);
+                    }
+
+                    pingNode(UUID.randomUUID(), false);
+                }
+                catch (Exception e) {
+                    error("Can't get SPI.", e);
+                }
+
+                synchronized (mux) {
+                    if (isCanceled) {
+                        try {
+                            mux.wait(getPingFrequency() * (1 + 
rnd.nextInt(10)));
+                        }
+                        catch (InterruptedException e) {
+                            //No-op.
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * @param nodeId Node UUID.
+         * @param exists Exists flag.
+         * @throws Exception If failed.
+         */
+        private void pingNode(UUID nodeId, boolean exists) throws Exception {
+            boolean flag = getSpi().pingNode(nodeId);
+
+            info((flag != exists ? "***Error*** " : "") + "Ping " + (exists ? 
"exist" : "random") +
+                " node [nodeId=" + nodeId + ", pingResult=" + flag + ']');
+        }
+
+        /** {@inheritDoc} */
+        @Override public void interrupt() {
+            synchronized (mux) {
+                isCanceled = true;
+
+                mux.notifyAll();
+            }
+
+            super.interrupt();
+        }
+    }
+
+    /**
+     * @return Ping frequency.
+     */
+    public abstract long getPingFrequency();
+
+    /**
+     * @return Pinger start flag.
+     */
+    public boolean isPingerStart() {
+        return true;
+    }
+
+    /** */
+    private class DiscoveryListener implements GridLocalEventListener {
+        /** {@inheritDoc} */
+        @Override public void onEvent(IgniteEvent evt) {
+            info("Discovery event [event=" + evt + ']');
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDiscovery() throws Exception {
+        GridLocalEventListener discoLsnr = new DiscoveryListener();
+
+        getSpiContext().addLocalEventListener(discoLsnr);
+
+        Pinger pinger = null;
+
+        if (isPingerStart()) {
+            pinger = new Pinger();
+
+            pinger.start();
+        }
+
+        JOptionPane.showMessageDialog(null, "Press OK to end test.");
+
+        if (pinger != null)
+            pinger.interrupt();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Map<String, Serializable> getNodeAttributes() {
+        Map<String, Serializable> attrs = new HashMap<>(1);
+
+        attrs.put("testDiscoveryAttribute", new Date());
+
+        return attrs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridDiscoveryMetricsHelperSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridDiscoveryMetricsHelperSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridDiscoveryMetricsHelperSelfTest.java
new file mode 100644
index 0000000..fffd5aa
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/GridDiscoveryMetricsHelperSelfTest.java
@@ -0,0 +1,141 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.spi.discovery;
+
+import org.apache.ignite.cluster.*;
+import org.gridgain.testframework.junits.common.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Grid discovery metrics test.
+ */
+@GridCommonTest(group = "Utils")
+public class GridDiscoveryMetricsHelperSelfTest extends GridCommonAbstractTest 
{
+    /** */
+    private static final int METRICS_COUNT = 500;
+
+    /** */
+    public GridDiscoveryMetricsHelperSelfTest() {
+        super(false /*don't start grid*/);
+    }
+
+    /** */
+    public void testMetricsSize() {
+        byte[] data = new byte[DiscoveryMetricsHelper.METRICS_SIZE];
+
+        // Test serialization.
+        int off = DiscoveryMetricsHelper.serialize(data, 0, createMetrics());
+
+        assert off == DiscoveryMetricsHelper.METRICS_SIZE;
+
+        // Test deserialization.
+        ClusterNodeMetrics res = DiscoveryMetricsHelper.deserialize(data, 0);
+
+        assert res != null;
+    }
+
+    /** */
+    public void testSerialization() {
+        byte[] data = new byte[DiscoveryMetricsHelper.METRICS_SIZE];
+
+        ClusterNodeMetrics metrics1 = createMetrics();
+
+        // Test serialization.
+        int off = DiscoveryMetricsHelper.serialize(data, 0, metrics1);
+
+        assert off == DiscoveryMetricsHelper.METRICS_SIZE;
+
+        // Test deserialization.
+        ClusterNodeMetrics metrics2 = DiscoveryMetricsHelper.deserialize(data, 
0);
+
+        assert metrics2 != null;
+
+        assert metrics1.equals(metrics2);
+    }
+
+    /**
+     * @throws IOException If I/O error occurs.
+     */
+    public void testMultipleMetricsSerialization() throws IOException {
+        Map<UUID, ClusterNodeMetrics> metrics = new HashMap<>(METRICS_COUNT);
+
+        for (int i = 0; i < METRICS_COUNT; i++)
+            metrics.put(UUID.randomUUID(), createMetrics());
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(1024 * 1024);
+
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+
+        oos.writeObject(metrics);
+
+        oos.close();
+
+        info(">>> Size of metrics map <UUID, GridNodeMetrics> in KB 
[metricsCount=" + METRICS_COUNT +
+            ", size=" + bos.size() / 1024.0 + ']');
+    }
+
+    /**
+     * @return Test metrics.
+     */
+    private ClusterNodeMetrics createMetrics() {
+        DiscoveryNodeMetricsAdapter metrics = new 
DiscoveryNodeMetricsAdapter();
+
+        metrics.setAvailableProcessors(1);
+        metrics.setAverageActiveJobs(2);
+        metrics.setAverageCancelledJobs(3);
+        metrics.setAverageJobExecuteTime(4);
+        metrics.setAverageJobWaitTime(5);
+        metrics.setAverageRejectedJobs(6);
+        metrics.setAverageWaitingJobs(7);
+        metrics.setCurrentActiveJobs(8);
+        metrics.setCurrentCancelledJobs(9);
+        metrics.setCurrentIdleTime(10);
+        metrics.setCurrentIdleTime(11);
+        metrics.setCurrentJobExecuteTime(12);
+        metrics.setCurrentJobWaitTime(13);
+        metrics.setCurrentRejectedJobs(14);
+        metrics.setCurrentWaitingJobs(15);
+        metrics.setCurrentDaemonThreadCount(16);
+        metrics.setHeapMemoryCommitted(17);
+        metrics.setHeapMemoryInitialized(18);
+        metrics.setHeapMemoryMaximum(19);
+        metrics.setHeapMemoryUsed(20);
+        metrics.setLastUpdateTime(21);
+        metrics.setMaximumActiveJobs(22);
+        metrics.setMaximumCancelledJobs(23);
+        metrics.setMaximumJobExecuteTime(24);
+        metrics.setMaximumJobWaitTime(25);
+        metrics.setMaximumRejectedJobs(26);
+        metrics.setMaximumWaitingJobs(27);
+        metrics.setNonHeapMemoryCommitted(28);
+        metrics.setNonHeapMemoryInitialized(29);
+        metrics.setNonHeapMemoryMaximum(30);
+        metrics.setNonHeapMemoryUsed(31);
+        metrics.setMaximumThreadCount(32);
+        metrics.setStartTime(33);
+        metrics.setCurrentCpuLoad(34);
+        metrics.setCurrentThreadCount(35);
+        metrics.setTotalCancelledJobs(36);
+        metrics.setTotalExecutedJobs(37);
+        metrics.setTotalIdleTime(38);
+        metrics.setTotalRejectedJobs(39);
+        metrics.setTotalStartedThreadCount(40);
+        metrics.setUpTime(41);
+        metrics.setSentMessagesCount(42);
+        metrics.setSentBytesCount(43);
+        metrics.setReceivedMessagesCount(44);
+        metrics.setReceivedBytesCount(45);
+        metrics.setOutboundMessagesQueueSize(46);
+
+        return metrics;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/package.html
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/package.html 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/package.html
new file mode 100644
index 0000000..5cad80a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/package.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<!--
+    @html.file.header
+    _________        _____ __________________        _____
+    __  ____/___________(_)______  /__  ____/______ ____(_)_______
+    _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+    / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+    \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+-->
+<html>
+<body>
+    <!-- Package description. -->
+    Contains internal tests or test related classes and interfaces.
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1ef8f69b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/GridTcpClientDiscoverySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/GridTcpClientDiscoverySelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/GridTcpClientDiscoverySelfTest.java
new file mode 100644
index 0000000..25299cb
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/GridTcpClientDiscoverySelfTest.java
@@ -0,0 +1,683 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.spi.discovery.tcp;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cluster.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.events.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.resources.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.gridgain.grid.util.*;
+import org.gridgain.grid.util.typedef.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import org.gridgain.testframework.*;
+import org.gridgain.testframework.junits.common.*;
+
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import static java.util.concurrent.TimeUnit.*;
+import static org.apache.ignite.events.IgniteEventType.*;
+
+/**
+ * Client-based discovery tests.
+ */
+public class GridTcpClientDiscoverySelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final AtomicInteger srvIdx = new AtomicInteger();
+
+    /** */
+    private static final AtomicInteger clientIdx = new AtomicInteger();
+
+    /** */
+    private static Collection<UUID> srvNodeIds;
+
+    /** */
+    private static Collection<UUID> clientNodeIds;
+
+    /** */
+    private static int clientsPerSrv;
+
+    /** */
+    private static CountDownLatch srvJoinedLatch;
+
+    /** */
+    private static CountDownLatch srvLeftLatch;
+
+    /** */
+    private static CountDownLatch srvFailedLatch;
+
+    /** */
+    private static CountDownLatch clientJoinedLatch;
+
+    /** */
+    private static CountDownLatch clientLeftLatch;
+
+    /** */
+    private static CountDownLatch clientFailedLatch;
+
+    /** */
+    private static CountDownLatch msgLatch;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setLocalHost("127.0.0.1");
+
+        if (gridName.startsWith("server")) {
+            TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+            disco.setIpFinder(IP_FINDER);
+
+            cfg.setDiscoverySpi(disco);
+        }
+        else if (gridName.startsWith("client")) {
+            TcpClientDiscoverySpi disco = new TcpClientDiscoverySpi();
+
+            TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
+
+            String addr = new ArrayList<>(IP_FINDER.getRegisteredAddresses()).
+                get((clientIdx.get() - 1) / clientsPerSrv).toString();
+
+            if (addr.startsWith("/"))
+                addr = addr.substring(1);
+
+            ipFinder.setAddresses(Arrays.asList(addr));
+
+            disco.setIpFinder(ipFinder);
+
+            cfg.setDiscoverySpi(disco);
+        }
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        Collection<InetSocketAddress> addrs = 
IP_FINDER.getRegisteredAddresses();
+
+        if (!F.isEmpty(addrs))
+            IP_FINDER.unregisterAddresses(addrs);
+
+        srvIdx.set(0);
+        clientIdx.set(0);
+
+        srvNodeIds = new GridConcurrentHashSet<>();
+        clientNodeIds = new GridConcurrentHashSet<>();
+
+        clientsPerSrv = 2;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllClients(true);
+        stopAllServers(true);
+
+        assert G.allGrids().isEmpty();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeJoin() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvJoinedLatch = new CountDownLatch(3);
+        clientJoinedLatch = new CountDownLatch(3);
+
+        attachListeners(3, 3);
+
+        startClientNodes(1);
+
+        await(srvJoinedLatch);
+        await(clientJoinedLatch);
+
+        checkNodes(3, 4);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeLeave() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvLeftLatch = new CountDownLatch(3);
+        clientLeftLatch = new CountDownLatch(2);
+
+        attachListeners(3, 3);
+
+        stopGrid("client-2");
+
+        await(srvLeftLatch);
+        await(clientLeftLatch);
+
+        checkNodes(3, 2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeFail() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvFailedLatch = new CountDownLatch(3);
+        clientFailedLatch = new CountDownLatch(2);
+
+        attachListeners(3, 3);
+
+        failClient(2);
+
+        await(srvFailedLatch);
+        await(clientFailedLatch);
+
+        checkNodes(3, 2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testServerNodeJoin() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvJoinedLatch = new CountDownLatch(3);
+        clientJoinedLatch = new CountDownLatch(3);
+
+        attachListeners(3, 3);
+
+        startServerNodes(1);
+
+        await(srvJoinedLatch);
+        await(clientJoinedLatch);
+
+        checkNodes(4, 3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testServerNodeLeave() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvLeftLatch = new CountDownLatch(2);
+        clientLeftLatch = new CountDownLatch(3);
+
+        attachListeners(3, 3);
+
+        stopGrid("server-2");
+
+        await(srvLeftLatch);
+        await(clientLeftLatch);
+
+        checkNodes(2, 3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testServerNodeFail() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        srvFailedLatch = new CountDownLatch(2);
+        clientFailedLatch = new CountDownLatch(3);
+
+        attachListeners(3, 3);
+
+        assert 
U.<Map>field(G.grid("server-2").configuration().getDiscoverySpi(), 
"clientMsgWorkers").isEmpty();
+
+        failServer(2);
+
+        await(srvFailedLatch);
+        await(clientFailedLatch);
+
+        checkNodes(2, 3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientReconnect() throws Exception {
+        clientsPerSrv = 1;
+
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        resetClientIpFinder(2);
+
+        srvFailedLatch = new CountDownLatch(2);
+        clientFailedLatch = new CountDownLatch(3);
+
+        attachListeners(2, 3);
+
+        failServer(2);
+
+        await(srvFailedLatch);
+        await(clientFailedLatch);
+
+        checkNodes(2, 3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeJoinOneServer() throws Exception {
+        startServerNodes(1);
+
+        srvJoinedLatch = new CountDownLatch(1);
+
+        attachListeners(1, 0);
+
+        startClientNodes(1);
+
+        await(srvJoinedLatch);
+
+        checkNodes(1, 1);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeLeaveOneServer() throws Exception {
+        startServerNodes(1);
+        startClientNodes(1);
+
+        checkNodes(1, 1);
+
+        srvLeftLatch = new CountDownLatch(1);
+
+        attachListeners(1, 0);
+
+        stopGrid("client-0");
+
+        await(srvLeftLatch);
+
+        checkNodes(1, 0);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeFailOneServer() throws Exception {
+        startServerNodes(1);
+        startClientNodes(1);
+
+        checkNodes(1, 1);
+
+        srvFailedLatch = new CountDownLatch(1);
+
+        attachListeners(1, 0);
+
+        failClient(0);
+
+        await(srvFailedLatch);
+
+        checkNodes(1, 0);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMetrics() throws Exception {
+        startServerNodes(3);
+        startClientNodes(3);
+
+        checkNodes(3, 3);
+
+        attachListeners(3, 3);
+
+        assertTrue(checkMetrics(3, 3, 0));
+
+        G.grid("client-0").compute().broadcast(F.noop());
+
+        assertTrue(GridTestUtils.waitForCondition(new PA() {
+            @Override public boolean apply() {
+                return checkMetrics(3, 3, 1);
+            }
+        }, 10000));
+
+        checkMetrics(3, 3, 1);
+
+        G.grid("server-0").compute().broadcast(F.noop());
+
+        assertTrue(GridTestUtils.waitForCondition(new PA() {
+            @Override public boolean apply() {
+                return checkMetrics(3, 3, 2);
+            }
+        }, 10000));
+    }
+
+    /**
+     * @param srvCnt Number of Number of server nodes.
+     * @param clientCnt Number of client nodes.
+     * @param execJobsCnt Expected number of executed jobs.
+     * @return Whether metrics are correct.
+     */
+    private boolean checkMetrics(int srvCnt, int clientCnt, int execJobsCnt) {
+        for (int i = 0; i < srvCnt; i++) {
+            Ignite g = G.grid("server-" + i);
+
+            for (ClusterNode n : g.cluster().nodes()) {
+                if (n.metrics().getTotalExecutedJobs() != execJobsCnt)
+                    return false;
+            }
+        }
+
+        for (int i = 0; i < clientCnt; i++) {
+            Ignite g = G.grid("client-" + i);
+
+            for (ClusterNode n : g.cluster().nodes()) {
+                if (n.metrics().getTotalExecutedJobs() != execJobsCnt)
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDataExchangeFromServer() throws Exception {
+        testDataExchange("server-0");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    // TODO: GG-9174
+    public void _testDataExchangeFromClient() throws Exception {
+        testDataExchange("client-0");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void testDataExchange(String masterName) throws Exception {
+        startServerNodes(2);
+        startClientNodes(2);
+
+        checkNodes(2, 2);
+
+        IgniteMessaging msg = grid(masterName).message();
+
+        UUID id = null;
+
+        try {
+            id = msg.remoteListen(null, new MessageListener());
+
+            msgLatch = new CountDownLatch(4);
+
+            msg.send(null, "Message 1");
+
+            await(msgLatch);
+
+            startServerNodes(1);
+            startClientNodes(1);
+
+            checkNodes(3, 3);
+
+            msgLatch = new CountDownLatch(6);
+
+            msg.send(null, "Message 2");
+
+            await(msgLatch);
+        }
+        finally {
+            if (id != null)
+                msg.stopRemoteListen(id);
+        }
+    }
+
+    /**
+     * @param idx Index.
+     * @throws Exception In case of error.
+     */
+    private void resetClientIpFinder(int idx) throws Exception {
+        TcpClientDiscoverySpi disco =
+            (TcpClientDiscoverySpi)G.grid("client-" + 
idx).configuration().getDiscoverySpi();
+
+        TcpDiscoveryVmIpFinder ipFinder = 
(TcpDiscoveryVmIpFinder)disco.getIpFinder();
+
+        String addr = 
IP_FINDER.getRegisteredAddresses().iterator().next().toString();
+
+        if (addr.startsWith("/"))
+            addr = addr.substring(1);
+
+        ipFinder.setAddresses(Arrays.asList(addr));
+    }
+
+    /**
+     * @param cnt Number of nodes.
+     * @throws Exception In case of error.
+     */
+    private void startServerNodes(int cnt) throws Exception {
+        for (int i = 0; i < cnt; i++) {
+            Ignite g = startGrid("server-" + srvIdx.getAndIncrement());
+
+            srvNodeIds.add(g.cluster().localNode().id());
+        }
+    }
+
+    /**
+     * @param cnt Number of nodes.
+     * @throws Exception In case of error.
+     */
+    private void startClientNodes(int cnt) throws Exception {
+        for (int i = 0; i < cnt; i++) {
+            Ignite g = startGrid("client-" + clientIdx.getAndIncrement());
+
+            clientNodeIds.add(g.cluster().localNode().id());
+        }
+    }
+
+    /**
+     * @param idx Index.
+     */
+    private void failServer(int idx) {
+        ((TcpDiscoverySpi)G.grid("server-" + 
idx).configuration().getDiscoverySpi()).simulateNodeFailure();
+    }
+
+    /**
+     * @param idx Index.
+     */
+    private void failClient(int idx) {
+        ((TcpClientDiscoverySpi)G.grid("client-" + 
idx).configuration().getDiscoverySpi()).simulateNodeFailure();
+    }
+
+    /**
+     * @param srvCnt Number of server nodes.
+     * @param clientCnt Number of client nodes.
+     */
+    private void attachListeners(int srvCnt, int clientCnt) throws Exception {
+        if (srvJoinedLatch != null) {
+            for (int i = 0; i < srvCnt; i++) {
+                G.grid("server-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Joined event fired on server: " + evt);
+
+                        srvJoinedLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_JOINED);
+            }
+        }
+
+        if (srvLeftLatch != null) {
+            for (int i = 0; i < srvCnt; i++) {
+                G.grid("server-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Left event fired on server: " + evt);
+
+                        srvLeftLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_LEFT);
+            }
+        }
+
+        if (srvFailedLatch != null) {
+            for (int i = 0; i < srvCnt; i++) {
+                G.grid("server-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Failed event fired on server: " + evt);
+
+                        srvFailedLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_FAILED);
+            }
+        }
+
+        if (clientJoinedLatch != null) {
+            for (int i = 0; i < clientCnt; i++) {
+                G.grid("client-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Joined event fired on client: " + evt);
+
+                        clientJoinedLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_JOINED);
+            }
+        }
+
+        if (clientLeftLatch != null) {
+            for (int i = 0; i < clientCnt; i++) {
+                G.grid("client-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Left event fired on client: " + evt);
+
+                        clientLeftLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_LEFT);
+            }
+        }
+
+        if (clientFailedLatch != null) {
+            for (int i = 0; i < clientCnt; i++) {
+                G.grid("client-" + i).events().localListen(new 
IgnitePredicate<IgniteEvent>() {
+                    @Override public boolean apply(IgniteEvent evt) {
+                        info("Failed event fired on client: " + evt);
+
+                        clientFailedLatch.countDown();
+
+                        return true;
+                    }
+                }, EVT_NODE_FAILED);
+            }
+        }
+    }
+
+    /**
+     * @param srvCnt Number of server nodes.
+     * @param clientCnt Number of client nodes.
+     */
+    private void checkNodes(int srvCnt, int clientCnt) {
+        for (int i = 0; i < srvCnt; i++) {
+            Ignite g = G.grid("server-" + i);
+
+            assertTrue(srvNodeIds.contains(g.cluster().localNode().id()));
+
+            assertFalse(g.cluster().localNode().isClient());
+
+            checkRemoteNodes(g, srvCnt + clientCnt - 1);
+        }
+
+        for (int i = 0; i < clientCnt; i++) {
+            Ignite g = G.grid("client-" + i);
+
+            assertTrue(clientNodeIds.contains(g.cluster().localNode().id()));
+
+            assertTrue(g.cluster().localNode().isClient());
+
+            checkRemoteNodes(g, srvCnt + clientCnt - 1);
+        }
+    }
+
+    /**
+     * @param ignite Grid.
+     * @param expCnt Expected nodes count.
+     */
+    @SuppressWarnings("TypeMayBeWeakened")
+    private void checkRemoteNodes(Ignite ignite, int expCnt) {
+        Collection<ClusterNode> nodes = ignite.cluster().forRemotes().nodes();
+
+        assertEquals(expCnt, nodes.size());
+
+        for (ClusterNode node : nodes) {
+            UUID id = node.id();
+
+            if (clientNodeIds.contains(id))
+                assertTrue(node.isClient());
+            else if (srvNodeIds.contains(id))
+                assertFalse(node.isClient());
+            else
+                assert false : "Unexpected node ID: " + id;
+        }
+    }
+
+    /**
+     * @param latch Latch.
+     * @throws InterruptedException If interrupted.
+     */
+    private void await(CountDownLatch latch) throws InterruptedException {
+        assertTrue("Latch count: " + latch.getCount(), latch.await(10000, 
MILLISECONDS));
+    }
+
+    /**
+     */
+    private static class MessageListener implements IgniteBiPredicate<UUID, 
Object> {
+        @IgniteLocalNodeIdResource
+        private UUID nodeId;
+
+        /** {@inheritDoc} */
+        @Override public boolean apply(UUID uuid, Object msg) {
+            X.println(">>> Received [locNodeId=" + nodeId + ", msg=" + msg + 
']');
+
+            msgLatch.countDown();
+
+            return true;
+        }
+    }
+}

Reply via email to