ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sboi...@apache.org
Subject [13/50] [abbrv] ignite git commit: IGNITE-9082 Throwing checked exception during tx commit without node stopping leads to data corruption - Fixes #4809.
Date Tue, 23 Oct 2018 15:01:17 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/5eb871e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDataConsistencyOnCommitFailureTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDataConsistencyOnCommitFailureTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDataConsistencyOnCommitFailureTest.java
new file mode 100644
index 0000000..881c680
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxDataConsistencyOnCommitFailureTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.transactions;
+
+import java.util.UUID;
+import java.util.function.Supplier;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.testsuites.IgniteIgnore;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.jetbrains.annotations.Nullable;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * Tests data consistency if transaction is failed due to heuristic exception on originating
node.
+ */
+public class TxDataConsistencyOnCommitFailureTest extends GridCommonAbstractTest {
+    /** */
+    public static final int KEY = 0;
+
+    /** */
+    public static final String CLIENT = "client";
+
+    /** */
+    private int nodesCnt;
+
+    /** */
+    private int backups;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws
Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.setClientMode(igniteInstanceName.startsWith(CLIENT));
+
+        cfg.setCacheConfiguration(new CacheConfiguration(DEFAULT_CACHE_NAME).
+            setCacheMode(CacheMode.PARTITIONED).
+            setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL).
+            setBackups(backups).
+            setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /** */
+    public void testCommitErrorOnNearNode2PC() throws Exception {
+        nodesCnt = 3;
+
+        backups = 2;
+
+        doTestCommitError(() -> {
+            try {
+                return startGrid("client");
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /** */
+    public void testCommitErrorOnNearNode1PC() throws Exception {
+        nodesCnt = 2;
+
+        backups = 1;
+
+        doTestCommitError(() -> {
+            try {
+                return startGrid("client");
+            }
+            catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /** */
+    @IgniteIgnore(value = "https://issues.apache.org/jira/browse/IGNITE-9806", forceFailure
= false)
+    public void testCommitErrorOnColocatedNode2PC() throws Exception {
+        nodesCnt = 3;
+
+        backups = 2;
+
+        doTestCommitError(() -> primaryNode(KEY, DEFAULT_CACHE_NAME));
+    }
+
+    /**
+     * @param factory Factory.
+     */
+    private void doTestCommitError(Supplier<Ignite> factory) throws Exception {
+        Ignite crd = startGridsMultiThreaded(nodesCnt);
+
+        crd.cache(DEFAULT_CACHE_NAME).put(KEY, KEY);
+
+        Ignite ignite = factory.get();
+
+        if (ignite == null)
+            ignite = startGrid("client");
+
+        assertNotNull(ignite.cache(DEFAULT_CACHE_NAME));
+
+        injectMockedTxManager(ignite);
+
+        checkKey();
+
+        IgniteTransactions transactions = ignite.transactions();
+
+        try(Transaction tx = transactions.txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ,
0, 1)) {
+            assertNotNull(transactions.tx());
+
+            ignite.cache(DEFAULT_CACHE_NAME).put(KEY, KEY + 1);
+
+            tx.commit();
+
+            fail();
+        }
+        catch (Exception t) {
+            // No-op.
+        }
+
+        checkKey();
+
+        checkFutures();
+    }
+
+    /**
+     * @param ignite Ignite.
+     */
+    private void injectMockedTxManager(Ignite ignite) {
+        IgniteEx igniteEx = (IgniteEx)ignite;
+
+        GridCacheSharedContext<Object, Object> ctx = igniteEx.context().cache().context();
+
+        IgniteTxManager tm = ctx.tm();
+
+        IgniteTxManager mockTm = Mockito.spy(tm);
+
+        MockGridNearTxLocal locTx = new MockGridNearTxLocal(ctx, false, false, false, GridIoPolicy.SYSTEM_POOL,
+            TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ, 0,
true, null, 1, null, 0, null);
+
+        Mockito.doAnswer(new Answer<GridNearTxLocal>() {
+            @Override public GridNearTxLocal answer(InvocationOnMock invocation) throws Throwable
{
+                mockTm.onCreated(null, locTx);
+
+                return locTx;
+            }
+        }).when(mockTm).
+            newTx(locTx.implicit(), locTx.implicitSingle(), null, locTx.concurrency(),
+                locTx.isolation(), locTx.timeout(), locTx.storeEnabled(), null, locTx.size(),
locTx.label());
+
+        ctx.setTxManager(mockTm);
+    }
+
+    /** */
+    private void checkKey() {
+        for (Ignite ignite : G.allGrids()) {
+            if (!ignite.configuration().isClientMode())
+                assertNotNull(ignite.cache(DEFAULT_CACHE_NAME).localPeek(KEY));
+        }
+    }
+
+    /** */
+    private static class MockGridNearTxLocal extends GridNearTxLocal {
+        /** Empty constructor. */
+        public MockGridNearTxLocal() {
+        }
+
+        /**
+         * @param ctx Context.
+         * @param implicit Implicit.
+         * @param implicitSingle Implicit single.
+         * @param sys System.
+         * @param plc Policy.
+         * @param concurrency Concurrency.
+         * @param isolation Isolation.
+         * @param timeout Timeout.
+         * @param storeEnabled Store enabled.
+         * @param mvccOp Mvcc op.
+         * @param txSize Tx size.
+         * @param subjId Subj id.
+         * @param taskNameHash Task name hash.
+         * @param lb Label.
+         */
+        public MockGridNearTxLocal(GridCacheSharedContext ctx, boolean implicit, boolean
implicitSingle, boolean sys,
+            byte plc, TransactionConcurrency concurrency, TransactionIsolation isolation,
long timeout,
+            boolean storeEnabled, Boolean mvccOp, int txSize, @Nullable UUID subjId, int
taskNameHash, @Nullable String lb) {
+            super(ctx, implicit, implicitSingle, sys, plc, concurrency, isolation, timeout,
storeEnabled, mvccOp,
+                txSize, subjId, taskNameHash, lb);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void userCommit() throws IgniteCheckedException {
+            throw new IgniteCheckedException("Force failure");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5eb871e1/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
index 7e98ec7..7091a09 100755
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
@@ -1996,17 +1996,26 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest
{
 
             final Collection<GridCacheFuture<?>> futs = ig.context().cache().context().mvcc().activeFutures();
 
-            for (GridCacheFuture<?> fut : futs)
-                log.info("Waiting for future: " + fut);
+            boolean hasFutures = false;
 
-            assertTrue("Expecting no active futures: node=" + ig.localNode().id(), futs.isEmpty());
+            for (GridCacheFuture<?> fut : futs) {
+                if (!fut.isDone()) {
+                    log.error("Expecting no active future [node=" + ig.localNode().id() +
", fut=" + fut + ']');
+
+                    hasFutures = true;
+                }
+            }
+
+            if (hasFutures)
+                fail("Some mvcc futures are not finished");
 
             Collection<IgniteInternalTx> txs = ig.context().cache().context().tm().activeTransactions();
 
             for (IgniteInternalTx tx : txs)
-                log.info("Waiting for tx: " + tx);
+                log.error("Expecting no active transaction [node=" + ig.localNode().id()
+ ", tx=" + tx + ']');
 
-            assertTrue("Expecting no active transactions: node=" + ig.localNode().id(), txs.isEmpty());
+            if (!txs.isEmpty())
+                fail("Some transaction are not finished");
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5eb871e1/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
index 386b17b..7dba461 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
@@ -25,6 +25,7 @@ import org.apache.ignite.internal.processors.cache.distributed.CacheAtomicPrimar
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCachePrimarySyncTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteTxCachePrimarySyncTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteTxCacheWriteSynchronizationModesMultithreadedTest;
+import org.apache.ignite.internal.processors.cache.transactions.TxDataConsistencyOnCommitFailureTest;
 import org.apache.ignite.testframework.junits.GridAbstractTest;
 
 /**
@@ -49,6 +50,8 @@ public class IgniteCacheTestSuite9 extends TestSuite {
 
         suite.addTestSuite(CacheAtomicPrimarySyncBackPressureTest.class);
 
+        suite.addTestSuite(TxDataConsistencyOnCommitFailureTest.class);
+
         return suite;
     }
 }


Mime
View raw message