/* * 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; import static org.junit.Assert.*; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.experimental.categories.Category; import org.apache.geode.LogWriter; import org.apache.geode.cache.CacheException; import org.apache.geode.cache.EvictionAction; import org.apache.geode.cache.EvictionAttributes; import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.RegionDestroyedException; import org.apache.geode.cache.RegionExistsException; import org.apache.geode.cache30.CacheSerializableRunnable; import org.apache.geode.cache30.CacheTestCase; import org.apache.geode.internal.logging.InternalLogWriter; import org.apache.geode.internal.logging.LogWriterImpl; import org.apache.geode.internal.logging.PureLogWriter; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.Invoke; import org.apache.geode.test.dunit.SerializableRunnable; import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; import org.apache.geode.test.dunit.standalone.DUnitLauncher; import org.apache.geode.test.junit.categories.DistributedTest; /** * This class is extended by some PartitionedRegion related DUnit test cases */ @Category(DistributedTest.class) public class PartitionedRegionDUnitTestCase extends JUnit4CacheTestCase { static int oldLogLevel; public void setVMInfoLogLevel() { SerializableRunnable runnable = new SerializableRunnable() { public void run() { oldLogLevel = setLogLevel(getCache().getLogger(), InternalLogWriter.INFO_LEVEL); } }; for (int i = 0; i < 4; i++) { Host.getHost(0).getVM(i).invoke(runnable); } } public void resetVMLogLevel() { SerializableRunnable runnable = new SerializableRunnable() { public void run() { setLogLevel(getCache().getLogger(), oldLogLevel); } }; for (int i = 0; i < 4; i++) { Host.getHost(0).getVM(i).invoke(runnable); } } /** * Sets the loglevel for the provided log writer * * @param l the {@link LogWriter} * @param logLevl the new log level as specified in {@link LogWriterImpl} * @return the old log level */ public static int setLogLevel(LogWriter l, int logLevl) { int ret = -1; l.config("PartitionedRegionDUnitTest attempting to set log level on LogWriter instance class:" + l.getClass().getName()); if (l instanceof PureLogWriter) { PureLogWriter pl = (PureLogWriter) l; ret = pl.getLogWriterLevel(); l.config("PartitiionedRegionDUnitTest forcing log level to " + LogWriterImpl.levelToString(logLevl) + " from " + LogWriterImpl.levelToString(ret)); pl.setLevel(logLevl); } return ret; } /** * Tear down a PartitionedRegionTestCase by cleaning up the existing cache (mainly because we want * to destroy any existing PartitionedRegions) */ @Override public final void preTearDownCacheTestCase() throws Exception { preTearDownPartitionedRegionDUnitTest(); closeCache(); Invoke.invokeInEveryVM(CacheTestCase.class, "closeCache"); } protected void preTearDownPartitionedRegionDUnitTest() throws Exception {} @BeforeClass public static void caseSetUp() { DUnitLauncher.launchIfNeeded(); // this makes sure we don't have any connection left over from previous tests disconnectAllFromDS(); } @AfterClass public static void caseTearDown() { // this makes sure we don't leave anything for the next tests disconnectAllFromDS(); } /** * This function creates multiple partition regions in a VM. The name of the Partition Region will * be PRPrefix+index (index starts from startIndexForRegion and ends to endIndexForRegion) * * @param PRPrefix : Used in the name of the Partition Region * * These indices Represents range of the Partition Region */ public CacheSerializableRunnable createMultiplePartitionRegion(final String PRPrefix, final int startIndexForRegion, final int endIndexForRegion, final int redundancy, final int localmaxMemory) { return createMultiplePartitionRegion(PRPrefix, startIndexForRegion, endIndexForRegion, redundancy, localmaxMemory, false); } /** * This function creates multiple partition regions in a VM. The name of the Partition Region will * be PRPrefix+index (index starts from startIndexForRegion and ends to endIndexForRegion) * * @param PRPrefix : Used in the name of the Partition Region * * These indices Represents range of the Partition Region * @param startIndexForRegion : * @param endIndexForRegion * @param redundancy * @param localmaxMemory * @param evict * @return */ public CacheSerializableRunnable createMultiplePartitionRegion(final String PRPrefix, final int startIndexForRegion, final int endIndexForRegion, final int redundancy, final int localmaxMemory, final boolean evict) { return new CacheSerializableRunnable("createPrRegions_" + PRPrefix) { String innerPRPrefix = PRPrefix; int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; int innerRedundancy = redundancy; int innerlocalmaxMemory = localmaxMemory; public void run2() throws CacheException { System.setProperty(PartitionedRegion.RETRY_TIMEOUT_PROPERTY, "20000"); EvictionAttributes evictionAttrs = evict ? EvictionAttributes .createLRUEntryAttributes(Integer.MAX_VALUE, EvictionAction.LOCAL_DESTROY) : null; for (int i = startIndexForRegion; i < endIndexForRegion; i++) { Region partitionedregion = getCache().createRegion(innerPRPrefix + i, createRegionAttrsForPR(innerRedundancy, innerlocalmaxMemory, PartitionAttributesFactory.RECOVERY_DELAY_DEFAULT, evictionAttrs)); getCache().getLogger() .info("Successfully created PartitionedRegion = " + partitionedregion); } System.setProperty(PartitionedRegion.RETRY_TIMEOUT_PROPERTY, Integer.toString(PartitionedRegionHelper.DEFAULT_TOTAL_WAIT_RETRY_ITERATION)); getCache().getLogger() .info("createMultiplePartitionRegion() - Partition Regions Successfully Completed "); } }; } protected RegionAttributes<?, ?> createRegionAttrsForPR(int red, int localMaxMem, long recoveryDelay, EvictionAttributes evictionAttrs) { return PartitionedRegionTestHelper.createRegionAttrsForPR(red, localMaxMem, recoveryDelay, evictionAttrs, null); } public CacheSerializableRunnable getCreateMultiplePRregion(final String prPrefix, final int maxIndex, final int redundancy, final int localmaxMemory, final long recoveryDelay) { return new CacheSerializableRunnable("getCreateMultiplePRregion") { public void run2() throws CacheException { // final Random ra = new Random(); for (int i = 0; i < maxIndex; i++) { // final int rind = ra.nextInt(maxIndex); try { getCache().createRegion(prPrefix + i, PartitionedRegionTestHelper .createRegionAttrsForPR(redundancy, localmaxMemory, recoveryDelay)); org.apache.geode.test.dunit.LogWriterUtils.getLogWriter() .info("Created Region new --- " + prPrefix + i); } catch (RegionExistsException ignore) { } } org.apache.geode.test.dunit.LogWriterUtils.getLogWriter() .info("getCreateMultiplePRregion() - Partition Regions Successfully Completed "); } }; } /** * This function performs following checks on allPartitionRegion and bucket2Node region of * Partition Region 1. allPartitionRegion should not be null 2. size of allPartitionRegion should * be no. of regions + 1. 3.Bucket2Node should not be null and size should = no. of regions 4. * Name of the Bucket2Node should be PartitionedRegionHelper.BUCKET_2_NODE_TABLE_PREFIX + * pr.getName(). */ public CacheSerializableRunnable validateMultiplePartitionRegion(final String PRPrefix, final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateAllPRs; validateAllPRs = new CacheSerializableRunnable("validateAllPRs") { String innerPRPrefix = PRPrefix; int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; public void run2() throws CacheException { Region rootRegion = getCache().getRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME); assertNotNull(rootRegion); assertEquals("PR root size is not correct", innerEndIndexForRegion, rootRegion.size()); // Region allPR = // rootRegion.getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME); // assertNotNull(allPR); // assertIndexDetailsEquals("allPR size is not correct", innerEndIndexForRegion, // allPR.size()); assertEquals("prIdToPR size is not correct", innerEndIndexForRegion, PartitionedRegion.prIdToPR.size()); getCache().getLogger() .info("validateMultiplePartitionRegion() - Partition Regions Successfully Validated "); } }; return validateAllPRs; } /** * This function performs put() operations in multiple Partition Regions */ public CacheSerializableRunnable putInMultiplePartitionRegion(final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions) { CacheSerializableRunnable putInPRs = new CacheSerializableRunnable("doPutOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); for (int k = innerStartIndexForKey; k < innerEndIndexForKey; k++) { pr.put(j + innerPRPrefix + k, innerPRPrefix + k); } getCache().getLogger() .info("putInMultiplePartitionRegion() - Put() done Successfully in Partition Region " + pr.getName()); } } }; return putInPRs; } /** * This function performs get() operations in multiple Partitions Regions and checks return values */ public CacheSerializableRunnable getInMultiplePartitionRegion(final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions) { CacheSerializableRunnable getInPRs = new CacheSerializableRunnable("doGetOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); for (int k = innerStartIndexForKey; k < innerEndIndexForKey; k++) { Object Obj = pr.get(j + innerPRPrefix + k); assertNotNull(Obj); assertEquals("Values are not equal", Obj, (innerPRPrefix + k)); } getCache().getLogger() .info("putInMultiplePartitionRegion() - Get() done Successfully in Partition Region " + pr.getName()); } } }; return getInPRs; } /** * This function performs put() operations in multiple Partition Regions after the region is * destroyed. */ public CacheSerializableRunnable putAfterDestroyInMultiplePartitionedRegion(final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions) { CacheSerializableRunnable putInPRs = new CacheSerializableRunnable("doPutAfterDestroyOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); for (int k = innerStartIndexForKey; k < innerEndIndexForKey; k++) { try { pr.put(j + innerPRPrefix + k, innerPRPrefix + k); fail("You can not put after the region is destroyed "); } catch (RegionDestroyedException e) { // do nothing It's a valid exception } } } } }; return putInPRs; } /** * this function performs get() operations for the removed and destroyed entries */ public CacheSerializableRunnable getRemovedOrDestroyedInMultiplePartitionRegion( final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions, final int afterPutFlag) { CacheSerializableRunnable getInPRs = new CacheSerializableRunnable("doDetroyedGetOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; int innerAfterPutFlag = afterPutFlag; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); for (int k = innerStartIndexForKey; k < innerEndIndexForKey; k++) { Object Obj = pr.get(j + innerPRPrefix + k); if (innerAfterPutFlag == 0) assertNull(Obj); else assertNotNull(Obj); } getCache().getLogger().info( "getRmovedOrDestroyedInMultiplePartitionRegion() - Get() of Destroy Keys done Successfully in Partition Region " + pr.getName()); } } }; return getInPRs; } /** this functions destroys regions in a node */ public CacheSerializableRunnable destroyRegionInMultiplePartitionRegion(final String PRPrefix, final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable getInPRs = new CacheSerializableRunnable("destroyRegionInMultiplePartitionRegion") { String innerPRPrefix = PRPrefix; int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; public void run2() throws CacheException { for (int j = innerStartIndexForRegion; j < innerEndIndexForRegion; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); getCache().getLogger().info("region going to destroy is : " + pr); pr.destroyRegion(); } } }; return getInPRs; } /** * This function performs destroy() operations in multiple partitions for destroying key-value * pair so that entry corresponding to that key becomes null */ public CacheSerializableRunnable destroyInMultiplePartitionRegion(final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions) { CacheSerializableRunnable destroyInPRs = new CacheSerializableRunnable("doDestroyKeyOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); for (int k = startIndexForKey; k < endIndexForKey; k++) { try { pr.destroy(j + innerPRPrefix + k); } catch (Exception e) { fail( "destroyInMultiplePartitionRegion()- Entry not found in the Partition region " + pr.getName()); } } getCache().getLogger().info( "destroyInMultiplePartitionRegion() - destroy() done Successfully in Partition Region " + pr.getName()); } } }; return destroyInPRs; } /** * This function performs invalidate() operation in multiple partition regions. */ public CacheSerializableRunnable invalidatesInMultiplePartitionRegion(final String PRPrefix, final int startIndexForKey, final int endIndexForKey, final int startIndexNumOfRegions, final int endIndexNumOfRegions) { CacheSerializableRunnable invalidateInPRs = new CacheSerializableRunnable("doInvalidateKeyOperations") { String innerPRPrefix = PRPrefix; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexNumOfRegions = startIndexNumOfRegions; int innerEndIndexNumOfRegions = endIndexNumOfRegions; public void run2() throws CacheException { for (int j = innerStartIndexNumOfRegions; j < innerEndIndexNumOfRegions; j++) { Region pr = getCache().getRegion(Region.SEPARATOR + innerPRPrefix + j); assertNotNull(pr); for (int k = startIndexForKey; k < endIndexForKey; k++) { try { pr.invalidate(j + innerPRPrefix + k); } catch (Exception e) { fail( "invalidateInMultiplePartitionRegion()- Entry not found in the Partition region " + pr.getName()); } } getCache().getLogger().info( "invalidateInMultiplePartitionRegion() - invalidate() done Successfully in Partition Region " + pr.getName()); } } }; return invalidateInPRs; } public CacheSerializableRunnable disconnectVM() { CacheSerializableRunnable csr = new CacheSerializableRunnable("disconnectVM") { public void run2() throws CacheException { getCache(); // DistributedMember dsMember = ((InternalDistributedSystem)getCache() // .getDistributedSystem()).getDistributionManager().getId(); getCache().getDistributedSystem().disconnect(); getCache().getLogger().info("disconnectVM() completed .."); } }; return csr; } }