http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicNearEnabledSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicNearEnabledSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicNearEnabledSelfTest.java new file mode 100644 index 0000000..928d7b7 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicNearEnabledSelfTest.java @@ -0,0 +1,39 @@ +/* + * 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; + +import org.apache.ignite.cache.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class GridCacheMultinodeUpdateAtomicNearEnabledSelfTest extends GridCacheMultinodeUpdateAbstractSelfTest { + /** {@inheritDoc} */ + @SuppressWarnings("RedundantMethodOverride") + @Override protected GridCacheDistributionMode distributionMode() { + return NEAR_PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return ATOMIC; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicSelfTest.java new file mode 100644 index 0000000..068dec0 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateAtomicSelfTest.java @@ -0,0 +1,38 @@ +/* + * 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; + +import org.apache.ignite.cache.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class GridCacheMultinodeUpdateAtomicSelfTest extends GridCacheMultinodeUpdateAbstractSelfTest { + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return ATOMIC; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledNoBackupsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledNoBackupsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledNoBackupsSelfTest.java new file mode 100644 index 0000000..a5e816f --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledNoBackupsSelfTest.java @@ -0,0 +1,39 @@ +/* + * 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; + +import org.apache.ignite.cache.*; + +/** + * + */ +public class GridCacheMultinodeUpdateNearEnabledNoBackupsSelfTest extends GridCacheMultinodeUpdateNearEnabledSelfTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 2; + } + + /** {@inheritDoc} */ + @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception { + CacheConfiguration ccfg = super.cacheConfiguration(gridName); + + ccfg.setBackups(0); + + return ccfg; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledSelfTest.java new file mode 100644 index 0000000..3ff7d42 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateNearEnabledSelfTest.java @@ -0,0 +1,40 @@ +/* + * 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; + +import org.apache.ignite.cache.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class GridCacheMultinodeUpdateNearEnabledSelfTest extends GridCacheMultinodeUpdateAbstractSelfTest { + /** {@inheritDoc} */ + @SuppressWarnings("RedundantMethodOverride") + @Override protected GridCacheDistributionMode distributionMode() { + return NEAR_PARTITIONED; + } + + /** {@inheritDoc} */ + @SuppressWarnings("RedundantMethodOverride") + @Override protected GridCacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateSelfTest.java new file mode 100644 index 0000000..483b4f9 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMultinodeUpdateSelfTest.java @@ -0,0 +1,39 @@ +/* + * 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; + +import org.apache.ignite.cache.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class GridCacheMultinodeUpdateSelfTest extends GridCacheMultinodeUpdateAbstractSelfTest { + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } + + /** {@inheritDoc} */ + @SuppressWarnings("RedundantMethodOverride") + @Override protected GridCacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManagerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManagerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManagerSelfTest.java new file mode 100644 index 0000000..887ea17 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManagerSelfTest.java @@ -0,0 +1,116 @@ +/* + * 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; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.processors.cache.*; +import org.apache.ignite.transactions.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.junits.common.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheMode.*; + +/** + * Tests for {@link GridCacheMvccManager}. + */ +public class GridCacheMvccManagerSelfTest extends GridCommonAbstractTest { + /** VM ip finder for TCP discovery. */ + private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** Cache mode. */ + private GridCacheMode mode; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setMaxMissedHeartbeats(Integer.MAX_VALUE); + disco.setIpFinder(ipFinder); + + cfg.setDiscoverySpi(disco); + cfg.setCacheConfiguration(cacheConfiguration()); + + return cfg; + } + + /** @return Cache configuration. */ + protected CacheConfiguration cacheConfiguration() { + CacheConfiguration cfg = defaultCacheConfiguration(); + + cfg.setCacheMode(mode); + cfg.setWriteSynchronizationMode(GridCacheWriteSynchronizationMode.FULL_SYNC); + cfg.setAtomicityMode(TRANSACTIONAL); + + return cfg; + } + + /** @throws Exception If failed. */ + public void testLocalCache() throws Exception { + mode = LOCAL; + + testCandidates(1); + } + + /** @throws Exception If failed. */ + public void testReplicatedCache() throws Exception { + mode = REPLICATED; + + testCandidates(3); + } + + /** @throws Exception If failed. */ + public void testPartitionedCache() throws Exception { + mode = PARTITIONED; + + testCandidates(3); + } + + /** + * @param gridCnt Grid count. + * @throws Exception If failed. + */ + private void testCandidates(int gridCnt) throws Exception { + try { + Ignite ignite = startGridsMultiThreaded(gridCnt); + + GridCache<Integer, Integer> cache = ignite.cache(null); + + IgniteTx tx = cache.txStart(); + + cache.put(1, 1); + + tx.commit(); + + for (int i = 0; i < gridCnt; i++) { + assert ((GridKernal)grid(i)).internalCache().context().mvcc().localCandidates().isEmpty(); + assert ((GridKernal)grid(i)).internalCache().context().mvcc().remoteCandidates().isEmpty(); + } + } + finally { + stopAllGrids(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/968c3cf8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java new file mode 100644 index 0000000..b21b642 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java @@ -0,0 +1,688 @@ +/* + * 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; + +import org.apache.ignite.cache.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.processors.cache.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.junits.common.*; + +import java.util.*; + +import static org.apache.ignite.cache.GridCacheAtomicityMode.*; +import static org.apache.ignite.cache.GridCacheMode.*; +import static org.apache.ignite.cache.GridCacheDistributionMode.*; + +/** + * Test cases for multi-threaded tests in partitioned cache. + */ +public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest { + /** Grid. */ + private GridKernal grid; + + /** VM ip finder for TCP discovery. */ + private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** + * + */ + public GridCacheMvccPartitionedSelfTest() { + super(true /*start grid. */); + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + grid = (GridKernal)grid(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + grid = null; + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration() throws Exception { + IgniteConfiguration cfg = super.getConfiguration(); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + cfg.setDiscoverySpi(disco); + + CacheConfiguration cacheCfg = defaultCacheConfiguration(); + + cacheCfg.setCacheMode(PARTITIONED); + cacheCfg.setBackups(1); + cacheCfg.setAtomicityMode(TRANSACTIONAL); + cacheCfg.setDistributionMode(NEAR_PARTITIONED); + + cfg.setCacheConfiguration(cacheCfg); + + return cfg; + } + + /** + * Tests remote candidates. + */ + public void testNearLocalsWithPending() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + + GridCacheMvccCandidate<String> c1 = entry.addRemote(node1, 1, ver1, 0, false, true); + GridCacheMvccCandidate<String> c2 = entry.addNearLocal(node1, 1, ver2, 0, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver2, nearLocCands.iterator().next().version()); + + assertEquals(1, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.readyNearLocal(ver2, ver2, empty(), empty(), Arrays.asList(ver1)); + + checkLocalOwner(c2, ver2, false); + checkRemote(c1, ver1, false, false); + + assertNotNull(entry.anyOwner()); + assertEquals(ver2, entry.anyOwner().version()); + } + + /** + * Tests remote candidates. + */ + public void testNearLocalsWithCommitted() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + + GridCacheMvccCandidate<String> c1 = entry.addNearLocal(node1, 1, ver1, 0, true); + GridCacheMvccCandidate<String> c2 = entry.addRemote(node1, 1, ver2, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver1, nearLocCands.iterator().next().version()); + + assertEquals(1, rmtCands.size()); + assertEquals(ver2, rmtCands.iterator().next().version()); + + entry.readyNearLocal(ver1, ver1, Arrays.asList(ver2), empty(), empty()); + + checkLocal(c1, ver1, true, false, false); + checkRemote(c2, ver2, true, false); + + assertNull(entry.anyOwner()); + } + + /** + * Tests remote candidates. + */ + public void testNearLocalsWithRolledback() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + + GridCacheMvccCandidate<String> c1 = entry.addNearLocal(node1, 1, ver1, 0, true); + GridCacheMvccCandidate<String> c2 = entry.addRemote(node1, 1, ver2, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver1, nearLocCands.iterator().next().version()); + + assertEquals(1, rmtCands.size()); + assertEquals(ver2, rmtCands.iterator().next().version()); + + entry.readyNearLocal(ver1, ver1, empty(), Arrays.asList(ver2), empty()); + + checkLocal(c1, ver1, true, false, false); + checkRemote(c2, ver2, true, false); + + assertNull(entry.anyOwner()); + } + + /** + * Tests remote candidates. + */ + public void testNearLocals() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + + GridCacheMvccCandidate<String> c1 = entry.addNearLocal(node1, 1, ver1, 0, true); + GridCacheMvccCandidate<String> c2 = entry.addNearLocal(node1, 1, ver2, 0, true); + + entry.readyNearLocal(ver2, ver2, empty(), empty(), empty()); + + checkLocalOwner(c2, ver2, false); + checkLocal(c1, ver1, false, false, false); + + Collection<GridCacheMvccCandidate<String>> cands = entry.localCandidates(); + + assert cands.size() == 2; + assert cands.iterator().next().version().equals(ver2); + + checkLocalOwner(c2, ver2, false); + checkLocal(c1, ver1, false, false, false); + } + + /** + * Tests remote candidates. + */ + public void testNearLocalsWithOwned() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + + GridCacheMvccCandidate<String> c1 = entry.addRemote(node1, 1, ver1, 0, false, true); + GridCacheMvccCandidate<String> c2 = entry.addNearLocal(node1, 1, ver2, 0, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver2, nearLocCands.iterator().next().version()); + + assertEquals(1, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.orderOwned(ver1, ver2); + + entry.readyNearLocal(ver2, ver2, empty(), empty(), empty()); + + checkRemote(c1, ver1, false, false); + + assertFalse(c1.owner()); + + checkLocalOwner(c2, ver2, false); + + assertNotNull(entry.anyOwner()); + assertEquals(ver2, entry.anyOwner().version()); + } + + /** + * @throws Exception If failed. + */ + public void testAddPendingRemote0() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver0 = version(0); + GridCacheVersion ver1 = version(1); + + entry.addNearLocal(node1, 1, ver1, 0, true); + + entry.readyNearLocal(ver1, ver1, empty(), empty(), Collections.<GridCacheVersion>singletonList(ver0)); + + entry.addRemote(node1, 1, ver0, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver1, nearLocCands.iterator().next().version()); + + assertEquals(1, rmtCands.size()); + assertEquals(ver0, rmtCands.iterator().next().version()); + + assertNotNull(entry.anyOwner()); + assertEquals(ver1, entry.anyOwner().version()); + } + + /** + * @throws Exception If failed. + */ + public void testAddPendingRemote1() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver0 = version(0); + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + GridCacheVersion ver3 = version(3); + + GridCacheMvccCandidate<String> c3 = entry.addNearLocal(node1, 1, ver3, 0, true); + + entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2)); + + GridCacheMvccCandidate<String> c2 = entry.addRemote(node1, 1, ver2, 0, false, true); + GridCacheMvccCandidate<String> c1 = entry.addRemote(node1, 1, ver1, 0, false, true); + GridCacheMvccCandidate<String> c0 = entry.addRemote(node1, 1, ver0, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + + assert rmtCands.size() == 3; + + // DHT remote candidates are not reordered and sorted. + GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c2, c1, c0}; + + rmtCands = entry.remoteMvccSnapshot(); + + int i = 0; + + for (GridCacheMvccCandidate<String> cand : rmtCands) { + assert cand == candArr[i] : "Invalid candidate in position " + i; + + i++; + } + + assertEquals(c3, entry.anyOwner()); + } + + /** + * @throws Exception If failed. + */ + public void testAddPendingRemote2() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver0 = version(0); + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + GridCacheVersion ver3 = version(3); + + GridCacheMvccCandidate<String> c3 = entry.addNearLocal(node1, 1, ver3, 0, true); + entry.addNearLocal(node1, 1, ver2, 0, true); + + entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2)); + + GridCacheMvccCandidate<String> c1 = entry.addRemote(node1, 1, ver1, 0, false, true); + GridCacheMvccCandidate<String> c0 = entry.addRemote(node1, 1, ver0, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + + assertEquals(2, rmtCands.size()); + + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(2, nearLocCands.size()); + + GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c1, c0}; + + int i = 0; + + for (GridCacheMvccCandidate<String> cand : rmtCands) { + assert cand == candArr[i] : "Invalid candidate in position " + i; + + i++; + } + + assertEquals(c3, entry.anyOwner()); + } + + /** + * Tests salvageRemote method + */ + public void testSalvageRemote() { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(1); + GridCacheVersion ver2 = version(2); + GridCacheVersion ver3 = version(3); + GridCacheVersion ver4 = version(4); + GridCacheVersion ver5 = version(5); + GridCacheVersion ver6 = version(6); + + entry.addRemote(node1, 1, ver1, 0, false, true); + entry.addRemote(node1, 1, ver2, 0, false, true); + GridCacheMvccCandidate<String> c3 = entry.addNearLocal(node1, 1, ver3, 0, true); + GridCacheMvccCandidate<String> c4 = entry.addRemote(node1, 1, ver4, 0, false, true); + entry.addRemote(node1, 1, ver5, 0, false, true); + entry.addRemote(node1, 1, ver6, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + + assertEquals(5, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(ver3, nearLocCands.iterator().next().version()); + + entry.salvageRemote(ver4); + + rmtCands = entry.remoteMvccSnapshot(); + + boolean before = true; + + for (GridCacheMvccCandidate<String> cand : rmtCands) { + if (cand == c4) { + before = false; + + continue; + } + + if (before && cand != c3) { + assertTrue(cand.owner()); + assertTrue(cand.used()); + } + else { + assertFalse(cand.owner()); + assertFalse(cand.used()); + } + } + } + + /** + * @throws Exception If failed. + */ + public void testNearRemoteConsistentOrdering0() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(10); + GridCacheVersion nearVer2 = version(5); + GridCacheVersion ver2 = version(20); + GridCacheVersion ver3 = version(30); + + entry.addRemote(node1, 1, ver1, 0, false, true); + entry.addNearLocal(node1, 1, nearVer2, 0, true); + entry.addRemote(node1, 1, ver3, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(nearVer2, nearLocCands.iterator().next().version()); + + assertEquals(2, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.readyNearLocal(nearVer2, ver2, empty(), empty(), empty()); + + assertNull(entry.anyOwner()); + + rmtCands = entry.remoteMvccSnapshot(); + + assertEquals(ver1, rmtCands.iterator().next().version()); + assertTrue(rmtCands.iterator().next().owner()); + } + + /** + * @throws Exception If failed. + */ + public void testNearRemoteConsistentOrdering1() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(10); + GridCacheVersion nearVer2 = version(5); + GridCacheVersion ver2 = version(20); + GridCacheVersion ver3 = version(30); + + entry.addRemote(node1, 1, ver1, 0, false, true); + entry.addNearLocal(node1, 1, nearVer2, 0, true); + entry.addRemote(node1, 1, ver3, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(nearVer2, nearLocCands.iterator().next().version()); + + assertEquals(2, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.orderCompleted(nearVer2, Arrays.asList(ver3), empty()); + entry.readyNearLocal(nearVer2, ver2, empty(), empty(), Arrays.asList(ver1)); + + nearLocCands = entry.localCandidates(); + rmtCands = entry.remoteMvccSnapshot(); + + assertNull(entry.anyOwner()); + assertEquals(ver3, rmtCands.iterator().next().version()); + assertTrue(rmtCands.iterator().next().owner()); + + GridCacheMvccCandidate<String> cand = nearLocCands.iterator().next(); + + assertTrue(cand.ready()); + assertFalse(cand.owner()); + assertFalse(cand.used()); + } + + /** + * @throws Exception If failed. + */ + public void testNearRemoteConsistentOrdering2() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(10); + GridCacheVersion nearVer2 = version(5); + GridCacheVersion ver2 = version(20); + GridCacheVersion ver3 = version(30); + + entry.addRemote(node1, 1, ver1, 0, false, true); + entry.addNearLocal(node1, 1, nearVer2, 0, true); + entry.addRemote(node1, 1, ver3, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(nearVer2, nearLocCands.iterator().next().version()); + + assertEquals(2, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.orderCompleted(nearVer2, empty(), empty()); + entry.readyNearLocal(nearVer2, ver2, empty(), empty(), empty()); + + nearLocCands = entry.localCandidates(); + rmtCands = entry.remoteMvccSnapshot(); + + assertNull(entry.anyOwner()); + assertEquals(ver1, rmtCands.iterator().next().version()); + assertTrue(rmtCands.iterator().next().owner()); + + GridCacheMvccCandidate<String> cand = nearLocCands.iterator().next(); + + assertTrue(cand.ready()); + assertFalse(cand.used()); + assertFalse(cand.owner()); + } + + /** + * @throws Exception If failed. + */ + public void testNearRemoteConsistentOrdering3() throws Exception { + GridCacheAdapter<String, String> cache = grid.internalCache(); + + GridCacheTestEntryEx<String, String> entry = new GridCacheTestEntryEx<>(cache.context(), "1"); + + UUID node1 = UUID.randomUUID(); + + GridCacheVersion ver1 = version(10); + GridCacheVersion nearVer2 = version(5); + GridCacheVersion ver2 = version(20); + GridCacheVersion ver3 = version(30); + + entry.addRemote(node1, 1, ver1, 0, false, true); + entry.addNearLocal(node1, 1, nearVer2, 0, true); + entry.addRemote(node1, 1, ver3, 0, false, true); + + Collection<GridCacheMvccCandidate<String>> rmtCands = entry.remoteMvccSnapshot(); + Collection<GridCacheMvccCandidate<String>> nearLocCands = entry.localCandidates(); + + assertEquals(1, nearLocCands.size()); + assertEquals(nearVer2, nearLocCands.iterator().next().version()); + + assertEquals(2, rmtCands.size()); + assertEquals(ver1, rmtCands.iterator().next().version()); + + entry.orderCompleted(nearVer2, empty(), empty()); + entry.readyNearLocal(nearVer2, ver2, empty(), empty(), Arrays.asList(ver1)); + + rmtCands = entry.remoteMvccSnapshot(); + + assertNotNull(entry.anyOwner()); + checkLocalOwner(entry.anyOwner(), nearVer2, false); + + assertEquals(ver1, rmtCands.iterator().next().version()); + } + + /** + * Gets version based on order. + * + * @param order Order. + * @return Version. + */ + private GridCacheVersion version(int order) { + return new GridCacheVersion(1, 0, order, order, 0); + } + + /** + * Creates an empty list of {@code GridCacheVersion}. + * + * @return Empty list. + */ + private Collection<GridCacheVersion> empty() { + return Collections.emptyList(); + } + + /** + * Checks flags on local owner candidate. + * + * @param cand Candidate to check. + * @param ver Cache version. + * @param reentry Reentry flag. + */ + private void checkLocalOwner(GridCacheMvccCandidate<String> cand, GridCacheVersion ver, boolean reentry) { + assert cand != null; + + info("Done candidate: " + cand); + + assert cand.version().equals(ver); + + // Check flags. + assert cand.reentry() == reentry; + + assert !cand.used(); + + assert cand.ready(); + assert cand.owner(); + assert cand.local(); + } + + /** + * @param cand Candidate to check. + * @param ver Version. + * @param owner Owner flag. + * @param used Done flag. + */ + private void checkRemote(GridCacheMvccCandidate<String> cand, GridCacheVersion ver, boolean owner, boolean used) { + assert cand != null; + + info("Done candidate: " + cand); + + assert cand.version().equals(ver); + + // Check flags. + assert cand.used() == used; + assert cand.owner() == owner; + + assert !cand.ready(); + assert !cand.reentry(); + assert !cand.local(); + } + + /** + * Checks flags on local candidate. + * + * @param cand Candidate to check. + * @param ver Cache version. + * @param ready Ready flag. + * @param owner Lock owner. + * @param reentry Reentry flag. + */ + private void checkLocal(GridCacheMvccCandidate<String> cand, GridCacheVersion ver, boolean ready, + boolean owner, boolean reentry) { + assert cand != null; + + info("Done candidate: " + cand); + + assert cand.version().equals(ver); + + // Check flags. + assert cand.ready() == ready; + assert cand.owner() == owner; + assert cand.reentry() == reentry; + + assert !cand.used(); + + assert cand.local(); + } +}