You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by av...@apache.org on 2020/06/26 08:16:47 UTC

[ignite] branch master updated: IGNITE-13051 #2 check mvcc configuration after register caches futu… (#7902)

This is an automated email from the ASF dual-hosted git repository.

av pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 1413af0  IGNITE-13051 #2 check mvcc configuration after register caches futu… (#7902)
1413af0 is described below

commit 1413af0be38372a496dec03339e1c0f8fcb04982
Author: Maksim Timonin <ti...@gmail.com>
AuthorDate: Fri Jun 26 11:16:25 2020 +0300

    IGNITE-13051 #2 check mvcc configuration after register caches futu… (#7902)
---
 .../cache/CacheAffinitySharedManager.java          |   3 +
 .../processors/cache/GridCacheProcessor.java       |   3 +
 .../CachePartitionLossWithRestartsTest.java        |  36 ++-
 .../cache/mvcc/CacheMvccClientTopologyTest.java    | 305 +++++++++++++++++++++
 .../mvcc/CacheMvccConfigurationValidationTest.java |  30 --
 .../testsuites/IgniteCacheMvccTestSuite.java       |   2 +
 6 files changed, 336 insertions(+), 43 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index 94d6bed..7c4371e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -853,6 +853,9 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
         IgniteInternalFuture<?> res = cachesRegistry.update(exchActions);
 
+        for (ExchangeActions.CacheActionData d: exchActions.cacheStartRequests())
+            cctx.coordinators().validateCacheConfiguration(d.descriptor().cacheConfiguration());
+
         // Affinity did not change for existing caches.
         onCustomMessageNoAffinityChange(fut, exchActions);
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index aff0dc2..97d46a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -1692,6 +1692,9 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         IgniteInternalFuture<?> res = sharedCtx.affinity().initCachesOnLocalJoin(
             locJoinCtx.cacheGroupDescriptors(), locJoinCtx.cacheDescriptors());
 
+        for (DynamicCacheDescriptor d: locJoinCtx.cacheDescriptors().values())
+            ctx.coordinators().validateCacheConfiguration(d.cacheConfiguration());
+
         List<StartCacheInfo> startCacheInfos = locJoinCtx.caches().stream()
             .map(cacheInfo -> new StartCacheInfo(cacheInfo.get1(), cacheInfo.get2(), exchTopVer, false))
             .collect(Collectors.toList());
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossWithRestartsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossWithRestartsTest.java
index abf40e0..da527e4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossWithRestartsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossWithRestartsTest.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.DataRegionConfiguration;
@@ -70,27 +71,33 @@ public class CachePartitionLossWithRestartsTest extends GridCommonAbstractTest {
     @Parameterized.Parameter(value = 3)
     public int clientIdx;
 
+    /** Possible values: true, false */
+    @Parameterized.Parameter(value = 4)
+    public boolean mvccEnabled;
+
     /** */
     @Parameterized.Parameters(name = "{0} {1} {2} {3}")
     public static List<Object[]> parameters() {
         ArrayList<Object[]> params = new ArrayList<>();
 
-        for (boolean persistent : new boolean[]{false, true}) {
-            params.add(new Object[]{-1, false, persistent, 3});
-            params.add(new Object[]{0, false, persistent, 3});
-            params.add(new Object[]{2, false, persistent, 3});
+        for (boolean mvcc : new boolean[]{false, true}) {
+            for (boolean persistent : new boolean[] {false, true}) {
+                params.add(new Object[] {-1, false, persistent, 3, mvcc});
+                params.add(new Object[] {0, false, persistent, 3, mvcc});
+                params.add(new Object[] {2, false, persistent, 3, mvcc});
 
-            params.add(new Object[]{-1, false, persistent, -1});
-            params.add(new Object[]{0, false, persistent, -1});
-            params.add(new Object[]{2, false, persistent, -1});
+                params.add(new Object[] {-1, false, persistent, -1, mvcc});
+                params.add(new Object[] {0, false, persistent, -1, mvcc});
+                params.add(new Object[] {2, false, persistent, -1, mvcc});
 
-            params.add(new Object[]{-1, true, persistent, 3});
-            params.add(new Object[]{0, true, persistent, 3});
-            params.add(new Object[]{2, true, persistent, 3});
+                params.add(new Object[] {-1, true, persistent, 3, mvcc});
+                params.add(new Object[] {0, true, persistent, 3, mvcc});
+                params.add(new Object[] {2, true, persistent, 3, mvcc});
 
-            params.add(new Object[]{-1, true, persistent, -1});
-            params.add(new Object[]{0, true, persistent, -1});
-            params.add(new Object[]{2, true, persistent, -1});
+                params.add(new Object[] {-1, true, persistent, -1, mvcc});
+                params.add(new Object[] {0, true, persistent, -1, mvcc});
+                params.add(new Object[] {2, true, persistent, -1, mvcc});
+            }
         }
 
         return params;
@@ -128,6 +135,9 @@ public class CachePartitionLossWithRestartsTest extends GridCommonAbstractTest {
                 setBackups(0).
                 setAffinity(new RendezvousAffinityFunction(false, PARTS_CNT));
 
+        if (mvccEnabled)
+            ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT);
+
         if (startClientCache)
             cfg.setCacheConfiguration(ccfg);
 
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccClientTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccClientTopologyTest.java
new file mode 100644
index 0000000..c1b9cbc
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccClientTopologyTest.java
@@ -0,0 +1,305 @@
+/*
+ * 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.mvcc;
+
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.util.AttributeNodeFilter;
+import org.junit.Test;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT;
+
+/**
+ * Tests cover cases for correct MVCC flag set for client topology.
+ * Client topology, in relation to a specific cache, consist of nodes that match both conditions:
+ * - filtered with AttributeNodeFilter for the cache;
+ * - don't configured with CacheConfiguration for the cache.
+ */
+@SuppressWarnings("unchecked")
+public class CacheMvccClientTopologyTest extends GridCommonAbstractTest {
+    /**
+     * Index of node that in client topology
+     */
+    private static final int clientModeIdx = 0;
+
+    /**
+     * Index of node that holds a cache
+     */
+    private static final int cacheModeIdx = 1;
+
+    /**
+     * Check that by default MVCC is disabled for client topology
+     */
+    @Test
+    public void testMvccDisabledByDefaultForClientTopology() throws Exception {
+        // when
+        final IgniteEx crd = startGrid(getTestIgniteInstanceName(clientModeIdx));
+        checkTopology(1);
+
+        // then
+        assertNodesMvccDisabled(crd);
+    }
+
+    /**
+     * Check that MVCC is enabled for client topology if node with MVCC cache joined
+     */
+    @Test
+    public void testMvccEnabledForClientTopology() throws Exception {
+        // when
+        final IgniteEx crd = startGrid(getTestIgniteInstanceName(clientModeIdx));
+        final IgniteEx node = startGrid(getTestIgniteInstanceName(cacheModeIdx));
+
+        checkTopology(2);
+
+        // then
+        assertNodesMvccEnabled(crd, node);
+    }
+
+    /**
+     * Check that MVCC status doesn't change for client topology when MVCC cache node left
+     */
+    @Test
+    public void testMvccEnabledForClientTopologyAfterCacheNodeLeft() throws Exception {
+        // when
+        final IgniteEx crd = startGrid(getTestIgniteInstanceName(clientModeIdx));
+        startGrid(getTestIgniteInstanceName(cacheModeIdx));
+
+        checkTopology(2);
+        stopGrid(cacheModeIdx);
+        checkTopology(1);
+
+        // then
+        assertNodesMvccEnabled(crd);
+    }
+
+    /**
+     * Check that MVCC status doesn't change for client topology when MVCC cache node coordinator left
+     */
+    @Test
+    public void testMvccEnabledForClientTopologyStartedAfterCacheJoined() throws Exception {
+        // when
+        startGrid(getTestIgniteInstanceName(cacheModeIdx));
+        final IgniteEx node = startGrid(getTestIgniteInstanceName(clientModeIdx));
+
+        checkTopology(2);
+        stopGrid(cacheModeIdx);
+        checkTopology(1);
+
+        // then
+        assertNodesMvccEnabled(node);
+    }
+
+    /**
+     * Check that MVCC is disabled when cluster state changed to INACTIVE
+     */
+    @Test
+    public void testMvccDisbledForClientTopologyAfterClusterStateChangeToInactive() throws Exception {
+        // when
+        final IgniteEx crd = startGrid(getTestIgniteInstanceName(clientModeIdx));
+        final IgniteEx node = startGrid(getTestIgniteInstanceName(cacheModeIdx));
+
+        checkTopology(2);
+        crd.cluster().state(ClusterState.INACTIVE);
+
+        // then
+        assertNodesMvccDisabled(crd, node);
+    }
+
+    /**
+     * Check that MVCC is disabled for client topology if cluster state is INACTIVE but cache node joined
+     */
+    @Test
+    public void testMvccDisabledForClientTopologyCrdBeforeClusterStateChange() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getInactiveConfiguration(clientModeIdx);
+        IgniteConfiguration nodeCfg = getInactiveConfiguration(cacheModeIdx);
+
+        // when
+        final IgniteEx crd = startGrid(crdCfg);
+        final IgniteEx node = startGrid(nodeCfg);
+        checkTopology(2);
+
+        // then
+        assertNodesMvccDisabled(crd);
+        assertNodesMvccEnabled(node);
+    }
+
+    /**
+     * Check that MVCC is disabled for client topology if cluster state is INACTIVE but cache node joined
+     */
+    @Test
+    public void testMvccDisabledForClientTopologyBeforeClusterStateChange() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getInactiveConfiguration(cacheModeIdx);
+        IgniteConfiguration nodeCfg = getInactiveConfiguration(clientModeIdx);
+
+        // when
+        final IgniteEx crd = startGrid(crdCfg);
+        final IgniteEx node = startGrid(nodeCfg);
+        checkTopology(2);
+
+        // then
+        assertNodesMvccEnabled(crd);
+        assertNodesMvccDisabled(node);
+    }
+
+    /**
+     * Check that MVCC is disabled for client topology if cluster changed state to ACTIVE
+     */
+    @Test
+    public void testMvccDisabledForClientTopologyAfterClusterStateChange() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getConfiguration(getTestIgniteInstanceName(clientModeIdx))
+            .setClusterStateOnStart(ClusterState.INACTIVE);
+
+        // when
+        final IgniteEx crd = (IgniteEx) startGrid(getTestIgniteInstanceName(clientModeIdx), crdCfg);
+
+        checkTopology(1);
+        crd.cluster().state(ClusterState.ACTIVE);
+
+        // then
+        assertNodesMvccDisabled(crd);
+    }
+
+    /**
+     * Check that MVCC is enabled for client topology if cluster state changed to ACTIVE and cache node joined
+     */
+    @Test
+    public void testMvccEnabledForClientTopologyAfterClusterStateChange() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getInactiveConfiguration(clientModeIdx);
+        IgniteConfiguration nodeCfg = getInactiveConfiguration(cacheModeIdx);
+
+        // when
+        final IgniteEx crd = startGrid(crdCfg);
+        final IgniteEx node = startGrid(nodeCfg);
+        checkTopology(2);
+
+        crd.cluster().state(ClusterState.ACTIVE);
+
+        // then
+        assertNodesMvccEnabled(crd, node);
+    }
+
+    /**
+     * Check that MVCC is enabled for client topology when cluster state changed to ACTIVE and cache node left
+     */
+    @Test
+    public void testMvccEnabledForClientTopologyAfterClusterStateChangeAndNodeLeft() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getInactiveConfiguration(clientModeIdx);
+        IgniteConfiguration nodeCfg = getInactiveConfiguration(cacheModeIdx);
+
+        // when
+        final IgniteEx crd = startGrid(crdCfg);
+        startGrid(nodeCfg);
+
+        checkTopology(2);
+        crd.cluster().state(ClusterState.ACTIVE);
+
+        stopGrid(cacheModeIdx);
+        checkTopology(1);
+
+        // then
+        assertNodesMvccEnabled(crd);
+    }
+
+    /**
+     * Check that MVCC is enabled for client topology when cluster state changed to ACTIVE and new cache node joined
+     */
+    @Test
+    public void testMvccEnabledForClientTopologyAfterClusterStateChangeAndCacheNodeJoined() throws Exception {
+        // given
+        IgniteConfiguration crdCfg = getInactiveConfiguration(clientModeIdx);
+
+        // when
+        final IgniteEx crd = startGrid(crdCfg);
+        crd.cluster().state(ClusterState.ACTIVE);
+
+        final IgniteEx node = startGrid(getTestIgniteInstanceName(cacheModeIdx));
+        checkTopology(2);
+
+        // then
+        assertNodesMvccEnabled(crd, node);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+        stopAllGrids();
+    }
+
+    /**
+     * Configure nodes in client mode (filtered by AttributeNodeFilter, no CacheConfiguration is set)
+     * or in ordinary server mode.
+     */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        if (getTestIgniteInstanceIndex(igniteInstanceName) != clientModeIdx) {
+            String attrName = "has_cache";
+            Object attrVal = Boolean.TRUE;
+
+            CacheConfiguration ccfg = defaultCacheConfiguration()
+                .setNearConfiguration(null)
+                .setNodeFilter(new AttributeNodeFilter(attrName, attrVal))
+                .setAtomicityMode(TRANSACTIONAL_SNAPSHOT);
+
+            return cfg
+                .setCacheConfiguration(ccfg)
+                .setUserAttributes(F.asMap(attrName, attrVal));
+        }
+
+        return cfg;
+    }
+
+    /**
+     * Configuration with INACTIVE state on start
+     */
+    private IgniteConfiguration getInactiveConfiguration(int idx) throws Exception {
+        return getConfiguration(getTestIgniteInstanceName(idx))
+            .setClusterStateOnStart(ClusterState.INACTIVE);
+    }
+
+    /**
+     * Asserts if any node enables MVCC
+     */
+    private void assertNodesMvccDisabled(IgniteEx... nodes) {
+        assertNodesMvccIs(false, nodes);
+    }
+
+    /**
+     * Asserts if any node doesn't enable MVCC
+     */
+    private void assertNodesMvccEnabled(IgniteEx... nodes) {
+        assertNodesMvccIs(true, nodes);
+    }
+
+    /**
+     * Asserts if any node MVCC status doesn't equal expected
+     */
+    private void assertNodesMvccIs(boolean enabled, IgniteEx... nodes) {
+        for (IgniteEx n: nodes)
+            assertEquals("Check node: " + n.name(), enabled, n.context().coordinators().mvccEnabled());
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccConfigurationValidationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccConfigurationValidationTest.java
index a8dba15..fb83ae0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccConfigurationValidationTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccConfigurationValidationTest.java
@@ -37,13 +37,10 @@ import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 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.X;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.apache.ignite.util.AttributeNodeFilter;
 import org.jetbrains.annotations.Nullable;
 import org.junit.Test;
 
@@ -326,33 +323,6 @@ public class CacheMvccConfigurationValidationTest extends GridCommonAbstractTest
     }
 
     /**
-     * Check that node in client mode (filtered by AttributeNodeFilter) correctly works with MVCC.
-     */
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testMvccEnabledForClientMode() throws Exception {
-        String attrName = "has_cache";
-        Object attrVal = Boolean.TRUE;
-
-        final IgniteEx crd = (IgniteEx) startGrid(getTestIgniteInstanceName(0), getConfiguration());
-
-        // Do not start cache on non-affinity node.
-        CacheConfiguration ccfg = defaultCacheConfiguration()
-                .setNearConfiguration(null)
-                .setNodeFilter(new AttributeNodeFilter(attrName, attrVal))
-                .setAtomicityMode(TRANSACTIONAL_SNAPSHOT);
-
-        final IgniteEx node = (IgniteEx) startGrid(getTestIgniteInstanceName(1), getConfiguration()
-                .setCacheConfiguration(ccfg)
-                .setUserAttributes(F.asMap(attrName, attrVal)));
-
-        checkTopology(2);
-
-        assertTrue(crd.context().coordinators().mvccEnabled());
-        assertTrue(node.context().coordinators().mvccEnabled());
-    }
-
-    /**
      * Checks if passed in {@code 'Throwable'} has given class in {@code 'cause'} hierarchy
      * <b>including</b> that throwable itself and it contains passed message.
      * <p>
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite.java
index b43bd33..9c6c940 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.testsuites;
 
+import org.apache.ignite.internal.processors.cache.mvcc.CacheMvccClientTopologyTest;
 import org.apache.ignite.internal.processors.cache.mvcc.CacheMvccClientReconnectTest;
 import org.apache.ignite.internal.processors.cache.mvcc.CacheMvccClusterRestartTest;
 import org.apache.ignite.internal.processors.cache.mvcc.CacheMvccConfigurationValidationTest;
@@ -47,6 +48,7 @@ import org.junit.runners.Suite;
     CacheMvccProcessorTest.class,
     CacheMvccVacuumTest.class,
     CacheMvccConfigurationValidationTest.class,
+    CacheMvccClientTopologyTest.class,
 
     DataStreamProcessorMvccSelfTest.class,
     DataStreamProcessorMvccPersistenceSelfTest.class,