/* * 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 java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.*; import org.apache.geode.cache.Cache; import org.apache.geode.cache.Region; import org.apache.geode.cache30.*; 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 class tests PRID generation in multiple partiton regions on 4 VMs */ @Category(DistributedTest.class) public class PartitionedRegionPRIDDUnitTest extends PartitionedRegionDUnitTestCase { /** Maximum number of regions * */ public final static int MAX_REGIONS = 1; /** redundancy used for the creation of the partition region */ // int redundancy = 0; /** local maxmemory used for the creation of the partition region */ int localMaxMemory = 200; /** to store references of 4 vms */ VM vm[] = new VM[4]; public PartitionedRegionPRIDDUnitTest() { super(); } /** * This test performs following operations 1. creates 25 partition regions on 3 nodes. 2. creates * more 25 partition regions on 4 nodes 3. tests PRID generation * */ @Test public void testPRIDGenerationInMultiplePartitionRegion() throws Exception { Host host = Host.getHost(0); /** creating 4 VMs */ createVMs(host); /** Prefix will be used for naming the partititon Region */ String prPrefix = "testBucketCreationInMultiPlePartitionRegion"; /** these indices represents range of partition regions present in each VM */ int startIndexForRegion = 0; int endIndexForRegion = MAX_REGIONS; int startIndexForNode; int endIndexForNode; List vmList = new ArrayList(); startIndexForNode = 0; endIndexForNode = 3; addNodeToList(vmList, startIndexForNode, endIndexForNode); localMaxMemory = 200; final int redundancy = 0; // Create 1/2 * MAX_REGIONS regions in VM 0,1,2 with scope D_ACK. createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, redundancy, prPrefix); LogWriterUtils.getLogWriter().info( "testPRIDGenerationInMultiplePartitionRegion() - Partition regions on 3 nodes successfully created"); startIndexForRegion = MAX_REGIONS; endIndexForRegion = 2 * MAX_REGIONS; // creating partition regions on 4 with scope DISTRIBUTED_ACK startIndexForNode = 0; endIndexForNode = 4; addNodeToList(vmList, startIndexForNode, endIndexForNode); localMaxMemory = 200; final int pr2_redundancy = 1; // Create MAX_REGION regions on VM 0,1,2,3. // VM 3 contains regions from id MAX_REGIONS to 2*MAX_REGIONS only. createPartitionRegion(vmList, startIndexForRegion, endIndexForRegion, localMaxMemory, pr2_redundancy, prPrefix); LogWriterUtils.getLogWriter().info( "testPRIDGenerationInMultiplePartitionRegion() - Partition regions on 4 nodes successfully created"); // validating PRID generation for multiple partition regions int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; async[0] = vm[0].invokeAsync(validatePRIDCreation(0, endIndexForRegion, prPrefix)); async[1] = vm[1].invokeAsync(validatePRIDCreation(0, endIndexForRegion, prPrefix)); async[2] = vm[2].invokeAsync(validatePRIDCreation(0, endIndexForRegion, prPrefix)); async[3] = vm[3].invokeAsync(validatePRIDCreation(MAX_REGIONS, endIndexForRegion, prPrefix)); /** 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("VM " + count + " encountered this exception during async invocation", async[count].getException()); } } } /** * This function perfoms following checks on PRID creation 1. PRID generated should be between 0 * to number of partition regions in distributed system 2. PRID should be unique for the partition * regions * * @param startIndexForRegion * @param endIndexForRegion * @return */ private CacheSerializableRunnable validatePRIDCreation(final int startIndexForRegion, final int endIndexForRegion, final String prPrefix) { CacheSerializableRunnable validatePRID = new CacheSerializableRunnable("validatePRIDCreation") { String innerPrPrefix = prPrefix; public void run2() { int noPartitionRegions = endIndexForRegion - startIndexForRegion; Cache cache = getCache(); // getting root region Region root = cache.getRegion(Region.SEPARATOR + PartitionedRegionHelper.PR_ROOT_REGION_NAME); // root region should niot be null assertNotNull("Root region can not be null", root); // getting allParititionedRegions // Region allPartitionedRegions = root // .getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME); // allPartitionedRegion should not be null // assertNotNull("allPartitionedRegion can not be null", // allPartitionedRegions); // scope of all partition region should be DISTRIBUTED_ACK List prIdList = new ArrayList(); for (int i = startIndexForRegion; i < endIndexForRegion; i++) { final String rName = Region.SEPARATOR + innerPrPrefix + i; PartitionedRegion pr = (PartitionedRegion) cache.getRegion(rName); assertNotNull("This Partitioned Region " + rName + " cannot be null", pr); PartitionRegionConfig prConfig = (PartitionRegionConfig) root.get(pr.getRegionIdentifier()); assertNotNull("PRConfig for Partitioned Region " + rName + " can not be null", prConfig); prIdList.add(Integer.toString(prConfig.getPRId())); // this partition region should present in prIdToPr /* * if (PartitionedRegion.prIdToPR.containsKey(Integer.toString(prConfig .getPRId())) == * false) fail("this partition region is not present in the prIdToPR map " + * pr.getName()); */ } // checking uniqueness of prId in allPartitionRegion SortedSet prIdSet = new TreeSet(prIdList); if (prIdSet.size() != prIdList.size()) fail("Duplicate PRID are generated"); // prId generated should be between 0 to number of partition regions-1 Iterator prIdSetItr = prIdSet.iterator(); while (prIdSetItr.hasNext()) { int val = Integer.parseInt((String) prIdSetItr.next()); if (val > noPartitionRegions - 1 & val < 0) { fail("PRID limit is out of range"); } } // no of PRID generated in allPartitionRegion should be equal to number of partition region if (prIdSet.size() != noPartitionRegions) fail("Different PRID generated equal to " + prIdSet.size()); // no of PRID generated in prIdToPR should be equal to number of partition region if (PartitionedRegion.prIdToPR.size() != noPartitionRegions) fail("number of entries in the prIdToPR is " + PartitionedRegion.prIdToPR.size()); // checking uniqueness of prId in prIdToPR SortedSet prIdPRSet = new TreeSet(PartitionedRegion.prIdToPR.keySet()); if (prIdPRSet.size() != PartitionedRegion.prIdToPR.size()) fail("Duplicate PRID are generated in prIdToPR"); LogWriterUtils.getLogWriter().info("Size of allPartition region : " + prIdSet.size()); LogWriterUtils.getLogWriter().info("Size of prIdToPR region : " + prIdPRSet.size()); LogWriterUtils.getLogWriter().info("PRID generated successfully"); } }; return validatePRID; } /** * This function createas multiple partition regions on nodes specified in the vmList */ private void createPartitionRegion(List vmList, int startIndexForRegion, int endIndexForRegion, int localMaxMemory, int redundancy, String prPrefix) throws Exception { int AsyncInvocationArrSize = 4; AsyncInvocation[] async = new AsyncInvocation[AsyncInvocationArrSize]; int numNodes = 0; Iterator nodeIterator = vmList.iterator(); while (nodeIterator.hasNext()) { VM vm = (VM) nodeIterator.next(); async[numNodes] = vm.invokeAsync(createMultiplePartitionRegion(prPrefix, startIndexForRegion, endIndexForRegion, redundancy, localMaxMemory)); numNodes++; } for (int i = 0; i < numNodes; i++) { ThreadUtils.join(async[i], 30 * 1000); } for (int i = 0; i < numNodes; i++) { if (async[i].exceptionOccurred()) { Assert.fail("VM " + i + " encountered this exception during async invocation", async[i].getException()); } } } /** * This function adds nodes to node list in the range specified by startIndexForNode and * endIndexForNode */ private void addNodeToList(List vmList, int startIndexForNode, int endIndexForNode) { vmList.clear(); for (int i = startIndexForNode; i < endIndexForNode; i++) { vmList.add(vm[i]); } } /** creates 4 VMS on the given host */ private void createVMs(Host host) { for (int i = 0; i < 4; i++) { vm[i] = host.getVM(i); } } }