# 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,

Reply via email to