ignite-1635, ignite-1616 Added unit-tests for the bugs.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/077af17f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/077af17f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/077af17f Branch: refs/heads/ignite-1655 Commit: 077af17f7e62ed1c4d0f699c9fd39b9d8161ae1f Parents: 3a29b97 Author: ashutak <[email protected]> Authored: Thu Oct 15 16:58:23 2015 +0300 Committer: ashutak <[email protected]> Committed: Thu Oct 15 16:58:23 2015 +0300 ---------------------------------------------------------------------- .../CacheAbstractRestartSelfTest.java | 247 +++++++++++++++++++ ...NearDisabledAtomicInvokeRestartSelfTest.java | 179 ++++++++++++++ ...abledTransactionalInvokeRestartSelfTest.java | 173 +++++++++++++ ...edTransactionalWriteReadRestartSelfTest.java | 124 ++++++++++ .../IgniteCacheLoadConsistencyTestSuite.java | 42 ++++ 5 files changed, 765 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/077af17f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheAbstractRestartSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheAbstractRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheAbstractRestartSelfTest.java new file mode 100644 index 0000000..7537af1 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheAbstractRestartSelfTest.java @@ -0,0 +1,247 @@ +/* +* 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.internal.processors.cache.distributed; + +import java.util.ArrayList; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.cache.IgniteCacheAbstractTest; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; +import org.apache.ignite.testframework.GridTestUtils; + +/** + * Abstract restart test. + */ +public abstract class CacheAbstractRestartSelfTest extends IgniteCacheAbstractTest { + /** */ + private volatile CountDownLatch cacheCheckedLatch = new CountDownLatch(1); + + /** */ + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(true); + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + if (gridName.equals(getTestGridName(gridCount() - 1))) + cfg.setClientMode(true); + + cfg.setPeerClassLoadingEnabled(false); + + ((TcpCommunicationSpi)cfg.getCommunicationSpi()).setSharedMemoryPort(-1); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected long getTestTimeout() { + return 8 * 60_000; + } + + /** + * @return Number of updaters threads. + */ + protected int updatersNumber() { + return 64; + } + + /** + * @throws Exception If failed. + */ + public void testRestart() throws Exception { + final int clientGrid = gridCount() - 1; + + assertTrue(ignite(clientGrid).configuration().isClientMode()); + + final IgniteEx grid = grid(clientGrid); + + final IgniteCache cache = jcache(clientGrid); + + updateCache(grid, cache); + + final AtomicBoolean stop = new AtomicBoolean(); + + ArrayList<IgniteInternalFuture> updaterFuts = new ArrayList<>(); + + for (int i = 0; i < updatersNumber(); i++) { + final int threadIdx = i; + + IgniteInternalFuture<?> updateFut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + Thread.currentThread().setName("update-thread-" + threadIdx); + + assertTrue(cacheCheckedLatch.await(30_000, TimeUnit.MILLISECONDS)); + + int iter = 0; + + while (!stop.get()) { + log.info("Start update: " + iter); + + rwl.readLock().lock(); + + try { + updateCache(grid, cache); + } + finally { + rwl.readLock().unlock(); + } + + log.info("End update: " + iter++); + } + + log.info("Update iterations: " + iter); + + return null; + } + }); + + updaterFuts.add(updateFut); + } + + IgniteInternalFuture<?> restartFut = GridTestUtils.runAsync(new Callable<Void>() { + @Override public Void call() throws Exception { + Thread.currentThread().setName("restart-thread"); + + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + while (!stop.get()) { + assertTrue(cacheCheckedLatch.await(30_000, TimeUnit.MILLISECONDS)); + + int node = rnd.nextInt(0, gridCount() - 1); + + log.info("Stop node: " + node); + + stopGrid(node); + + U.sleep(restartSleep()); + + log.info("Start node: " + node); + + startGrid(node); + + cacheCheckedLatch = new CountDownLatch(1); + + U.sleep(restartDelay()); + + awaitPartitionMapExchange(); + } + + return null; + } + }); + + long endTime = System.currentTimeMillis() + getTestDuration(); + + try { + int iter = 0; + + while (System.currentTimeMillis() < endTime && !isAnyDone(updaterFuts) && !restartFut.isDone()) { + try { + log.info("Start of cache checking: " + iter); + + rwl.writeLock().lock(); + + try { + checkCache(grid, cache); + } + finally { + rwl.writeLock().unlock(); + } + + log.info("End of cache checking: " + iter++); + } + finally { + cacheCheckedLatch.countDown(); + } + } + + log.info("Checking iteration: " + iter); + } + finally { + cacheCheckedLatch.countDown(); + + stop.set(true); + } + + for (IgniteInternalFuture fut : updaterFuts) + fut.get(); + + restartFut.get(); + + checkCache(grid, cache); + } + + /** + * @return Test duration. + * @see #getTestTimeout() + */ + protected int getTestDuration() { + return 60_000; + } + + /** + * @return Restart sleep in milliseconds. + */ + private int restartSleep() { + return 100; + } + + /** + * @return Restart delay in milliseconds. + */ + private int restartDelay() { + return 100; + } + + /** + * Checks cache in one thread. All update operations are not executed. + * + * @param cache Cache. + */ + protected abstract void checkCache(IgniteEx grid, IgniteCache cache) throws Exception ; + + /** + * Updates cache in many threads. + * + * @param grid Grid. + * @param cache Cache. + */ + protected abstract void updateCache(IgniteEx grid, IgniteCache cache) throws Exception ; + + /** + * @param futs Futers. + * @return {@code True} if all futures are done. + */ + private static boolean isAnyDone(ArrayList<IgniteInternalFuture> futs) { + for (IgniteInternalFuture fut : futs) { + if (fut.isDone()) + return true; + } + + return false; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/077af17f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledAtomicInvokeRestartSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledAtomicInvokeRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledAtomicInvokeRestartSelfTest.java new file mode 100644 index 0000000..90427f5 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledAtomicInvokeRestartSelfTest.java @@ -0,0 +1,179 @@ +/* + * 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.internal.processors.cache.distributed; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicLong; +import javax.cache.processor.EntryProcessorException; +import javax.cache.processor.MutableEntry; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheAtomicWriteOrderMode; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CacheEntryProcessor; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; +import static org.apache.ignite.cache.CacheMode.PARTITIONED; + +/** + * Invoke retry consistency test. + */ +public class CacheNearDisabledAtomicInvokeRestartSelfTest extends CacheAbstractRestartSelfTest { + /** */ + public static final int RANGE = 50; + + /** */ + private static final long FIRST_VAL = 1; + + /** */ + private final ConcurrentMap<String, AtomicLong> nextValMap = new ConcurrentHashMap<>(); + + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 4; + } + + /** {@inheritDoc} */ + @Override protected CacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected CacheAtomicityMode atomicityMode() { + return ATOMIC; + } + + /** {@inheritDoc} */ + @Override protected CacheAtomicWriteOrderMode atomicWriteOrderMode() { + return CacheAtomicWriteOrderMode.PRIMARY; + } + + /** */ + @Override protected NearCacheConfiguration nearConfiguration() { + return null; + } + + /** {@inheritDoc} */ + protected void checkCache(IgniteEx ignite, IgniteCache cache) throws Exception { + log.info("Start cache validation."); + + long startTime = U.currentTimeMillis(); + + Map<String, Set> badCacheEntries = new HashMap<>(); + + for (Map.Entry<String, AtomicLong> e : nextValMap.entrySet()) { + String key = e.getKey(); + + Set set = (Set)cache.get(key); + + if (set == null || e.getValue() == null || !Objects.equals(e.getValue().get(), (long)set.size())) + badCacheEntries.put(key, set); + } + + if (!badCacheEntries.isEmpty()) { + // Print all usefull information and finish. + for (Map.Entry<String, Set> e : badCacheEntries.entrySet()) { + String key = e.getKey(); + + U.error(log, "Got unexpected set size [key='" + key + "', expSize=" + nextValMap.get(key) + + ", cacheVal=" + e.getValue() + "]"); + } + + log.info("Next values map contant:"); + for (Map.Entry<String, AtomicLong> e : nextValMap.entrySet()) + log.info("Map Entry [key=" + e.getKey() + ", val=" + e.getValue() + "]"); + + log.info("Cache content:"); + + for (int k2 = 0; k2 < RANGE; k2++) { + String key2 = "key-" + k2; + + Object val = cache.get(key2); + + if (val != null) + log.info("Cache Entry [key=" + key2 + ", val=" + val + "]"); + + } + + fail("Cache and local map are in inconsistent state [badKeys=" + badCacheEntries.keySet() + ']'); + } + + log.info("Clearing all data."); + + cache.removeAll(); + nextValMap.clear(); + + log.info("Cache validation successfully finished in " + + (U.currentTimeMillis() - startTime) / 1000 + " sec."); + } + + /** {@inheritDoc} */ + @Override protected void updateCache(IgniteEx ignite, IgniteCache cache) { + final int k = ThreadLocalRandom.current().nextInt(RANGE); + + String key = "key-" + k; + + AtomicLong nextAtomicVal = nextValMap.putIfAbsent(key, new AtomicLong(FIRST_VAL)); + + Long nextVal = FIRST_VAL; + + if (nextAtomicVal != null) + nextVal = nextAtomicVal.incrementAndGet(); + + cache.invoke(key, new AddInSetEntryProcessor(), nextVal); + } + + /** + */ + private static class AddInSetEntryProcessor implements CacheEntryProcessor<String, Set, Object> { + /** */ + private static final long serialVersionUID = 0; + + /** {@inheritDoc} */ + @Override public Object process(MutableEntry<String, Set> entry, + Object... arguments) throws EntryProcessorException { + assert !F.isEmpty(arguments); + + Object val = arguments[0]; + + Set set; + + if (!entry.exists()) + set = new HashSet<>(); + else + set = entry.getValue(); + + set.add(val); + + entry.setValue(set); + + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/077af17f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalInvokeRestartSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalInvokeRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalInvokeRestartSelfTest.java new file mode 100644 index 0000000..f4eea6c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalInvokeRestartSelfTest.java @@ -0,0 +1,173 @@ +/* + * 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.internal.processors.cache.distributed; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicLong; +import javax.cache.processor.EntryProcessorException; +import javax.cache.processor.MutableEntry; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CacheEntryProcessor; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; +import static org.apache.ignite.cache.CacheMode.PARTITIONED; + +/** + * Invoke retry consistency test. + */ +public class CacheNearDisabledTransactionalInvokeRestartSelfTest extends CacheAbstractRestartSelfTest { + /** */ + public static final int RANGE = 100; + + /** */ + private static final int KEYS_CNT = 5; + + /** */ + protected final ConcurrentMap<String, AtomicLong> map = new ConcurrentHashMap<>(); + + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 4; + } + + /** {@inheritDoc} */ + @Override protected CacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected CacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } + + /** */ + @Override protected NearCacheConfiguration nearConfiguration() { + return null; + } + + /** {@inheritDoc} */ + protected void checkCache(IgniteEx ignite, IgniteCache cache) { + log.info("Start cache validation."); + + long startTime = U.currentTimeMillis(); + + Map<String, Long> notEqualsCacheVals = new HashMap<>(); + Map<String, Long> notEqualsLocMapVals = new HashMap<>(); + + for (int k = 0; k < RANGE; k++) { + if (k % 10_000 == 0) + log.info("Start validation for keys like 'key-" + k + "-*'"); + + for (int i = 0; i < KEYS_CNT; i++) { + String key = "key-" + k + "-" + i; + + Long cacheVal = (Long)cache.get(key); + + AtomicLong aVal = map.get(key); + Long mapVal = aVal != null ? aVal.get() : null; + + if (!Objects.equals(cacheVal, mapVal)) { + notEqualsCacheVals.put(key, cacheVal); + notEqualsLocMapVals.put(key, mapVal); + } + } + } + + assert notEqualsCacheVals.size() == notEqualsLocMapVals.size() : "Invalid state " + + "[cacheMapVals=" + notEqualsCacheVals + ", mapVals=" + notEqualsLocMapVals + "]"; + + if (!notEqualsCacheVals.isEmpty()) { + // Print all usefull information and finish. + for (Map.Entry<String, Long> eLocMap : notEqualsLocMapVals.entrySet()) { + String key = eLocMap.getKey(); + Long mapVal = eLocMap.getValue(); + Long cacheVal = notEqualsCacheVals.get(key); + + U.error(log, "Got different values [key='" + key + + "', cacheVal=" + cacheVal + ", localMapVal=" + mapVal + "]"); + } + + log.info("Local driver map contant:\n " + map); + + log.info("Cache content:"); + + for (int k2 = 0; k2 < RANGE; k2++) { + for (int i2 = 0; i2 < KEYS_CNT; i2++) { + String key2 = "key-" + k2 + "-" + i2; + + Long val = (Long)cache.get(key2); + + if (val != null) + log.info("Entry [key=" + key2 + ", val=" + val + "]"); + } + } + + throw new IllegalStateException("Cache and local map are in inconsistent state [badKeys=" + + notEqualsCacheVals.keySet() + ']'); + } + + log.info("Cache validation successfully finished in " + + (U.currentTimeMillis() - startTime) / 1000 + " sec."); + } + + /** {@inheritDoc} */ + @Override protected void updateCache(IgniteEx ignite, IgniteCache cache) { + final int k = ThreadLocalRandom.current().nextInt(RANGE); + + final String[] keys = new String[KEYS_CNT]; + + for (int i = 0; i < keys.length; i++) + keys[i] = "key-" + k + "-" + i; + + for (String key : keys) { + cache.invoke(key, new IncrementCacheEntryProcessor()); + + AtomicLong prevVal = map.putIfAbsent(key, new AtomicLong(0)); + + if (prevVal != null) + prevVal.incrementAndGet(); + } + } + + /** + */ + private static class IncrementCacheEntryProcessor implements CacheEntryProcessor<String, Long, Long> { + /** */ + private static final long serialVersionUID = 0; + + /** {@inheritDoc} */ + @Override public Long process(MutableEntry<String, Long> entry, + Object... arguments) throws EntryProcessorException { + long newVal = entry.getValue() == null ? 0 : entry.getValue() + 1; + + entry.setValue(newVal); + + return newVal; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/077af17f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalWriteReadRestartSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalWriteReadRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalWriteReadRestartSelfTest.java new file mode 100644 index 0000000..875aef3 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheNearDisabledTransactionalWriteReadRestartSelfTest.java @@ -0,0 +1,124 @@ +/* + * 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.internal.processors.cache.distributed; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ThreadLocalRandom; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; +import static org.apache.ignite.cache.CacheMode.PARTITIONED; + +/** + * Transactional write read consistency test. + */ +public class CacheNearDisabledTransactionalWriteReadRestartSelfTest extends CacheAbstractRestartSelfTest{ + /** */ + public static final int RANGE = 100; + + /** */ + private static final int KEYS_CNT = 5; + + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 4; + } + + /** {@inheritDoc} */ + @Override protected CacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected CacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } + + /** */ + @Override protected NearCacheConfiguration nearConfiguration() { + return null; + } + + /** {@inheritDoc} */ + @Override protected void checkCache(IgniteEx ignite, IgniteCache cache) { + // No-op. + } + + /** {@inheritDoc} */ + @Override protected void updateCache(IgniteEx ignite, IgniteCache cache) throws Exception { + final int k = ThreadLocalRandom.current().nextInt(RANGE); + + final String[] keys = new String[KEYS_CNT]; + + for (int i = 0; i < keys.length; i++) + keys[i] = "key-" + k + "-" + i; + + doInTransaction(ignite, new Callable<Void>() { + @Override public Void call() throws Exception { + Map<String, Long> map = new HashMap<>(); + + for (String key : keys) { + Long val = (Long)cache.get(key); + + map.put(key, val); + } + + Set<Long> values = new HashSet<>(map.values()); + + if (values.size() != 1) { + // Print all usefull information and finish. + U.error(log, "Got different values for keys [map=" + map + "]"); + + log.info("Cache content:"); + + for (int k = 0; k < RANGE; k++) { + for (int i = 0; i < KEYS_CNT; i++) { + String key = "key-" + k + "-" + i; + + Long val = (Long)cache.get(key); + + if (val != null) + log.info("Entry [key=" + key + ", val=" + val + "]"); + } + } + + throw new IllegalStateException("Found different values for keys (see above information) [map=" + + map + ']'); + } + + final Long oldVal = map.get(keys[0]); + + final Long newVal = oldVal == null ? 0 : oldVal + 1; + + for (String key : keys) + cache.put(key, newVal); + + return null; + } + }); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/077af17f/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheLoadConsistencyTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheLoadConsistencyTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheLoadConsistencyTestSuite.java new file mode 100644 index 0000000..cd0be9c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheLoadConsistencyTestSuite.java @@ -0,0 +1,42 @@ +/* + * 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.testsuites; + +import junit.framework.TestSuite; +import org.apache.ignite.internal.processors.cache.distributed.CacheNearDisabledAtomicInvokeRestartSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.CacheNearDisabledTransactionalInvokeRestartSelfTest; +import org.apache.ignite.internal.processors.cache.distributed.CacheNearDisabledTransactionalWriteReadRestartSelfTest; + +/** + * Test suite. + */ +public class IgniteCacheLoadConsistencyTestSuite extends TestSuite { + /** + * @return Ignite Cache Failover test suite. + * @throws Exception Thrown in case of the failure. + */ + public static TestSuite suite() throws Exception { + TestSuite suite = new TestSuite("Cache Load Consistency Test Suite"); + + suite.addTestSuite(CacheNearDisabledAtomicInvokeRestartSelfTest.class); + suite.addTestSuite(CacheNearDisabledTransactionalInvokeRestartSelfTest.class); + suite.addTestSuite(CacheNearDisabledTransactionalWriteReadRestartSelfTest.class); + + return suite; + } +}
