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

sboikov pushed a commit to branch ignite-835
in repository https://gitbox.apache.org/repos/asf/ignite.git

commit af58de599e013c4eae99dcdb4f0a2971de6ed47f
Author: sboikov <sboi...@apache.org>
AuthorDate: Thu Jan 24 19:02:23 2019 +0300

    ignite-835
---
 .../distributed/CacheLockChangingTopologyTest.java | 158 +++++++++++++++++++++
 .../distributed/GridCacheLockAbstractTest.java     |   8 ++
 .../ignite/testsuites/IgniteCacheTestSuite3.java   |   3 +
 3 files changed, 169 insertions(+)

diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLockChangingTopologyTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLockChangingTopologyTest.java
new file mode 100644
index 0000000..22519b0
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheLockChangingTopologyTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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 org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+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.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+
+/**
+ *
+ */
+@RunWith(JUnit4.class)
+public class CacheLockChangingTopologyTest extends GridCommonAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testLockOnChangingTopology_Partitioned() throws Exception {
+        lockOnChangingTopology(CacheMode.PARTITIONED, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testLockOnChangingTopology_PartitionedNearEnabled() throws 
Exception {
+        lockOnChangingTopology(CacheMode.PARTITIONED, true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testLockOnChangingTopology_Replicated() throws Exception {
+        lockOnChangingTopology(CacheMode.REPLICATED, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void lockOnChangingTopology(CacheMode cacheMode, boolean 
nearEnabled) throws Exception {
+        Ignite ignite = startGrid(0);
+
+        CacheConfiguration<Long, Long> ccfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
+
+        ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+        
ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        ccfg.setCacheMode(cacheMode);
+
+        if (nearEnabled)
+            ccfg.setNearConfiguration(new NearCacheConfiguration<>());
+
+        IgniteCache<Long, Long> cache = ignite.createCache(ccfg);
+
+        IgniteInternalFuture<?> nodeStart = GridTestUtils.runAsync(new 
Callable<Void>() {
+            @Override public Void call() throws Exception {
+                for (int i = 0; i < 3; i++) {
+                    Thread.sleep(ThreadLocalRandom.current().nextLong(500) + 
1000);
+
+                    startGrid(1);
+
+                    awaitPartitionMapExchange();
+                }
+
+                return null;
+            }
+        });
+
+        long stopTime = System.currentTimeMillis() + 60_000;
+
+        long cnt = 0;
+
+        final AtomicReference<Throwable> err = new AtomicReference<>();
+
+        while (!nodeStart.isDone() && System.currentTimeMillis() < stopTime) {
+            final long key = cnt++ % 100;
+
+            info("Iteration: " + cnt);
+
+            final Lock lock = cache.lock(key);
+
+            boolean unlocked = false;
+
+            lock.lock();
+
+            try {
+                Thread t =  new Thread(new Runnable() {
+                    @Override public void run() {
+                        try {
+                            lock.lock();
+                            lock.unlock();
+                        }
+                        catch (Throwable e) {
+                            err.set(e);
+                        }
+                    }
+                });
+
+                t.setName("lock-thread");
+                t.start();
+
+                Thread.sleep(ThreadLocalRandom.current().nextLong(100) + 50);
+
+                // Check lock was not acquired while it is still locked.
+                assertTrue(t.isAlive());
+
+                lock.unlock();
+
+                unlocked = true;
+
+                t.join();
+            } finally {
+                if (!unlocked)
+                    lock.unlock();
+            }
+
+            if (err.get() != null)
+                fail("Unexpected error: " + err);
+        }
+
+        assertTrue("Failed to wait for node start", nodeStart.isDone());
+    }
+}
\ No newline at end of file
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java
index 71b76dc..16069ce 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java
@@ -516,6 +516,14 @@ public abstract class GridCacheLockAbstractTest extends 
GridCommonAbstractTest {
      */
     @Test
     public void testLockReentrancy() throws Throwable {
+        /**
+         * awaitPartitionMapExchange is needed, otherwise deadlock is possible:
+         * main thread acquires lock and starts and wait for new thread while 
lock is acquired.
+         * New thread tries to get lock, at this moment exchanges starts and 
new thread
+         * waits for it. But exchange is not able to finish since there is 
acquired lock.
+         */
+        awaitPartitionMapExchange();
+
         Affinity<Integer> aff = ignite1.affinity(DEFAULT_CACHE_NAME);
 
         for (int i = 10; i < 100; i++) {
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index 81e0749..cd31fe0 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -37,6 +37,7 @@ import 
org.apache.ignite.internal.processors.cache.IgniteCacheGroupsTest;
 import 
org.apache.ignite.internal.processors.cache.IgniteCacheInterceptorSelfTestSuite;
 import 
org.apache.ignite.internal.processors.cache.IgniteCacheScanPredicateDeploymentSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.CacheAsyncOperationsTest;
+import 
org.apache.ignite.internal.processors.cache.distributed.CacheLockChangingTopologyTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.GridCacheMixedModeSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.IgniteTxGetAfterStopTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.IgniteTxRemoveTimeoutObjectsNearTest;
@@ -130,6 +131,8 @@ public class IgniteCacheTestSuite3 {
         
GridTestUtils.addTestIfNeeded(suite,GridCacheReplicatedPreloadLifecycleSelfTest.class,
 ignoredTests);
         
GridTestUtils.addTestIfNeeded(suite,GridCacheSyncReplicatedPreloadSelfTest.class,
 ignoredTests);
 
+        GridTestUtils.addTestIfNeeded(suite, 
CacheLockChangingTopologyTest.class, ignoredTests);
+
         
//GridTestUtils.addTestIfNeeded(suite,GridCacheReplicatedEntrySetSelfTest.class,
 ignoredTests);
         
//GridTestUtils.addTestIfNeeded(suite,GridCacheReplicatedMarshallerTxTest.class,
 ignoredTests);
         
//GridTestUtils.addTestIfNeeded(suite,GridCacheReplicatedOnheapFullApiSelfTest.class,
 ignoredTests);

Reply via email to