# ignite-656 more tests, fixed 'read-through' disabling for for atomic cache
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/3fc44aa8 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/3fc44aa8 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/3fc44aa8 Branch: refs/heads/ignite-646 Commit: 3fc44aa895429f94669bf375d3283d8dc382f19a Parents: 5b20c92 Author: sboikov <semen.boi...@inria.fr> Authored: Wed Apr 22 21:30:52 2015 +0300 Committer: sboikov <semen.boi...@inria.fr> Committed: Wed Apr 22 21:30:52 2015 +0300 ---------------------------------------------------------------------- .../processors/cache/GridCacheEntryEx.java | 4 + .../processors/cache/GridCacheMapEntry.java | 20 +- .../dht/atomic/GridDhtAtomicCache.java | 15 +- .../distributed/near/GridNearAtomicCache.java | 2 + .../local/atomic/GridLocalAtomicCache.java | 2 + .../cache/GridCacheAbstractFullApiSelfTest.java | 306 ++++++++++++++----- .../processors/cache/GridCacheTestEntryEx.java | 2 + 7 files changed, 256 insertions(+), 95 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java index 52b6a38..8d3d089 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java @@ -398,6 +398,7 @@ public interface GridCacheEntryEx { * @param val Value. Type depends on operation. * @param invokeArgs Optional arguments for entry processor. * @param writeThrough Write through flag. + * @param readThrough Read through flag. * @param retval Return value flag. * @param expiryPlc Expiry policy. * @param evt Event flag. @@ -430,6 +431,7 @@ public interface GridCacheEntryEx { @Nullable Object val, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, boolean evt, @@ -456,6 +458,7 @@ public interface GridCacheEntryEx { * @param writeObj Value. Type depends on operation. * @param invokeArgs Optional arguments for EntryProcessor. * @param writeThrough Write through flag. + * @param readThrough Read through flag. * @param retval Return value flag. * @param expiryPlc Expiry policy.. * @param evt Event flag. @@ -474,6 +477,7 @@ public interface GridCacheEntryEx { @Nullable Object writeObj, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, boolean evt, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java index 77590f2..c9f55f5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java @@ -1284,6 +1284,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { @Nullable Object writeObj, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, boolean evt, @@ -1315,11 +1316,11 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { // Possibly get old value form store. old = needVal ? rawGetOrUnmarshalUnlocked(!retval) : val; - boolean readThrough = false; + boolean readFromStore = false; Object old0 = null; - if (needVal && old == null && + if (readThrough && needVal && old == null && (cctx.readThrough() && (op == GridCacheOperation.TRANSFORM || cctx.loadPreviousValue()))) { old0 = readThrough(null, key, false, subjId, taskName); @@ -1364,7 +1365,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { boolean pass = cctx.isAllLocked(this, filter); if (!pass) { - if (expiryPlc != null && !readThrough && !cctx.putIfAbsentFilter(filter) && hasValueUnlocked()) + if (expiryPlc != null && !readFromStore && !cctx.putIfAbsentFilter(filter) && hasValueUnlocked()) updateTtl(expiryPlc); return new T3<>(false, retval ? CU.value(old, cctx, false) : null, null); @@ -1410,7 +1411,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { } if (!entry.modified()) { - if (expiryPlc != null && !readThrough && hasValueUnlocked()) + if (expiryPlc != null && !readFromStore && hasValueUnlocked()) updateTtl(expiryPlc); return new GridTuple3<>(false, null, invokeRes); @@ -1585,6 +1586,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { @Nullable Object writeObj, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, boolean evt, @@ -1802,17 +1804,17 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { oldVal = needVal ? rawGetOrUnmarshalUnlocked(!retval) : val; // Possibly read value from store. - boolean readThrough = false; + boolean readFromStore = false; Object old0 = null; - if (needVal && oldVal == null && (cctx.readThrough() && + if (readThrough && needVal && oldVal == null && (cctx.readThrough() && (op == GridCacheOperation.TRANSFORM || cctx.loadPreviousValue()))) { old0 = readThrough(null, key, false, subjId, taskName); oldVal = cctx.toCacheObject(old0); - readThrough = true; + readFromStore = true; // Detach value before index update. oldVal = cctx.kernalContext().cacheObjects().prepareForCache(oldVal, cctx); @@ -1855,7 +1857,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { boolean pass = cctx.isAllLocked(this, filter); if (!pass) { - if (expiryPlc != null && !readThrough && hasValueUnlocked() && !cctx.putIfAbsentFilter(filter)) + if (expiryPlc != null && !readFromStore && hasValueUnlocked() && !cctx.putIfAbsentFilter(filter)) updateTtl(expiryPlc); return new GridCacheUpdateAtomicResult(false, @@ -1902,7 +1904,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx { } if (!entry.modified()) { - if (expiryPlc != null && !readThrough && hasValueUnlocked()) + if (expiryPlc != null && !readFromStore && hasValueUnlocked()) updateTtl(expiryPlc); return new GridCacheUpdateAtomicResult(false, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 38e3604..ccacca1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -1668,6 +1668,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> { writeVal, req.invokeArguments(), primary && writeThrough() && !req.skipStore(), + !req.skipStore(), req.returnValue(), expiry, true, @@ -1935,11 +1936,12 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> { op, writeVal, null, - false, - false, + /*write-through*/false, + /*read-through*/false, + /*retval*/false, expiry, - true, - true, + /*event*/true, + /*metrics*/true, primary, ctx.config().getAtomicWriteOrderMode() == CLOCK, // Check version in CLOCK mode on primary node. topVer, @@ -1948,8 +1950,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> { CU.TTL_NOT_CHANGED, CU.EXPIRE_TIME_CALCULATE, null, - false, - false, + /*conflict resolve*/false, + /*intercept*/false, req.subjectId(), taskName); @@ -2406,6 +2408,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> { op == TRANSFORM ? entryProcessor : val, op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/false, + /*read-through*/false, /*retval*/false, /*expiry policy*/null, /*event*/true, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java index 29989e7..e3123e7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -222,6 +222,7 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> { val, null, /*write-through*/false, + /*read-through*/false, /*retval*/false, /**expiry policy*/null, /*event*/true, @@ -319,6 +320,7 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> { op == TRANSFORM ? entryProcessor : val, op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/false, + /*read-through*/false, /*retval*/false, null, /*event*/true, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java index 00a7a22..eae3c2c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java @@ -863,6 +863,7 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> { val, invokeArgs, storeEnabled, + storeEnabled, retval, expiryPlc, true, @@ -1315,6 +1316,7 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> { null, false, false, + false, expiryPlc, true, true, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java index 88c1cd8..ea2f37a 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java @@ -47,6 +47,7 @@ import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import static java.util.concurrent.TimeUnit.*; +import static org.apache.ignite.cache.CacheAtomicityMode.*; import static org.apache.ignite.cache.CacheMemoryMode.*; import static org.apache.ignite.cache.CacheMode.*; import static org.apache.ignite.events.EventType.*; @@ -4319,10 +4320,28 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract for (int i = 0; i < keys.size(); ++i) cache.put(keys.get(i), i); - for (String key : keys) { + for (int i = 0; i < keys.size(); ++i) { + String key = keys.get(i); + assertNotNull(cacheSkipStore.get(key)); assertNotNull(cache.get(key)); - assertTrue(map.containsKey(key)); + assertEquals(i, map.get(key)); + } + + for (int i = 0; i < keys.size(); ++i) { + String key = keys.get(i); + + Integer val1 = -1; + + cacheSkipStore.put(key, val1); + assertEquals(i, map.get(key)); + assertEquals(val1, cacheSkipStore.get(key)); + + Integer val2 = -2; + + assertEquals(val1, cacheSkipStore.invoke(key, new SetValueProcessor(val2))); + assertEquals(i, map.get(key)); + assertEquals(val2, cacheSkipStore.get(key)); } for (String key : keys) { @@ -4339,6 +4358,32 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertNull(cacheSkipStore.get(key)); assertNull(cache.get(key)); assertFalse(map.containsKey(key)); + + map.put(key, 0); + + Integer val = -1; + + assertNull(cacheSkipStore.invoke(key, new SetValueProcessor(val))); + assertEquals(0, map.get(key)); + assertEquals(val, cacheSkipStore.get(key)); + + cache.remove(key); + + map.put(key, 0); + + assertTrue(cacheSkipStore.putIfAbsent(key, val)); + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(0, map.get(key)); + + cache.remove(key); + + map.put(key, 0); + + assertNull(cacheSkipStore.getAndPut(key, val)); + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(0, map.get(key)); + + cache.remove(key); } assertFalse(cacheSkipStore.iterator().hasNext()); @@ -4402,7 +4447,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertTrue(map.size() == 0); - // Miscellaneous checks + // Miscellaneous checks. String newKey = "New key"; @@ -4439,20 +4484,18 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertTrue(map.size() == 0); - if (atomicityMode() == CacheAtomicityMode.TRANSACTIONAL) { - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.OPTIMISTIC, - TransactionIsolation.READ_COMMITTED); - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.OPTIMISTIC, - TransactionIsolation.REPEATABLE_READ); - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.OPTIMISTIC, - TransactionIsolation.SERIALIZABLE); + if (txEnabled()) { + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC,READ_COMMITTED); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, REPEATABLE_READ); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, SERIALIZABLE); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, READ_COMMITTED); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, REPEATABLE_READ); - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.PESSIMISTIC, - TransactionIsolation.READ_COMMITTED); - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.PESSIMISTIC, - TransactionIsolation.REPEATABLE_READ); - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, TransactionConcurrency.PESSIMISTIC, - TransactionIsolation.SERIALIZABLE); + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, SERIALIZABLE); } } @@ -4460,8 +4503,8 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract * @throws Exception If failed. */ public void testWithSkipStoreRemoveAll() throws Exception { - if (atomicityMode() == CacheAtomicityMode.TRANSACTIONAL || - (atomicityMode() == CacheAtomicityMode.ATOMIC && nearEnabled())) + if (atomicityMode() == TRANSACTIONAL || + (atomicityMode() == ATOMIC && nearEnabled())) fail("https://issues.apache.org/jira/browse/IGNITE-373"); IgniteCache<String, Integer> cache = grid(0).cache(null); @@ -4513,98 +4556,118 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract Map<String, Integer> data, List<String> keys, TransactionConcurrency txConcurrency, - TransactionIsolation txIsolation) throws Exception { - + TransactionIsolation txIsolation) + throws Exception + { cache.removeAll(data.keySet()); checkEmpty(cache, cacheSkipStore); - IgniteTransactions txs = grid(0).transactions(); + IgniteTransactions txs = cache.unwrap(Ignite.class).transactions(); - // Several put check - Transaction tx = txs.txStart(txConcurrency, txIsolation); + Integer val = -1; - for (int i = 0; i < keys.size(); i++) - cacheSkipStore.put(keys.get(i), i); + // Several put check. + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + for (String key: keys) + cacheSkipStore.put(key, val); + + for (String key: keys) { + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); + assertFalse(map.containsKey(key)); + } + + tx.commit(); + } for (String key: keys) { - assertNotNull(cacheSkipStore.get(key)); - assertNotNull(cache.get(key)); + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); assertFalse(map.containsKey(key)); } - tx.commit(); - - assert map.size() == 0; + assertEquals(0, map.size()); - // cacheSkipStore putAll(..)/removeAll(..) check - tx = txs.txStart(txConcurrency, txIsolation); + // cacheSkipStore putAll(..)/removeAll(..) check. + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + cacheSkipStore.putAll(data); - cacheSkipStore.putAll(data); + tx.commit(); + } for (String key: keys) { - assertNotNull(cacheSkipStore.get(key)); - assertNotNull(cache.get(key)); + val = data.get(key); + + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); assertFalse(map.containsKey(key)); } - cacheSkipStore.removeAll(data.keySet()); + map.putAll(data); + + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + cacheSkipStore.removeAll(data.keySet()); + + tx.commit(); + } for (String key: keys) { assertNull(cacheSkipStore.get(key)); - assertNull(cache.get(key)); - assertFalse(map.containsKey(key)); - } + assertNotNull(cache.get(key)); + assertTrue(map.containsKey(key)); - tx.commit(); + cache.remove(key); + } assertTrue(map.size() == 0); - // cache putAll(..)/removeAll(..) check - tx = txs.txStart(txConcurrency, txIsolation); + // cache putAll(..)/removeAll(..) check. + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + cache.putAll(data); - cache.putAll(data); + for (String key: keys) { + assertNotNull(cacheSkipStore.get(key)); + assertNotNull(cache.get(key)); + assertFalse(map.containsKey(key)); + } - for (String key: keys) { - assertNotNull(cacheSkipStore.get(key)); - assertNotNull(cache.get(key)); - assertFalse(map.containsKey(key)); - } + cache.removeAll(data.keySet()); - cache.removeAll(data.keySet()); + for (String key: keys) { + assertNull(cacheSkipStore.get(key)); + assertNull(cache.get(key)); + assertFalse(map.containsKey(key)); + } - for (String key: keys) { - assertNull(cacheSkipStore.get(key)); - assertNull(cache.get(key)); - assertFalse(map.containsKey(key)); + tx.commit(); } - tx.commit(); - assertTrue(map.size() == 0); - // putAll(..) from both cacheSkipStore and cache - tx = txs.txStart(txConcurrency, txIsolation); + // putAll(..) from both cacheSkipStore and cache. + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + Map<String, Integer> subMap = new HashMap<>(); - Map<String, Integer> subMap = new HashMap<>(); + for (int i = 0; i < keys.size() / 2; i++) + subMap.put(keys.get(i), i); - for (int i = 0; i < keys.size() / 2; i++) - subMap.put(keys.get(i), i); + cacheSkipStore.putAll(subMap); - cacheSkipStore.putAll(subMap); + subMap.clear(); - subMap.clear(); - for (int i = keys.size() / 2; i < keys.size(); i++) - subMap.put(keys.get(i), i); + for (int i = keys.size() / 2; i < keys.size(); i++) + subMap.put(keys.get(i), i); - cache.putAll(subMap); + cache.putAll(subMap); - for (String key: keys) { - assertNotNull(cacheSkipStore.get(key)); - assertNotNull(cache.get(key)); - assertFalse(map.containsKey(key)); - } + for (String key: keys) { + assertNotNull(cacheSkipStore.get(key)); + assertNotNull(cache.get(key)); + assertFalse(map.containsKey(key)); + } - tx.commit(); + tx.commit(); + } for (int i = 0; i < keys.size() / 2; i++) { String key = keys.get(i); @@ -4630,7 +4693,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertFalse(map.containsKey(key)); } - // Check that read-through is disabled when cacheSkipStore is used + // Check that read-through is disabled when cacheSkipStore is used. for (int i = 0; i < keys.size(); i++) putToStore(keys.get(i), i); @@ -4638,20 +4701,79 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertTrue(cache.size(CachePeekMode.ALL) == 0); assertTrue(map.size() != 0); - tx = txs.txStart(txConcurrency, txIsolation); + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + assertTrue(cacheSkipStore.getAll(data.keySet()).size() == 0); - assertTrue(cacheSkipStore.getAll(data.keySet()).size() == 0); + for (String key : keys) { + assertNull(cacheSkipStore.get(key)); - for (String key : keys) { - assertNull(cacheSkipStore.get(key)); + if (txIsolation == READ_COMMITTED) { + assertNotNull(cache.get(key)); + assertNotNull(cacheSkipStore.get(key)); + } + } - if (txIsolation == READ_COMMITTED) { - assertNotNull(cache.get(key)); - assertNotNull(cacheSkipStore.get(key)); + tx.commit(); + } + + cache.removeAll(data.keySet()); + + val = -1; + + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + for (String key : data.keySet()) { + map.put(key, 0); + + assertNull(cacheSkipStore.invoke(key, new SetValueProcessor(val))); + } + + tx.commit(); + } + + for (String key : data.keySet()) { + assertEquals(0, map.get(key)); + + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); + } + + cache.removeAll(data.keySet()); + + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + for (String key : data.keySet()) { + map.put(key, 0); + + assertTrue(cacheSkipStore.putIfAbsent(key, val)); + } + + tx.commit(); + } + + for (String key : data.keySet()) { + assertEquals(0, map.get(key)); + + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); + } + + cache.removeAll(data.keySet()); + + try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) { + for (String key : data.keySet()) { + map.put(key, 0); + + assertNull(cacheSkipStore.getAndPut(key, val)); } + + tx.commit(); } - tx.commit(); + for (String key : data.keySet()) { + assertEquals(0, map.get(key)); + + assertEquals(val, cacheSkipStore.get(key)); + assertEquals(val, cache.get(key)); + } cache.removeAll(data.keySet()); checkEmpty(cache, cacheSkipStore); @@ -4686,6 +4808,30 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract } /** + * Sets given value, returns old value. + */ + public static final class SetValueProcessor implements EntryProcessor<String, Integer, Integer> { + /** */ + private Integer newVal; + + /** + * @param newVal New value to set. + */ + SetValueProcessor(Integer newVal) { + this.newVal = newVal; + } + + /** {@inheritDoc} */ + @Override public Integer process(MutableEntry<String, Integer> entry, Object... arguments) throws EntryProcessorException { + Integer val = entry.getValue(); + + entry.setValue(newVal); + + return val; + } + } + + /** * */ public enum CacheStartMode { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3fc44aa8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java index a21fea5..9a24109 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java @@ -465,6 +465,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr @Nullable Object writeObj, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, boolean evt, @@ -486,6 +487,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr @Nullable Object val, @Nullable Object[] invokeArgs, boolean writeThrough, + boolean readThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, boolean evt,