| /* |
| * 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.geode.internal.cache.versions; |
| |
| import static java.util.concurrent.TimeUnit.SECONDS; |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.assertj.core.api.Assertions.assertThatCode; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.when; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.DataInput; |
| import java.io.DataInputStream; |
| import java.io.DataOutput; |
| import java.io.DataOutputStream; |
| import java.io.IOException; |
| import java.net.UnknownHostException; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.Future; |
| |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.ExpectedException; |
| |
| import org.apache.geode.DataSerializer; |
| import org.apache.geode.InternalGemFireError; |
| import org.apache.geode.cache.DataPolicy; |
| import org.apache.geode.distributed.internal.membership.InternalDistributedMember; |
| import org.apache.geode.internal.HeapDataOutputStream; |
| import org.apache.geode.internal.Version; |
| import org.apache.geode.internal.cache.LocalRegion; |
| import org.apache.geode.internal.cache.persistence.DiskStoreID; |
| import org.apache.geode.internal.net.SocketCreator; |
| import org.apache.geode.test.junit.rules.ExecutorServiceRule; |
| |
| public class RegionVersionVectorTest { |
| |
| @Rule |
| public ExecutorServiceRule executorServiceRule = new ExecutorServiceRule(); |
| |
| @Rule |
| public ExpectedException expectedException = ExpectedException.none(); |
| |
| /** |
| * server1 will simulate doing a sync with another server for operations performed |
| * by server2. server3 is another server in the cluster that we don't care about |
| */ |
| @Test |
| public void testSynchronizationVectorContainsAllVersionsForOwnerAndNonTarget() { |
| final String local = getIPLiteral(); |
| InternalDistributedMember server1 = new InternalDistributedMember(local, 101); |
| InternalDistributedMember server2 = new InternalDistributedMember(local, 102); |
| InternalDistributedMember server3 = new InternalDistributedMember(local, 103); |
| |
| RegionVersionVector rv1 = new VMRegionVersionVector(server1); |
| rv1.updateLocalVersion(10); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server3, 3); |
| RegionVersionVector singletonRVV = rv1.getCloneForTransmission(server2); |
| assertTrue(singletonRVV.isForSynchronization()); |
| assertEquals(singletonRVV.getOwnerId(), server1); |
| assertTrue(singletonRVV.getMemberToVersion().containsKey(server2)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server3)); |
| |
| assertTrue(singletonRVV.contains(server1, 1)); |
| assertTrue(singletonRVV.contains(server1, 11)); |
| |
| assertTrue(singletonRVV.contains(server3, 1)); |
| assertTrue(singletonRVV.contains(server3, 11)); |
| |
| assertTrue(singletonRVV.contains(server2, 1)); |
| assertTrue(singletonRVV.contains(server2, 5)); |
| assertTrue(singletonRVV.contains(server2, 8)); |
| |
| assertFalse(singletonRVV.contains(server2, 2)); |
| assertFalse(singletonRVV.contains(server2, 3)); |
| assertFalse(singletonRVV.contains(server2, 4)); |
| assertFalse(singletonRVV.contains(server2, 6)); |
| assertFalse(singletonRVV.contains(server2, 7)); |
| assertFalse(singletonRVV.contains(server2, 9)); |
| } |
| |
| @Test |
| public void testSynchronizationVectorContainsAllVersionsForSameOwnerAsTargetAndNonTarget() { |
| final String local = getIPLiteral(); |
| InternalDistributedMember server1 = new InternalDistributedMember(local, 101); |
| InternalDistributedMember server2 = new InternalDistributedMember(local, 102); |
| InternalDistributedMember server3 = new InternalDistributedMember(local, 103); |
| |
| RegionVersionVector rv1 = new VMRegionVersionVector(server1); |
| rv1.updateLocalVersion(10); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server3, 3); |
| RegionVersionVector singletonRVV = rv1.getCloneForTransmission(server1); |
| assertTrue(singletonRVV.isForSynchronization()); |
| assertEquals(singletonRVV.getOwnerId(), server1); |
| assertTrue(singletonRVV.getMemberToVersion().containsKey(server1)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server2)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server3)); |
| |
| assertTrue(singletonRVV.contains(server1, 1)); |
| assertTrue(singletonRVV.contains(server1, 11)); |
| |
| assertTrue(singletonRVV.contains(server3, 1)); |
| assertTrue(singletonRVV.contains(server3, 11)); |
| |
| assertTrue(singletonRVV.contains(server2, 1)); |
| assertTrue(singletonRVV.contains(server2, 5)); |
| assertTrue(singletonRVV.contains(server2, 8)); |
| assertTrue(singletonRVV.contains(server2, 2)); |
| assertTrue(singletonRVV.contains(server2, 3)); |
| assertTrue(singletonRVV.contains(server2, 4)); |
| assertTrue(singletonRVV.contains(server2, 6)); |
| assertTrue(singletonRVV.contains(server2, 7)); |
| assertTrue(singletonRVV.contains(server2, 9)); |
| } |
| |
| /** |
| * server1 will simulate doing a sync with another server for operations performed |
| * by server2. server3 is another server in the cluster that we don't care about |
| * servers have version source as dist store id |
| */ |
| @Test |
| public void testSynchronizationVectorWithDiskStoreIdContainsAllVersionsForNonTarget() { |
| DiskStoreID server1 = new DiskStoreID(0, 0); |
| DiskStoreID server2 = new DiskStoreID(0, 1); |
| DiskStoreID server3 = new DiskStoreID(1, 0); |
| |
| RegionVersionVector rv1 = new DiskRegionVersionVector(server1); |
| rv1.updateLocalVersion(10); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server3, 3); |
| RegionVersionVector singletonRVV = rv1.getCloneForTransmission(server2); |
| assertTrue(singletonRVV.isForSynchronization()); |
| assertEquals(singletonRVV.getOwnerId(), server1); |
| assertTrue(singletonRVV.getMemberToVersion().containsKey(server2)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server3)); |
| |
| assertTrue(singletonRVV.contains(server1, 1)); |
| assertTrue(singletonRVV.contains(server1, 11)); |
| |
| assertTrue(singletonRVV.contains(server3, 1)); |
| assertTrue(singletonRVV.contains(server3, 11)); |
| } |
| |
| @Test |
| public void testSynchronizationVectorWithDiskStoreIdContainsVersionsForTarget() { |
| DiskStoreID server1 = new DiskStoreID(0, 0); |
| DiskStoreID server2 = new DiskStoreID(0, 1); |
| DiskStoreID server3 = new DiskStoreID(1, 0); |
| |
| RegionVersionVector rv1 = new DiskRegionVersionVector(server1); |
| rv1.updateLocalVersion(10); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server3, 3); |
| RegionVersionVector singletonRVV = rv1.getCloneForTransmission(server2); |
| assertTrue(singletonRVV.isForSynchronization()); |
| assertEquals(singletonRVV.getOwnerId(), server1); |
| assertTrue(singletonRVV.getMemberToVersion().containsKey(server2)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server3)); |
| |
| assertTrue(singletonRVV.contains(server2, 1)); |
| assertTrue(singletonRVV.contains(server2, 5)); |
| assertTrue(singletonRVV.contains(server2, 8)); |
| |
| assertFalse(singletonRVV.contains(server2, 2)); |
| assertFalse(singletonRVV.contains(server2, 3)); |
| assertFalse(singletonRVV.contains(server2, 4)); |
| assertFalse(singletonRVV.contains(server2, 6)); |
| assertFalse(singletonRVV.contains(server2, 7)); |
| assertFalse(singletonRVV.contains(server2, 9)); |
| } |
| |
| @Test |
| public void testSynchronizationVectorWithDiskStoreIdContainsVersionsForTargetAsOriginator() { |
| DiskStoreID server1 = new DiskStoreID(0, 0); |
| DiskStoreID server2 = new DiskStoreID(0, 1); |
| DiskStoreID server3 = new DiskStoreID(1, 0); |
| |
| RegionVersionVector rv1 = new DiskRegionVersionVector(server1); |
| RegionVersionHolder localExceptions = rv1.getLocalExceptions(); |
| localExceptions.addException(2, 5); |
| localExceptions.addException(7, 9); |
| rv1.updateLocalVersion(10); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server3, 3); |
| RegionVersionVector singletonRVV = rv1.getCloneForTransmission(server1); |
| assertTrue(singletonRVV.isForSynchronization()); |
| assertEquals(singletonRVV.getOwnerId(), server1); |
| assertTrue(singletonRVV.getMemberToVersion().containsKey(server1)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server2)); |
| assertFalse(singletonRVV.getMemberToVersion().containsKey(server3)); |
| |
| assertTrue(singletonRVV.contains(server1, 1)); |
| assertTrue(singletonRVV.contains(server1, 2)); |
| assertTrue(singletonRVV.contains(server1, 5)); |
| assertTrue(singletonRVV.contains(server1, 6)); |
| assertTrue(singletonRVV.contains(server1, 7)); |
| assertTrue(singletonRVV.contains(server1, 9)); |
| assertTrue(singletonRVV.contains(server1, 10)); |
| |
| assertFalse(singletonRVV.contains(server1, 3)); |
| assertFalse(singletonRVV.contains(server1, 4)); |
| assertFalse(singletonRVV.contains(server1, 8)); |
| } |
| |
| @Test |
| public void testExceptionsWithContains() { |
| DiskStoreID ownerId = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| DiskStoreID id2 = new DiskStoreID(1, 0); |
| |
| DiskRegionVersionVector rvv = new DiskRegionVersionVector(ownerId); |
| |
| doExceptionsWithContains(ownerId, rvv); |
| doExceptionsWithContains(id1, rvv); |
| } |
| |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| @Test |
| public void testRegionVersionVectors() throws Exception { |
| // this is just a quick set of unit tests for basic RVV functionality |
| |
| final String local = getIPLiteral(); |
| InternalDistributedMember server1 = new InternalDistributedMember(local, 101); |
| InternalDistributedMember server2 = new InternalDistributedMember(local, 102); |
| InternalDistributedMember server3 = new InternalDistributedMember(local, 103); |
| InternalDistributedMember server4 = new InternalDistributedMember(local, 104); |
| |
| RegionVersionVector rv1 = null; |
| |
| // (a) Test that an exception is mended when the versions that are missing are |
| // added |
| rv1 = new VMRegionVersionVector(server1); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| System.out.println("for test (a) formed this RVV: " + rv1.fullToString()); |
| // there should now be two exceptions: 1-5 and 5-8 |
| assertEquals(8, rv1.getVersionForMember(server2)); |
| assertEquals(2, rv1.getExceptionCount(server2)); |
| rv1.recordVersion(server2, 3); |
| System.out.println("for test (a) RVV is now: " + rv1.fullToString()); |
| assertEquals(8, rv1.getVersionForMember(server2)); |
| assertEquals(2, rv1.getExceptionCount(server2)); |
| rv1.recordVersion(server2, 4); |
| rv1.recordVersion(server2, 2); |
| System.out.println("for test (a) RVV is now: " + rv1.fullToString()); |
| assertEquals(1, rv1.getExceptionCount(server2)); |
| rv1.recordVersion(server2, 6); |
| rv1.recordVersion(server2, 7); |
| System.out.println("for test (a) RVV is now: " + rv1.fullToString()); |
| assertEquals(0, rv1.getExceptionCount(server2)); |
| |
| // (b) Test the contains() operation |
| rv1 = new VMRegionVersionVector(server1); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 5); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server2, 10); |
| System.out.println("for test (b) formed this RVV: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 1)); |
| assertTrue(rv1.contains(server2, 5)); |
| assertTrue(rv1.contains(server2, 8)); |
| assertTrue(rv1.contains(server2, 10)); |
| assertFalse(rv1.contains(server2, 2)); |
| assertFalse(rv1.contains(server2, 3)); |
| assertFalse(rv1.contains(server2, 4)); |
| assertFalse(rv1.contains(server2, 9)); |
| assertFalse(rv1.contains(server2, 11)); |
| rv1.recordVersion(server2, 3); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 3)); |
| rv1.recordVersion(server2, 2); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 2)); |
| assertTrue(rv1.contains(server2, 3)); |
| rv1.recordVersion(server2, 4); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 1)); |
| assertTrue(rv1.contains(server2, 2)); |
| assertTrue(rv1.contains(server2, 3)); |
| assertTrue(rv1.contains(server2, 4)); |
| assertTrue(rv1.contains(server2, 5)); |
| rv1.recordVersion(server2, 11); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 11)); |
| assertTrue(rv1.contains(server2, 10)); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| rv1.recordVersion(server2, 6); |
| assertTrue(rv1.contains(server2, 2)); |
| assertTrue(rv1.contains(server2, 5)); |
| assertTrue(rv1.contains(server2, 6)); |
| assertFalse(rv1.contains(server2, 7)); |
| assertTrue(rv1.contains(server2, 8)); |
| rv1.recordVersion(server2, 7); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 7)); |
| rv1.recordVersion(server2, 9); |
| System.out.println("for test (b) RVV is now: " + rv1.fullToString()); |
| assertTrue(rv1.contains(server2, 9)); |
| assertTrue(rv1.getExceptionCount(server2) == 0); |
| assertTrue(rv1.contains(server2, 8)); |
| |
| // Test RVV comparisons for GII Delta |
| rv1 = new VMRegionVersionVector(server1); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server2, 4); |
| rv1.recordVersion(server2, 8); |
| rv1.recordVersion(server2, 9); |
| rv1.recordVersion(server2, 10); |
| rv1.recordVersion(server2, 11); |
| rv1.recordVersion(server2, 12); |
| |
| rv1.recordVersion(server3, 2); |
| rv1.recordVersion(server3, 3); |
| rv1.recordVersion(server3, 4); |
| rv1.recordVersion(server3, 6); |
| rv1.recordVersion(server3, 7); |
| |
| RegionVersionVector rv2 = rv1.getCloneForTransmission(); |
| System.out.println("rv1 is " + rv1.fullToString()); |
| System.out.println("rv2 is " + rv2.fullToString()); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| assertFalse(rv2.isNewerThanOrCanFillExceptionsFor(rv1)); |
| |
| rv1.recordVersion(server2, 6); |
| assertTrue(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv2.recordVersion(server2, 6); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| |
| // fill an exception gap |
| rv1.recordVersion(server2, 5); |
| assertTrue(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv2.recordVersion(server2, 5); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv1.recordVersion(server2, 7); |
| assertTrue(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv2.recordVersion(server2, 7); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| |
| // add a more recent revision |
| rv1.recordVersion(server3, 8); |
| assertTrue(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv2.recordVersion(server3, 8); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| |
| // fill another exception gap |
| rv1.recordVersion(server3, 5); |
| assertTrue(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| rv2.recordVersion(server3, 5); |
| assertFalse(rv1.isNewerThanOrCanFillExceptionsFor(rv2)); |
| |
| // test that old members are removed from the vector |
| InternalDistributedMember server5 = new InternalDistributedMember(local, 105); |
| rv1 = new VMRegionVersionVector(server1); |
| rv1.recordVersion(server2, 1); |
| rv1.recordVersion(server3, 1); |
| rv1.recordVersion(server4, 1); |
| rv1.recordVersion(server5, 1); |
| rv1.memberDeparted(null, server2, false); |
| rv1.memberDeparted(null, server4, true); |
| assertTrue(rv1.containsMember(server2)); |
| assertTrue(rv1.containsMember(server3)); |
| assertTrue(rv1.containsMember(server4)); |
| Set retain = new HashSet(); |
| retain.add(server2); // still have data from server2 |
| retain.add(server3); // still have data from server3 |
| // no data found from server4 in region |
| retain.add(server5); // still have data from server5 |
| rv1.removeOldMembers(retain); |
| assertFalse(rv1.containsMember(server4)); |
| |
| rv1.memberDeparted(null, server3, false); // {server2, server3(departed), server5} |
| |
| // Now test that departed members are transferred with GII. We simulate |
| // a new server, server6, doing a GII from server1 |
| |
| InternalDistributedMember server6 = new InternalDistributedMember(local, 106); |
| RegionVersionVector giiReceiverRVV = new VMRegionVersionVector(server6); |
| // the gii request will cause server1 to clone its RVV and send it to server6 |
| rv2 = rv1.getCloneForTransmission(); |
| // serialize/deserialize to mimic sending the rvv in a message |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); |
| DataOutputStream out = new DataOutputStream(baos); |
| DataSerializer.writeObject(rv2, out); |
| ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
| DataInputStream in = new DataInputStream(bais); |
| RegionVersionVector transmittedVector = (RegionVersionVector) DataSerializer.readObject(in); |
| // record the provider's rvv in the receiver of the image |
| giiReceiverRVV.recordVersions(transmittedVector); |
| // removedMembers in the receiver should hold {server4, server3}. Simulate |
| // another member departure to kick out server4 |
| assertTrue(giiReceiverRVV.containsMember(server2)); |
| assertTrue(giiReceiverRVV.containsMember(server5)); |
| assertTrue(giiReceiverRVV.containsMember(server3)); |
| assertTrue(giiReceiverRVV.isDepartedMember(server3)); |
| |
| // unit test for bit-set boundary. First boundary is 3/4 of bitset width, |
| // which is the amount dumped to the exceptions list when the bitset becomes full |
| rv1 = new VMRegionVersionVector(server1); |
| long bitSetRollPoint = RegionVersionHolder.BIT_SET_WIDTH + 1; |
| long boundary = RegionVersionHolder.BIT_SET_WIDTH * 3 / 4; |
| for (long i = 1; i < boundary; i++) { |
| rv1.recordVersion(server2, i); |
| assertTrue(rv1.contains(server2, i)); |
| } |
| assertFalse(rv1.contains(server2, boundary + 1)); |
| |
| rv1.recordVersion(server2, bitSetRollPoint); |
| rv1.recordVersion(server2, bitSetRollPoint + 1); // bitSet should be rolled at this point |
| RegionVersionHolder h = (RegionVersionHolder) rv1.getMemberToVersion().get(server2); |
| long versionBoundary = h.getBitSetVersionForTesting(); |
| assertEquals("expected holder bitset version to roll to this value", boundary - 1, |
| versionBoundary); |
| assertFalse(rv1.contains(server2, bitSetRollPoint - 1)); |
| assertTrue(rv1.contains(server2, bitSetRollPoint)); |
| assertTrue(rv1.contains(server2, bitSetRollPoint + 1)); |
| assertFalse(rv1.contains(server2, bitSetRollPoint + 2)); |
| |
| assertTrue(rv1.contains(server2, boundary - 1)); |
| assertFalse(rv1.contains(server2, boundary)); |
| assertFalse(rv1.contains(server2, boundary + 1)); |
| |
| // now test the merge |
| System.out.println("testing merge for " + rv1.fullToString()); |
| assertEquals(1, rv1.getExceptionCount(server2)); // one exception from boundary-1 to |
| // bitSetRollPoint |
| assertFalse(rv1.contains(server2, bitSetRollPoint - 1)); |
| assertTrue(rv1.contains(server2, bitSetRollPoint)); |
| assertTrue(rv1.contains(server2, bitSetRollPoint + 1)); |
| assertFalse(rv1.contains(server2, bitSetRollPoint + 2)); |
| } |
| |
| @Test |
| public void testRVVSerialization() throws Exception { |
| DiskStoreID ownerId = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| DiskStoreID id2 = new DiskStoreID(1, 0); |
| |
| DiskRegionVersionVector rvv = new DiskRegionVersionVector(ownerId); |
| rvv.recordVersion(id1, 5); |
| rvv.recordVersion(id1, 6); |
| rvv.recordVersion(id1, 7); |
| rvv.recordVersion(id1, 9); |
| rvv.recordVersion(id1, 20); |
| rvv.recordVersion(id1, 11); |
| rvv.recordVersion(id1, 12); |
| rvv.recordGCVersion(id2, 5); |
| rvv.recordGCVersion(id1, 3); |
| |
| assertTrue(rvv.sameAs(rvv.getCloneForTransmission())); |
| |
| HeapDataOutputStream out = new HeapDataOutputStream(Version.CURRENT); |
| DataSerializer.writeObject(rvv.getCloneForTransmission(), out); |
| byte[] bytes = out.toByteArray(); |
| |
| DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes)); |
| DiskRegionVersionVector rvv2 = DataSerializer.readObject(dis); |
| |
| assertTrue(rvv.sameAs(rvv2)); |
| } |
| |
| /** |
| * Test that we can copy the member to version map correctly. |
| */ |
| @Test |
| public void testCopyMemberToVersion() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| DiskStoreID id2 = new DiskStoreID(1, 0); |
| |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| |
| rvv0.recordVersion(id1, 1); |
| rvv0.recordVersion(id1, 3); |
| |
| DiskRegionVersionVector rvv1 = new DiskRegionVersionVector(id1); |
| rvv1.recordVersions(rvv0); |
| |
| assertEquals(3, rvv1.getCurrentVersion()); |
| assertFalse(rvv1.contains(id1, 2)); |
| assertTrue(rvv1.contains(id1, 1)); |
| assertTrue(rvv1.contains(id1, 3)); |
| |
| assertTrue(rvv1.contains(id0, 3)); |
| |
| assertTrue(rvv0.sameAs(rvv1)); |
| |
| rvv1.recordVersion(id1, 2); |
| assertTrue(rvv1.isNewerThanOrCanFillExceptionsFor(rvv0)); |
| assertFalse(rvv0.isNewerThanOrCanFillExceptionsFor(rvv1)); |
| assertTrue(rvv1.dominates(rvv0)); |
| assertFalse(rvv0.dominates(rvv1)); |
| } |
| |
| @Test |
| public void testSpecialException() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| DiskStoreID id2 = new DiskStoreID(1, 0); |
| |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| |
| rvv0.recordVersion(id1, 1); |
| rvv0.recordVersion(id1, 2); |
| |
| DiskRegionVersionVector rvv1 = new DiskRegionVersionVector(id1); |
| rvv1.recordVersions(rvv0); |
| |
| rvv1.recordVersion(id1, 3); |
| RegionVersionHolder holder_at_rvv1 = rvv1.getLocalExceptions(); |
| RegionVersionHolder holder_at_rvv0 = rvv0.getMemberToVersion().get(id1); |
| holder_at_rvv1.addException(2, 4); |
| assertFalse(rvv1.isNewerThanOrCanFillExceptionsFor(rvv0)); |
| assertFalse(rvv0.isNewerThanOrCanFillExceptionsFor(rvv1)); |
| assertTrue(rvv1.dominates(rvv0)); |
| assertTrue(rvv0.dominates(rvv1)); |
| } |
| |
| @Test |
| public void test48066_1() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| for (int i = 1; i <= 3; i++) { |
| rvv0.recordVersion(id0, i); |
| } |
| System.out.println("rvv0=" + rvv0.fullToString()); |
| |
| DiskRegionVersionVector rvv1 = (DiskRegionVersionVector) rvv0.getCloneForTransmission(); |
| System.out.println("after clone, rvv1=" + rvv1.fullToString()); |
| |
| DiskRegionVersionVector rvv2 = new DiskRegionVersionVector(id0); |
| for (int i = 1; i <= 10; i++) { |
| rvv2.recordVersion(id0, i); |
| } |
| rvv2.recordVersions(rvv1); |
| System.out.println("after init, rvv2=" + rvv2.fullToString()); |
| |
| rvv2.recordVersion(id0, 4); |
| System.out.println("after record 4, rvv2=" + rvv2.fullToString()); |
| assertEquals(4, rvv2.getCurrentVersion()); |
| |
| rvv2.recordVersion(id0, 7); |
| System.out.println("after record 7, rvv2=" + rvv2.fullToString()); |
| assertEquals(7, rvv2.getCurrentVersion()); |
| } |
| |
| @Test |
| public void test48066_2() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| for (int i = 1; i <= 10; i++) { |
| rvv0.recordVersion(id0, i); |
| } |
| |
| DiskRegionVersionVector rvv1 = new DiskRegionVersionVector(id0); |
| rvv0.recordVersions(rvv1); |
| System.out.println("rvv0=" + rvv0.fullToString()); |
| |
| rvv0.recordVersion(id0, 4); |
| System.out.println("after record 4, rvv0=" + rvv0.fullToString()); |
| assertEquals(4, rvv0.getCurrentVersion()); |
| |
| rvv0.recordVersion(id0, 7); |
| System.out.println("after record 7, rvv0=" + rvv0.fullToString()); |
| assertEquals(7, rvv0.getCurrentVersion()); |
| assertFalse(rvv0.contains(id0, 5)); |
| |
| DiskRegionVersionVector rvv2 = (DiskRegionVersionVector) rvv0.getCloneForTransmission(); |
| System.out.println("after clone, rvv2=" + rvv2.fullToString()); |
| assertEquals(11, rvv0.getNextVersion()); |
| assertFalse(rvv2.contains(id0, 5)); |
| assertEquals(11, rvv2.getNextVersion()); |
| } |
| |
| /** |
| * Test for bug 47023. Make sure recordGCVersion works correctly and doesn't generate exceptions |
| * for the local member. |
| */ |
| @Test |
| public void testRecordGCVersion() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| |
| // generate 3 local versions |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| |
| // record some version from a remote member |
| rvv0.recordVersion(id1, 1); |
| rvv0.recordVersion(id1, 3); |
| rvv0.recordVersion(id1, 5); |
| |
| // Assert that the exceptions are present |
| { |
| Map<DiskStoreID, RegionVersionHolder<DiskStoreID>> memberToVersion = |
| rvv0.getMemberToVersion(); |
| RegionVersionHolder<DiskStoreID> holder1 = memberToVersion.get(id1); |
| |
| // Make sure the exceptions are present |
| assertFalse(holder1.contains(2)); |
| assertFalse(holder1.contains(4)); |
| } |
| |
| // Record some GC versions |
| rvv0.recordGCVersion(id0, 2); |
| rvv0.recordGCVersion(id1, 3); |
| |
| { |
| Map<DiskStoreID, RegionVersionHolder<DiskStoreID>> memberToVersion = |
| rvv0.getMemberToVersion(); |
| RegionVersionHolder<DiskStoreID> holder0 = memberToVersion.get(id0); |
| // Make sure we didn't generate a bogus exception for |
| // the local member by calling record GC version - bug 47023 |
| assertTrue(holder0.getExceptionForTest().isEmpty()); |
| } |
| |
| // Clean up old exceptions |
| rvv0.pruneOldExceptions(); |
| |
| // Make assertions about what exceptions are still present |
| Map<DiskStoreID, RegionVersionHolder<DiskStoreID>> memberToVersion = rvv0.getMemberToVersion(); |
| RegionVersionHolder<DiskStoreID> holder0 = memberToVersion.get(id0); |
| RegionVersionHolder<DiskStoreID> holder1 = memberToVersion.get(id1); |
| assertTrue(holder0.getExceptionForTest().isEmpty()); |
| |
| // exceptions less than the GC version should have been removed |
| assertTrue(holder1.contains(2)); |
| |
| // exceptions greater than the GC version should still be there. |
| assertFalse(holder1.contains(4)); |
| } |
| |
| |
| @Test |
| public void recordLargeGCVersionShouldRecordSuccessfully() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| |
| rvv0.recordGCVersion(id1, ((long) Integer.MAX_VALUE) - 10L); |
| } |
| |
| @Test |
| public void incrementingTheLocalVersionShouldNotCreateExceptions() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| |
| DiskRegionVersionVector rvv0 = new DiskRegionVersionVector(id0); |
| |
| // Increment the version a couple of times |
| rvv0.getNextVersion(); |
| rvv0.getNextVersion(); |
| |
| RegionVersionVector<DiskStoreID> clone = rvv0.getCloneForTransmission(); |
| |
| assertThat(clone.getHolderForMember(id0).getExceptionForTest()).isEmpty(); |
| assertThat(rvv0.getHolderForMember(id0).getExceptionForTest()).isEmpty(); |
| } |
| |
| @Test |
| public void testRemoveOldVersions() { |
| DiskStoreID id0 = new DiskStoreID(0, 0); |
| DiskStoreID id1 = new DiskStoreID(0, 1); |
| DiskStoreID id2 = new DiskStoreID(0, 2); |
| |
| DiskRegionVersionVector rvv = new DiskRegionVersionVector(id0); |
| |
| // generate 3 local versions |
| rvv.getNextVersion(); |
| rvv.getNextVersion(); |
| rvv.getNextVersion(); |
| |
| // record some version from a remote member |
| rvv.recordVersion(id1, 1); |
| rvv.recordVersion(id1, 3); |
| rvv.recordVersion(id1, 5); |
| // record a GC version for that member that is older than its version |
| rvv.recordGCVersion(id1, 3); |
| |
| rvv.recordGCVersion(id2, 4950); |
| rvv.recordVersion(id2, 5000); |
| rvv.recordVersion(id2, 5001); |
| rvv.recordVersion(id2, 5005); |
| |
| rvv.removeOldVersions(); |
| |
| assertEquals("expected gc version to be set to current version for " + rvv.fullToString(), |
| rvv.getCurrentVersion(), rvv.getGCVersion(null)); |
| assertEquals("expected gc version to be set to current version for " + rvv.fullToString(), |
| rvv.getVersionForMember(id1), rvv.getGCVersion(id1)); |
| assertEquals("expected gc version to be set to current version for " + rvv.fullToString(), |
| rvv.getVersionForMember(id2), rvv.getGCVersion(id2)); |
| |
| assertEquals("expected exceptions to be erased for " + rvv.fullToString(), |
| rvv.getExceptionCount(id1), 0); |
| assertEquals("expected exceptions to be erased for " + rvv.fullToString(), |
| rvv.getExceptionCount(id2), 0); |
| } |
| |
| @Test |
| public void testRegionVersionInTags() { |
| VMVersionTag tag = new VMVersionTag(); |
| long version = 0x8080000000L; |
| tag.setRegionVersion(version); |
| assertEquals("failed test for bug #48576", version, tag.getRegionVersion()); |
| } |
| |
| @Test |
| public void testRecordVersionDuringRegionInit() { |
| LocalRegion mockRegion = mock(LocalRegion.class); |
| when(mockRegion.isInitialized()).thenReturn(false); |
| final String local = getIPLiteral(); |
| InternalDistributedMember ownerId = new InternalDistributedMember(local, 101); |
| VMVersionTag tag = new VMVersionTag(); |
| tag.setRegionVersion(1L); |
| |
| RegionVersionVector rvv = createRegionVersionVector(ownerId, mockRegion); |
| rvv.recordVersion(ownerId, tag); |
| assertEquals(1, rvv.getVersionForMember(ownerId)); |
| } |
| |
| @Test |
| public void recordVersionIntoLocalMemberShouldFailIfRegionIsPersistent() { |
| LocalRegion mockRegion = mock(LocalRegion.class); |
| when(mockRegion.isInitialized()).thenReturn(true); |
| when(mockRegion.getDataPolicy()).thenReturn(DataPolicy.PERSISTENT_REPLICATE); |
| final String local = getIPLiteral(); |
| DiskStoreID ownerId = new DiskStoreID(); |
| |
| DiskRegionVersionVector rvv = new DiskRegionVersionVector(ownerId, mockRegion); |
| |
| DiskVersionTag tag = new DiskVersionTag(); |
| tag.setRegionVersion(1L); |
| tag.setMemberID(ownerId); |
| |
| expectedException.expect(InternalGemFireError.class); |
| rvv.recordVersion(ownerId, tag); |
| } |
| |
| @Test |
| public void recordVersionIntoLocalMemberShouldPassfRegionIsNonPersistent() { |
| LocalRegion mockRegion = mock(LocalRegion.class); |
| when(mockRegion.isInitialized()).thenReturn(true); |
| when(mockRegion.getDataPolicy()).thenReturn(DataPolicy.REPLICATE); |
| final String local = getIPLiteral(); |
| InternalDistributedMember ownerId = new InternalDistributedMember(local, 101); |
| RegionVersionVector rvv = createRegionVersionVector(ownerId, mockRegion); |
| |
| VMVersionTag tag = new VMVersionTag(); |
| tag.setRegionVersion(1); |
| tag.setMemberID(ownerId); |
| |
| rvv.recordVersion(ownerId, tag); |
| assertEquals(1, rvv.getLocalExceptions().version); |
| assertEquals(2, rvv.getNextVersion()); |
| } |
| |
| @Test |
| public void usesNewVersionIfGreaterThanOldVersion() throws Exception { |
| VersionSource<InternalDistributedMember> ownerId = mock(VersionSource.class); |
| long oldVersion = 1; |
| long newVersion = 2; |
| |
| RegionVersionVector rvv = new TestableRegionVersionVector(ownerId, oldVersion); |
| rvv.updateLocalVersion(newVersion); |
| assertThat(rvv.getVersionForMember(ownerId)).isEqualTo(newVersion); |
| } |
| |
| @Test |
| public void usesOldVersionIfGreaterThanNewVersion() throws Exception { |
| VersionSource<InternalDistributedMember> ownerId = mock(VersionSource.class); |
| long oldVersion = 2; |
| long newVersion = 1; |
| |
| RegionVersionVector rvv = new TestableRegionVersionVector(ownerId, oldVersion); |
| rvv.updateLocalVersion(newVersion); |
| assertThat(rvv.getVersionForMember(ownerId)).isEqualTo(oldVersion); |
| } |
| |
| @Test |
| public void doesNothingIfVersionsAreSame() throws Exception { |
| VersionSource<InternalDistributedMember> ownerId = mock(VersionSource.class); |
| long oldVersion = 2; |
| long sameVersion = 2; |
| |
| RegionVersionVector rvv = new TestableRegionVersionVector(ownerId, oldVersion); |
| rvv.updateLocalVersion(sameVersion); |
| assertThat(rvv.getVersionForMember(ownerId)).isEqualTo(oldVersion); |
| } |
| |
| @Test |
| public void doesNotHangIfOtherThreadChangedVersion() throws Exception { |
| VersionSource<InternalDistributedMember> ownerId = mock(VersionSource.class); |
| long oldVersion = 1; |
| long newVersion = 2; |
| |
| RegionVersionVector rvv = new VersionRaceConditionRegionVersionVector(ownerId, oldVersion); |
| Future<Void> result = executorServiceRule.runAsync(() -> rvv.updateLocalVersion(newVersion)); |
| |
| assertThatCode(() -> result.get(2, SECONDS)).doesNotThrowAnyException(); |
| assertThat(rvv.getVersionForMember(ownerId)).isEqualTo(newVersion); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsTrueIfRequesterRvvForLostMemberDominates() |
| throws Exception { |
| InternalDistributedMember lostMember = mock(InternalDistributedMember.class); |
| ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = |
| new ConcurrentHashMap<>(); |
| memberToGcVersion.put(lostMember, new Long(1) /* lostMemberGcVersion */); |
| RegionVersionVector providerRvv = new VMRegionVersionVector(lostMember, null, |
| 0, memberToGcVersion, 0, true, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(lostMember); |
| regionVersionHolder.recordVersion(1); |
| regionVersionHolder.recordVersion(2); |
| memberToRegionVersionHolder.put(lostMember, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(lostMember, memberToRegionVersionHolder, |
| 0, null, 0, true, null); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isTrue(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsFalseIfRequesterRvvForLostMemberDominates() |
| throws Exception { |
| InternalDistributedMember lostMember = mock(InternalDistributedMember.class); |
| ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = |
| new ConcurrentHashMap<>(); |
| memberToGcVersion.put(lostMember, new Long(1) /* lostMemberGcVersion */); |
| RegionVersionVector providerRvv = new VMRegionVersionVector(lostMember, null, |
| 0, memberToGcVersion, 0, true, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(lostMember); |
| memberToRegionVersionHolder.put(lostMember, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(lostMember, memberToRegionVersionHolder, |
| 0, null, 0, true, null); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isFalse(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsFalseIfProviderRvvIsNotPresent() |
| throws Exception { |
| final String local = getIPLiteral(); |
| InternalDistributedMember provider = new InternalDistributedMember(local, 101); |
| InternalDistributedMember requester = new InternalDistributedMember(local, 102); |
| |
| RegionVersionVector providerRvv = new VMRegionVersionVector(provider, null, |
| 1, null, 1, false, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(provider); |
| // memberToRegionVersionHolder.put(provider, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(requester, memberToRegionVersionHolder, |
| 0, null, 0, false, null); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isFalse(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsFalseIfRequesterRvvDominatesProvider() |
| throws Exception { |
| final String local = getIPLiteral(); |
| InternalDistributedMember provider = new InternalDistributedMember(local, 101); |
| InternalDistributedMember requester = new InternalDistributedMember(local, 102); |
| |
| RegionVersionVector providerRvv = new VMRegionVersionVector(provider, null, |
| 1, null, 1, false, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(provider); |
| memberToRegionVersionHolder.put(provider, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(requester, memberToRegionVersionHolder, |
| 0, null, 0, false, null); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isFalse(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsTrueIfRequesterRvvDominatesWithNoGcVersion() |
| throws Exception { |
| final String local = getIPLiteral(); |
| InternalDistributedMember provider = new InternalDistributedMember(local, 101); |
| InternalDistributedMember requester = new InternalDistributedMember(local, 102); |
| |
| ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = |
| new ConcurrentHashMap<>(); |
| RegionVersionVector providerRvv = new VMRegionVersionVector(provider, null, |
| 1, memberToGcVersion, 1, false, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(provider); |
| regionVersionHolder.recordVersion(1); |
| regionVersionHolder.recordVersion(2); |
| memberToRegionVersionHolder.put(provider, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(requester, memberToRegionVersionHolder, |
| 0, null, 0, false, null); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isTrue(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsTrueIfRequesterRvvDominates() throws Exception { |
| final String local = getIPLiteral(); |
| InternalDistributedMember provider = new InternalDistributedMember(local, 101); |
| InternalDistributedMember requester = new InternalDistributedMember(local, 102); |
| ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = |
| new ConcurrentHashMap<>(); |
| memberToGcVersion.put(requester, new Long(1)); |
| RegionVersionVector providerRvv = new VMRegionVersionVector(provider, null, |
| 1, memberToGcVersion, 1, false, null); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(provider); |
| regionVersionHolder.recordVersion(1); |
| regionVersionHolder.recordVersion(2); |
| memberToRegionVersionHolder.put(provider, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(requester, memberToRegionVersionHolder, |
| 2, null, 0, false, regionVersionHolder); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isTrue(); |
| } |
| |
| @Test |
| public void isRvvGcDominatedByRequesterRvvReturnsFalseIfRequesterRvvDominates() throws Exception { |
| final String local = getIPLiteral(); |
| InternalDistributedMember provider = new InternalDistributedMember(local, 101); |
| InternalDistributedMember requester = new InternalDistributedMember(local, 102); |
| ConcurrentHashMap<InternalDistributedMember, Long> memberToGcVersion = |
| new ConcurrentHashMap<>(); |
| memberToGcVersion.put(requester, new Long(3)); |
| RegionVersionHolder pRegionVersionHolder = new RegionVersionHolder(provider); |
| pRegionVersionHolder.recordVersion(1); |
| pRegionVersionHolder.recordVersion(2); |
| pRegionVersionHolder.recordVersion(3); |
| pRegionVersionHolder.recordVersion(4); |
| |
| RegionVersionVector providerRvv = new VMRegionVersionVector(provider, null, |
| 1, memberToGcVersion, 1, false, pRegionVersionHolder); |
| |
| ConcurrentHashMap<InternalDistributedMember, RegionVersionHolder<InternalDistributedMember>> memberToRegionVersionHolder = |
| new ConcurrentHashMap<>(); |
| RegionVersionHolder regionVersionHolder = new RegionVersionHolder(provider); |
| regionVersionHolder.recordVersion(1); |
| regionVersionHolder.recordVersion(2); |
| memberToRegionVersionHolder.put(provider, regionVersionHolder); |
| RegionVersionVector requesterRvv = |
| new VMRegionVersionVector(requester, memberToRegionVersionHolder, |
| 2, null, 0, false, regionVersionHolder); |
| |
| assertThat(providerRvv.isRVVGCDominatedBy(requesterRvv)).isFalse(); |
| } |
| |
| private RegionVersionVector createRegionVersionVector(InternalDistributedMember ownerId, |
| LocalRegion owner) { |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| RegionVersionVector rvv = new RegionVersionVector(ownerId, owner) { |
| @Override |
| public int getDSFID() { |
| return 0; |
| } |
| |
| @Override |
| protected RegionVersionVector createCopy(VersionSource ownerId, ConcurrentHashMap vector, |
| long version, ConcurrentHashMap gcVersions, long gcVersion, boolean singleMember, |
| RegionVersionHolder clonedLocalHolder) { |
| return null; |
| } |
| |
| @Override |
| protected void writeMember(VersionSource member, DataOutput out) throws IOException {} |
| |
| @Override |
| protected VersionSource readMember(DataInput in) throws IOException, ClassNotFoundException { |
| return null; |
| } |
| }; |
| return rvv; |
| } |
| |
| private void doExceptionsWithContains(DiskStoreID id, DiskRegionVersionVector rvv) { |
| rvv.recordVersion(id, 10); |
| |
| // Make sure we have exceptions from 0-10 |
| assertFalse(rvv.contains(id, 5)); |
| |
| rvv.recordVersion(id, 5); |
| assertTrue(rvv.contains(id, 5)); |
| assertFalse(rvv.contains(id, 4)); |
| assertFalse(rvv.contains(id, 6)); |
| |
| for (int i = 0; i < 10; i++) { |
| rvv.recordVersion(id, i); |
| } |
| |
| for (int i = 0; i < 10; i++) { |
| assertTrue(rvv.contains(id, i)); |
| } |
| assertEquals(0, rvv.getExceptionCount(id)); |
| } |
| |
| private static class TestableRegionVersionVector |
| extends RegionVersionVector<VersionSource<InternalDistributedMember>> { |
| |
| TestableRegionVersionVector(VersionSource<InternalDistributedMember> ownerId, long version) { |
| super(ownerId, null, version); |
| } |
| |
| @Override |
| protected RegionVersionVector createCopy(VersionSource ownerId, ConcurrentHashMap vector, |
| long version, ConcurrentHashMap gcVersions, long gcVersion, boolean singleMember, |
| RegionVersionHolder clonedLocalHolder) { |
| return null; |
| } |
| |
| @Override |
| protected VersionSource<InternalDistributedMember> readMember(DataInput in) |
| throws IOException, ClassNotFoundException { |
| return null; |
| } |
| |
| @Override |
| protected void writeMember(VersionSource member, DataOutput out) throws IOException { |
| |
| } |
| |
| @Override |
| public int getDSFID() { |
| return 0; |
| } |
| } |
| |
| private static String getIPLiteral() { |
| try { |
| return SocketCreator.getLocalHost().getHostAddress(); |
| } catch (UnknownHostException e) { |
| throw new Error("Problem determining host IP address", e); |
| } |
| } |
| |
| private static class VersionRaceConditionRegionVersionVector extends TestableRegionVersionVector { |
| |
| VersionRaceConditionRegionVersionVector(VersionSource<InternalDistributedMember> ownerId, |
| long version) { |
| super(ownerId, version); |
| } |
| |
| @Override |
| boolean compareAndSetVersion(long currentVersion, long newVersion) { |
| super.compareAndSetVersion(currentVersion, newVersion); |
| return false; |
| } |
| |
| } |
| } |