ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sboi...@apache.org
Subject [03/19] ignite git commit: ignite-2521: Configuration variations tests framework + IgniteCacheBasicConfigVariationsFullApiTestSuite + ignite-2554: Fixed Affinity.mapKeyToNode() for dynamically started LOCAL cache
Date Wed, 02 Mar 2016 08:11:22 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/CacheStartMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/CacheStartMode.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/CacheStartMode.java
new file mode 100644
index 0000000..ef8bdf0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/CacheStartMode.java
@@ -0,0 +1,29 @@
+/*
+ * 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.testframework.configvariations;
+
+/**
+ * Cache start mode.
+ */
+public enum CacheStartMode {
+    /** Start caches together with nodes (not dynamically). */
+    STATIC,
+
+    /** Starts nodes first and then starts caches dynamically. */
+    DYNAMIC
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigFactory.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigFactory.java
new file mode 100644
index 0000000..9541c1a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.testframework.configvariations;
+
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+
+/**
+ * Configuration factory.
+ */
+public interface ConfigFactory {
+    /**
+     * @param gridName Grid name.
+     * @param srcCfg Source config.
+     * @return IgniteConfiguration.
+     */
+    public IgniteConfiguration getConfiguration(String gridName, IgniteConfiguration srcCfg);
+
+    /**
+     * @param gridName Name.
+     * @return CacheConfiguration.
+     */
+    public CacheConfiguration cacheConfiguration(String gridName);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigParameter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigParameter.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigParameter.java
new file mode 100644
index 0000000..5a29d25
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigParameter.java
@@ -0,0 +1,34 @@
+/*
+ * 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.testframework.configvariations;
+
+/**
+ * Configuration parameter.
+ */
+public interface ConfigParameter<T> {
+    /**
+     * @return Name
+     */
+    public String name();
+
+    /**
+     * @param cfg Configuration.
+     * @return Configuration.
+     */
+    public T apply(T cfg);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariations.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariations.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariations.java
new file mode 100644
index 0000000..e5856f0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariations.java
@@ -0,0 +1,346 @@
+/*
+ * 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.testframework.configvariations;
+
+import java.util.Collection;
+import javax.cache.Cache;
+import javax.cache.configuration.CacheEntryListenerConfiguration;
+import javax.cache.configuration.Factory;
+import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
+import javax.cache.event.CacheEntryCreatedListener;
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListener;
+import javax.cache.event.CacheEntryListenerException;
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheInterceptorAdapter;
+import org.apache.ignite.cache.CacheMemoryMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
+import org.apache.ignite.cache.eviction.EvictionFilter;
+import org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy;
+import org.apache.ignite.cache.store.CacheStoreSession;
+import org.apache.ignite.cache.store.CacheStoreSessionListener;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.configuration.TopologyValidator;
+import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.spi.swapspace.inmemory.GridTestSwapSpaceSpi;
+import org.apache.ignite.testframework.junits.IgniteCacheConfigVariationsAbstractTest;
+
+import static org.apache.ignite.internal.util.lang.GridFunc.asArray;
+
+/**
+ * Cache configuration variations.
+ */
+@SuppressWarnings("serial")
+public class ConfigVariations {
+    /** */
+    private static final ConfigParameter<Object> EVICTION_PARAM = Parameters.complexParameter(
+        Parameters.parameter("setEvictionPolicy", Parameters.factory(FifoEvictionPolicy.class)),
+        Parameters.parameter("setEvictionFilter", Parameters.factory(NoopEvictionFilter.class))
+    );
+
+    /** */
+    private static final ConfigParameter<Object> CACHE_STORE_PARAM = Parameters.complexParameter(
+        Parameters.parameter("setCacheStoreFactory", Parameters.factory(IgniteCacheConfigVariationsAbstractTest.TestStoreFactory.class)),
+        Parameters.parameter("setReadThrough", true),
+        Parameters.parameter("setWriteThrough", true),
+        Parameters.parameter("setCacheStoreSessionListenerFactories", noopCacheStoreSessionListenerFactory())
+    );
+
+    /** */
+    private static final ConfigParameter<Object> SIMPLE_CACHE_STORE_PARAM = Parameters.complexParameter(
+        Parameters.parameter("setCacheStoreFactory", Parameters.factory(IgniteCacheConfigVariationsAbstractTest.TestStoreFactory.class)),
+        Parameters.parameter("setReadThrough", true),
+        Parameters.parameter("setWriteThrough", true)
+    );
+
+    /** */
+    private static final ConfigParameter<Object> REBALANCING_PARAM = Parameters.complexParameter(
+        Parameters.parameter("setRebalanceBatchSize", 2028 * 1024),
+        Parameters.parameter("setRebalanceBatchesPrefetchCount", 5L),
+        Parameters.parameter("setRebalanceThreadPoolSize", 5),
+        Parameters.parameter("setRebalanceTimeout", CacheConfiguration.DFLT_REBALANCE_TIMEOUT * 2),
+        Parameters.parameter("setRebalanceDelay", 1000L)
+    );
+
+    /** */
+    private static final ConfigParameter<Object> ONHEAP_TIERED_MEMORY_PARAM =
+        Parameters.parameter("setMemoryMode", CacheMemoryMode.ONHEAP_TIERED);
+
+    /** */
+    private static final ConfigParameter<Object> OFFHEAP_TIERED_MEMORY_PARAM =
+        Parameters.parameter("setMemoryMode", CacheMemoryMode.OFFHEAP_TIERED);
+
+    /** */
+    private static final ConfigParameter<Object> OFFHEAP_VALUES_MEMORY_PARAM =
+        Parameters.parameter("setMemoryMode", CacheMemoryMode.OFFHEAP_VALUES);
+
+    /** */
+    private static final ConfigParameter<Object> OFFHEAP_ENABLED =
+        Parameters.parameter("setOffHeapMaxMemory", 10 * 1024 * 1024L);
+
+    /** */
+    @SuppressWarnings("unchecked")
+    private static final ConfigParameter<IgniteConfiguration>[][] BASIC_IGNITE_SET = new ConfigParameter[][] {
+        Parameters.objectParameters("setMarshaller", Parameters.factory(BinaryMarshaller.class), optimizedMarshallerFactory()),
+        Parameters.booleanParameters("setPeerClassLoadingEnabled"),
+        Parameters.objectParameters("setSwapSpaceSpi", Parameters.factory(GridTestSwapSpaceSpi.class)),
+    };
+
+    /** */
+    @SuppressWarnings("unchecked")
+    private static final ConfigParameter<CacheConfiguration>[][] BASIC_CACHE_SET = new ConfigParameter[][] {
+        Parameters.objectParameters("setCacheMode", CacheMode.REPLICATED, CacheMode.PARTITIONED),
+        Parameters.enumParameters("setAtomicityMode", CacheAtomicityMode.class),
+        Parameters.enumParameters("setMemoryMode", CacheMemoryMode.class),
+        // Set default parameters.
+        Parameters.objectParameters("setLoadPreviousValue", true),
+        Parameters.objectParameters("setSwapEnabled", true),
+        asArray(SIMPLE_CACHE_STORE_PARAM),
+        Parameters.objectParameters("setWriteSynchronizationMode", CacheWriteSynchronizationMode.FULL_SYNC),
+        Parameters.objectParameters("setAtomicWriteOrderMode", CacheAtomicWriteOrderMode.PRIMARY),
+        Parameters.objectParameters("setStartSize", 1024),
+    };
+
+    /** */
+    @SuppressWarnings("unchecked")
+    private static final ConfigParameter<CacheConfiguration>[][] FULL_CACHE_SET = new ConfigParameter[][] {
+        Parameters.enumParameters("setCacheMode", CacheMode.class),
+        Parameters.enumParameters("setAtomicityMode", CacheAtomicityMode.class),
+        asArray(ONHEAP_TIERED_MEMORY_PARAM,
+            Parameters.complexParameter(ONHEAP_TIERED_MEMORY_PARAM, OFFHEAP_ENABLED),
+            Parameters.complexParameter(OFFHEAP_TIERED_MEMORY_PARAM, OFFHEAP_ENABLED),
+            Parameters.complexParameter(OFFHEAP_VALUES_MEMORY_PARAM, OFFHEAP_ENABLED)
+        ),
+        Parameters.booleanParameters("setLoadPreviousValue"),
+        Parameters.booleanParameters("setReadFromBackup"),
+        Parameters.booleanParameters("setStoreKeepBinary"),
+        Parameters.objectParameters("setRebalanceMode", CacheRebalanceMode.SYNC, CacheRebalanceMode.ASYNC),
+        Parameters.booleanParameters("setSwapEnabled"),
+        Parameters.booleanParameters("setCopyOnRead"),
+        Parameters.objectParameters(true, "setNearConfiguration", nearCacheConfigurationFactory()),
+        asArray(null,
+            Parameters.complexParameter(
+                EVICTION_PARAM,
+                CACHE_STORE_PARAM,
+                REBALANCING_PARAM,
+                Parameters.parameter("setAffinity", Parameters.factory(FairAffinityFunction.class)),
+                Parameters.parameter("setInterceptor", Parameters.factory(NoopInterceptor.class)),
+                Parameters.parameter("setTopologyValidator", Parameters.factory(NoopTopologyValidator.class)),
+                Parameters.parameter("addCacheEntryListenerConfiguration", Parameters.factory(EmptyCacheEntryListenerConfiguration.class))
+            )
+        ),
+        // Set default parameters.
+        Parameters.objectParameters("setWriteSynchronizationMode", CacheWriteSynchronizationMode.FULL_SYNC),
+        Parameters.objectParameters("setAtomicWriteOrderMode", CacheAtomicWriteOrderMode.PRIMARY),
+        Parameters.objectParameters("setStartSize", 1024),
+    };
+
+    /**
+     * Private constructor.
+     */
+    private ConfigVariations() {
+        // No-op.
+    }
+
+    /**
+     * @return Custom near cache config.
+     */
+    private static Factory nearCacheConfigurationFactory() {
+        return new Factory() {
+            @Override public Object create() {
+                NearCacheConfiguration cfg = new NearCacheConfiguration<>();
+
+                cfg.setNearEvictionPolicy(new FifoEvictionPolicy());
+
+                return cfg;
+            }
+        };
+    }
+
+    /**
+     * @return Noop cache store session listener factory.
+     */
+    private static Factory noopCacheStoreSessionListenerFactory() {
+        return new Factory() {
+            @Override public Object create() {
+                return new Factory[] {new NoopCacheStoreSessionListenerFactory()};
+            }
+        };
+    }
+
+    /**
+     * @return Default matrix of availiable variations.
+     */
+    public static ConfigParameter<CacheConfiguration>[][] cacheBasicSet() {
+        return BASIC_CACHE_SET;
+    }
+
+    /**
+     * @return Full matrix of availiable variations.
+     */
+    public static ConfigParameter<CacheConfiguration>[][] cacheFullSet() {
+        return FULL_CACHE_SET;
+    }
+
+    /**
+     * @return Default matrix of availiable variations.
+     */
+    public static ConfigParameter<IgniteConfiguration>[][] igniteBasicSet() {
+        return BASIC_IGNITE_SET;
+    }
+
+    /**
+     * @return Marshaller.
+     */
+    private static Factory<OptimizedMarshaller> optimizedMarshallerFactory() {
+        return new Factory<OptimizedMarshaller>() {
+            @Override public OptimizedMarshaller create() {
+                OptimizedMarshaller marsh = new OptimizedMarshaller(true);
+
+                marsh.setRequireSerializable(false);
+
+                return marsh;
+            }
+        };
+    }
+
+    /**
+     *
+     */
+    public static class NoopEvictionFilter implements EvictionFilter {
+        /** */
+        private static final long serialVersionUID = 0;
+
+        /** {@inheritDoc} */
+        @Override public boolean evictAllowed(Cache.Entry entry) {
+            return true;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class NoopInterceptor extends CacheInterceptorAdapter {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        // No-op.
+    }
+
+    /**
+     *
+     */
+    public static class NoopCacheStoreSessionListenerFactory implements Factory<NoopCacheStoreSessionListener> {
+        /** Serial version uid. */
+        private static final long serialVersionUID = 0L;
+
+        /** {@inheritDoc} */
+        @Override public NoopCacheStoreSessionListener create() {
+            return new NoopCacheStoreSessionListener();
+        }
+    }
+
+    /**
+     *
+     */
+    public static class NoopCacheStoreSessionListener implements CacheStoreSessionListener {
+        /** {@inheritDoc} */
+        @Override public void onSessionStart(CacheStoreSession ses) {
+            // No-op.
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onSessionEnd(CacheStoreSession ses, boolean commit) {
+            // No-op.
+        }
+    }
+
+    /**
+     *
+     */
+    public static class NoopTopologyValidator implements TopologyValidator {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** {@inheritDoc} */
+        @Override public boolean validate(Collection<ClusterNode> nodes) {
+            return true;
+        }
+    }
+
+    /**
+     *
+     */
+    @SuppressWarnings({"serial", "unchecked"})
+    public static class EmptyCacheEntryListenerConfiguration extends MutableCacheEntryListenerConfiguration {
+        /**
+         *
+         */
+        public EmptyCacheEntryListenerConfiguration() {
+            super(new NoopCacheEntryListenerConfiguration());
+        }
+    }
+
+    /**
+     *
+     */
+    @SuppressWarnings("serial")
+    public static class NoopCacheEntryListenerConfiguration implements CacheEntryListenerConfiguration {
+        /** {@inheritDoc} */
+        @Override public Factory<CacheEntryListener> getCacheEntryListenerFactory() {
+            return new Factory<CacheEntryListener>() {
+                @Override public CacheEntryListener create() {
+                    return new NoopCacheEntryListener();
+                }
+            };
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean isOldValueRequired() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Factory<CacheEntryEventFilter> getCacheEntryEventFilterFactory() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean isSynchronous() {
+            return false;
+        }
+    }
+
+    /**
+     *
+     */
+    public static class NoopCacheEntryListener implements CacheEntryCreatedListener {
+        /** {@inheritDoc} */
+        @Override public void onCreated(Iterable iterable) throws CacheEntryListenerException {
+            // No-op.
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsFactory.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsFactory.java
new file mode 100644
index 0000000..f5e7d57
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsFactory.java
@@ -0,0 +1,197 @@
+/*
+ * 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.testframework.configvariations;
+
+import java.util.Arrays;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Configurations variations factory.
+ */
+public class ConfigVariationsFactory implements ConfigFactory {
+    /** */
+    private final ConfigParameter<IgniteConfiguration>[][] igniteParams;
+
+    /** */
+    private final int[] igniteCfgVariation;
+
+    /** */
+    private final ConfigParameter<CacheConfiguration>[][] cacheParams;
+
+    /** */
+    private final int[] cacheCfgVariation;
+
+    /** */
+    private int backups = -1;
+
+    /**
+     * @param igniteParams Ignite Params.
+     * @param igniteCfgVariation Ignite configuration variation.
+     * @param cacheParams Cache Params.
+     * @param cacheCfgVariation Cache config variation.
+     */
+    public ConfigVariationsFactory(ConfigParameter<IgniteConfiguration>[][] igniteParams,
+        int[] igniteCfgVariation,
+        @Nullable ConfigParameter<CacheConfiguration>[][] cacheParams,
+        @Nullable int[] cacheCfgVariation) {
+        this.igniteParams = igniteParams;
+        this.igniteCfgVariation = igniteCfgVariation;
+        this.cacheParams = cacheParams;
+        this.cacheCfgVariation = cacheCfgVariation;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public IgniteConfiguration getConfiguration(String gridName, IgniteConfiguration srcCfg) {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        if (srcCfg != null)
+            copyDefaultsFromSource(cfg, srcCfg);
+
+        if (igniteParams == null)
+            return cfg;
+
+        for (int i = 0; i < igniteCfgVariation.length; i++) {
+            int var = igniteCfgVariation[i];
+
+            ConfigParameter<IgniteConfiguration> cfgC = igniteParams[i][var];
+
+            if (cfgC != null)
+                cfgC.apply(cfg);
+        }
+
+        return cfg;
+    }
+
+    /**
+     * @param cfg Config.
+     * @param srcCfg Source config.
+     */
+    private static void copyDefaultsFromSource(IgniteConfiguration cfg, IgniteConfiguration srcCfg) {
+        cfg.setGridName(srcCfg.getGridName());
+        cfg.setGridLogger(srcCfg.getGridLogger());
+        cfg.setNodeId(srcCfg.getNodeId());
+        cfg.setIgniteHome(srcCfg.getIgniteHome());
+        cfg.setMBeanServer(srcCfg.getMBeanServer());
+        cfg.setMetricsLogFrequency(srcCfg.getMetricsLogFrequency());
+        cfg.setConnectorConfiguration(srcCfg.getConnectorConfiguration());
+        cfg.setCommunicationSpi(srcCfg.getCommunicationSpi());
+        cfg.setNetworkTimeout(srcCfg.getNetworkTimeout());
+        cfg.setDiscoverySpi(srcCfg.getDiscoverySpi());
+        cfg.setCheckpointSpi(srcCfg.getCheckpointSpi());
+        cfg.setIncludeEventTypes(srcCfg.getIncludeEventTypes());
+
+        // Specials.
+        ((TcpCommunicationSpi)cfg.getCommunicationSpi()).setSharedMemoryPort(-1);
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setForceServerMode(true);
+        cfg.getTransactionConfiguration().setTxSerializableEnabled(true);
+    }
+
+    /**
+     * @return Description.
+     */
+    public String getIgniteConfigurationDescription() {
+        if (igniteParams == null)
+            return "";
+
+        SB sb = new SB("[");
+
+        for (int i = 0; i < igniteCfgVariation.length; i++) {
+            int var = igniteCfgVariation[i];
+
+            ConfigParameter<IgniteConfiguration> cfgC = igniteParams[i][var];
+
+            if (cfgC != null) {
+                sb.a(cfgC.name());
+
+                if (i + 1 < igniteCfgVariation.length)
+                    sb.a(", ");
+            }
+        }
+
+        sb.a("]");
+
+        return sb.toString();
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheConfiguration cacheConfiguration(String gridName) {
+        if (cacheParams == null || cacheCfgVariation == null)
+            throw new IllegalStateException("Failed to configure cache [cacheParams=" + Arrays.deepToString(cacheParams)
+                + ", cacheCfgVariation=" + Arrays.toString(cacheCfgVariation) + "]");
+
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        for (int i = 0; i < cacheCfgVariation.length; i++) {
+            int var = cacheCfgVariation[i];
+
+            ConfigParameter<CacheConfiguration> cfgC = cacheParams[i][var];
+
+            if (cfgC != null)
+                cfgC.apply(cfg);
+        }
+
+        if (backups > 0)
+            cfg.setBackups(backups);
+
+        return cfg;
+    }
+
+    /**
+     * @return Description.
+     */
+    public String getCacheConfigurationDescription() {
+        if (cacheCfgVariation == null)
+            return "";
+
+        SB sb = new SB("[");
+
+        for (int i = 0; i < cacheCfgVariation.length; i++) {
+            int var = cacheCfgVariation[i];
+
+            ConfigParameter cfgC = cacheParams[i][var];
+
+            if (cfgC != null) {
+                sb.a(cfgC.name());
+
+                if (i + 1 < cacheCfgVariation.length)
+                    sb.a(", ");
+            }
+        }
+
+        if (backups > 0)
+            sb.a(", backups=").a(backups);
+
+        sb.a("]");
+
+        return sb.toString();
+    }
+
+    /**
+     * @param backups New backups.
+     */
+    public void backups(int backups) {
+        this.backups = backups;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsTestSuiteBuilder.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsTestSuiteBuilder.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsTestSuiteBuilder.java
new file mode 100644
index 0000000..71d7987
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/ConfigVariationsTestSuiteBuilder.java
@@ -0,0 +1,382 @@
+/*
+ * 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.testframework.configvariations;
+
+import java.util.Arrays;
+import junit.framework.TestSuite;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.testframework.junits.IgniteCacheConfigVariationsAbstractTest;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.testframework.junits.IgniteConfigVariationsAbstractTest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Configuration variations test suite builder.
+ */
+public class ConfigVariationsTestSuiteBuilder {
+    /** */
+    private final TestSuite suite;
+
+    /** */
+    @SuppressWarnings("unchecked")
+    private ConfigParameter<IgniteConfiguration>[][] igniteParams =
+        ConfigVariations.igniteBasicSet();
+
+    /** */
+    @SuppressWarnings("unchecked")
+    private ConfigParameter<CacheConfiguration>[][] cacheParams;
+
+    /** */
+    private CacheStartMode cacheStartMode = CacheStartMode.DYNAMIC;
+
+    /** */
+    private boolean withClients;
+
+    /** */
+    private int gridsCnt = 3;
+
+    /** */
+    private int testedNodeCnt = 1;
+
+    /** */
+    private Class<? extends IgniteConfigVariationsAbstractTest> cls;
+
+    /** */
+    private int[] specificIgniteParam;
+
+    /** */
+    private int[] specificCacheParam;
+
+    /** */
+    private int backups = -1;
+
+    /** */
+    private IgnitePredicate<IgniteConfiguration>[] igniteCfgFilters;
+
+    /** */
+    private IgnitePredicate<CacheConfiguration>[] cacheCfgFilters;
+
+    /**
+     * @param name Name.
+     * @param cls Test class.
+     */
+    public ConfigVariationsTestSuiteBuilder(String name, Class<? extends IgniteConfigVariationsAbstractTest> cls) {
+        suite = new TestSuite(name);
+        this.cls = cls;
+    }
+
+    /**
+     * @return Test suite.
+     */
+    public TestSuite build() {
+        assert testedNodeCnt > 0;
+        assert gridsCnt > 0;
+
+        VariationsIterator igniteCfgIter;
+
+        if (specificIgniteParam == null)
+            igniteCfgIter = new VariationsIterator(igniteParams);
+        else
+            igniteCfgIter = new OneElementVariationsIterator(specificIgniteParam, igniteParams);
+
+        for (; igniteCfgIter.hasNext(); ) {
+            final int[] igniteCfgVariation = igniteCfgIter.next();
+
+            if (!passIgniteConfigFilter(igniteCfgVariation))
+                continue;
+
+            if (cacheParams == null) {
+                TestSuite addedSuite = build(igniteCfgVariation, null, true);
+
+                suite.addTest(addedSuite);
+            }
+            else {
+                VariationsIterator cacheCfgIter;
+
+                if (specificCacheParam == null)
+                    cacheCfgIter = new VariationsIterator(cacheParams);
+                else
+                    cacheCfgIter = new OneElementVariationsIterator(specificCacheParam, cacheParams);
+
+                for (; cacheCfgIter.hasNext(); ) {
+                    int[] cacheCfgVariation = cacheCfgIter.next();
+
+                    if (!passCacheConfigFilter(cacheCfgVariation))
+                        continue;
+
+                    // Stop all grids before starting new ignite configuration.
+                    boolean stopNodes = !cacheCfgIter.hasNext();
+
+                    TestSuite addedSuite = build(igniteCfgVariation, cacheCfgVariation, stopNodes);
+
+                    suite.addTest(addedSuite);
+                }
+            }
+        }
+
+        return suite;
+    }
+
+    /**
+     * @param variation Variation.
+     * @return {@code True} if variation pass filters.
+     */
+    private boolean passIgniteConfigFilter(int[] variation) {
+        ConfigVariationsFactory factory = new ConfigVariationsFactory(igniteParams, variation, null, null);
+
+        IgniteConfiguration cfg = factory.getConfiguration(null, null);
+
+        if (igniteCfgFilters != null) {
+            for (IgnitePredicate<IgniteConfiguration> filter : igniteCfgFilters) {
+                if (!filter.apply(cfg))
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @param variation Variation.
+     * @return {@code True} if variation pass filters.
+     */
+    private boolean passCacheConfigFilter(int[] variation) {
+        ConfigVariationsFactory factory = new ConfigVariationsFactory(null, null, cacheParams, variation);
+
+        CacheConfiguration cfg = factory.cacheConfiguration(null);
+
+        if (cacheCfgFilters != null) {
+            for (IgnitePredicate<CacheConfiguration> filter : cacheCfgFilters) {
+                if (!filter.apply(cfg))
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @param igniteCfgVariation Ignite Variation.
+     * @param cacheCfgVariation Cache Variation.
+     * @param stopNodes Stop nodes.
+     * @return Test suite.
+     */
+    private TestSuite build(int[] igniteCfgVariation, @Nullable int[] cacheCfgVariation, boolean stopNodes) {
+        ConfigVariationsFactory factory = new ConfigVariationsFactory(igniteParams,
+            igniteCfgVariation, cacheParams, cacheCfgVariation);
+
+        factory.backups(backups);
+
+        String clsNameSuffix = "[igniteCfgVariation=" + Arrays.toString(igniteCfgVariation)
+            + ", cacheCfgVariation=" + Arrays.toString(cacheCfgVariation)
+            + ", igniteCfg=" + factory.getIgniteConfigurationDescription()
+            + ", cacheCfg=" + factory.getCacheConfigurationDescription() + "]";
+
+        VariationsTestsConfig testCfg = new VariationsTestsConfig(factory, clsNameSuffix, stopNodes, cacheStartMode,
+            gridsCnt);
+
+        TestSuite addedSuite;
+
+        if (testedNodeCnt > 1)
+            addedSuite = createMultiNodeTestSuite((Class<? extends IgniteCacheConfigVariationsAbstractTest>)cls, 
+                testCfg, testedNodeCnt, withClients);
+        else
+            addedSuite = new IgniteConfigVariationsTestSuite(cls, testCfg);
+
+        return addedSuite;
+    }
+
+    /**
+     * @param cls Test class.
+     * @param cfg Configuration.
+     * @param testedNodeCnt Count of tested nodes.
+     */
+    private static TestSuite createMultiNodeTestSuite(Class<? extends IgniteCacheConfigVariationsAbstractTest> cls,
+        VariationsTestsConfig cfg, int testedNodeCnt, boolean withClients) {
+        TestSuite suite = new TestSuite();
+
+        if (cfg.gridCount() < testedNodeCnt)
+            throw new IllegalArgumentException("Failed to initialize test suite [nodeCnt=" + testedNodeCnt
+                + ", cfgGridCnt=" + cfg.gridCount() + "]");
+
+        for (int i = 0; i < testedNodeCnt; i++) {
+            boolean stopNodes = cfg.isStopNodes() && i + 1 == testedNodeCnt;
+            boolean startCache = i == 0;
+            boolean stopCache = i + 1 == testedNodeCnt;
+
+            VariationsTestsConfig cfg0 = new VariationsTestsConfig(cfg.configurationFactory(), cfg.description(),
+                stopNodes, startCache, stopCache, cfg.cacheStartMode(), cfg.gridCount(), i, withClients);
+
+            suite.addTest(new IgniteConfigVariationsTestSuite(cls, cfg0));
+        }
+
+        return suite;
+    }
+
+    /**
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder withClients() {
+        if (testedNodeCnt < 2)
+            throw new IllegalStateException("Tested node count should be more than 1: " + testedNodeCnt);
+
+        withClients = true;
+
+        return this;
+    }
+
+    /**
+     * @param testedNodeCnt Tested node count.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder testedNodesCount(int testedNodeCnt) {
+        this.testedNodeCnt = testedNodeCnt;
+
+        return this;
+    }
+
+    /**
+     * @param cnt Count.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder gridsCount(int cnt) {
+        assert cnt > 0;
+
+        gridsCnt = cnt;
+
+        return this;
+    }
+
+    /**
+     * @param igniteParams New ignite params.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder igniteParams(
+        ConfigParameter<IgniteConfiguration>[][] igniteParams) {
+        this.igniteParams = igniteParams;
+
+        return this;
+    }
+
+    /**
+     * @param cacheParams New cache params.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder cacheParams(ConfigParameter<CacheConfiguration>[][] cacheParams) {
+        this.cacheParams = cacheParams;
+
+        return this;
+    }
+
+    /**
+     * Sets basic cache params and basic count of backups.
+     *
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder withBasicCacheParams() {
+        cacheParams = ConfigVariations.cacheBasicSet();
+        backups = 1;
+
+        return this;
+    }
+
+    /**
+     * @param backups Backups.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder backups(int backups) {
+        assert backups > 0 : backups;
+
+        this.backups = backups;
+
+        return this;
+    }
+
+    /**
+     * @param singleIgniteParam Param.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder specifyIgniteParam(int... singleIgniteParam) {
+        specificIgniteParam = singleIgniteParam;
+
+        return this;
+    }
+
+    /**
+     * @param singleParam Param.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder specifyCacheParam(int... singleParam) {
+        specificCacheParam = singleParam;
+
+        return this;
+    }
+
+    /**
+     * @param filters Ignite configuration filters.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder withIgniteConfigFilters(IgnitePredicate<IgniteConfiguration>... filters) {
+        igniteCfgFilters = filters;
+
+        return this;
+    }
+
+    /**
+     * @param filters Ignite configuration filters.
+     * @return {@code this} for chaining.
+     */
+    public ConfigVariationsTestSuiteBuilder withCacheConfigFilters(IgnitePredicate<CacheConfiguration>... filters) {
+        cacheCfgFilters = filters;
+
+        return this;
+    }
+
+    /**
+     *
+     */
+    private static class OneElementVariationsIterator extends VariationsIterator {
+        /** */
+        private int[] elem;
+
+        /** */
+        private boolean hasNext = true;
+
+        /**
+         * @param elem Element.
+         */
+        OneElementVariationsIterator(int[] elem, Object[][] params) {
+            super(params);
+
+            this.elem = elem;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean hasNext() {
+            return hasNext;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int[] next() {
+            hasNext = false;
+
+            return elem;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/IgniteConfigVariationsTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/IgniteConfigVariationsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/IgniteConfigVariationsTestSuite.java
new file mode 100644
index 0000000..d953c27
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/IgniteConfigVariationsTestSuite.java
@@ -0,0 +1,50 @@
+/*
+ * 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.testframework.configvariations;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import org.apache.ignite.testframework.junits.IgniteConfigVariationsAbstractTest;
+
+/**
+ * Configuration variations test suite.
+ */
+public class IgniteConfigVariationsTestSuite extends TestSuite {
+    /** */
+    protected final VariationsTestsConfig cfg;
+
+    /**
+     * @param cls Test class.
+     * @param cfg Configuration.
+     */
+    public IgniteConfigVariationsTestSuite(Class<? extends IgniteConfigVariationsAbstractTest> cls,
+        VariationsTestsConfig cfg) {
+        super(cls);
+
+        this.cfg = cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void runTest(Test test, TestResult res) {
+        if (test instanceof IgniteConfigVariationsAbstractTest)
+            ((IgniteConfigVariationsAbstractTest)test).setTestsConfiguration(cfg);
+
+        super.runTest(test, res);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/Parameters.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/Parameters.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/Parameters.java
new file mode 100644
index 0000000..27c0a48
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/Parameters.java
@@ -0,0 +1,377 @@
+/*
+ * 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.testframework.configvariations;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.cache.configuration.Factory;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Parameters utils.
+ */
+public class Parameters {
+    /**
+     * Private constructor.
+     */
+    private Parameters() {
+        // No-op.
+    }
+
+    /**
+     * @return Array of configuration processors for given enum.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ConfigParameter<T>[] enumParameters(String mtdName, Class<?> enumCls) {
+        return enumParameters(false, mtdName, enumCls);
+    }
+
+    /**
+     * @return Array of configuration processors for given enum.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ConfigParameter<T>[] enumParameters(boolean withNull, String mtdName, Class<?> enumCls) {
+        return parameters0(mtdName, withNull, enumCls.getEnumConstants());
+    }
+
+    /**
+     * @param mtdName Method name.
+     * @param values Values.
+     * @return Array of configuration paramethers.
+     */
+    @SuppressWarnings("unchecked")
+    private static <T> ConfigParameter<T>[] parameters0(String mtdName, boolean withNull, Object[] values) {
+        for (Object val : values) {
+            if (!isPrimitiveOrEnum(val) && !(val instanceof Factory))
+                throw new IllegalArgumentException("Value have to be primite, enum or factory: " + val);
+        }
+
+        if (withNull) {
+            Object[] valuesWithNull = new Object[values.length + 1];
+
+            valuesWithNull[0] = null;
+
+            System.arraycopy(values, 0, valuesWithNull, 1, valuesWithNull.length - 1);
+
+            values = valuesWithNull;
+        }
+
+        assert values != null && values.length > 0 : "MtdName:" + mtdName;
+
+        ConfigParameter<T>[] resArr = new ConfigParameter[values.length];
+
+        for (int i = 0; i < resArr.length; i++)
+            resArr[i] = new ReflectionParameter<>(mtdName, values[i]);
+
+        return resArr;
+    }
+
+    /**
+     * @param val Value.
+     * @return Primitive or enum or not.
+     */
+    private static boolean isPrimitiveOrEnum(Object val) {
+        return val.getClass().isPrimitive()
+            || val.getClass().equals(Boolean.class)
+            || val.getClass().equals(Byte.class)
+            || val.getClass().equals(Short.class)
+            || val.getClass().equals(Character.class)
+            || val.getClass().equals(Integer.class)
+            || val.getClass().equals(Long.class)
+            || val.getClass().equals(Float.class)
+            || val.getClass().equals(Double.class)
+            || val.getClass().isEnum();
+    }
+
+    /**
+     * @return Array of configuration processors for given enum.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ConfigParameter<T>[] booleanParameters(String mtdName) {
+        return parameters0(mtdName, false, new Boolean[] {true, false});
+    }
+
+    /**
+     * @return Array of configuration processors for given enum.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ConfigParameter<T>[] booleanParameters(boolean withNull, String mtdName) {
+        return parameters0(mtdName, withNull, new Boolean[] {true, false});
+    }
+
+    /**
+     * @param mtdName Method name.
+     * @param values Values.
+     * @return Array of configuration processors for given classes.
+     */
+    public static ConfigParameter[] objectParameters(String mtdName, Object... values) {
+        return objectParameters(false, mtdName, values);
+    }
+
+    /**
+     * @param mtdName Method name.
+     * @param values Values.
+     * @return Array of configuration processors for given classes.
+     */
+    public static ConfigParameter[] objectParameters(boolean withNull, String mtdName, Object... values) {
+        return parameters0(mtdName, withNull, values);
+    }
+
+    /**
+     * @param mtdName Method name.
+     * @param val Value.
+     * @return Configuration parameter.
+     */
+    public static <T> ConfigParameter<T> parameter(String mtdName, Object val) {
+        return new ReflectionParameter<>(mtdName, val);
+    }
+
+    /**
+     * @return Complex parameter.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ConfigParameter<T> complexParameter(ConfigParameter<T>... params) {
+        return new ComplexParameter<T>(params);
+    }
+
+    /**
+     * @param cls Class.
+     * @return Factory that uses default constructor to initiate object by given class.
+     */
+    public static <T> Factory<T> factory(Class<?> cls) {
+        return new ReflectionFactory<>(cls);
+    }
+
+    /**
+     * Reflection configuration applier.
+     */
+    @SuppressWarnings("serial")
+    private static class ReflectionParameter<T> implements ConfigParameter<T> {
+        /** Classes of marameters cache. */
+        private static final ConcurrentMap<T2<Class, String>, Class> paramClassesCache = new ConcurrentHashMap();
+
+        /** */
+        private final String mtdName;
+
+        /** Primitive, enum or factory. */
+        private final Object val;
+
+        /**
+         * @param mtdName Method name.
+         */
+        ReflectionParameter(String mtdName, @Nullable Object val) {
+            if (val != null && !isPrimitiveOrEnum(val) && !(val instanceof Factory))
+                throw new IllegalArgumentException("Value have to be primite, enum or factory: " + val);
+
+            this.mtdName = mtdName;
+            this.val = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String name() {
+            String mtdName0 = mtdName;
+
+            if (mtdName0.startsWith("set") && mtdName0.length() > 3)
+                mtdName0 = mtdName0.substring(3, mtdName0.length());
+
+            String val0;
+
+            if (val == null)
+                val0 = "null";
+            else if (val instanceof Factory)
+                val0 = ((Factory)val).create().toString();
+            else
+                val0 = val.toString();
+
+            return mtdName0 + "=" + val0;
+        }
+
+        /** {@inheritDoc} */
+        @Override public T apply(T cfg) {
+            if (val == null)
+                return null;
+
+            try {
+                Object val0 = val;
+
+                if (!isPrimitiveOrEnum(val))
+                    val0 = ((Factory)val0).create();
+
+                Class<?> paramCls = paramClassesCache.get(new T2<Class, String>(cfg.getClass(), mtdName));
+
+                if (paramCls == null)
+                    paramCls = val0.getClass();
+                else if (!paramCls.isInstance(val0))
+                    throw new IgniteException("Class parameter from cache does not match value argument class " +
+                        "[paramCls=" + paramCls + ", val=" + val0 + "]");
+
+                if (val0.getClass().equals(Boolean.class))
+                    paramCls = Boolean.TYPE;
+                else if (val0.getClass().equals(Byte.class))
+                    paramCls = Byte.TYPE;
+                else if (val0.getClass().equals(Short.class))
+                    paramCls = Short.TYPE;
+                else if (val0.getClass().equals(Character.class))
+                    paramCls = Character.TYPE;
+                else if (val0.getClass().equals(Integer.class))
+                    paramCls = Integer.TYPE;
+                else if (val0.getClass().equals(Long.class))
+                    paramCls = Long.TYPE;
+                else if (val0.getClass().equals(Float.class))
+                    paramCls = Float.TYPE;
+                else if (val0.getClass().equals(Double.class))
+                    paramCls = Double.TYPE;
+
+                Method mtd;
+
+                Queue<Class> queue = new ArrayDeque<>();
+
+                boolean failed = false;
+
+                while (true) {
+                    try {
+                        mtd = cfg.getClass().getMethod(mtdName, paramCls);
+
+                        if (failed)
+                            paramClassesCache.put(new T2<Class, String>(cfg.getClass(), mtdName), paramCls);
+
+                        break;
+                    }
+                    catch (NoSuchMethodException e) {
+                        failed = true;
+
+                        U.warn(null, "Method not found [cfgCls=" + cfg.getClass() + ", mtdName=" + mtdName
+                            + ", paramCls=" + paramCls + "]");
+
+                        Class<?>[] interfaces = paramCls.getInterfaces();
+
+                        Class<?> superclass = paramCls.getSuperclass();
+
+                        if (superclass != null)
+                            queue.add(superclass);
+
+                        if (!F.isEmpty(interfaces))
+                            queue.addAll(Arrays.asList(interfaces));
+
+                        if (queue.isEmpty())
+                            throw new IgniteException("Method not found [cfgCls=" + cfg.getClass() + ", mtdName="
+                                + mtdName + ", paramCls=" + val0.getClass() + "]", e);
+
+                        paramCls = queue.remove();
+                    }
+                }
+
+                mtd.invoke(cfg, val0);
+            }
+            catch (InvocationTargetException | IllegalAccessException e) {
+                throw new IgniteException(e);
+            }
+
+            return null;
+        }
+    }
+
+    /**
+     *
+     */
+    private static class ReflectionFactory<T> implements Factory<T> {
+        /** */
+        private static final long serialVersionUID = 0;
+
+        /** */
+        private Class<?> cls;
+
+        /**
+         * @param cls Class.
+         */
+        ReflectionFactory(Class<?> cls) {
+            this.cls = cls;
+        }
+
+        /** {@inheritDoc} */
+        @Override public T create() {
+            try {
+                Constructor<?> constructor = cls.getConstructor();
+
+                return (T)constructor.newInstance();
+            }
+            catch (NoSuchMethodException | InstantiationException | InvocationTargetException |
+                IllegalAccessException e) {
+                throw new IgniteException("Failed to create object using default constructor: " + cls, e);
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private static class ComplexParameter<T> implements ConfigParameter<T> {
+        /** */
+        private final String name;
+
+        /** */
+        private ConfigParameter<T>[] params;
+
+        /**
+         * @param params Params
+         */
+        @SafeVarargs 
+        ComplexParameter(ConfigParameter<T>... params) {
+            A.notEmpty(params, "params");
+
+            this.params = params;
+
+            if (params.length == 1)
+                name = params[0].name();
+            else {
+                SB sb = new SB(params[0].name());
+
+                for (int i = 1; i < params.length; i++)
+                    sb.a('-').a(params[i]);
+
+                name = sb.toString();
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public String name() {
+            return name;
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
+        @Override public T apply(T cfg) {
+            for (ConfigParameter param : params)
+                param.apply(cfg);
+
+            return cfg;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsIterator.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsIterator.java
new file mode 100644
index 0000000..fa1c216
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsIterator.java
@@ -0,0 +1,174 @@
+/*
+ * 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.testframework.configvariations;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * Variations iterator.
+ */
+public class VariationsIterator implements Iterator<int[]> {
+    /** */
+    private final Object[][] params;
+
+    /** */
+    private final int[] vector;
+
+    /** */
+    private int position;
+
+    /** */
+    private final int expCntOfVectors;
+
+    /** */
+    private int cntOfVectors;
+
+    /**
+     * @param params Paramethers.
+     */
+    public VariationsIterator(Object[][] params) {
+        assert params != null;
+        assert params.length > 0;
+
+        for (int i = 0; i < params.length; i++) {
+            assert params[i] != null : i;
+            assert params[i].length > 0 : i;
+        }
+
+        this.params = params;
+
+        vector = new int[params.length];
+
+        for (int i = 0; i < vector.length; i++)
+            vector[i] = 0;
+
+        position = -1;
+
+        int cntOfVectors0 = 1;
+
+        for (int i = 0; i < params.length; i++)
+            cntOfVectors0 *= params[i].length;
+
+        expCntOfVectors = cntOfVectors0;
+
+        cntOfVectors = 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean hasNext() {
+        return cntOfVectors < expCntOfVectors;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int[] next() {
+        // Only first call.
+        if (position == -1) {
+            position = 0;
+
+            cntOfVectors++;
+
+            return arraycopy(vector);
+        }
+
+        if (!updateVector(vector, position)) {
+            if (position + 1 == params.length)
+                throw new IllegalStateException("[position=" + position + ", vector=" +
+                    Arrays.toString(vector) + ", params=" + Arrays.deepToString(params));
+
+            position++;
+
+            // Skip params with length 1. We cannot set 1 at this position.
+            while (position < params.length && params[position].length < 2)
+                position++;
+
+            if (position == params.length)
+                throw new IllegalStateException("[position=" + position + ", vector=" +
+                    Arrays.toString(vector) + ", params=" + Arrays.deepToString(params));
+
+            vector[position] = 1;
+
+            cntOfVectors++;
+
+            return arraycopy(vector);
+        }
+
+        cntOfVectors++;
+
+        return arraycopy(vector);
+    }
+
+    /**
+     * Updates vector starting from position.
+     *
+     * @param vector Vector.
+     * @param position Position.
+     * @return {@code True} if vector has been updated. When {@code false} is returned it means that all positions
+     *          before has been set to {@code 0}.
+     */
+    private boolean updateVector(int[] vector, int position) {
+        if (position == 0) {
+            int val = vector[0];
+
+            if (val + 1 < params[0].length) {
+                vector[0] = val + 1;
+
+                return true;
+            }
+            else {
+                vector[0] = 0;
+
+                return false;
+            }
+        }
+
+        if (updateVector(vector, position - 1))
+            return true;
+
+        int val = vector[position];
+
+        if (val + 1 < params[position].length) {
+            vector[position] = val + 1;
+
+            return true;
+        }
+        else {
+            vector[position] = 0;
+
+            return false;
+        }
+
+    }
+
+    /**
+     * @param arr Array.
+     * @return Array copy.
+     */
+    private static int[] arraycopy(int[] arr) {
+        int[] dest = new int[arr.length];
+
+        System.arraycopy(arr, 0, dest, 0, arr.length);
+
+        return dest;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void remove() {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsTestsConfig.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsTestsConfig.java b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsTestsConfig.java
new file mode 100644
index 0000000..7bcfc7f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/configvariations/VariationsTestsConfig.java
@@ -0,0 +1,161 @@
+/*
+ * 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.testframework.configvariations;
+
+import org.apache.ignite.internal.util.typedef.internal.A;
+
+/**
+ * Immutable tests configuration.
+ */
+public class VariationsTestsConfig {
+    /** */
+    private final ConfigFactory factory;
+
+    /** */
+    private final String desc;
+
+    /** */
+    private final boolean stopNodes;
+
+    /** */
+    private final int gridCnt;
+
+    /** */
+    private final CacheStartMode cacheStartMode;
+
+    /** */
+    private final int testedNodeIdx;
+
+    /** */
+    private boolean startCache;
+
+    /** */
+    private boolean stopCache;
+
+    /** */
+    private boolean withClients;
+
+    /**
+     * @param factory Factory.
+     * @param desc Class suffix.
+     * @param stopNodes Stope nodes.
+     * @param gridCnt Grdi count.
+     */
+    public VariationsTestsConfig(
+        ConfigFactory factory,
+        String desc,
+        boolean stopNodes,
+        CacheStartMode cacheStartMode,
+        int gridCnt
+    ) {
+        this(factory, desc, stopNodes, true, true, cacheStartMode, gridCnt, 0, false);
+    }
+
+    /**
+     * @param factory Factory.
+     * @param desc Config description.
+     * @param stopNodes Stope nodes.
+     * @param gridCnt Grdi count.
+     */
+    public VariationsTestsConfig(
+        ConfigFactory factory,
+        String desc,
+        boolean stopNodes,
+        boolean startCache,
+        boolean stopCache,
+        CacheStartMode cacheStartMode,
+        int gridCnt,
+        int testedNodeIdx,
+        boolean withClients
+    ) {
+        A.ensure(gridCnt >= 1, "Grids count cannot be less then 1.");
+
+        this.factory = factory;
+        this.desc = desc;
+        this.gridCnt = gridCnt;
+        this.cacheStartMode = cacheStartMode;
+        this.testedNodeIdx = testedNodeIdx;
+        this.stopNodes = stopNodes;
+        this.startCache = startCache;
+        this.stopCache = stopCache;
+        this.withClients = withClients;
+    }
+
+    /**
+     * @return Configuration factory.
+     */
+    public ConfigFactory configurationFactory() {
+        return factory;
+    }
+
+    /**
+     * @return Configuration description..
+     */
+    public String description() {
+        return desc;
+    }
+
+    /**
+     * @return Grids count.
+     */
+    public int gridCount() {
+        return gridCnt;
+    }
+
+    /**
+     * @return Whether nodes should be stopped after tests execution or not.
+     */
+    public boolean isStopNodes() {
+        return stopNodes;
+    }
+
+    /**
+     * @return Cache start type.
+     */
+    public CacheStartMode cacheStartMode() {
+        return cacheStartMode;
+    }
+
+    /**
+     * @return Index of node which should be tested or {@code null}.
+     */
+    public int testedNodeIndex() {
+        return testedNodeIdx;
+    }
+
+    /**
+     * @return Whether cache should be started before tests execution or not.
+     */
+    public boolean isStartCache() {
+        return startCache;
+    }
+
+    /**
+     * @return Whether cache should be destroyed after tests execution or not.
+     */
+    public boolean isStopCache() {
+        return stopCache;
+    }
+
+    /**
+     * @return With clients.
+     */
+    public boolean withClients() {
+        return withClients;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/953b575f/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index 614e634..2f8155c 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -153,7 +153,7 @@ public abstract class GridAbstractTest extends TestCase {
     private static long ts = System.currentTimeMillis();
 
     /** Starting grid name. */
-    protected final static ThreadLocal<String> startingGrid = new ThreadLocal<>();
+    protected static final ThreadLocal<String> startingGrid = new ThreadLocal<>();
 
     /**
      *
@@ -528,7 +528,7 @@ public abstract class GridAbstractTest extends TestCase {
         }
 
         if (isFirstTest()) {
-            info(">>> Starting test class: " + GridTestUtils.fullSimpleName(getClass()) + " <<<");
+            info(">>> Starting test class: " + testClassDescription() + " <<<");
 
             if (startGrid) {
                 IgniteConfiguration cfg = optimize(getConfiguration());
@@ -561,7 +561,7 @@ public abstract class GridAbstractTest extends TestCase {
             }
         }
 
-        info(">>> Starting test: " + getName() + " <<<");
+        info(">>> Starting test: " + testDescription() + " <<<");
 
         try {
             beforeTest();
@@ -581,6 +581,20 @@ public abstract class GridAbstractTest extends TestCase {
     }
 
     /**
+     * @return Test description.
+     */
+    protected String testDescription() {
+        return GridTestUtils.fullSimpleName(getClass()) + "#" + getName();
+    }
+
+    /**
+     * @return Test class description.
+     */
+    protected String testClassDescription() {
+        return GridTestUtils.fullSimpleName(getClass());
+    }
+
+    /**
      * @return Started grid.
      * @throws Exception If anything failed.
      */
@@ -738,16 +752,29 @@ public abstract class GridAbstractTest extends TestCase {
      * @throws Exception If failed.
      */
     protected Ignite startGrid(String gridName, GridSpringResourceContext ctx) throws Exception {
+        return startGrid(gridName, optimize(getConfiguration(gridName)), ctx);
+    }
+    /**
+     * Starts new grid with given name.
+     *
+     * @param gridName Grid name.
+     * @param ctx Spring context.
+     * @return Started grid.
+     * @throws Exception If failed.
+     */
+    protected Ignite startGrid(String gridName, IgniteConfiguration cfg, GridSpringResourceContext ctx)
+        throws Exception {
         if (!isRemoteJvm(gridName)) {
             startingGrid.set(gridName);
 
             try {
-                Ignite node = IgnitionEx.start(optimize(getConfiguration(gridName)), ctx);
+                Ignite node = IgnitionEx.start(cfg, ctx);
 
-                IgniteConfiguration cfg = node.configuration();
+                IgniteConfiguration nodeCfg = node.configuration();
 
                 log.info("Node started with the following configuration [id=" + node.cluster().localNode().id()
-                    + ", marshaller=" + cfg.getMarshaller() + ", binaryCfg=" + cfg.getBinaryConfiguration() + "]");
+                    + ", marshaller=" + nodeCfg.getMarshaller()
+                    + ", binaryCfg=" + nodeCfg.getBinaryConfiguration() + "]");
 
                 return node;
             }
@@ -1382,7 +1409,7 @@ public abstract class GridAbstractTest extends TestCase {
     @Override protected void tearDown() throws Exception {
         long dur = System.currentTimeMillis() - ts;
 
-        info(">>> Stopping test: " + getName() + " in " + dur + " ms <<<");
+        info(">>> Stopping test: " + testDescription() + " in " + dur + " ms <<<");
 
         TestCounters cntrs = getTestCounters();
 
@@ -1397,7 +1424,7 @@ public abstract class GridAbstractTest extends TestCase {
             serializedObj.clear();
 
             if (isLastTest()) {
-                info(">>> Stopping test class: " + GridTestUtils.fullSimpleName(getClass()) + " <<<");
+                info(">>> Stopping test class: " + testClassDescription() + " <<<");
 
                 TestCounters counters = getTestCounters();
 


Mime
View raw message