ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agoncha...@apache.org
Subject [2/4] ignite git commit: IGNITE-5392 - Joining node must accept cluster active status
Date Sun, 11 Jun 2017 18:54:21 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/AbstractNodeJoinTemplate.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/AbstractNodeJoinTemplate.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/AbstractNodeJoinTemplate.java
new file mode 100644
index 0000000..112ea03
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/AbstractNodeJoinTemplate.java
@@ -0,0 +1,743 @@
+/*
+ * 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.cache.database.standbycluster;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Assert;
+
+import static org.apache.ignite.internal.util.IgniteUtils.field;
+
+/**
+ *
+ */
+public abstract class AbstractNodeJoinTemplate extends GridCommonAbstractTest {
+    /** Cache 1. */
+    protected static final String cache1 = "cache1";
+
+    /** Cache 2. */
+    protected static final String cache2 = "cache2";
+
+    //Todo Cache with node filter.
+    protected static final String cache3 = "cache3";
+
+    protected static final String cache4 = "cache4";
+
+    protected static final String cache5 = "cache5";
+
+    /** Caches info. */
+    public static final String CACHES_INFO = "cachesInfo";
+
+    /** Registered caches. */
+    public static final String REGISTERED_CACHES = "registeredCaches";
+
+    /** Caches. */
+    public static final String CACHES = "caches";
+
+    /**
+     * @param ig Ig.
+     */
+    protected static Map<String, DynamicCacheDescriptor> cacheDescriptors(IgniteEx ig) {
+        return field(field(ig.context().cache(), CACHES_INFO), REGISTERED_CACHES);
+    }
+
+    /**
+     * @param ig Ig.
+     */
+    protected static Map<String, GridCacheAdapter> caches(IgniteEx ig){
+        return field(ig.context().cache(), CACHES);
+    }
+
+    /**
+     *
+     */
+    public abstract JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception;
+
+    /**
+     *
+     */
+    public abstract JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception;
+
+    /**
+     *
+     */
+    public abstract JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception;
+
+    /**
+     *
+     */
+    public abstract JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception;
+
+    /**
+     *
+     */
+    public abstract JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception;
+
+    // Client node join.
+
+    public abstract JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception;
+
+    public abstract JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception;
+
+    public abstract JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception;
+
+    public abstract JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationSameOnBothTemplate() throws Exception;
+
+    public abstract JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinWithOutConfiguration() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testStaticCacheConfigurationOnJoin() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testStaticCacheConfigurationInCluster() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testStaticCacheConfigurationSameOnBoth() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testStaticCacheConfigurationDifferentOnBoth() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinClientWithOutConfiguration() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinClientStaticCacheConfigurationOnJoin() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinClientStaticCacheConfigurationInCluster() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinClientStaticCacheConfigurationSameOnBoth() throws Exception;
+
+    /**
+     *
+     */
+    public abstract void testJoinClientStaticCacheConfigurationDifferentOnBoth() throws Exception;
+
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+    }
+
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+    }
+
+    /**
+     * @param idx Index.
+     */
+    protected String name(int idx) {
+        return getTestIgniteInstanceName(idx);
+    }
+
+    /**
+     * @param name Name.
+     */
+    protected IgniteConfiguration cfg(String name) throws Exception {
+        try {
+            return getConfiguration(name);
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     *
+     */
+    protected JoinNodeTestPlanBuilder builder() {
+        return JoinNodeTestPlanBuilder.builder();
+    }
+
+    /**
+     * @param cfgs Cfgs.
+     */
+    protected static <T> T[] buildConfiguration(T... cfgs) {
+        return cfgs;
+    }
+
+    /**
+     *
+     */
+    protected CacheConfiguration atomicCfg() {
+        return new CacheConfiguration(cache1)
+            .setAtomicityMode(CacheAtomicityMode.ATOMIC);
+    }
+
+    /**
+     *
+     */
+    protected CacheConfiguration transactionCfg() {
+        return new CacheConfiguration(cache2)
+            .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+    }
+
+    /**
+     *
+     */
+    protected CacheConfiguration[] allCacheConfigurations() {
+        return buildConfiguration(atomicCfg(), transactionCfg());
+    }
+
+    /** Set client. */
+    protected final IgniteClosure<IgniteConfiguration, IgniteConfiguration> setClient =
+        new IgniteClosure<IgniteConfiguration, IgniteConfiguration>() {
+            @Override public IgniteConfiguration apply(IgniteConfiguration cfg) {
+                return cfg.setClientMode(true);
+            }
+        };
+
+    /** Ip finder. */
+    private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String name) throws Exception {
+        return super.getConfiguration(name)
+            .setDiscoverySpi(
+                new TcpDiscoverySpi()
+                    .setIpFinder(ipFinder)
+            );
+    }
+
+    /** {@inheritDoc} */
+    protected IgniteConfiguration persistentCfg(IgniteConfiguration cfg) throws Exception {
+        cfg.setPersistentStoreConfiguration(new PersistentStoreConfiguration());
+
+        return cfg;
+    }
+
+    /**
+     *
+     */
+    public static class JoinNodeTestPlanBuilder extends GridCommonAbstractTest {
+        /** String plan builder. */
+        private final StringBuilder strPlanBuilder = new StringBuilder().append("**** Execution plan ****\n");
+
+        /** Nodes. */
+        protected List<String> nodes = new ArrayList<>(4);
+
+        /** Cluster config. */
+        private IgniteConfiguration[] clusterCfg;
+
+        /** Node config. */
+        private IgniteConfiguration nodeCfg;
+
+        /** State default. */
+        private static final Boolean stateDefault = new Boolean(true);
+
+        /** State. */
+        private Boolean state = stateDefault;
+
+        /** Noop. */
+        private static final Runnable Noop = new Runnable() {
+            @Override public void run() {
+            }
+        };
+
+        /** After cluster started. */
+        private Runnable afterClusterStarted = Noop;
+
+        /** After node join. */
+        private Runnable afterNodeJoin = Noop;
+
+        /** After activate. */
+        private Runnable afterActivate = Noop;
+
+        /** After de activate. */
+        private Runnable afterDeActivate = Noop;
+
+        private IgniteCallable<List<CacheConfiguration>> dynamicCacheStart =
+            new IgniteCallable<List<CacheConfiguration>>() {
+                @Override public List<CacheConfiguration> call() throws Exception {
+                    return Arrays.asList(new CacheConfiguration(cache4), new CacheConfiguration(cache5));
+                }
+            };
+
+        private IgniteCallable<List<String>> dynamicCacheStop =
+            new IgniteCallable<List<String>>() {
+                @Override public List<String> call() throws Exception {
+                    return Arrays.asList(cache4, cache5);
+                }
+            };
+
+        private Runnable afterDynamicCacheStarted = Noop;
+
+        private Runnable afterDynamicCacheStopped = Noop;
+
+        /** End. */
+        private Runnable end = Noop;
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder clusterConfiguration(IgniteConfiguration... cfgs) throws Exception {
+            clusterCfg = cfgs;
+
+            strPlanBuilder.append("Start cluster:\n");
+
+            for (IgniteConfiguration cfg : cfgs) {
+                strPlanBuilder.append("node: ")
+                    .append(cfg.getIgniteInstanceName())
+                    .append(" activeOnStart - ")
+                    .append(cfg.isActiveOnStart())
+                    .append("\n");
+
+                CacheConfiguration[] ccfgs = cfg.getCacheConfiguration();
+
+                if (ccfgs != null) {
+                    for (CacheConfiguration ccfg : ccfgs)
+                        strPlanBuilder.append("  cache - ")
+                            .append(ccfg.getName())
+                            .append("\n");
+                }
+            }
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder nodeConfiguration(IgniteConfiguration cfg) {
+            nodeCfg = cfg;
+
+            strPlanBuilder.append("Join node:\n")
+                .append(cfg.getIgniteInstanceName())
+                .append(cfg.isClientMode() != null && cfg.isClientMode() ? " (client)" : "")
+                .append(" activeOnStart - ")
+                .append(cfg.isActiveOnStart())
+                .append("\n");
+
+            CacheConfiguration[] ccfgs = cfg.getCacheConfiguration();
+
+            if (ccfgs != null)
+                for (CacheConfiguration ccfg : ccfgs)
+                    strPlanBuilder.append("  cache - ").append(ccfg.getName()).append("\n");
+
+            return this;
+        }
+
+        /**
+         * @param func Func.
+         */
+        public JoinNodeTestPlanBuilder nodeConfiguration(
+            IgniteClosure<IgniteConfiguration, IgniteConfiguration> func
+        ) {
+
+            nodeCfg = func.apply(nodeCfg);
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder afterClusterStarted(Runnable r) {
+            strPlanBuilder.append("Check after cluster start\n");
+
+            afterClusterStarted = r;
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder afterNodeJoin(Runnable r) {
+            strPlanBuilder.append("Check after node join")
+                .append("\n");
+
+            afterNodeJoin = r;
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder stateAfterJoin(boolean state) {
+            strPlanBuilder.append("Check state on all nodes after join, must be ")
+                .append(state ? "<<active>>" : "<<inactive>>")
+                .append(" \n");
+
+            this.state = state;
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder afterActivate(Runnable r) {
+            strPlanBuilder.append("Check after activate")
+                .append("\n");
+
+            afterActivate = r;
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public JoinNodeTestPlanBuilder afterDeActivate(Runnable r) {
+            strPlanBuilder.append("Check after deActivate")
+                .append("\n");
+
+            afterDeActivate = r;
+
+            return this;
+        }
+
+        public JoinNodeTestPlanBuilder dynamicCacheStart(IgniteCallable<List<CacheConfiguration>> caches){
+            strPlanBuilder.append("Dynamic caches start")
+                .append("\n");
+
+            dynamicCacheStart = caches;
+
+            return this;
+        }
+
+        public JoinNodeTestPlanBuilder afterDynamicCacheStarted(Runnable r){
+            strPlanBuilder.append("Check after dynamic caches start")
+                .append("\n");
+
+            afterDynamicCacheStarted = r;
+
+            return this;
+        }
+
+        public JoinNodeTestPlanBuilder dynamicCacheStop(IgniteCallable<List<String>> caches){
+            strPlanBuilder.append("Dynamic caches stop")
+                .append("\n");
+
+            dynamicCacheStop = caches;
+
+            return this;
+        }
+
+        public JoinNodeTestPlanBuilder afterDynamicCacheStopped(Runnable r){
+            strPlanBuilder.append("Check after dynamic caches stop")
+                .append("\n");
+
+            afterDynamicCacheStopped = r;
+
+            return this;
+        }
+
+        /**
+         * @param end End.
+         */
+        public JoinNodeTestPlanBuilder setEnd(Runnable end) {
+            strPlanBuilder.append("Check before stop")
+                .append("\n");
+
+            this.end = end;
+
+            return this;
+        }
+
+        /**
+         *
+         */
+        public void execute() throws Exception {
+            try {
+                if (state == stateDefault)
+                    fail("State after join must be specific. See JoinNodeTestPlanBuilder.stateAfterJoin(boolean).");
+
+                System.out.println(strPlanBuilder.append("********************").toString());
+
+                IgniteConfiguration[] cfgs = clusterCfg;
+
+                System.out.println(">>> Start cluster");
+
+                for (IgniteConfiguration cfg : cfgs) {
+                    startGrid(cfg);
+
+                    nodes.add(cfg.getIgniteInstanceName());
+                }
+
+                System.out.println(">>> Check after cluster started");
+
+                afterClusterStarted.run();
+
+                System.out.println(">>> Start new node");
+
+                startGrid(nodeCfg);
+
+                nodes.add(nodeCfg.getIgniteInstanceName());
+
+                System.out.println(">>> Check after new node join in cluster");
+
+                afterNodeJoin.run();
+
+                System.out.println(">>> Check cluster state on all nodes");
+
+                IgniteEx crd = grid(nodes.get(0));
+
+                for (IgniteEx ig : grids())
+                    assertEquals((boolean)state, ig.active());
+
+                if (!state) {
+                    System.out.println(">>> Activate cluster");
+
+                    crd.active(true);
+
+                    System.out.println(">>> Check after cluster activated");
+
+                    afterActivate.run();
+                }
+                else {
+                    System.out.println(">>> DeActivate cluster");
+
+                    crd.active(false);
+
+                    System.out.println(">>> Check after cluster deActivated");
+
+                    afterDeActivate.run();
+
+                    System.out.println(">>> Activate cluster");
+
+                    crd.active(true);
+                }
+
+                AffinityTopologyVersion next0Ver = nextMinorVersion(crd);
+
+                crd.createCaches(dynamicCacheStart.call());
+
+                awaitTopologyVersion(next0Ver);
+
+                afterDynamicCacheStarted.run();
+
+                onAllNode(new CI1<IgniteEx>() {
+                    @Override public void apply(IgniteEx ig) {
+                        if (ig.context().discovery().localNode().isClient())
+                            return;
+
+                        Assert.assertNotNull(ig.context().cache().cache(cache4));
+                        Assert.assertNotNull(ig.context().cache().cache(cache5));
+
+                    }
+                });
+
+                AffinityTopologyVersion next1Ver = nextMinorVersion(crd);
+
+                crd.destroyCaches(dynamicCacheStop.call());
+
+                afterDynamicCacheStopped.run();
+
+                awaitTopologyVersion(next1Ver);
+
+                onAllNode(new CI1<IgniteEx>() {
+                    @Override public void apply(IgniteEx ig) {
+                        if (ig.context().discovery().localNode().isClient())
+                            return;
+
+                        Assert.assertNull(ig.context().cache().cache(cache4));
+                        Assert.assertNull(ig.context().cache().cache(cache5));
+
+                    }
+                });
+
+                System.out.println(">>> Finish check");
+
+                end.run();
+            }
+            finally {
+                stopAllGrids();
+            }
+        }
+
+        private AffinityTopologyVersion nextMinorVersion(IgniteEx ig){
+            AffinityTopologyVersion cur = ig.context().discovery().topologyVersionEx();
+
+           return new AffinityTopologyVersion(cur.topologyVersion(), cur.minorTopologyVersion() + 1);
+        }
+
+        private void awaitTopologyVersion(final AffinityTopologyVersion ver){
+            onAllNode(new CI1<IgniteEx>() {
+                @Override public void apply(IgniteEx ig) {
+                    while (true) {
+                        AffinityTopologyVersion locTopVer = ig.context().cache().context()
+                            .exchange().readyAffinityVersion();
+
+                        if (locTopVer.compareTo(ver) < 0){
+                            System.out.println("Top ready " + locTopVer + " on " + ig.localNode().id());
+
+                            try {
+                                Thread.sleep(100);
+                            }
+                            catch (InterruptedException e) {
+                                break;
+                            }
+                        }
+                        else
+                            break;
+                    }
+                }
+            }).run();
+
+        }
+
+        /**
+         *
+         */
+        protected List<IgniteEx> grids() {
+            List<IgniteEx> res = new ArrayList<>();
+
+            for (String name : nodes)
+                res.add(grid(name));
+
+            return res;
+        }
+
+        /**
+         *
+         */
+        public static JoinNodeTestPlanBuilder builder() {
+            return new JoinNodeTestPlanBuilder();
+        }
+
+        /**
+         *
+         */
+        public Runnable checkCacheOnlySystem() {
+            return onAllNode(new IgniteInClosure<IgniteEx>() {
+                @Override public void apply(IgniteEx ig) {
+                    Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                    Assert.assertEquals(2, desc.size());
+
+                    Assert.assertNull(ig.context().cache().cache(cache1));
+                    Assert.assertNull(ig.context().cache().cache(cache2));
+
+                    Map<String, GridCacheAdapter> caches = caches(ig);
+
+                    Assert.assertEquals(2, caches.size());
+                }
+            });
+        }
+
+        /**
+         *
+         */
+        public Runnable checkCacheEmpty() {
+            return onAllNode(new IgniteInClosure<IgniteEx>() {
+                @Override public void apply(IgniteEx ig) {
+                    Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                    Assert.assertTrue(desc.isEmpty());
+
+                    Assert.assertNull(ig.context().cache().cache(cache1));
+                    Assert.assertNull(ig.context().cache().cache(cache2));
+
+                    Map<String, GridCacheAdapter> caches = caches(ig);
+
+                    Assert.assertEquals(0, caches.size());
+                }
+            });
+        }
+
+        /**
+         *
+         */
+        public Runnable checkCacheNotEmpty() {
+            return onAllNode(new IgniteInClosure<IgniteEx>() {
+                @Override public void apply(IgniteEx ig) {
+                    Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                    Assert.assertEquals(4, desc.size());
+
+                    Assert.assertNotNull(ig.context().cache().cache(cache1));
+                    Assert.assertNotNull(ig.context().cache().cache(cache2));
+
+                    Map<String, GridCacheAdapter> caches = caches(ig);
+
+                    Assert.assertEquals(4, caches.size());
+                }
+            });
+        }
+
+        /**
+         * @param cls Closure.
+         */
+        private Runnable onAllNode(final IgniteInClosure<IgniteEx> cls) {
+            return new Runnable() {
+                @Override public void run() {
+                    for (IgniteEx ig : grids()) {
+                        try {
+                            cls.apply(ig);
+                        }
+                        catch (AssertionError e) {
+                            System.out.println("Assertion on " + ig.name());
+
+                            throw e;
+                        }
+                    }
+                }
+            };
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteChangeGlobalStateAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteChangeGlobalStateAbstractTest.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteChangeGlobalStateAbstractTest.java
index f392e6b..5bc5c3a 100644
--- a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteChangeGlobalStateAbstractTest.java
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteChangeGlobalStateAbstractTest.java
@@ -344,8 +344,8 @@ public abstract class IgniteChangeGlobalStateAbstractTest extends GridCommonAbst
         memCfg.setConcurrencyLevel(64);
 
         MemoryPolicyConfiguration memPlcCfg = new MemoryPolicyConfiguration();
-        memPlcCfg.setInitialSize(5 * 1024 * 1024);
-        memPlcCfg.setMaxSize(5 * 1024 * 1024);
+        memPlcCfg.setInitialSize(20 * 1024 * 1024);
+        memPlcCfg.setMaxSize(20 * 1024 * 1024);
         memPlcCfg.setName("dfltMemPlc");
 
         memCfg.setMemoryPolicies(memPlcCfg);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteStandByClusterTest.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteStandByClusterTest.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteStandByClusterTest.java
new file mode 100644
index 0000000..b248208
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/IgniteStandByClusterTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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.cache.database.standbycluster;
+
+import java.util.Arrays;
+import java.util.Map;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Assert;
+
+/**
+ *
+ */
+public class IgniteStandByClusterTest extends GridCommonAbstractTest {
+    private static final TcpDiscoveryIpFinder vmIpFinder = new TcpDiscoveryVmIpFinder(true);
+
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(vmIpFinder));
+        cfg.setPersistentStoreConfiguration(new PersistentStoreConfiguration());
+        cfg.setConsistentId(igniteInstanceName);
+
+        return cfg;
+    }
+
+    public void testNotStartDynamicCachesOnClientAfterActivation() throws Exception {
+        final String cacheName0 = "cache0";
+        final String cacheName = "cache";
+
+        IgniteConfiguration cfg1 = getConfiguration("serv1");
+        IgniteConfiguration cfg2 = getConfiguration("serv2");
+
+        IgniteConfiguration cfg3 = getConfiguration("client");
+        cfg3.setCacheConfiguration(new CacheConfiguration(cacheName0));
+
+        cfg3.setClientMode(true);
+
+        IgniteEx ig1 = startGrid(cfg1);
+        IgniteEx ig2 = startGrid(cfg2);
+        IgniteEx ig3 = startGrid(cfg3);
+
+        assertTrue(!ig1.active());
+        assertTrue(!ig2.active());
+        assertTrue(!ig3.active());
+
+        ig3.active(true);
+
+        assertTrue(ig1.active());
+        assertTrue(ig2.active());
+        assertTrue(ig3.active());
+
+        ig3.createCache(new CacheConfiguration<>(cacheName));
+
+        assertNotNull(ig3.cache(cacheName));
+        assertNotNull(ig1.cache(cacheName));
+        assertNotNull(ig2.cache(cacheName));
+
+        assertNotNull(ig1.cache(cacheName0));
+        assertNotNull(ig3.cache(cacheName0));
+        assertNotNull(ig2.cache(cacheName0));
+
+        ig3.active(false);
+
+        assertTrue(!ig1.active());
+        assertTrue(!ig2.active());
+        assertTrue(!ig3.active());
+
+        ig3.active(true);
+
+        assertTrue(ig1.active());
+        assertTrue(ig2.active());
+        assertTrue(ig3.active());
+
+        assertNotNull(ig1.cache(cacheName));
+        assertNotNull(ig2.cache(cacheName));
+
+        Map<String, GridCacheAdapter<?, ?>> caches = U.field(ig3.context().cache(), "caches");
+
+        // Only system caches and cache0
+        assertTrue(caches.size() == 3);
+
+        assertNull(caches.get(cacheName));
+
+        assertNotNull(caches.get(cacheName0));
+
+        assertNotNull(ig3.cache(cacheName));
+    }
+
+    public void testStaticCacheStartAfterActivationWithCacheFilter() throws Exception {
+        String cache1 = "cache1";
+        String cache2 = "cache2";
+        String cache3 = "cache3";
+
+        IgniteConfiguration cfg1 = getConfiguration("node1");
+
+        cfg1.setCacheConfiguration(
+            new CacheConfiguration(cache1).setNodeFilter(new NodeFilterIgnoreByName("node2")));
+
+        IgniteConfiguration cfg2 = getConfiguration("node2");
+
+        cfg2.setCacheConfiguration(
+            new CacheConfiguration(cache2).setNodeFilter(new NodeFilterIgnoreByName("node3")));
+
+        IgniteConfiguration cfg3 = getConfiguration("node3");
+
+        cfg3.setCacheConfiguration(
+            new CacheConfiguration(cache3).setNodeFilter(new NodeFilterIgnoreByName("node1")));
+
+        IgniteEx ig1 = startGrid(cfg1);
+        IgniteEx ig2 = startGrid(cfg2);
+        IgniteEx ig3 = startGrid(cfg3);
+
+        assertTrue(!ig1.active());
+        assertTrue(!ig2.active());
+        assertTrue(!ig3.active());
+
+        for (IgniteEx ig: Arrays.asList(ig1,ig2,ig3)){
+            Map<String, DynamicCacheDescriptor> desc = U.field(U.field(ig.context().cache(), "cachesInfo"), "registeredCaches");
+
+            assertEquals(0, desc.size());
+        }
+
+        ig3.active(true);
+
+        assertTrue(ig1.active());
+        assertTrue(ig2.active());
+        assertTrue(ig3.active());
+
+        for (IgniteEx ig: Arrays.asList(ig1,ig2,ig3)){
+            Map<String, DynamicCacheDescriptor> desc = U.field(
+                U.field(ig.context().cache(), "cachesInfo"), "registeredCaches");
+
+            assertEquals(5, desc.size());
+
+            Map<String, GridCacheAdapter<?, ?>> caches = U.field(ig.context().cache(), "caches");
+
+            assertEquals(4, caches.keySet().size());
+        }
+
+        Map<String, GridCacheAdapter<?, ?>> caches1 = U.field(ig1.context().cache(), "caches");
+
+        Assert.assertNotNull(caches1.get(cache1));
+        Assert.assertNotNull(caches1.get(cache2));
+        Assert.assertNull(caches1.get(cache3));
+
+        Map<String, GridCacheAdapter<?, ?>> caches2 = U.field(ig2.context().cache(), "caches");
+
+        Assert.assertNull(caches2.get(cache1));
+        Assert.assertNotNull(caches2.get(cache2));
+        Assert.assertNotNull(caches2.get(cache3));
+
+        Map<String, GridCacheAdapter<?, ?>> caches3 = U.field(ig3.context().cache(), "caches");
+
+        Assert.assertNotNull(caches3.get(cache1));
+        Assert.assertNull(caches3.get(cache2));
+        Assert.assertNotNull(caches3.get(cache3));
+    }
+
+    private static class NodeFilterIgnoreByName implements IgnitePredicate<ClusterNode>{
+        private final String name;
+
+        private NodeFilterIgnoreByName(String name) {
+            this.name = name;
+        }
+
+        @Override public boolean apply(ClusterNode node) {
+            return !name.equals(node.consistentId());
+        }
+    }
+
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true));
+    }
+
+    @Override protected void afterTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToActiveCluster.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToActiveCluster.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToActiveCluster.java
new file mode 100644
index 0000000..6042267
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToActiveCluster.java
@@ -0,0 +1,431 @@
+/*
+ * 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.cache.database.standbycluster.join;
+
+import java.util.Map;
+import org.apache.ignite.cache.database.standbycluster.AbstractNodeJoinTemplate;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.junit.Assert;
+
+/**
+ *
+ */
+public class JoinActiveNodeToActiveCluster extends AbstractNodeJoinTemplate {
+    /**
+     *
+     */
+    @Override public JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(true),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheOnlySystem()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(true)
+        ).afterNodeJoin(
+            b.checkCacheOnlySystem()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheOnlySystem()
+        );
+
+        return b;
+    }
+
+    /**
+     *
+     */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(true),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheOnlySystem()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /**
+     *
+     */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheNotEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /**
+     *
+     */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheNotEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /**
+     *
+     */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(atomicCfg()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(3, desc.size());
+
+                        Assert.assertNotNull(ig.context().cache().cache(cache1));
+                        Assert.assertNull(ig.context().cache().cache(cache2));
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(3, caches.size());
+                    }
+                }
+            }
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(transactionCfg())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    // Server node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinWithOutConfiguration() throws Exception {
+        withOutConfigurationTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testStaticCacheConfigurationOnJoin() throws Exception {
+        staticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testStaticCacheConfigurationInCluster() throws Exception {
+        staticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testStaticCacheConfigurationSameOnBoth() throws Exception {
+        staticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        staticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    // Client node join.
+
+    /**
+     *
+     */
+    @Override public void testJoinClientWithOutConfiguration() throws Exception {
+        joinClientWithOutConfigurationTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testJoinClientStaticCacheConfigurationOnJoin() throws Exception {
+        joinClientStaticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testJoinClientStaticCacheConfigurationInCluster() throws Exception {
+        joinClientStaticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testJoinClientStaticCacheConfigurationSameOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /**
+     *
+     */
+    @Override public void testJoinClientStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception {
+        return withOutConfigurationTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception {
+        return staticCacheConfigurationOnJoinTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception {
+        return staticCacheConfigurationInClusterTemplate()
+            .nodeConfiguration(setClient)
+            .afterActivate(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient()) {
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+                        else {
+                            Assert.assertNull(ig.context().cache().cache(cache1));
+                            Assert.assertNull(ig.context().cache().cache(cache2));
+                        }
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(4, caches.size());
+                    }
+                }
+            }).afterNodeJoin(
+                new Runnable() {
+                    @Override public void run() {
+                        for (int i = 0; i < 3; i++) {
+                            IgniteEx ig = grid(name(i));
+
+                            Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                            Assert.assertEquals(4, desc.size());
+
+                            if (!ig.context().discovery().localNode().isClient()) {
+                                Assert.assertNotNull(ig.context().cache().cache(cache1));
+                                Assert.assertNotNull(ig.context().cache().cache(cache2));
+                            }
+                            else {
+                                Assert.assertNull(ig.context().cache().cache(cache1));
+                                Assert.assertNull(ig.context().cache().cache(cache2));
+                            }
+
+                            Map<String, GridCacheAdapter> caches = caches(ig);
+
+                            Assert.assertEquals(4, caches.size());
+                        }
+                    }
+                }).setEnd(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient()) {
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+                        else {
+                            Assert.assertNull(ig.context().cache().cache(cache1));
+                            Assert.assertNull(ig.context().cache().cache(cache2));
+                        }
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(4, caches.size());
+                    }
+                }
+            });
+    }
+
+    @Override
+    public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return staticCacheConfigurationDifferentOnBothTemplate()
+            .nodeConfiguration(setClient)
+            .afterActivate(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient()) {
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+                        else {
+                            Assert.assertNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(4, caches.size());
+                    }
+                }
+            })
+            .afterNodeJoin(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 4; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient())
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+
+                        Assert.assertNotNull(ig.context().cache().cache(cache2));
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        if (!ig.context().discovery().localNode().isClient())
+                            Assert.assertEquals(4, caches.size());
+                        else
+                            Assert.assertEquals(3, caches.size());
+                    }
+                }
+            })
+            .setEnd(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 4; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient())
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+
+                        Assert.assertNotNull(ig.context().cache().cache(cache2));
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        if (!ig.context().discovery().localNode().isClient())
+                            Assert.assertEquals(4, caches.size());
+                        else
+                            Assert.assertEquals(3, caches.size());
+                    }
+                }
+            });
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationSameOnBothTemplate() throws Exception {
+        return staticCacheConfigurationSameOnBothTemplate().nodeConfiguration(setClient);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToInActiveCluster.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToInActiveCluster.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToInActiveCluster.java
new file mode 100644
index 0000000..62ab114
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinActiveNodeToInActiveCluster.java
@@ -0,0 +1,227 @@
+/*
+ * 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.cache.database.standbycluster.join;
+
+import org.apache.ignite.cache.database.standbycluster.AbstractNodeJoinTemplate;
+
+/**
+ *
+ */
+public class JoinActiveNodeToInActiveCluster extends AbstractNodeJoinTemplate {
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(false),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheOnlySystem()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(false),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(true)
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(atomicCfg()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(transactionCfg())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    // Server node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinWithOutConfiguration() throws Exception {
+        withOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationOnJoin() throws Exception {
+        staticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationInCluster() throws Exception {
+        staticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationSameOnBoth() throws Exception {
+        staticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        staticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    // Client node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientWithOutConfiguration() throws Exception {
+        joinClientWithOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationOnJoin() throws Exception {
+        joinClientStaticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationInCluster() throws Exception {
+        joinClientStaticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationSameOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception {
+        return withOutConfigurationTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception {
+        return staticCacheConfigurationOnJoinTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception {
+        return staticCacheConfigurationInClusterTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return staticCacheConfigurationDifferentOnBothTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationSameOnBothTemplate() throws Exception {
+        return staticCacheConfigurationSameOnBothTemplate().nodeConfiguration(setClient);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToActiveCluster.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToActiveCluster.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToActiveCluster.java
new file mode 100644
index 0000000..d0cc7b3
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToActiveCluster.java
@@ -0,0 +1,356 @@
+/*
+ * 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.cache.database.standbycluster.join;
+
+import java.util.Map;
+import org.apache.ignite.cache.database.standbycluster.AbstractNodeJoinTemplate;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.junit.Assert;
+
+/**
+ *
+ */
+public class JoinInActiveNodeToActiveCluster extends AbstractNodeJoinTemplate {
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(true),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheOnlySystem()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(false)
+        ).afterNodeJoin(
+            b.checkCacheOnlySystem()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheOnlySystem()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(true),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheOnlySystem()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheNotEmpty()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(false)
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            b.checkCacheNotEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(true)
+                .setCacheConfiguration(atomicCfg()),
+            cfg(name(1)).setActiveOnStart(true),
+            cfg(name(2)).setActiveOnStart(true)
+        ).afterClusterStarted(
+            new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(3, desc.size());
+
+                        Assert.assertNotNull(ig.context().cache().cache(cache1));
+                        Assert.assertNull(ig.context().cache().cache(cache2));
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(3, caches.size());
+                    }
+                }
+            }
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(transactionCfg())
+        ).afterNodeJoin(
+            b.checkCacheNotEmpty()
+        ).stateAfterJoin(
+            true
+        ).afterDeActivate(
+            b.checkCacheEmpty()
+        ).setEnd(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    // Server node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinWithOutConfiguration() throws Exception {
+        withOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationOnJoin() throws Exception {
+        staticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationInCluster() throws Exception {
+        staticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationSameOnBoth() throws Exception {
+        staticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        staticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    // Client node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientWithOutConfiguration() throws Exception {
+        joinClientWithOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationOnJoin() throws Exception {
+        joinClientStaticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationInCluster() throws Exception {
+        joinClientStaticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationSameOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception {
+        return withOutConfigurationTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception {
+        return staticCacheConfigurationOnJoinTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception {
+        return staticCacheConfigurationInClusterTemplate()
+            .nodeConfiguration(setClient)
+            .afterNodeJoin(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient()) {
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+                        else {
+                            Assert.assertNull(ig.context().cache().cache(cache1));
+                            Assert.assertNull(ig.context().cache().cache(cache2));
+                        }
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(4, caches.size());
+                    }
+                }
+            }).setEnd(new Runnable() {
+                @Override public void run() {
+                    for (int i = 0; i < 3; i++) {
+                        IgniteEx ig = grid(name(i));
+
+                        Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                        Assert.assertEquals(4, desc.size());
+
+                        if (!ig.context().discovery().localNode().isClient()) {
+                            Assert.assertNotNull(ig.context().cache().cache(cache1));
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+                        }
+                        else {
+                            Assert.assertNull(ig.context().cache().cache(cache1));
+                            Assert.assertNull(ig.context().cache().cache(cache2));
+                        }
+
+                        Map<String, GridCacheAdapter> caches = caches(ig);
+
+                        Assert.assertEquals(4, caches.size());
+                    }
+                }
+            });
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationSameOnBothTemplate() throws Exception {
+        return staticCacheConfigurationSameOnBothTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return  staticCacheConfigurationDifferentOnBothTemplate()
+            .nodeConfiguration(setClient)
+            .afterNodeJoin(
+                new Runnable() {
+                    @Override public void run() {
+                        for (int i = 0; i < 4; i++) {
+                            IgniteEx ig = grid(name(i));
+
+                            Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                            Assert.assertEquals(4, desc.size());
+
+                            if (!ig.context().discovery().localNode().isClient())
+                                Assert.assertNotNull(ig.context().cache().cache(cache1));
+
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+
+                            Map<String, GridCacheAdapter> caches = caches(ig);
+
+                            if (!ig.context().discovery().localNode().isClient())
+                                Assert.assertEquals(4, caches.size());
+                            else
+                                Assert.assertEquals(3, caches.size());
+                        }
+                    }
+                }
+            ).setEnd(
+                new Runnable() {
+                    @Override public void run() {
+                        for (int i = 0; i < 4; i++) {
+                            IgniteEx ig = grid(name(i));
+
+                            Map<String, DynamicCacheDescriptor> desc = cacheDescriptors(ig);
+
+                            Assert.assertEquals(4, desc.size());
+
+                            if (!ig.context().discovery().localNode().isClient())
+                                Assert.assertNotNull(ig.context().cache().cache(cache1));
+
+                            Assert.assertNotNull(ig.context().cache().cache(cache2));
+
+                            Map<String, GridCacheAdapter> caches = caches(ig);
+
+                            if (!ig.context().discovery().localNode().isClient())
+                                Assert.assertEquals(4, caches.size());
+                            else
+                                Assert.assertEquals(3, caches.size());
+                        }
+                    }
+                }
+            );
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToInActiveCluster.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToInActiveCluster.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToInActiveCluster.java
new file mode 100644
index 0000000..7333c2e
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/JoinInActiveNodeToInActiveCluster.java
@@ -0,0 +1,226 @@
+/*
+ * 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.cache.database.standbycluster.join;
+
+import org.apache.ignite.cache.database.standbycluster.AbstractNodeJoinTemplate;
+
+/**
+ *
+ */
+public class JoinInActiveNodeToInActiveCluster extends AbstractNodeJoinTemplate {
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(false),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(false)
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheOnlySystem()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0)).setActiveOnStart(false),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3)).setActiveOnStart(false)
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(allCacheConfigurations())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = builder();
+
+        b.clusterConfiguration(
+            cfg(name(0))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(transactionCfg()),
+            cfg(name(1)).setActiveOnStart(false),
+            cfg(name(2)).setActiveOnStart(false)
+        ).afterClusterStarted(
+            b.checkCacheEmpty()
+        ).nodeConfiguration(
+            cfg(name(3))
+                .setActiveOnStart(false)
+                .setCacheConfiguration(atomicCfg())
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    // Server node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinWithOutConfiguration() throws Exception {
+        withOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationOnJoin() throws Exception {
+        staticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationInCluster() throws Exception {
+        staticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationSameOnBoth() throws Exception {
+        staticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        staticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    // Client node join.
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientWithOutConfiguration() throws Exception {
+        joinClientWithOutConfigurationTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationOnJoin() throws Exception {
+        joinClientStaticCacheConfigurationOnJoinTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationInCluster() throws Exception {
+        joinClientStaticCacheConfigurationInClusterTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationSameOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationSameOnBothTemplate().execute();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void testJoinClientStaticCacheConfigurationDifferentOnBoth() throws Exception {
+        joinClientStaticCacheConfigurationDifferentOnBothTemplate().execute();
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception {
+        return withOutConfigurationTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception {
+        return staticCacheConfigurationOnJoinTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception {
+        return staticCacheConfigurationInClusterTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationSameOnBothTemplate() throws Exception {
+        return staticCacheConfigurationSameOnBothTemplate().nodeConfiguration(setClient);
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return staticCacheConfigurationDifferentOnBothTemplate().nodeConfiguration(setClient);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToActiveClusterWithPersistence.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToActiveClusterWithPersistence.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToActiveClusterWithPersistence.java
new file mode 100644
index 0000000..fc4b5ce
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToActiveClusterWithPersistence.java
@@ -0,0 +1,97 @@
+/*
+ * 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.cache.database.standbycluster.join.persistence;
+
+import org.apache.ignite.cache.database.standbycluster.join.JoinActiveNodeToActiveCluster;
+import org.apache.ignite.configuration.IgniteConfiguration;
+
+/**
+ *
+ */
+public class JoinActiveNodeToActiveClusterWithPersistence extends JoinActiveNodeToActiveCluster {
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration cfg(String name) throws Exception {
+        return persistentCfg(super.cfg(name));
+    }
+
+    private JoinNodeTestPlanBuilder persistent(JoinNodeTestPlanBuilder b) {
+        b.afterClusterStarted(
+            b.checkCacheEmpty()
+        ).stateAfterJoin(
+            false
+        ).afterNodeJoin(
+            b.checkCacheEmpty()
+        ).afterActivate(
+            b.checkCacheNotEmpty()
+        );
+
+        return b;
+    }
+
+    @Override public JoinNodeTestPlanBuilder withOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = persistent(super.withOutConfigurationTemplate());
+
+        b.afterActivate(b.checkCacheOnlySystem());
+
+        return b;
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientWithOutConfigurationTemplate() throws Exception {
+        JoinNodeTestPlanBuilder b = persistent(super.joinClientWithOutConfigurationTemplate());
+
+        b.afterActivate(b.checkCacheOnlySystem());
+
+        return b;
+    }
+
+    @Override public void testJoinWithOutConfiguration() throws Exception {
+        withOutConfigurationTemplate().execute();
+    }
+
+    @Override public void testJoinClientWithOutConfiguration() throws Exception {
+        joinClientWithOutConfigurationTemplate().execute();
+    }
+
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationOnJoinTemplate() throws Exception {
+        return persistent(super.staticCacheConfigurationOnJoinTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationInClusterTemplate() throws Exception {
+        return persistent(super.staticCacheConfigurationInClusterTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationSameOnBothTemplate() throws Exception {
+        return persistent(super.staticCacheConfigurationSameOnBothTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder staticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return persistent(super.staticCacheConfigurationDifferentOnBothTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationOnJoinTemplate() throws Exception {
+        return persistent(super.joinClientStaticCacheConfigurationOnJoinTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationInClusterTemplate() throws Exception {
+        return persistent(super.joinClientStaticCacheConfigurationInClusterTemplate());
+    }
+
+    @Override public JoinNodeTestPlanBuilder joinClientStaticCacheConfigurationDifferentOnBothTemplate() throws Exception {
+        return persistent(super.joinClientStaticCacheConfigurationDifferentOnBothTemplate());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bdbba0ee/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToInActiveClusterWithPersistence.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToInActiveClusterWithPersistence.java b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToInActiveClusterWithPersistence.java
new file mode 100644
index 0000000..9981322
--- /dev/null
+++ b/modules/pds/src/test/java/org/apache/ignite/cache/database/standbycluster/join/persistence/JoinActiveNodeToInActiveClusterWithPersistence.java
@@ -0,0 +1,31 @@
+/*
+ * 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.cache.database.standbycluster.join.persistence;
+
+import org.apache.ignite.cache.database.standbycluster.join.JoinActiveNodeToInActiveCluster;
+import org.apache.ignite.configuration.IgniteConfiguration;
+
+/**
+ *
+ */
+public class JoinActiveNodeToInActiveClusterWithPersistence extends JoinActiveNodeToInActiveCluster {
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration cfg(String name) throws Exception {
+        return persistentCfg(super.cfg(name));
+    }
+}


Mime
View raw message