Search in sources :

Example 11 with VersionTag

use of org.apache.geode.internal.cache.versions.VersionTag in project geode by apache.

the class GIIDeltaDUnitTest method testDeltaGIIWithOnlyUnfinishedOp_GCAtR.

/**
   * This is to test a race condition for bug#47616 vm0 and vm1 are peers, each holds a DR. create
   * some exception list. Before GII, P's RVV is P6,R6(3-6), R's RVV is P6,R6, RVVGC are both P4,R0
   * vm1 becomes offline then restarts. The deltaGII should send delta which only contains
   * unfinished opeation R4,R5
   */
@Test
public void testDeltaGIIWithOnlyUnfinishedOp_GCAtR() throws Throwable {
    prepareForEachTest();
    final DiskStoreID memberP = getMemberID(P);
    final DiskStoreID memberR = getMemberID(R);
    final long[] exceptionlist = { 4, 5 };
    assertEquals(0, DistributedCacheOperation.SLOW_DISTRIBUTION_MS);
    prepareCommonTestData(6);
    VersionTag expect_tag = getVersionTag(R, "key5");
    // force tombstone GC to let RVVGC to become P4:R0
    forceGC(P, 2);
    // P's rvv=p6, gc=4
    waitForToVerifyRVV(P, memberP, 6, null, 4);
    // P's rvv=r3, gc=0
    waitForToVerifyRVV(P, memberR, 3, null, 0);
    createUnfinishedOperationsR4R5();
    // P's rvv=r6, gc=0
    waitForToVerifyRVV(P, memberR, 6, exceptionlist, 0);
    // 2
    R.invoke(new SerializableRunnable() {

        public void run() {
            Mycallback myAfterRequestRVV = new Mycallback(GIITestHookType.AfterRequestRVV, REGION_NAME);
            InitialImageOperation.setGIITestHook(myAfterRequestRVV);
        }
    });
    // now P's cache still only has key1, key3, key5
    byte[] R_rvv_bytes = getRVVByteArray(R, REGION_NAME);
    closeCache(R);
    // restart and gii
    checkIfFullGII(P, REGION_NAME, R_rvv_bytes, false);
    AsyncInvocation async3 = createDistributedRegionAsync(R);
    // 2
    waitForCallbackStarted(R, GIITestHookType.AfterRequestRVV);
    forceGC(R, 1);
    R.invoke(() -> InitialImageOperation.resetGIITestHook(GIITestHookType.AfterRequestRVV, true));
    async3.join(MAX_WAIT);
    // verify unfinished op for key5 is revoked
    waitToVerifyKey(R, "key5", generateValue(R));
    VersionTag tag = getVersionTag(R, "key5");
    assertTrue(expect_tag.equals(tag));
    verifyTombstoneExist(R, "key5", false, false);
    // If fullGII, the key size in gii chunk is 3, i.e. key1,key3,key5. key2 is GCed.
    // If delta GII, the key size should be 1 (key5(T) which is unfinished operation)
    verifyDeltaSizeFromStats(R, 3, 0);
}
Also used : VersionTag(org.apache.geode.internal.cache.versions.VersionTag) DiskStoreID(org.apache.geode.internal.cache.persistence.DiskStoreID) FlakyTest(org.apache.geode.test.junit.categories.FlakyTest) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Example 12 with VersionTag

use of org.apache.geode.internal.cache.versions.VersionTag in project geode by apache.

the class TombstoneCreationJUnitTest method testDestroyCreatesTombstone.

@Test
public void testDestroyCreatesTombstone() throws Exception {
    String name = nameRule.getMethodName();
    Properties props = new Properties();
    props.put(LOCATORS, "");
    props.put(MCAST_PORT, "0");
    props.put(LOG_LEVEL, "config");
    GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.create(DistributedSystem.connect(props));
    RegionFactory f = cache.createRegionFactory(RegionShortcut.REPLICATE);
    DistributedRegion region = (DistributedRegion) f.create(name);
    EntryEventImpl ev = EntryEventImpl.create(region, Operation.DESTROY, "myDestroyedKey", null, null, true, new InternalDistributedMember(InetAddress.getLocalHost(), 1234));
    VersionTag tag = VersionTag.create((InternalDistributedMember) ev.getDistributedMember());
    tag.setIsRemoteForTesting();
    tag.setEntryVersion(2);
    tag.setRegionVersion(12345);
    tag.setVersionTimeStamp(System.currentTimeMillis());
    tag.setDistributedSystemId(1);
    ev.setVersionTag(tag);
    cache.getLogger().info("destroyThread is trying to destroy the entry: " + region.getRegionEntry("myDestroyedKey"));
    // expectedOldValue not supported on
    region.basicDestroy(ev, false, null);
    RegionEntry entry = region.getRegionEntry("myDestroyedKey");
    Assert.assertTrue(entry != null, "expected to find a region entry for myDestroyedKey");
    Assert.assertTrue(entry.isTombstone(), "expected entry to be found and be a tombstone but it is " + entry);
}
Also used : InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) ConfigurationProperties(org.apache.geode.distributed.ConfigurationProperties) Properties(java.util.Properties) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 13 with VersionTag

use of org.apache.geode.internal.cache.versions.VersionTag in project geode by apache.

the class TombstoneCreationJUnitTest method testConcurrentCreateAndDestroy.

/**
   * In bug #47868 a thread puts a REMOVED_PHASE1 entry in the map but is unable to lock the entry
   * before a Destroy thread gets it. The Destroy thread did not apply its operation but threw an
   * EntryNotFoundException. It is supposed to create a Tombstone.
   * 
   * @throws Exception
   */
@Test
public void testConcurrentCreateAndDestroy() throws Exception {
    String name = nameRule.getMethodName();
    Properties props = new Properties();
    props.put(LOCATORS, "");
    props.put(MCAST_PORT, "0");
    props.put(LOG_LEVEL, "config");
    final GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.create(DistributedSystem.connect(props));
    RegionFactory f = cache.createRegionFactory(RegionShortcut.REPLICATE);
    final DistributedRegion region = (DistributedRegion) f.create(name);
    // simulate a put() getting into AbstractRegionMap.basicPut() and creating an entry
    // that has not yet been initialized with values. Then do a destroy that will encounter
    // the entry
    String key = "destroyedKey1";
    VersionedThinRegionEntryHeap entry = new VersionedThinRegionEntryHeapObjectKey(region, key, Token.REMOVED_PHASE1);
    ((AbstractRegionMap) region.getRegionMap()).putEntryIfAbsentForTest(entry);
    cache.getLogger().info("entry inserted into cache: " + entry);
    EntryEventImpl ev = EntryEventImpl.create(region, Operation.DESTROY, key, null, null, true, new InternalDistributedMember(InetAddress.getLocalHost(), 1234));
    VersionTag tag = VersionTag.create((InternalDistributedMember) ev.getDistributedMember());
    tag.setIsRemoteForTesting();
    tag.setEntryVersion(2);
    tag.setRegionVersion(12345);
    tag.setVersionTimeStamp(System.currentTimeMillis());
    tag.setDistributedSystemId(1);
    ev.setVersionTag(tag);
    cache.getLogger().info("destroyThread is trying to destroy the entry: " + region.getRegionEntry(key));
    // expectedOldValue not supported on
    region.basicDestroy(ev, false, null);
    entry = (VersionedThinRegionEntryHeap) region.getRegionEntry(key);
    region.dumpBackingMap();
    Assert.assertTrue(entry != null, "expected to find a region entry for " + key);
    Assert.assertTrue(entry.isTombstone(), "expected entry to be found and be a tombstone but it is " + entry);
    Assert.assertTrue(entry.getVersionStamp().getEntryVersion() == tag.getEntryVersion(), "expected " + tag.getEntryVersion() + " but found " + entry.getVersionStamp().getEntryVersion());
    RegionMap map = region.getRegionMap();
    tag = entry.asVersionTag();
    map.removeTombstone(entry, tag, false, true);
    // now do an op that has local origin
    entry = new VersionedThinRegionEntryHeapObjectKey(region, key, Token.REMOVED_PHASE1);
    ((AbstractRegionMap) region.getRegionMap()).putEntryIfAbsentForTest(entry);
    cache.getLogger().info("entry inserted into cache: " + entry);
    ev = EntryEventImpl.create(region, Operation.DESTROY, key, null, null, false, cache.getMyId());
    tag = VersionTag.create((InternalDistributedMember) ev.getDistributedMember());
    tag.setEntryVersion(2);
    tag.setRegionVersion(12345);
    tag.setVersionTimeStamp(System.currentTimeMillis());
    tag.setDistributedSystemId(1);
    ev.setVersionTag(tag);
    cache.getLogger().info("destroyThread is trying to destroy the entry: " + region.getRegionEntry(key));
    boolean caught = false;
    try {
        // expectedOldValue not supported on
        region.basicDestroy(ev, false, null);
    } catch (EntryNotFoundException e) {
        caught = true;
    }
    Assert.assertTrue(caught, "expected an EntryNotFoundException for origin=local destroy operation");
}
Also used : ConfigurationProperties(org.apache.geode.distributed.ConfigurationProperties) Properties(java.util.Properties) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) Test(org.junit.Test) IntegrationTest(org.apache.geode.test.junit.categories.IntegrationTest)

Example 14 with VersionTag

use of org.apache.geode.internal.cache.versions.VersionTag in project geode by apache.

the class DistributedAckRegionCCEDUnitTest method testConcurrentOpWithGII.

/**
   * test for bug #45564. a create() is received by region creator and then a later destroy() is
   * received in initial image and while the version info from the destroy is recorded we keep the
   * value from the create event
   */
@Test
public void testConcurrentOpWithGII() {
    if (this.getClass() != DistributedAckRegionCCEDUnitTest.class) {
        // not really a scope-related thing
        return;
    }
    final String name = this.getUniqueName() + "-CC";
    final String key = "mykey";
    VM vm1 = Host.getHost(0).getVM(1);
    VM vm2 = Host.getHost(0).getVM(2);
    // create some destroyed entries so the GC service is populated
    SerializableCallable create = new SerializableCallable("create region") {

        public Object call() {
            RegionFactory f = getCache().createRegionFactory(getRegionAttributes());
            CCRegion = (LocalRegion) f.create(name);
            return CCRegion.getDistributionManager().getDistributionManagerId();
        }
    };
    // do conflicting update() and destroy() on the region. We want the update() to
    // be sent with a message and the destroy() to be transferred in the initial image
    // and be the value that we want to keep
    InternalDistributedMember vm1ID = (InternalDistributedMember) vm1.invoke(create);
    AsyncInvocation partialCreate = vm2.invokeAsync(new SerializableCallable("create region with stall") {

        public Object call() throws Exception {
            final GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
            RegionFactory f = cache.createRegionFactory(getRegionAttributes());
            InitialImageOperation.VMOTION_DURING_GII = true;
            // this will stall region creation at the point of asking for an initial image
            VMotionObserverHolder.setInstance(new VMotionObserver() {

                @Override
                public void vMotionBeforeCQRegistration() {
                }

                @Override
                public void vMotionBeforeRegisterInterest() {
                }

                @Override
                public void vMotionDuringGII(Set recipientSet, LocalRegion region) {
                    InitialImageOperation.VMOTION_DURING_GII = false;
                    int oldLevel = LocalRegion.setThreadInitLevelRequirement(LocalRegion.BEFORE_INITIAL_IMAGE);
                    LocalRegion ccregion = cache.getRegionByPath("/" + name);
                    try {
                        // happen
                        while (!ccregion.isDestroyed() && ccregion.getRegionEntry(key) == null) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                return;
                            }
                        }
                    } finally {
                        LocalRegion.setThreadInitLevelRequirement(oldLevel);
                    }
                }
            });
            try {
                CCRegion = (LocalRegion) f.create(name);
                // at this point we should have received the update op and then the GII, which should
                // overwrite
                // the conflicting update op
                assertFalse("expected initial image transfer to destroy entry", CCRegion.containsKey(key));
            } finally {
                InitialImageOperation.VMOTION_DURING_GII = false;
            }
            return null;
        }
    });
    vm1.invoke(new SerializableRunnable("create conflicting events") {

        public void run() {
            // wait for the other to come on line
            long waitEnd = System.currentTimeMillis() + 45000;
            DistributionAdvisor adv = ((DistributedRegion) CCRegion).getCacheDistributionAdvisor();
            while (System.currentTimeMillis() < waitEnd && adv.adviseGeneric().isEmpty()) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
            if (adv.adviseGeneric().isEmpty()) {
                fail("other member never came on line");
            }
            // inhibit all messaging
            DistributedCacheOperation.LOSS_SIMULATION_RATIO = 200.0;
            try {
                CCRegion.put("mykey", "initialValue");
                CCRegion.destroy("mykey");
            } finally {
                DistributedCacheOperation.LOSS_SIMULATION_RATIO = 0.0;
            }
            // generate a fake version tag for the message
            VersionTag tag = CCRegion.getRegionEntry(key).getVersionStamp().asVersionTag();
            // create a fake member ID that will be < mine and lose a concurrency check
            NetMember nm = CCRegion.getDistributionManager().getDistributionManagerId().getNetMember();
            InternalDistributedMember mbr = null;
            try {
                mbr = new InternalDistributedMember(nm.getInetAddress().getCanonicalHostName(), nm.getPort() - 1, "fake_id", "fake_id_ustring", DistributionManager.NORMAL_DM_TYPE, null, null);
                tag.setMemberID(mbr);
            } catch (UnknownHostException e) {
                org.apache.geode.test.dunit.Assert.fail("could not create member id", e);
            }
            // generate an event to distribute that contains the fake version tag
            EntryEventImpl event = EntryEventImpl.create(CCRegion, Operation.UPDATE, key, false, mbr, true, false);
            event.setNewValue("newValue");
            event.setVersionTag(tag);
            // this should update the controller's cache with the updated value but leave this cache
            // alone
            DistributedCacheOperation op = new UpdateOperation(event, tag.getVersionTimeStamp());
            op.distribute();
            event.release();
        }
    });
    try {
        partialCreate.getResult();
    } catch (Throwable e) {
        org.apache.geode.test.dunit.Assert.fail("async invocation in vm2 failed", e);
    }
}
Also used : DistributionAdvisor(org.apache.geode.distributed.internal.DistributionAdvisor) DistributedCacheOperation(org.apache.geode.internal.cache.DistributedCacheOperation) Set(java.util.Set) UnknownHostException(java.net.UnknownHostException) EntryEventImpl(org.apache.geode.internal.cache.EntryEventImpl) SerializableRunnable(org.apache.geode.test.dunit.SerializableRunnable) VMotionObserver(org.apache.geode.internal.cache.vmotion.VMotionObserver) LocalRegion(org.apache.geode.internal.cache.LocalRegion) AsyncInvocation(org.apache.geode.test.dunit.AsyncInvocation) RegionClearedException(org.apache.geode.internal.cache.RegionClearedException) UnknownHostException(java.net.UnknownHostException) CacheException(org.apache.geode.cache.CacheException) RegionFactory(org.apache.geode.cache.RegionFactory) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) UpdateOperation(org.apache.geode.internal.cache.UpdateOperation) VM(org.apache.geode.test.dunit.VM) SerializableCallable(org.apache.geode.test.dunit.SerializableCallable) VMVersionTag(org.apache.geode.internal.cache.versions.VMVersionTag) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) GemFireCacheImpl(org.apache.geode.internal.cache.GemFireCacheImpl) NetMember(org.apache.geode.distributed.internal.membership.NetMember) FlakyTest(org.apache.geode.test.junit.categories.FlakyTest) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Example 15 with VersionTag

use of org.apache.geode.internal.cache.versions.VersionTag in project geode by apache.

the class DistributedAckRegionCCEDUnitTest method testTombstoneExpirationRace.

/**
   * make sure that an operation performed on a new region entry created after a tombstone has been
   * reaped is accepted by another member that has yet to reap the tombstone
   */
@Test
public void testTombstoneExpirationRace() {
    VM vm0 = Host.getHost(0).getVM(0);
    VM vm1 = Host.getHost(0).getVM(1);
    // VM vm2 = Host.getHost(0).getVM(2);
    final String name = this.getUniqueName() + "-CC";
    SerializableRunnable createRegion = new SerializableRunnable("Create Region") {

        public void run() {
            try {
                RegionFactory f = getCache().createRegionFactory(getRegionAttributes());
                CCRegion = (LocalRegion) f.create(name);
                CCRegion.put("cckey0", "ccvalue");
                // version number will end up at 4
                CCRegion.put("cckey0", "ccvalue");
            } catch (CacheException ex) {
                org.apache.geode.test.dunit.Assert.fail("While creating region", ex);
            }
        }
    };
    vm0.invoke(createRegion);
    vm1.invoke(createRegion);
    // vm2.invoke(createRegion);
    vm1.invoke(new SerializableRunnable("Create local tombstone and adjust time") {

        public void run() {
            // make the entry for cckey0 a tombstone in this VM and set its modification time to be
            // older
            // than the tombstone GC interval. This means it could be in the process of being reaped by
            // distributed-GC
            RegionEntry entry = CCRegion.getRegionEntry("cckey0");
            VersionTag tag = entry.getVersionStamp().asVersionTag();
            assertTrue(tag.getEntryVersion() > 1);
            tag.setVersionTimeStamp(System.currentTimeMillis() - TombstoneService.REPLICATE_TOMBSTONE_TIMEOUT - 1000);
            entry.getVersionStamp().setVersionTimeStamp(tag.getVersionTimeStamp());
            try {
                entry.makeTombstone(CCRegion, tag);
            } catch (RegionClearedException e) {
                org.apache.geode.test.dunit.Assert.fail("region was mysteriously cleared during unit testing", e);
            }
        }
    });
    // now remove the entry on vm0, simulating that it initiated a GC, and perform a CREATE with a
    // new version number
    vm0.invoke(new SerializableRunnable("Locally destroy the entry and do a create that will be propagated with v1") {

        public void run() {
            CCRegion.getRegionMap().removeEntry("cckey0", CCRegion.getRegionEntry("cckey0"), true);
            if (CCRegion.getRegionEntry("ckey0") != null) {
                fail("expected removEntry to remove the entry from the region's map");
            }
            CCRegion.put("cckey0", "updateAfterReap");
        }
    });
    vm1.invoke(new SerializableRunnable("Check that the create() was applied") {

        public void run() {
            RegionEntry entry = CCRegion.getRegionEntry("cckey0");
            assertTrue(entry.getVersionStamp().getEntryVersion() == 1);
        }
    });
    disconnectAllFromDS();
}
Also used : RegionFactory(org.apache.geode.cache.RegionFactory) CacheException(org.apache.geode.cache.CacheException) VM(org.apache.geode.test.dunit.VM) SerializableRunnable(org.apache.geode.test.dunit.SerializableRunnable) VMVersionTag(org.apache.geode.internal.cache.versions.VMVersionTag) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) RegionEntry(org.apache.geode.internal.cache.RegionEntry) RegionClearedException(org.apache.geode.internal.cache.RegionClearedException) FlakyTest(org.apache.geode.test.junit.categories.FlakyTest) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Aggregations

VersionTag (org.apache.geode.internal.cache.versions.VersionTag)225 Test (org.junit.Test)43 DistributedTest (org.apache.geode.test.junit.categories.DistributedTest)31 VM (org.apache.geode.test.dunit.VM)24 CacheException (org.apache.geode.cache.CacheException)22 LocalRegion (org.apache.geode.internal.cache.LocalRegion)22 Region (org.apache.geode.cache.Region)21 EntryNotFoundException (org.apache.geode.cache.EntryNotFoundException)19 VersionStamp (org.apache.geode.internal.cache.versions.VersionStamp)19 Host (org.apache.geode.test.dunit.Host)19 IOException (java.io.IOException)17 NonTXEntry (org.apache.geode.internal.cache.LocalRegion.NonTXEntry)16 ConcurrentCacheModificationException (org.apache.geode.internal.cache.versions.ConcurrentCacheModificationException)16 VersionSource (org.apache.geode.internal.cache.versions.VersionSource)16 SerializableCallable (org.apache.geode.test.dunit.SerializableCallable)16 FlakyTest (org.apache.geode.test.junit.categories.FlakyTest)16 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)15 RegionVersionVector (org.apache.geode.internal.cache.versions.RegionVersionVector)15 ArrayList (java.util.ArrayList)14 CancelException (org.apache.geode.CancelException)14