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();
