/* * 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.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runners.MethodSorters; import org.apache.geode.LogWriter; import org.apache.geode.cache.AttributesFactory; import org.apache.geode.cache.Cache; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.RegionExistsException; import org.apache.geode.cache.Scope; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.test.junit.categories.IntegrationTest; /** * This is a test for creation of Partition region(PR). * <p> * Following tests are included in PartitionedRegionCreationJUnitTest : * </p> * <p> * 1) testpartionedRegionCreate - Tests the PR creation. * </p> * <p> * 2) testpartionedRegionInitialization - Tests the PR initialization * </p> * <p> * 3) testpartionedRegionRegistration - Tests the PR registration * </p> * <p> * 4) testpartionedRegionBucketToNodeCreate - Tests the PR's BUCKET_2_NODE region creation * </p> * * */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Category(IntegrationTest.class) public class PartitionedRegionCreationJUnitTest { static volatile int PRNumber = 0; static Region root = null; static volatile boolean increamentFlag = false; static final int TOTAL_THREADS = 10; static volatile int TOTAL_PR_CREATED = 0; static volatile int TOTAL_RETURNS = 0; static volatile int TOTAL_PR_CREATION_FAIL = 0; static final Object PR_CREATE = new Object(); static final Object PR_CREATE_FAIL = new Object(); static final Object PR_INCREMENT = new Object(); static final Object PR_TOTAL_RETURNS = new Object(); public boolean PRCreateDone = false; List PRRegionList = new ArrayList(); LogWriter logger = null; private Object CREATE_COMPLETE_LOCK = new Object(); private volatile boolean createComplete = false; @Before public void setUp() throws Exception { TOTAL_RETURNS = 0; if (logger == null) logger = PartitionedRegionTestHelper.getLogger(); } /* * 1)Create 10 thread each. Each thread will try to create PartionedRegion total of 5 partitioned * region will be created. 5 threads should throw RegionExistException. 2) Tests for PR scope = * GLOBAL and PR scope = LOCAL </p> 3) Test for redundancy < 0 </p> 4) Test for redundancy > 3 * </p> 5) Test for localMaxMemory < 0 </p> */ @Test public void test000PartitionedRegionCreate() { createMultiplePartitionedRegions(); verifyCreateResults(); if (logger.fineEnabled()) { logger.fine( " PartitionedRegionCreationTest-testpartionedRegionCreate() Successfully Complete .. "); } final String regionname = "testPartionedRegionCreate"; int localMaxMemory = 0; PartitionedRegion pr = null; // Test vanilla creation of a Partitioned Region w/o Scope try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PARTITION); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); } finally { pr.destroyRegion(); } // Assert that setting any scope throws IllegalStateException final Scope[] scopes = {Scope.LOCAL, Scope.DISTRIBUTED_ACK, Scope.DISTRIBUTED_NO_ACK, Scope.GLOBAL}; for (int i = 0; i < scopes.length; i++) { try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PARTITION); af.setScope(scopes[i]); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for Scope " + scopes[i]); } catch (IllegalStateException expected) { } finally { if (pr != null && !pr.isDestroyed()) { pr.destroyRegion(); } } } // test for redundancy > 3 int redundancy = 10; try { pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname, String.valueOf(localMaxMemory), redundancy); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger.fine( "testpartionedRegionCreate() Got a correct exception-IllegalStateException for redundancy > 3 "); } } // test for redundancy < 0 if (pr != null && !pr.isDestroyed()) pr.destroyRegion(); redundancy = -5; try { pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname, String.valueOf(200), redundancy); fail( "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy < 0 "); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger.fine( "testpartionedRegionCreate() Got a correct exception-IllegalStateException for redundancy < 0 "); } } // test for localMaxMemory < 0 /* * if (pr!= null && !pr.isDestroyed()) pr.destroyRegion(); ; localMaxMemory = -5; try { pr = * (PartitionedRegion)PartitionedRegionTestHelper .createPartitionedRegion(regionname, * String.valueOf(localMaxMemory), 2, Scope.DISTRIBUTED_ACK); * fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for localMaxMemory < 0 " * ); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger * .fine("testpartionedRegionCreate() Got a correct exception-IllegalStateException for localMaxMemory < 0 " * ); } } */ } @Test public void test001PersistentPartitionedRegionCreate() { final String regionname = "testPersistentPartionedRegionCreate"; PartitionedRegion pr = null; // Test vanilla creation of a Partitioned Region w/o Scope try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); } finally { if (pr != null) { pr.destroyRegion(); } } // Assert that an accessor (localMaxMem == 0) can't be persistent try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); af.setPartitionAttributes(new PartitionAttributesFactory().setLocalMaxMemory(0).create()); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); fail("testpartionedRegionCreate() Expected IllegalStateException not thrown"); } catch (IllegalStateException expected) { assertEquals("Persistence is not allowed when local-max-memory is zero.", expected.getMessage()); } // Assert that a region can't be created // if configured with a diskStoreName and the disk store has not be created. try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); af.setDiskStoreName("nonexistentDiskStore"); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); fail("testpartionedRegionCreate() Expected IllegalStateException not thrown"); } catch (RuntimeException expected) { assertTrue(expected.getMessage().contains(LocalizedStrings.CacheCreation_DISKSTORE_NOTFOUND_0 .toLocalizedString("nonexistentDiskStore"))); } // Assert that you can't have a diskStoreName unless you are persistent or overflow. try { Cache cache = PartitionedRegionTestHelper.createCache(); cache.createDiskStoreFactory().create("existentDiskStore"); AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PARTITION); af.setDiskStoreName("existentDiskStore"); RegionAttributes ra = af.create(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); fail("testpartionedRegionCreate() Expected IllegalStateException not thrown"); } catch (IllegalStateException expected) { assertEquals("Only regions with persistence or overflow to disk can specify DiskStore", expected.getMessage()); } // Assert that setting any scope throws IllegalStateException final Scope[] scopes = {Scope.LOCAL, Scope.DISTRIBUTED_ACK, Scope.DISTRIBUTED_NO_ACK, Scope.GLOBAL}; for (int i = 0; i < scopes.length; i++) { try { AttributesFactory af = new AttributesFactory(); af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); af.setScope(scopes[i]); RegionAttributes ra = af.create(); Cache cache = PartitionedRegionTestHelper.createCache(); pr = (PartitionedRegion) cache.createRegion(regionname, ra); fail("testpartionedRegionCreate() Expected IllegalStateException not thrown for Scope " + scopes[i]); } catch (IllegalStateException expected) { } } // test for redundancy > 3 try { pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname, String.valueOf(0), 4); fail( "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy > 3 "); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger.fine( "testpartionedRegionCreate() Got a correct exception-IllegalStateException for redundancy > 3 "); } } // test for redundancy < 0 try { pr = (PartitionedRegion) PartitionedRegionTestHelper.createPartitionedRegion(regionname, String.valueOf(200), -1); fail( "testpartionedRegionCreate() Expected IllegalStateException not thrown for redundancy < 0 "); } catch (IllegalStateException illex) { if (logger.fineEnabled()) { logger.fine( "testpartionedRegionCreate() Got a correct exception-IllegalStateException for redundancy < 0 "); } } } /** * Test for initialization of PartitionedRegion. Following are tested for the PartitionedRegion: * <p> * (1) Test for Root == null * <p> * (2) Test for Root region scope is DIST_ACK * <p> * (3) Test if MirrorType.NONE for root region. * <p> * (4) Test if PARTITIONED_REGION_CONFIG_NAME exist and isDistributedAck and the mirror type is * MirrorType.KEYS_VALUES. * * @throws RegionExistsException */ @Test public void test002PartionedRegionInitialization() throws RegionExistsException { String PRName = "testpartionedRegionInitialization"; PartitionedRegionTestHelper.createPartionedRegion(PRName); Region root = (PartitionedRegionTestHelper .getExistingRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME)); if (root == null) fail("testpartionedRegionInitialization() - the " + PartitionedRegionHelper.PR_ROOT_REGION_NAME + " do not exists"); RegionAttributes regionAttribs = root.getAttributes(); Scope scope = regionAttribs.getScope(); if (!scope.isDistributedAck()) fail("testpartionedRegionInitialization() - the " + PartitionedRegionHelper.PR_ROOT_REGION_NAME + " scope is not distributed_ack"); assertEquals(DataPolicy.REPLICATE, regionAttribs.getDataPolicy()); // Region allPartitionedRegions = root // .getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME); // if (allPartitionedRegions == null) // fail("testpartionedRegionInitialization() - the " // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME // + " do not exists"); // // regionAttribs = allPartitionedRegions.getAttributes(); // scope = regionAttribs.getScope(); // if (!scope.isDistributedAck()) // fail("testpartionedRegionInitialization() - the " // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME // + " scope is not distributed_ack"); // MirrorType mirrortype = regionAttribs.getMirrorType(); // if (mirrortype != MirrorType.KEYS_VALUES) // fail("testpartionedRegionInitialization() - the " // + PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME // + " mirror type is not KEYS_VALUES "); if (logger.fineEnabled()) { logger.fine("testpartionedRegionInitialization() Successfully Complete .. "); } // System.out.println("testpartionedRegionInitialization"); } /** * Test for partitioned Region registration. All partitioned regions created must have a entry in * PARTITIONED_REGION_CONFIG_NAME. Every PR has PR name / PartitionRegionConfig entry in region * PARTITIONED_REGION_CONFIG_NAME * */ @Test public void test003partionedRegionRegistration() { createMultiplePartitionedRegions(); Region root = (PartitionedRegionTestHelper .getExistingRegion(PartitionedRegionHelper.PR_ROOT_REGION_NAME)); // // Region allPartitionedRegions = root // .getSubregion(PartitionedRegionHelper.PARTITIONED_REGION_CONFIG_NAME); Iterator itr = PRRegionList.iterator(); while (itr.hasNext()) { Region region = (Region) itr.next(); String name = ((PartitionedRegion) region).getRegionIdentifier(); PartitionRegionConfig prConfig = (PartitionRegionConfig) root.get(name); if (prConfig == null) fail("testpartionedRegionRegistration() - PartionedRegion - " + name + " configs do not exists in region - " + root.getName()); } if (logger.fineEnabled()) { logger.fine(" testpartionedRegionRegistration() Successfully Complete .. "); } // System.out.println("testpartionedRegionRegistration"); } /** * creates multiple partitioned region from different threads. * */ private void createMultiplePartitionedRegions() { if (PRCreateDone) return; int numthread = 0; while (numthread < TOTAL_THREADS) { PartionedRegionCreateThread pregionThread = new PartionedRegionCreateThread(); pregionThread.start(); numthread++; } while (!createComplete) { synchronized (CREATE_COMPLETE_LOCK) { if (!createComplete) { try { CREATE_COMPLETE_LOCK.wait(); } catch (Exception ex) { // no action } } } } } PRCreateDone = true; } /** * Verifies creation of partitioned region. * */ private void verifyCreateResults() { if (TOTAL_RETURNS != TOTAL_THREADS) fail("Failed -- Total thread returned is not same as number of threads created"); if (TOTAL_PR_CREATED != (TOTAL_THREADS / 2)) fail("Failed -- Total Partioned Region created is not correct"); if (TOTAL_PR_CREATION_FAIL != (TOTAL_THREADS / 2)) fail("Failed -- Total Partioned Region creation failures is not correct"); } /** * Thread to create the partitioned region. * */ public class PartionedRegionCreateThread extends Thread { public void run() { String prName = "PartitionedRegionCreationJUnitTest_" + getPRNumber(); try { Region region = PartitionedRegionTestHelper.createPartionedRegion(prName); PRRegionList.add(region); if (logger.fineEnabled()) { logger.fine( "PartitionedRegionCreationJUnitTest - partitioned region -" + prName + "Created"); } updatePRCreate(); } catch (RegionExistsException rex) { if (logger.fineEnabled()) { logger .fine("PartitionedRegionCreationTest - Thread - " + Thread.currentThread().getName() + " Failed to create a PartitionedRegion. Region already exists"); } updatePRCreateFail(); } updateTotalReturns(); } } /** * Increments and returns the PR nmber used for PR creation. Thread safe function. * * @return the PR number */ protected int getPRNumber() { int retNum = 0; synchronized (PR_INCREMENT) { if (increamentFlag) { retNum = PRNumber; PRNumber++; increamentFlag = false; } else { increamentFlag = true; } } return retNum; } protected void updatePRCreate() { synchronized (PR_CREATE) { TOTAL_PR_CREATED++; } } protected void updatePRCreateFail() { synchronized (PR_CREATE_FAIL) { TOTAL_PR_CREATION_FAIL++; } } /** * Increments total creation thread returns. * */ protected void updateTotalReturns() { synchronized (PR_TOTAL_RETURNS) { TOTAL_RETURNS++; System.out.println("TOTAL_RETURNS is " + TOTAL_RETURNS); } if (TOTAL_RETURNS == TOTAL_THREADS) { synchronized (CREATE_COMPLETE_LOCK) { createComplete = true; CREATE_COMPLETE_LOCK.notifyAll(); } } } }