You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/02/29 12:02:52 UTC
[2/4] ignite git commit: ignite-2521: Configuration variations tests
framework + IgniteCacheBasicConfigVariationsFullApiTestSuite + ignite-2554:
Fixed Affinity.mapKeyToNode() for dynamically started LOCAL cache
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();