blob: 58b5966e9cfdcaa7b7e6146d80f8f1691432fded [file] [log] [blame]
/*
* 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 java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.UUID;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
/**
* Test cases for multi-threaded tests in partitioned cache.
*/
public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
/** */
private static final UUID nodeId = UUID.randomUUID();
/** Grid. */
private IgniteKernal grid;
/**
*
*/
public GridCacheMvccPartitionedSelfTest() {
super(true /*start grid. */);
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
grid = (IgniteKernal)grid();
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
grid = null;
}
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration() throws Exception {
IgniteConfiguration cfg = super.getConfiguration();
CacheConfiguration cacheCfg = defaultCacheConfiguration();
cacheCfg.setCacheMode(PARTITIONED);
cacheCfg.setBackups(1);
cacheCfg.setAtomicityMode(TRANSACTIONAL);
cfg.setCacheConfiguration(cacheCfg);
return cfg;
}
/**
* Tests remote candidates.
*/
@Test
public void testNearLocalsWithPending() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testNearLocalsWithCommitted() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testNearLocalsWithRolledback() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testNearLocals() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
entry.readyNearLocal(ver2, ver2, empty(), empty(), empty());
checkLocalOwner(c2, ver2, false);
checkLocal(c1, ver1, false, false, false);
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testNearLocalsWithOwned() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testAddPendingRemote0() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx entry = new GridCacheTestEntryEx(cache.context(), "1");
UUID node1 = UUID.randomUUID();
GridCacheVersion ver0 = version(0);
GridCacheVersion ver1 = version(1);
entry.addNearLocal(node1, 1, ver1, true);
entry.readyNearLocal(ver1, ver1, empty(), empty(), Collections.singletonList(ver0));
entry.addRemote(node1, 1, ver0, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testAddPendingRemote1() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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 c3 = entry.addNearLocal(node1, 1, ver3, true);
entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2));
GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, true);
GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, true);
Collection<GridCacheMvccCandidate> 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 cand : rmtCands) {
assert cand == candArr[i] : "Invalid candidate in position " + i;
i++;
}
assertEquals(c3, entry.anyOwner());
}
/**
* @throws Exception If failed.
*/
@Test
public void testAddPendingRemote2() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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 c3 = entry.addNearLocal(node1, 1, ver3, true);
entry.addNearLocal(node1, 1, ver2, true);
entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2));
GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, true);
GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
assertEquals(2, rmtCands.size());
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
assertEquals(2, nearLocCands.size());
GridCacheMvccCandidate[] candArr = new GridCacheMvccCandidate[] {c1, c0};
int i = 0;
for (GridCacheMvccCandidate cand : rmtCands) {
assert cand == candArr[i] : "Invalid candidate in position " + i;
i++;
}
assertEquals(c3, entry.anyOwner());
}
/**
* Tests salvageRemote method
*/
@Test
public void testSalvageRemote() {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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, true);
entry.addRemote(node1, 1, ver2, true);
GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, true);
GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, true);
entry.addRemote(node1, 1, ver5, true);
entry.addRemote(node1, 1, ver6, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
assertEquals(5, rmtCands.size());
assertEquals(ver1, rmtCands.iterator().next().version());
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
assertEquals(1, nearLocCands.size());
assertEquals(ver3, nearLocCands.iterator().next().version());
entry.salvageRemote(ver4);
rmtCands = entry.remoteMvccSnapshot();
boolean before = true;
for (GridCacheMvccCandidate 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.
*/
@Test
public void testNearRemoteConsistentOrdering0() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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, true);
entry.addNearLocal(node1, 1, nearVer2, true);
entry.addRemote(node1, 1, ver3, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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.
*/
@Test
public void testNearRemoteConsistentOrdering1() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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, true);
entry.addNearLocal(node1, 1, nearVer2, true);
entry.addRemote(node1, 1, ver3, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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 cand = nearLocCands.iterator().next();
assertTrue(cand.ready());
assertFalse(cand.owner());
assertFalse(cand.used());
}
/**
* @throws Exception If failed.
*/
@Test
public void testNearRemoteConsistentOrdering2() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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, true);
entry.addNearLocal(node1, 1, nearVer2, true);
entry.addRemote(node1, 1, ver3, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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 cand = nearLocCands.iterator().next();
assertTrue(cand.ready());
assertFalse(cand.used());
assertFalse(cand.owner());
}
/**
* @throws Exception If failed.
*/
@Test
public void testNearRemoteConsistentOrdering3() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheTestEntryEx 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, true);
entry.addNearLocal(node1, 1, nearVer2, true);
entry.addRemote(node1, 1, ver3, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> 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());
}
/**
* @throws Exception If failed.
*/
@Test
public void testSerializableReadLocksAdd() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheVersion serOrder1 = new GridCacheVersion(0, 10, 1);
GridCacheVersion serOrder2 = new GridCacheVersion(0, 20, 1);
GridCacheVersion serOrder3 = new GridCacheVersion(0, 15, 1);
{
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
assertNull(cand3);
cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
assertNotNull(cand3);
}
{
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder2, true);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder1, true);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
assertNull(cand3);
cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
assertNotNull(cand3);
}
{
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder3, false);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder1, true);
assertNull(cand3);
cand3 = addLocal(mvcc, e, version(3), serOrder1, false);
assertNull(cand3);
}
}
/**
* @throws Exception If failed.
*/
@Test
public void testSerializableReadLocksAssign() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
GridCacheVersion serOrder1 = new GridCacheVersion(0, 10, 1);
GridCacheVersion serOrder2 = new GridCacheVersion(0, 20, 1);
GridCacheVersion serOrder3 = new GridCacheVersion(0, 15, 1);
{
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
assertNull(cand3);
cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
assertNotNull(cand3);
CacheLockCandidates owners = mvcc.recheck();
assertNull(owners);
cand1.setReady();
owners = mvcc.recheck();
assertSame(cand1, owners);
checkCandidates(owners, cand1.version());
cand2.setReady();
owners = mvcc.recheck();
checkCandidates(owners, cand1.version(), cand2.version());
mvcc.remove(cand1.version());
owners = mvcc.recheck();
assertSame(cand2, owners);
checkCandidates(owners, cand2.version());
}
{
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
assertNull(cand3);
cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
assertNotNull(cand3);
CacheLockCandidates owners = mvcc.recheck();
assertNull(owners);
cand2.setReady();
owners = mvcc.recheck();
assertSame(cand2, owners);
checkCandidates(owners, cand2.version());
cand1.setReady();
owners = mvcc.recheck();
checkCandidates(owners, cand1.version(), cand2.version());
mvcc.remove(cand2.version());
owners = mvcc.recheck();
assertSame(cand1, owners);
checkCandidates(owners, cand1.version());
}
}
/**
* @param all Candidates list.
* @param vers Expected candidates.
*/
private void checkCandidates(CacheLockCandidates all, GridCacheVersion...vers) {
assertNotNull(all);
assertEquals(vers.length, all.size());
for (GridCacheVersion ver : vers)
assertTrue(all.hasCandidate(ver));
}
/**
* @param mvcc Mvcc.
* @param e Entry.
* @param ver Version.
* @param serOrder Serializable tx version.
* @param read Read lock flag.
* @return Candidate.
*/
@Nullable private GridCacheMvccCandidate addLocal(GridCacheMvcc mvcc,
GridCacheEntryEx e,
GridCacheVersion ver,
GridCacheVersion serOrder,
boolean read) {
return mvcc.addLocal(e,
nodeId,
null,
1,
ver,
0,
serOrder,
false,
true,
false,
true,
read
);
}
/**
* @throws Exception If failed.
*/
@Test
public void testSerializableLocks() throws Exception {
checkSerializableAdd(false);
checkSerializableAdd(true);
checkNonSerializableConflict();
}
/**
* @throws Exception If failed.
*/
private void checkNonSerializableConflict() throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
UUID nodeId = UUID.randomUUID();
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
nodeId,
null,
1,
version(1),
0,
null,
false,
true,
false,
true,
false
);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
nodeId,
null,
1,
version(2),
0,
new GridCacheVersion(0, 0, 1),
false,
true,
false,
true,
false
);
assertNull(cand2);
}
/**
* @param incVer If {@code true} lock version is incremented.
* @throws Exception If failed.
*/
private void checkSerializableAdd(boolean incVer) throws Exception {
GridCacheAdapter<String, String> cache = grid.internalCache(DEFAULT_CACHE_NAME);
UUID nodeId = UUID.randomUUID();
GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
GridCacheVersion serOrder1 = new GridCacheVersion(0, 10, 1);
GridCacheVersion serOrder2 = new GridCacheVersion(0, 20, 1);
GridCacheVersion serOrder3 = new GridCacheVersion(0, 15, 1);
GridCacheVersion serOrder4 = new GridCacheVersion(0, 30, 1);
GridCacheVersion ver1 = incVer ? version(1) : version(4);
GridCacheVersion ver2 = incVer ? version(2) : version(3);
GridCacheVersion ver3 = incVer ? version(3) : version(2);
GridCacheVersion ver4 = incVer ? version(4) : version(1);
GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
nodeId,
null,
1,
ver1,
0,
serOrder1,
false,
true,
false,
true,
false
);
assertNotNull(cand1);
GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
nodeId,
null,
2,
ver2,
0,
serOrder2,
false,
true,
false,
true,
false
);
assertNotNull(cand2);
GridCacheMvccCandidate cand3 = mvcc.addLocal(e,
nodeId,
null,
3,
ver3,
0,
serOrder3,
false,
true,
false,
true,
false
);
assertNull(cand3);
GridCacheMvccCandidate cand4 = mvcc.addLocal(e,
nodeId,
null,
4,
ver4,
0,
serOrder4,
false,
true,
false,
true,
false
);
assertNotNull(cand4);
CacheLockCandidates owners = mvcc.recheck();
assertNull(owners);
cand2.setReady();
owners = mvcc.recheck();
assertNull(owners);
cand1.setReady();
owners = mvcc.recheck();
assertSame(cand1, owners);
owners = mvcc.recheck();
assertSame(cand1, owners);
mvcc.remove(cand1.version());
owners = mvcc.recheck();
assertSame(cand2, owners);
}
/**
* Gets version based on order.
*
* @param order Order.
* @return Version.
*/
private GridCacheVersion version(int order) {
return new GridCacheVersion(1, 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 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 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 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();
}
}