/* * 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 org.junit.experimental.categories.Category; import org.junit.Test; import static org.junit.Assert.*; import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; import org.apache.geode.test.junit.categories.DistributedTest; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheException; import org.apache.geode.cache.Region; import org.apache.geode.cache30.CacheSerializableRunnable; import org.apache.geode.test.dunit.Assert; import org.apache.geode.test.dunit.AsyncInvocation; import org.apache.geode.test.dunit.Host; import org.apache.geode.test.dunit.LogWriterUtils; import org.apache.geode.test.dunit.ThreadUtils; import org.apache.geode.test.dunit.VM; /** * This test is dunit test for the multiple Partition Regions in 4 VMs. * * */ @Category(DistributedTest.class) public class PartitionedRegionMultipleDUnitTest extends PartitionedRegionDUnitTestCase { /** Prefix is used in name of Partition Region */ protected static String prPrefix = null; /** Maximum number of regions * */ static int MAX_REGIONS = 1; /** Start index for destroying the kes */ int startIndexForDestroy = 20; /** End index for destroying keys */ int endIndexForDestroy = 40; /** Start index for key */ int startIndexForKey = 0; /** End index for key */ int endIndexForKey = 50; /** redundancy used for the creation of the partition region */ final int redundancy = 0; /** local maxmemory used for the creation of the partition region */ int localMaxMemory = 200; /** constructor */ public PartitionedRegionMultipleDUnitTest() { super(); } /** * This test performs following operations: <br> * 1. Create multiple Partition Regions in 4 VMs</br> * <br> * 2. Validates the Partitioned region metadata by checking sizes of allPartition Region, * bucket2Node.</br> * <br> * 3. Performs put()operations on all the partitioned region from all the VM's </br> * <br> * 4. Performs get() operations on all partitioned region and check the returned values.</br> */ @Test public void testPartitionedRegionPutAndGet() throws Throwable { Host host = Host.getHost(0); /** creating 4 VMs */ VM vm0 = host.getVM(0); VM vm1 = host.getVM(1); VM vm2 = host.getVM(2); VM vm3 = host.getVM(3); /** Prefix will be used for naming the partititon Region */ prPrefix = "testPartitionedRegionPutAndGet"; /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; /** creationg and performing put(),get() operations on Partition Region */ createMultiplePartitionRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter() .info("testPartitionedRegionPutAndGet() - Partition Regions Successfully Created "); validateMultiplePartitionedRegions(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter() .info("testPartitionedRegionPutAndGet() - Partition Regions Successfully Validated "); putInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionPutAndGet() - Put() Operation done Successfully in Partition Regions "); getInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter() .info("testPartitionedRegionPutAndGet() - Partition Regions Successfully Validated "); } /** * This test performs following operations: <br> * 1. Create multiple Partition Regions in 4 VMs</br> * <br> * 2. Performs put()operations on all the partitioned region from all the VM's </br> * <br> * 3. Performs destroy(key)operations for some of the keys of all the partitioned region from all * the VM's</br> * <br> * 4. Performs get() operations for destroyed keys on all partitioned region and checks the * returned values is null .</br> * <br> * 5. Performs put()operations for the destroyed keys on all the partitioned region from all the * VM's</br> * <br> * 4. Performs get() operations for destroyed keys on all partitioned region and checks the * returned values is not null .</br> */ @Test public void testPartitionedRegionDestroyKeys() throws Throwable { Host host = Host.getHost(0); /** creating 4 VM's */ VM vm0 = host.getVM(0); VM vm1 = host.getVM(1); VM vm2 = host.getVM(2); VM vm3 = host.getVM(3); prPrefix = "testPartitionedRegionDestroyKeys"; int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; int afterPutFlag = 0; /** * creating Partition Regions and performing put(), destroy(),get(),put() operations in the * sequence */ createMultiplePartitionRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter() .info("testPartitionedRegionDestroyKeys() - Partition Regions Successfully Created "); validateMultiplePartitionedRegions(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter() .info("testPartitionedRegionDestroyKeys() - Partition Regions Successfully Validated "); putInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyKeys() - Put() Operation done Successfully in Partition Regions "); destroyInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyKeys() - Destroy(Key) Operation done Successfully in Partition Regions "); getDestroyedEntryInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion, afterPutFlag); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyKeys() - Get() Operation after destoy keys done Successfully in Partition Regions "); putDestroyedEntryInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyKeys() - Put() Operation after destroy keys done Successfully in Partition Regions "); afterPutFlag = 1; getDestroyedEntryInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion, afterPutFlag); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyKeys() - Get() Operation after Put() done Successfully in Partition Regions "); } /** * This test performs following operations: <br> * 1. Create multiple Partition Regions in 4 VMs</br> * <br> * 2. Performs put()operations on all the partitioned region from all the VM's </br> * <br> * 3. Performs destroy(key)operations for some of the keys of all the partitioned region from all * the VM's</br> * <br> * 4. Chekcs containsKey and ContainsValueForKey APIs</br> */ @Test public void testPartitionedRegionDestroyAndContainsAPI() throws Throwable { Host host = Host.getHost(0); VM vm0 = host.getVM(0); VM vm1 = host.getVM(1); VM vm2 = host.getVM(2); VM vm3 = host.getVM(3); prPrefix = "testPartitionedRegionDestroyAndContainsAPI"; int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; /** creating Partition Regions and testing for the APIs contains() */ createMultiplePartitionRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyAndContainsAPI() - Partition Regions Successfully Created "); validateMultiplePartitionedRegions(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyAndContainsAPI() - Partition Regions Successfully Validated "); putInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyAndContainsAPI() - Put() Operation done Successfully in Partition Regions "); destroyInMultiplePartitionedRegion(vm0, vm1, vm2, vm3, startIndexForRegion, endIndexForRegion); LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyAndContainsAPI() - Destroy(Key) Operation done Successfully in Partition Regions "); async[0] = vm0 .invokeAsync(validateContainsAPIForPartitionRegion(startIndexForRegion, endIndexForRegion)); async[1] = vm1 .invokeAsync(validateContainsAPIForPartitionRegion(startIndexForRegion, endIndexForRegion)); async[2] = vm2 .invokeAsync(validateContainsAPIForPartitionRegion(startIndexForRegion, endIndexForRegion)); async[3] = vm3 .invokeAsync(validateContainsAPIForPartitionRegion(startIndexForRegion, endIndexForRegion)); for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 120 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } LogWriterUtils.getLogWriter().info( "testPartitionedRegionDestroyAndContainsAPI() - Validation of Contains APIs done Successfully in Partition Regions "); } /** * This function creates multiple partition regions in 4 VMs. The range is specified with * parameters startIndexForRegion, endIndexForRegion */ private void createMultiplePartitionRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) { // int AsyncInvocationArrSize = 8; // AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; vm0.invoke(createMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory)); vm1.invoke(createMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory)); vm2.invoke(createMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory)); vm3.invoke(createMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory)); } /** * <br> * This function performs following checks on allPartitionRegion and bucket2Node region of * Partition Region</br> * <br> * 1. allPartitionRegion should not be null</br> * <br> * 2. Size of allPartitionRegion should be no. of regions + 1.</br> * <br> * 3. Bucket2Node should not be null and size should = no. of regions</br> * <br> * 4. Name of the Bucket2Node should be PartitionedRegionHelper.BUCKET_2_NODE_TABLE_PREFIX + * pr.getName().</br> */ private void validateMultiplePartitionedRegions(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm0.invokeAsync( validateMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion)); async[1] = vm1.invokeAsync( validateMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion)); async[2] = vm2.invokeAsync( validateMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion)); async[3] = vm3.invokeAsync( validateMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion)); for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function performs put() operations in multiple Partition Regions. Range of the keys which * are put is 0 to 400. Each Vm puts different set of keys */ private void putInMultiplePartitionedRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForKey - startIndexForKey) / 4; async[0] = vm0.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey, startIndexForKey + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm1.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 1 * delta, startIndexForKey + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm2.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 2 * delta, startIndexForKey + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm3.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForKey + 3 * delta, endIndexForKey, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function performs get() operations in multiple Partition Regions. Each Vm gets keys from 0 * to 400. */ private void getInMultiplePartitionedRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm0.invokeAsync(getInMultiplePartitionRegion(prPrefix, startIndexForKey, endIndexForKey, startIndexForRegion, endIndexForRegion)); async[1] = vm1.invokeAsync(getInMultiplePartitionRegion(prPrefix, startIndexForKey, endIndexForKey, startIndexForRegion, endIndexForRegion)); async[2] = vm2.invokeAsync(getInMultiplePartitionRegion(prPrefix, startIndexForKey, endIndexForKey, startIndexForRegion, endIndexForRegion)); async[3] = vm3.invokeAsync(getInMultiplePartitionRegion(prPrefix, startIndexForKey, endIndexForKey, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("Failed due to exception: " + async[count].getException(), async[count].getException()); } } } /** * This function performs destroy(key) operations in multiple Partiton Regions. The range of keys * to be destroyed is from 100 to 200. Each Vm destroys different set of the keys. */ private void destroyInMultiplePartitionedRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForDestroy - startIndexForDestroy) / 4; async[0] = vm0.invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy, startIndexForDestroy + 1 * delta, startIndexForRegion, endIndexForRegion)); async[1] = vm1.invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 1 * delta, startIndexForDestroy + 2 * delta, startIndexForRegion, endIndexForRegion)); async[2] = vm2.invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 2 * delta, startIndexForDestroy + 3 * delta, startIndexForRegion, endIndexForRegion)); async[3] = vm3.invokeAsync(destroyInMultiplePartitionRegion(prPrefix, startIndexForDestroy + 3 * delta, endIndexForDestroy, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } /** * This function returns CacheSerializableRunnable Object which checks contains() and * containsValueForKey() APIs. */ private CacheSerializableRunnable validateContainsAPIForPartitionRegion( final int startIndexForRegion, final int endIndexForRegion) { CacheSerializableRunnable validateRegionAPIs = new CacheSerializableRunnable("validateInserts") { String innerprPrefix = prPrefix; int innerStartIndexForRegion = startIndexForRegion; int innerEndIndexForRegion = endIndexForRegion; int innerStartIndexForKey = startIndexForKey; int innerEndIndexForKey = endIndexForKey; int innerStartIndexForDestroy = startIndexForDestroy; int innerEndIndexForDestroy = endIndexForDestroy; public void run2() throws CacheException { Cache cache = getCache(); // Get Validation. for (int j = innerStartIndexForRegion; j < innerEndIndexForRegion; j++) { Region pr = cache.getRegion(Region.SEPARATOR + innerprPrefix + (j)); assertNotNull(pr); assertEquals(pr.getName(), innerprPrefix + (j)); for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { Object val = null; val = pr.get(j + innerprPrefix + i); if (i >= innerStartIndexForDestroy && i < innerEndIndexForDestroy) { assertNull(val); } else if (val != null) { assertEquals(val, innerprPrefix + i); assertTrue(pr.containsValue(innerprPrefix + i)); // pass } else { fail("Validation failed for key = " + j + innerprPrefix + i + "Value got = " + val); } } LogWriterUtils.getLogWriter().info( "validateContainsAPIForPartitionRegion() - Get() Validations done Successfully in Partition Region " + pr.getName()); // containsKey validation. for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { boolean conKey = pr.containsKey(j + innerprPrefix + i); if (i >= innerStartIndexForDestroy && i < innerEndIndexForDestroy) { assertFalse(conKey); } else { assertTrue(conKey); } } LogWriterUtils.getLogWriter().info( "validateContainsAPIForPartitionRegion() - containsKey() Validations done Successfully in Partition Region " + pr.getName()); // containsValueForKey for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { boolean conKey = pr.containsValueForKey(j + innerprPrefix + i); if (i >= innerStartIndexForDestroy && i < innerEndIndexForDestroy) { assertFalse(conKey); } else { assertTrue(conKey); } } LogWriterUtils.getLogWriter().info( "validateContainsAPIForPartitionRegion() - containsValueForKey() Validations done Successfully in Partition Region " + pr.getName()); // containsValue for (int i = innerStartIndexForKey; i < innerEndIndexForKey; i++) { boolean conKey = pr.containsValue(innerprPrefix + i); if (i >= innerStartIndexForDestroy && i < innerEndIndexForDestroy) { assertFalse(conKey); } else { assertTrue(conKey); } } LogWriterUtils.getLogWriter().info( "validateContainsAPIForPartitionRegion() - containsValue() Validations done Successfully in Partition Region " + pr.getName()); } } }; return validateRegionAPIs; } /** * This function performs get() operations in multiple Partition Regions after destroy of keys. * Each Vm gets keys from 100 to 200. */ private void getDestroyedEntryInMultiplePartitionedRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion, int afterPutFlag) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm0 .invokeAsync(getRemovedOrDestroyedInMultiplePartitionRegion(prPrefix, startIndexForDestroy, endIndexForDestroy, startIndexForRegion, endIndexForRegion, afterPutFlag)); async[1] = vm1 .invokeAsync(getRemovedOrDestroyedInMultiplePartitionRegion(prPrefix, startIndexForDestroy, endIndexForDestroy, startIndexForRegion, endIndexForRegion, afterPutFlag)); async[2] = vm2 .invokeAsync(getRemovedOrDestroyedInMultiplePartitionRegion(prPrefix, startIndexForDestroy, endIndexForDestroy, startIndexForRegion, endIndexForRegion, afterPutFlag)); async[3] = vm3 .invokeAsync(getRemovedOrDestroyedInMultiplePartitionRegion(prPrefix, startIndexForDestroy, endIndexForDestroy, startIndexForRegion, endIndexForRegion, afterPutFlag)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } // for (int count = 0; count < AsyncInvocationArrSize; count++) { // async[count].join(); // } // // for (int count = 0; count < AsyncInvocationArrSize; count++) { // if (async[count].exceptionOccurred()) { // fail("exception during " + count, async[count].getException()); // } // } } /** * This function performs put() operations in multiple Partition Regions after destroy of keys. * Range of the keys which are put is 100 to 200. Each Vm puts different set of keys */ private void putDestroyedEntryInMultiplePartitionedRegion(VM vm0, VM vm1, VM vm2, VM vm3, int startIndexForRegion, int endIndexForRegion) throws Throwable { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int delta = (endIndexForDestroy - startIndexForDestroy) / 4; async[0] = vm0.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForDestroy, startIndexForDestroy + delta * 1, startIndexForRegion, endIndexForRegion)); async[1] = vm1.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForDestroy + delta * 1, startIndexForDestroy + delta * 2, startIndexForRegion, endIndexForRegion)); async[2] = vm2.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForDestroy + delta * 2, startIndexForDestroy + delta * 3, startIndexForRegion, endIndexForRegion)); async[3] = vm3.invokeAsync(putInMultiplePartitionRegion(prPrefix, startIndexForDestroy + delta * 3, endIndexForDestroy, startIndexForRegion, endIndexForRegion)); /** main thread is waiting for the other threads to complete */ for (int count = 0; count < AsyncInvocationArrSize; count++) { ThreadUtils.join(async[count], 30 * 1000); } for (int count = 0; count < AsyncInvocationArrSize; count++) { if (async[count].exceptionOccurred()) { Assert.fail("exception during " + count, async[count].getException()); } } } }