/*
 * 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.cache30;

import static org.apache.geode.cache.Region.SEPARATOR;
import static org.apache.geode.distributed.ConfigurationProperties.ROLES;
import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort;
import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
import static org.apache.geode.test.util.ResourceUtils.createTempFileFromResource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.SAXException;

import org.apache.geode.DataSerializable;
import org.apache.geode.DataSerializer;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.AttributesMutator;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.CacheTransactionManager;
import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CacheXmlException;
import org.apache.geode.cache.CustomExpiry;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory;
import org.apache.geode.cache.DiskWriteAttributesFactory;
import org.apache.geode.cache.DynamicRegionFactory;
import org.apache.geode.cache.EvictionAction;
import org.apache.geode.cache.EvictionAlgorithm;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.FixedPartitionAttributes;
import org.apache.geode.cache.InterestPolicy;
import org.apache.geode.cache.LoaderHelper;
import org.apache.geode.cache.LossAction;
import org.apache.geode.cache.MembershipAttributes;
import org.apache.geode.cache.MirrorType;
import org.apache.geode.cache.PartitionAttributes;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Region.Entry;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.ResumptionAction;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.SubscriptionAttributes;
import org.apache.geode.cache.TransactionListener;
import org.apache.geode.cache.TransactionWriter;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory;
import org.apache.geode.cache.client.PoolManager;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.server.ClientSubscriptionConfig;
import org.apache.geode.cache.server.ServerLoad;
import org.apache.geode.cache.server.ServerLoadProbeAdapter;
import org.apache.geode.cache.server.ServerMetrics;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.cache.util.TransactionListenerAdapter;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.InternalInstantiator;
import org.apache.geode.internal.cache.DiskWriteAttributesImpl;
import org.apache.geode.internal.cache.DistributedRegion;
import org.apache.geode.internal.cache.FixedPartitionAttributesImpl;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.internal.cache.PoolFactoryImpl;
import org.apache.geode.internal.cache.functions.TestFunction;
import org.apache.geode.internal.cache.partitioned.fixed.QuarterPartitionResolver;
import org.apache.geode.internal.cache.persistence.DefaultDiskDirs;
import org.apache.geode.internal.cache.xmlcache.CacheCreation;
import org.apache.geode.internal.cache.xmlcache.CacheTransactionManagerCreation;
import org.apache.geode.internal.cache.xmlcache.CacheXml;
import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
import org.apache.geode.internal.cache.xmlcache.CacheXmlParser;
import org.apache.geode.internal.cache.xmlcache.ClientCacheCreation;
import org.apache.geode.internal.cache.xmlcache.Declarable2;
import org.apache.geode.internal.cache.xmlcache.FunctionServiceCreation;
import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
import org.apache.geode.internal.cache.xmlcache.RegionCreation;
import org.apache.geode.internal.cache.xmlcache.ResourceManagerCreation;
import org.apache.geode.internal.cache.xmlcache.SerializerCreation;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.LogWriterUtils;
import org.apache.geode.test.dunit.NetworkUtils;
import org.apache.geode.test.dunit.SerializableCallable;
import org.apache.geode.test.dunit.VM;

/**
 * Tests 7.0 cache.xml feature : Fixed Partitioning.
 *
 * @since GemFire 6.6
 */
public abstract class CacheXml66DUnitTest extends CacheXmlTestCase {

  @Override
  protected abstract String getGemFireVersion();

  private static final String ALIAS1;

  private static final String ALIAS2;

  static {
    String tmp_alias1 = "localhost";
    String tmp_alias2 = "localhost";
    ALIAS1 = tmp_alias1;
    ALIAS2 = tmp_alias2;
  }

  private static InetSocketAddress createINSA(String host, int port) {
    try {
      InetAddress hostAddr = InetAddress.getByName(host);
      return new InetSocketAddress(hostAddr, port);
    } catch (UnknownHostException cause) {
      throw new IllegalArgumentException("Unknown host " + host, cause);
    }
  }

  /**
   * test for checking default value of PR_Single_Hop feature. Test for checking default value of
   * multiuser-authentication attribute.
   */
  @Test
  public void testDefaultConnectionPool() throws Exception {
    getSystem();
    CacheCreation cache = new CacheCreation();
    PoolFactory f = cache.createPoolFactory();
    f.addLocator(ALIAS2, 3777);
    f.create("mypool");
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setPoolName("mypool");
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    Region r = c.getRegion("rootNORMAL");
    assertNotNull(r);
    assertEquals("mypool", r.getAttributes().getPoolName());
    Pool cp = PoolManager.find("mypool");
    assertNotNull(cp);
    assertEquals(1, cp.getLocators().size());
    assertEquals(0, cp.getServers().size());
    assertEquals(createINSA(ALIAS2, 3777), cp.getLocators().get(0));
    assertEquals(PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT, cp.getFreeConnectionTimeout());
    assertEquals(PoolFactory.DEFAULT_SERVER_CONNECTION_TIMEOUT, cp.getServerConnectionTimeout());
    assertEquals(PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL, cp.getLoadConditioningInterval());
    assertEquals(PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE, cp.getSocketBufferSize());
    assertEquals(PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS, cp.getThreadLocalConnections());
    assertEquals(PoolFactory.DEFAULT_READ_TIMEOUT, cp.getReadTimeout());
    assertEquals(PoolFactory.DEFAULT_MIN_CONNECTIONS, cp.getMinConnections());
    assertEquals(PoolFactory.DEFAULT_MAX_CONNECTIONS, cp.getMaxConnections());
    assertEquals(PoolFactory.DEFAULT_RETRY_ATTEMPTS, cp.getRetryAttempts());
    assertEquals(PoolFactory.DEFAULT_IDLE_TIMEOUT, cp.getIdleTimeout());
    assertEquals(PoolFactory.DEFAULT_PING_INTERVAL, cp.getPingInterval());
    assertEquals(PoolFactory.DEFAULT_STATISTIC_INTERVAL, cp.getStatisticInterval());
    assertEquals(PoolFactory.DEFAULT_SERVER_GROUP, cp.getServerGroup());
    assertEquals(PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED, cp.getSubscriptionEnabled());
    assertEquals(PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED, cp.getPRSingleHopEnabled());
    assertEquals(PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY, cp.getSubscriptionRedundancy());
    assertEquals(PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT,
        cp.getSubscriptionMessageTrackingTimeout());
    assertEquals(PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL, cp.getSubscriptionAckInterval());
    assertEquals(PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION, cp.getMultiuserAuthentication());
  }

  @Test
  public void testDiskStore() throws Exception {
    CacheCreation cache = new CacheCreation();
    DiskStoreFactory dsf = cache.createDiskStoreFactory();
    File[] dirs1 = new File[] {new File("").getAbsoluteFile()};
    DiskStore ds1 =
        dsf.setAllowForceCompaction(true).setAutoCompact(true).setCompactionThreshold(100)
            .setMaxOplogSize(2).setTimeInterval(10).setWriteBufferSize(15).setQueueSize(12)
            .setDiskDirsAndSizes(dirs1, new int[] {1024 * 20}).create(getUniqueName() + 1);
    File[] dirs2 = new File[] {new File("").getAbsoluteFile()};
    DiskStore ds2 =
        dsf.setAllowForceCompaction(false).setAutoCompact(false).setCompactionThreshold(99)
            .setMaxOplogSize(1).setTimeInterval(9).setWriteBufferSize(14).setQueueSize(11)
            .setDiskDirsAndSizes(dirs2, new int[] {1024 * 40}).create(getUniqueName() + 2);

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
    attrs.setDiskStoreName(getUniqueName() + 1);
    attrs.setDiskSynchronous(true);
    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);
    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_ACK);
      attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      attrs.setDiskStoreName(getUniqueName() + 2);
      Region subwithdiskstore = root.createSubregion("subwithdiskstore", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_ACK);
      attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      Region subwithdefaultdiskstore = root.createSubregion("subwithdefaultdiskstore", attrs);
    }

    testXml(cache);
  }

  /**
   * test for enabling PRsingleHop feature. Test for enabling multiuser-authentication attribute.
   */
  @Test
  public void testExplicitConnectionPool() throws Exception {
    getSystem();
    CacheCreation cache = new CacheCreation();
    PoolFactory f = cache.createPoolFactory();
    f.addServer(ALIAS2, 3777).addServer(ALIAS1, 3888);
    f.setFreeConnectionTimeout(12345).setServerConnectionTimeout(111)
        .setLoadConditioningInterval(12345).setSocketBufferSize(12345)
        .setThreadLocalConnections(true).setPRSingleHopEnabled(true).setReadTimeout(12345)
        .setMinConnections(12346).setMaxConnections(12347).setRetryAttempts(12348)
        .setIdleTimeout(12349).setPingInterval(12350).setStatisticInterval(12351)
        .setServerGroup("mygroup")
        // commented this out until queues are implemented
        // .setQueueEnabled(true)
        .setSubscriptionRedundancy(12345).setSubscriptionMessageTrackingTimeout(12345)
        .setSubscriptionAckInterval(333).setMultiuserAuthentication(true);
    f.create("mypool");
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setPoolName("mypool");
    attrs.setDataPolicy(DataPolicy.EMPTY); // required for multiuser mode
    cache.createVMRegion("rootNORMAL", attrs);
    addIgnoredException("Connection refused: connect");
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    Region r = c.getRegion("rootNORMAL");
    assertNotNull(r);
    assertEquals("mypool", r.getAttributes().getPoolName());
    Pool cp = PoolManager.find("mypool");
    assertNotNull(cp);
    assertEquals(0, cp.getLocators().size());
    assertEquals(2, cp.getServers().size());
    assertEquals(createINSA(ALIAS2, 3777), cp.getServers().get(0));
    assertEquals(createINSA(ALIAS1, 3888), cp.getServers().get(1));
    assertEquals(12345, cp.getFreeConnectionTimeout());
    assertEquals(111, cp.getServerConnectionTimeout());
    assertEquals(12345, cp.getLoadConditioningInterval());
    assertEquals(12345, cp.getSocketBufferSize());
    assertEquals(true, cp.getThreadLocalConnections());
    assertEquals(true, cp.getPRSingleHopEnabled());
    assertEquals(12345, cp.getReadTimeout());
    assertEquals(12346, cp.getMinConnections());
    assertEquals(12347, cp.getMaxConnections());
    assertEquals(12348, cp.getRetryAttempts());
    assertEquals(12349, cp.getIdleTimeout());
    assertEquals(12350, cp.getPingInterval());
    assertEquals(12351, cp.getStatisticInterval());
    assertEquals("mygroup", cp.getServerGroup());
    // TODO: commented this out until queues are implemented
    // assertIndexDetailsEquals(true, cp.getQueueEnabled());
    assertEquals(12345, cp.getSubscriptionRedundancy());
    assertEquals(12345, cp.getSubscriptionMessageTrackingTimeout());
    assertEquals(333, cp.getSubscriptionAckInterval());
    assertEquals(true, cp.getMultiuserAuthentication());
  }

  @Test
  public void testDiskStoreValidation() throws Exception {
    CacheCreation cache = new CacheCreation();
    DiskStoreFactory dsf = cache.createDiskStoreFactory();
    DiskStore ds1 = dsf.create(getUniqueName());

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setDataPolicy(DataPolicy.REPLICATE);
    attrs.setDiskStoreName(getUniqueName());
    RegionCreation root;
    try {
      root = (RegionCreation) cache.createRegion("root", attrs);
      fail("Expected IllegalStateException to be thrown");
    } catch (IllegalStateException e) {
      assertTrue(e.getMessage().contains(
          "Only regions with persistence or overflow to disk can specify DiskStore"));
    }

    EvictionAttributes ea =
        EvictionAttributes.createLRUEntryAttributes(1000, EvictionAction.OVERFLOW_TO_DISK);
    attrs.setEvictionAttributes(ea);
    root = (RegionCreation) cache.createRegion("root", attrs);

    File dir = new File("testDiskStoreValidation");
    dir.mkdir();
    dir.deleteOnExit();

    File[] dirs2 = new File[] {dir, new File("").getAbsoluteFile()};
    try {
      AttributesFactory factory = new AttributesFactory();
      factory.setDiskDirs(dirs2);
      factory.setDiskStoreName(getUniqueName());
      RegionAttributes ra = factory.create();
      fail("Expected IllegalStateException to be thrown");
    } catch (IllegalStateException e) {
      assertTrue(e.getMessage()
          .contains(String.format("Deprecated API %s cannot be used with DiskStore %s",
              "setDiskDirs or setDiskWriteAttributes", getUniqueName())));
    }

    try {
      AttributesFactory factory = new AttributesFactory();
      factory.setDiskStoreName(getUniqueName());
      factory.setDiskDirs(dirs2);
      RegionAttributes ra = factory.create();
      fail("Expected IllegalStateException to be thrown");
    } catch (IllegalStateException e) {
      assertTrue(e.getMessage()
          .contains(String.format("Deprecated API %s cannot be used with DiskStore %s",
              "setDiskDirs", getUniqueName())));
    }

    testXml(cache);
  }

  @Test
  public void testDiskStoreFactory() throws Exception {
    CacheCreation cache = new CacheCreation();
    DiskStoreFactory dsf = cache.createDiskStoreFactory();

    dsf.setDiskDirs(new File[] {new File("non_exist_dir")});
    DiskStore ds1 = dsf.create(getUniqueName());

    dsf.setDiskDirs(new File[] {new File(".")});
    ds1 = dsf.create(getUniqueName());

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
    attrs.setDiskStoreName(getUniqueName());
    AttributesFactory factory = new AttributesFactory(attrs);
    RegionAttributes ra = factory.create();

    RegionCreation root = (RegionCreation) cache.createRegion("root", ra);

    factory = new AttributesFactory();
    factory.setDiskStoreName(getUniqueName());
    factory.setScope(Scope.DISTRIBUTED_ACK);
    factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);

    ra = factory.create();

    RegionCreation root2 = (RegionCreation) cache.createRegion("root2", ra);

    factory = new AttributesFactory();
    factory.setDiskStoreName(null);
    factory.setScope(Scope.DISTRIBUTED_ACK);
    factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);

    ra = factory.create();

    RegionCreation root3 = (RegionCreation) cache.createRegion("root3", ra);

    testXml(cache);
  }

  @Test
  public void testRedefineOfDefaultDiskStore() throws Exception {
    CacheCreation cache = new CacheCreation();
    DiskStoreFactory dsf = cache.createDiskStoreFactory();
    dsf.setAutoCompact(!DiskStoreFactory.DEFAULT_AUTO_COMPACT);
    DiskStore ds1 = dsf.create(DiskStoreFactory.DEFAULT_DISK_STORE_NAME);

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
    AttributesFactory factory = new AttributesFactory(attrs);
    RegionAttributes ra = factory.create();

    RegionCreation root = (RegionCreation) cache.createRegion("root", ra);

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    DiskStore ds2 = c.findDiskStore(DiskStoreFactory.DEFAULT_DISK_STORE_NAME);
    assertNotNull(ds2);
    assertEquals(ds1.getAutoCompact(), ds2.getAutoCompact());
  }

  /**
   * Make sure you can create a persistent partitioned region from xml.
   */
  @Test
  public void testPersistentPartition() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);

    cache.createRegion("parRoot", attrs);

    Region r = cache.getRegion("parRoot");
    assertEquals(DataPolicy.PERSISTENT_PARTITION, r.getAttributes().getDataPolicy());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    assertEquals(DataPolicy.PERSISTENT_PARTITION, region.getAttributes().getDataPolicy());
    // since CacheTestCase remoteTearDown does not destroy PartitionedRegion
    region.localDestroyRegion();
  }

  @Test
  public void testBridgeAttributesRelatedToHAOverFlow65() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setMessageSyncInterval(3445);
    CacheServer bs = cache.addCacheServer();
    ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
    csc.setEvictionPolicy("entry");
    cache.getLogger().config("EvictionPolicy : " + csc.getEvictionPolicy());
    csc.setCapacity(501);
    cache.getLogger().config("EvictionCapacity : " + csc.getCapacity());
    File overflowDirectory = new File("overFlow");
    overflowDirectory.mkdirs();
    DiskStoreFactory dsf = cache.createDiskStoreFactory();
    File[] dirs1 = new File[] {overflowDirectory};
    DiskStore ds1 = dsf.setDiskDirs(dirs1).create(getUniqueName());
    csc.setDiskStoreName(getUniqueName());
    try {
      csc.setOverflowDirectory("overFlow");
    } catch (IllegalStateException e) {
      assertTrue(e.getMessage()
          .contains(String.format("Deprecated API %s cannot be used with DiskStore %s",
              "setOverflowDirectory", getUniqueName())));
    }

    cache.getLogger().config("Eviction disk store : " + csc.getDiskStoreName());
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    ClientSubscriptionConfig chaqf = server.getClientSubscriptionConfig();
    assertEquals("entry", chaqf.getEvictionPolicy());
    assertEquals(501, chaqf.getCapacity());
    DiskStore dsi = cache.findDiskStore(chaqf.getDiskStoreName());
    assertEquals("overFlow", dsi.getDiskDirs()[0].toString());
  }

  @Test
  public void testClientSubscriptionQueueUsingDefaultDS() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setMessageSyncInterval(3445);
    CacheServer bs = cache.addCacheServer();
    ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
    csc.setEvictionPolicy("entry");
    cache.getLogger().config("EvictionPolicy : " + csc.getEvictionPolicy());
    csc.setCapacity(501);
    // don't set diskstore or overflowdir
    cache.getLogger().config("EvictionCapacity : " + csc.getCapacity());
    cache.getLogger().config("Eviction disk store : " + csc.getDiskStoreName());
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    ClientSubscriptionConfig chaqf = server.getClientSubscriptionConfig();
    assertEquals("entry", chaqf.getEvictionPolicy());
    assertEquals(501, chaqf.getCapacity());
    File defaultDiskDir = DefaultDiskDirs.getDefaultDiskDirs()[0].getAbsoluteFile();
    File lockFile =
        new File(defaultDiskDir, "DRLK_IF" + GemFireCacheImpl.getDefaultDiskStoreName() + ".lk");
    assertTrue(lockFile.exists());
  }

  /**
   * Tests that a region created with a named attributes set programmatically for delta propogation
   * has the correct attributes.
   */
  @Test
  public void testTransactionWriter() throws Exception {
    CacheCreation creation = new CacheCreation();
    CacheTransactionManagerCreation ctmc = new CacheTransactionManagerCreation();
    ctmc.setWriter(new TestTransactionWriter());
    creation.addCacheTransactionManagerCreation(ctmc);
    testXml(creation);

    Cache c = getCache();
    assertTrue(c instanceof GemFireCacheImpl);
    c.loadCacheXml(generate(creation));

    TransactionWriter tw = c.getCacheTransactionManager().getWriter();
    assertTrue("tw should be TransactionWriter, but it is:" + tw,
        tw instanceof TestTransactionWriter);
  }

  /**
   * Tests that a region created with a named attributes with diskstore
   */
  @Test
  public void testDiskStoreInTemplates() throws Exception {
    File dir = new File("west");
    dir.mkdir();
    dir.deleteOnExit();

    dir = new File("east");
    dir.mkdir();
    dir.deleteOnExit();

    setXmlFile(findFile("ewtest.xml"));

    String regionName_west = "orders" + SEPARATOR + "west";
    String regionName_east = "orders" + SEPARATOR + "east";

    Cache cache = getCache();

    // verify diskstores
    DiskStore ds = cache.findDiskStore("persistentDiskStore1");
    assertNotNull(ds);
    assertEquals(500, ds.getQueueSize());
    File[] dirs = ds.getDiskDirs();
    assertEquals("west", dirs[0].getPath());

    ds = cache.findDiskStore("persistentDiskStore2");
    assertNotNull(ds);
    assertEquals(500, ds.getQueueSize());
    dirs = ds.getDiskDirs();
    assertEquals("east", dirs[0].getPath());

    // verify templates
    assertNotNull(cache.getRegionAttributes("nack"));
    RegionAttributes attrs = cache.getRegionAttributes("persistent");
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, attrs.getDataPolicy());
    assertEquals(false, attrs.isDiskSynchronous());
    assertEquals("persistentDiskStore1", attrs.getDiskStoreName());

    Region region = cache.getRegion(regionName_west);
    assertNotNull(region);

    attrs = region.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, attrs.getDataPolicy());
    assertEquals(false, attrs.isDiskSynchronous());
    assertEquals("persistentDiskStore1", attrs.getDiskStoreName());

    region = cache.getRegion(regionName_east);
    assertNotNull(region);

    // Make sure that attributes can be "overridden"
    attrs = region.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, attrs.getDataPolicy());
    assertEquals(false, attrs.isDiskSynchronous());
    assertEquals("persistentDiskStore2", attrs.getDiskStoreName());

    // bug 41934
    String regionName_datap = "data-p";
    region = cache.getRegion(regionName_datap);
    assertNotNull(region);
    attrs = region.getAttributes();
    PartitionAttributes pa = attrs.getPartitionAttributes();
    assertEquals(1, pa.getRedundantCopies());
    assertEquals(3, pa.getTotalNumBuckets());
    assertEquals(DataPolicy.PERSISTENT_PARTITION, attrs.getDataPolicy());
  }

  @Test
  public void testBackupFiles() throws Exception {
    CacheCreation cache = new CacheCreation();
    File backup1 = new File("/back/me/up");
    File backup2 = new File("/me/too/please");
    cache.addBackup(backup1);
    cache.addBackup(backup2);
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(Arrays.asList(backup1, backup2), c.getBackupFiles());
  }

  @Test
  public void testClientCache() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    cache.setCopyOnRead(true);
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.getCopyOnRead());
    assertEquals(true, c.isClient());
    for (ClientRegionShortcut pra : ClientRegionShortcut.values()) {
      assertNotNull(c.getRegionAttributes(pra.name()));
    }
    assertEquals(ClientRegionShortcut.values().length, c.listRegionAttributes().size());
  }

  @Test
  public void testNormalCache() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setCopyOnRead(true);
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.getCopyOnRead());
    assertEquals(false, c.isClient());
    for (RegionShortcut pra : RegionShortcut.values()) {
      assertNotNull(c.getRegionAttributes(pra.name()));
    }
    assertEquals(RegionShortcut.values().length, c.listRegionAttributes().size());
  }

  @Test
  public void testPARTITION() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("partition", "PARTITION");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("partition");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
  }

  @Test
  public void testPARTITION_REDUNDANT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("rpartition", "PARTITION_REDUNDANT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("rpartition");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
  }

  @Test
  public void testPARTITION_PERSISTENT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("ppartition", "PARTITION_PERSISTENT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("ppartition");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
  }

  @Test
  public void testPARTITION_REDUNDANT_PERSISTENT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("prpartition", "PARTITION_REDUNDANT_PERSISTENT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("prpartition");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
  }

  @Test
  public void testPARTITION_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    ResourceManagerCreation rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(55.0f);
    rmc.setCriticalHeapPercentage(80.0f);
    cache.setResourceManagerCreation(rmc);
    RegionCreation root =
        (RegionCreation) cache.createRegion("partitionoverflow", "PARTITION_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("partitionoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(55.0f, c.getResourceManager().getEvictionHeapPercentage(), 0);
    assertEquals(80.0f, c.getResourceManager().getCriticalHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_REDUNDANT_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("rpartitionoverflow", "PARTITION_REDUNDANT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("rpartitionoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_PERSISTENT_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    ResourceManagerCreation rmc = new ResourceManagerCreation();
    rmc.setCriticalHeapPercentage(80.0f);
    cache.setResourceManagerCreation(rmc);
    RegionCreation root =
        (RegionCreation) cache.createRegion("ppartitionoverflow", "PARTITION_PERSISTENT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("ppartitionoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(80.0f, c.getResourceManager().getCriticalHeapPercentage(), 0);
    assertEquals(75.0f, c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_REDUNDANT_PERSISTENT_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    ResourceManagerCreation rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(0.0f); // test bug 42130
    cache.setResourceManagerCreation(rmc);
    RegionCreation root = (RegionCreation) cache.createRegion("prpartitionoverflow",
        "PARTITION_REDUNDANT_PERSISTENT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("prpartitionoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(0.0f, c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_HEAP_LRU() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("partitionlru", "PARTITION_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("partitionlru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_REDUNDANT_HEAP_LRU() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("rpartitionlru", "PARTITION_REDUNDANT_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("rpartitionlru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testREPLICATE() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("replicate", "REPLICATE");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("replicate");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
  }

  @Test
  public void testREPLICATE_PERSISTENT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("preplicate", "REPLICATE_PERSISTENT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("preplicate");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
  }

  @Test
  public void testREPLICATE_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("replicateoverflow", "REPLICATE_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("replicateoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testREPLICATE_PERSISTENT_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("preplicateoverflow", "REPLICATE_PERSISTENT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("preplicateoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testREPLICATE_HEAP_LRU() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("replicatelru", "REPLICATE_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("replicatelru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PRELOADED, ra.getDataPolicy());
    assertEquals(new SubscriptionAttributes(InterestPolicy.ALL), ra.getSubscriptionAttributes());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testLOCAL() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("local", "LOCAL");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("local");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
  }

  @Test
  public void testLOCAL_PERSISTENT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("plocal", "LOCAL_PERSISTENT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("plocal");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
  }

  @Test
  public void testLOCAL_HEAP_LRU() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("locallru", "LOCAL_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("locallru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testLOCAL_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("localoverflow", "LOCAL_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("localoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testLOCAL_PERSISTENT_OVERFLOW() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("cpolocal", "LOCAL_PERSISTENT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("cpolocal");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testPARTITION_PROXY() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("partitionProxy", "PARTITION_PROXY");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("partitionProxy");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(0, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(0, ra.getPartitionAttributes().getLocalMaxMemory());
  }

  @Test
  public void testPARTITION_PROXY_REDUNDANT() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("rpartitionProxy", "PARTITION_PROXY_REDUNDANT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("rpartitionProxy");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PARTITION, ra.getDataPolicy());
    assertNotNull(ra.getPartitionAttributes());
    assertEquals(1, ra.getPartitionAttributes().getRedundantCopies());
    assertEquals(0, ra.getPartitionAttributes().getLocalMaxMemory());
  }

  @Test
  public void testREPLICATE_PROXY() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("replicateProxy", "REPLICATE_PROXY");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    Region r = c.getRegion("replicateProxy");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.EMPTY, ra.getDataPolicy());
    assertEquals(Scope.DISTRIBUTED_ACK, ra.getScope());
  }

  @Test
  public void testPROXY() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("proxy", "PROXY");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("proxy");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.EMPTY, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals("DEFAULT", ra.getPoolName());
  }

  @Test
  public void testCACHING_PROXY() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("cproxy", "CACHING_PROXY");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("cproxy");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals("DEFAULT", ra.getPoolName());
  }

  @Test
  public void testCACHING_PROXY_HEAP_LRU() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("cproxylru", "CACHING_PROXY_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("cproxylru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals("DEFAULT", ra.getPoolName());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testCACHING_PROXY_OVERFLOW() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("cproxyoverflow", "CACHING_PROXY_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("cproxyoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals("DEFAULT", ra.getPoolName());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testClientLOCAL() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("local", "LOCAL");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("local");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(null, ra.getPoolName());
  }

  @Test
  public void testClientLOCAL_HEAP_LRU() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("locallru", "LOCAL_HEAP_LRU");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("locallru");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(null, ra.getPoolName());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(), ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testClientLOCAL_OVERFLOW() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("localoverflow", "LOCAL_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("localoverflow");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.NORMAL, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(null, ra.getPoolName());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  @Test
  public void testClientLOCAL_PERSISTENT() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root = (RegionCreation) cache.createRegion("cplocal", "LOCAL_PERSISTENT");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("cplocal");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(null, ra.getPoolName());
  }

  @Test
  public void testClientLOCAL_PERSISTENT_OVERFLOW() throws Exception {
    ClientCacheCreation cache = new ClientCacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("cpolocal", "LOCAL_PERSISTENT_OVERFLOW");
    testXml(cache);
    GemFireCacheImpl c = (GemFireCacheImpl) getCache();
    assertEquals(true, c.isClient());
    Region r = c.getRegion("cpolocal");
    assertNotNull(r);
    RegionAttributes ra = r.getAttributes();
    assertEquals(DataPolicy.PERSISTENT_REPLICATE, ra.getDataPolicy());
    assertEquals(Scope.LOCAL, ra.getScope());
    assertEquals(null, ra.getPoolName());
    assertEquals(EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK),
        ra.getEvictionAttributes());
    assertEquals(LocalRegion.DEFAULT_HEAPLRU_EVICTION_HEAP_PERCENTAGE,
        c.getResourceManager().getEvictionHeapPercentage(), 0);
  }

  /**
   * Tests that a partitioned region is created with FixedPartitionAttributes set programatically
   * and correct cache.xml is generated with the same FixedPartitionAttributes
   */
  @Test
  public void testFixedPartitioning() throws Exception {

    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation();
    FixedPartitionAttributes fpa1 = FixedPartitionAttributes.createFixedPartition("Q1");
    FixedPartitionAttributes fpa2 = FixedPartitionAttributes.createFixedPartition("Q2", true);
    FixedPartitionAttributes fpa3 = FixedPartitionAttributes.createFixedPartition("Q3", 3);
    FixedPartitionAttributes fpa4 = FixedPartitionAttributes.createFixedPartition("Q4", false, 3);
    List<FixedPartitionAttributes> fpattrsList = new ArrayList<>();
    fpattrsList.add(fpa1);
    fpattrsList.add(fpa2);
    fpattrsList.add(fpa3);
    fpattrsList.add(fpa4);

    QuarterPartitionResolver resolver = new QuarterPartitionResolver();

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(1).setPartitionResolver(resolver).addFixedPartitionAttributes(fpa1)
        .addFixedPartitionAttributes(fpa2).addFixedPartitionAttributes(fpa3)
        .addFixedPartitionAttributes(fpa4);

    attrs.setPartitionAttributes(paf.create());
    cache.createRegion("Quarter", attrs);
    Region r = cache.getRegion("Quarter");
    validateAttributes(r, fpattrsList, resolver, false);

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);
    Region region = c.getRegion("Quarter");
    assertNotNull(region);
    validateAttributes(region, fpattrsList, resolver, false);
  }

  @Test
  public void testFixedPartitioning_colocation_WithAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    FixedPartitionAttributes fpa1 = FixedPartitionAttributes.createFixedPartition("Q1");
    FixedPartitionAttributes fpa2 = FixedPartitionAttributes.createFixedPartition("Q2", true);
    FixedPartitionAttributes fpa3 = FixedPartitionAttributes.createFixedPartition("Q3", 3);
    FixedPartitionAttributes fpa4 = FixedPartitionAttributes.createFixedPartition("Q4", false, 3);
    List<FixedPartitionAttributes> fpattrsList = new ArrayList<>();
    fpattrsList.add(fpa1);
    fpattrsList.add(fpa2);
    fpattrsList.add(fpa3);
    fpattrsList.add(fpa4);
    QuarterPartitionResolver resolver = new QuarterPartitionResolver();
    Region customerRegion = null;
    Region orderRegion = null;

    {
      RegionAttributesCreation attrs = new RegionAttributesCreation();
      PartitionAttributesFactory paf = new PartitionAttributesFactory();
      paf.setRedundantCopies(1).setPartitionResolver(resolver).addFixedPartitionAttributes(fpa1)
          .addFixedPartitionAttributes(fpa2).addFixedPartitionAttributes(fpa3)
          .addFixedPartitionAttributes(fpa4);
      attrs.setPartitionAttributes(paf.create());
      cache.createRegion("Customer", attrs);
    }
    customerRegion = cache.getRegion("Customer");
    validateAttributes(customerRegion, fpattrsList, resolver, false);

    try {
      RegionAttributesCreation attrs = new RegionAttributesCreation();
      PartitionAttributesFactory paf = new PartitionAttributesFactory();
      paf.setRedundantCopies(1).setPartitionResolver(resolver).addFixedPartitionAttributes(fpa1)
          .addFixedPartitionAttributes(fpa2).addFixedPartitionAttributes(fpa3)
          .addFixedPartitionAttributes(fpa4).setColocatedWith("Customer");

      attrs.setPartitionAttributes(paf.create());
      cache.createRegion("Order", attrs);
      orderRegion = cache.getRegion("Order");
      validateAttributes(orderRegion, fpattrsList, resolver, true);
    } catch (Exception illegal) {
      // TODO: clean this expected exception up
      if (!((illegal instanceof IllegalStateException) && (illegal.getMessage()
          .contains("can not be specified in PartitionAttributesFactory")))) {
        Assert.fail("Expected IllegalStateException ", illegal);
      }

      RegionAttributesCreation attrs = new RegionAttributesCreation();
      PartitionAttributesFactory paf = new PartitionAttributesFactory();
      paf.setRedundantCopies(1).setPartitionResolver(resolver).setColocatedWith("Customer");

      attrs.setPartitionAttributes(paf.create());
      cache.createRegion("Order", attrs);
      orderRegion = cache.getRegion("Order");
      validateAttributes(orderRegion, fpattrsList, resolver, true);
    }

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);
    customerRegion = c.getRegion("Customer");
    assertNotNull(customerRegion);
    validateAttributes(customerRegion, fpattrsList, resolver, false);

    orderRegion = c.getRegion("Order");
    assertNotNull(orderRegion);
    validateAttributes(orderRegion, fpattrsList, resolver, true);
  }

  private void validateAttributes(Region region, List<FixedPartitionAttributes> fpattrsList,
      QuarterPartitionResolver resolver, boolean isColocated) {
    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertNotNull(pa.getPartitionResolver().getClass());
    assertEquals(pa.getPartitionResolver(), resolver);
    List<FixedPartitionAttributesImpl> fixedPartitionsList = pa.getFixedPartitionAttributes();
    if (isColocated) {
      assertNull(fixedPartitionsList);
      assertNotNull(pa.getColocatedWith());
    } else {
      assertNull(pa.getColocatedWith());
      assertEquals(fixedPartitionsList.size(), 4);
      assertEquals(fixedPartitionsList.containsAll(fpattrsList), true);
      for (FixedPartitionAttributes fpa : fixedPartitionsList) {
        if (fpa.getPartitionName().equals("Q1")) {
          assertEquals(fpa.getNumBuckets(), 1);
          assertEquals(fpa.isPrimary(), false);
        }
        if (fpa.getPartitionName().equals("Q2")) {
          assertEquals(fpa.getNumBuckets(), 1);
          assertEquals(fpa.isPrimary(), true);
        }
        if (fpa.getPartitionName().equals("Q3")) {
          assertEquals(fpa.getNumBuckets(), 3);
          assertEquals(fpa.isPrimary(), false);
        }
        if (fpa.getPartitionName().equals("Q4")) {
          assertEquals(fpa.getNumBuckets(), 3);
          assertEquals(fpa.isPrimary(), false);
        }
      }
    }
  }

  @Test
  public void testPdxDefaults() throws Exception {
    CacheCreation creation = new CacheCreation();
    testXml(creation);

    Cache c = getCache();
    assertTrue(c instanceof GemFireCacheImpl);
    c.loadCacheXml(generate(creation));

    assertEquals(null, c.getPdxDiskStore());
    assertEquals(null, c.getPdxSerializer());
    assertEquals(false, c.getPdxPersistent());
    assertEquals(false, c.getPdxReadSerialized());
    assertEquals(false, c.getPdxIgnoreUnreadFields());
  }

  @Test
  public void testPdxAttributes() throws Exception {
    CacheCreation creation = new CacheCreation();
    creation.setPdxPersistent(true);
    creation.setPdxReadSerialized(true);
    creation.setPdxIgnoreUnreadFields(true);
    creation.setPdxDiskStore("my_disk_store");
    TestPdxSerializer serializer = new TestPdxSerializer();
    Properties props = new Properties();
    props.setProperty("hello", "there");
    serializer.init(props);
    creation.setPdxSerializer(serializer);
    testXml(creation);

    Cache c = getCache();
    assertTrue(c instanceof GemFireCacheImpl);
    c.loadCacheXml(generate(creation));

    assertEquals("my_disk_store", c.getPdxDiskStore());
    assertEquals(serializer, c.getPdxSerializer());
    assertEquals(true, c.getPdxPersistent());
    assertEquals(true, c.getPdxReadSerialized());
    assertEquals(true, c.getPdxIgnoreUnreadFields());

    // test that we can override the cache.xml attributes
    {
      closeCache();
      CacheFactory cf = new CacheFactory();
      cf.setPdxDiskStore("new disk store");
      c = getCache(cf);
      assertTrue(c instanceof GemFireCacheImpl);
      c.loadCacheXml(generate(creation));

      assertEquals("new disk store", c.getPdxDiskStore());
      assertEquals(serializer, c.getPdxSerializer());
      assertEquals(true, c.getPdxPersistent());
      assertEquals(true, c.getPdxReadSerialized());
      assertEquals(true, c.getPdxIgnoreUnreadFields());
    }

    {
      closeCache();
      CacheFactory cf = new CacheFactory();
      cf.setPdxPersistent(false);
      cf.setPdxIgnoreUnreadFields(false);
      c = getCache(cf);
      assertTrue(c instanceof GemFireCacheImpl);
      c.loadCacheXml(generate(creation));

      assertEquals("my_disk_store", c.getPdxDiskStore());
      assertEquals(serializer, c.getPdxSerializer());
      assertEquals(false, c.getPdxPersistent());
      assertEquals(true, c.getPdxReadSerialized());
      assertEquals(false, c.getPdxIgnoreUnreadFields());
    }

    {
      closeCache();
      CacheFactory cf = new CacheFactory();
      cf.setPdxSerializer(null);
      c = getCache(cf);
      assertTrue(c instanceof GemFireCacheImpl);
      c.loadCacheXml(generate(creation));

      assertEquals("my_disk_store", c.getPdxDiskStore());
      assertEquals(null, c.getPdxSerializer());
      assertEquals(true, c.getPdxPersistent());
      assertEquals(true, c.getPdxReadSerialized());
      assertEquals(true, c.getPdxIgnoreUnreadFields());
    }

    {
      closeCache();
      CacheFactory cf = new CacheFactory();
      cf.setPdxReadSerialized(false);
      c = getCache(cf);
      assertTrue(c instanceof GemFireCacheImpl);
      c.loadCacheXml(generate(creation));

      assertEquals("my_disk_store", c.getPdxDiskStore());
      assertEquals(serializer, c.getPdxSerializer());
      assertEquals(true, c.getPdxPersistent());
      assertEquals(false, c.getPdxReadSerialized());
      assertEquals(true, c.getPdxIgnoreUnreadFields());
    }

  }

  @Test
  public void testTXManagerOnClientCache() throws Exception {
    ClientCacheCreation cc = new ClientCacheCreation();
    // CacheCreation cc = new CacheCreation();
    CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
    txMgrCreation.addListener(new TestTXListener());
    cc.addCacheTransactionManagerCreation(txMgrCreation);
    testXml(cc);

    Cache c = getCache();
    assertTrue(c instanceof ClientCache);
    c.loadCacheXml(generate(cc));

    ClientCache clientC = (ClientCache) c;
    CacheTransactionManager mgr = clientC.getCacheTransactionManager();
    assertNotNull(mgr);
    assertTrue(mgr.getListeners()[0] instanceof TestTXListener);

  }

  @Test
  public void testNoTXWriterOnClient() throws Exception {
    // test writer is not created
    ClientCacheCreation cc = new ClientCacheCreation();
    CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
    txMgrCreation.setWriter(new TestTransactionWriter());
    cc.addCacheTransactionManagerCreation(txMgrCreation);
    IgnoredException expectedException =
        addIgnoredException("A TransactionWriter cannot be registered on a client");
    try {
      testXml(cc);
      fail("expected exception not thrown");
    } catch (IllegalStateException ignored) {
    } finally {
      expectedException.remove();
    }
  }

  public static class TestTXListener extends TransactionListenerAdapter implements Declarable {
    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object other) {
      return other instanceof TestTXListener;
    }
  }

  /**
   * Tests that a region created with a named attributes set programmatically for delta propogation
   * has the correct attributes.
   */
  @Test
  public void testRegionAttributesForRegionEntryCloning() throws Exception {
    final String rNameBase = getUniqueName();
    final String r1 = rNameBase + "1";

    // Setting multi-cast via nested region attributes
    CacheCreation creation = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.LOCAL);
    attrs.setEarlyAck(false);
    attrs.setCloningEnable(false);
    attrs.setMulticastEnabled(true);
    creation.createRegion(r1, attrs);

    testXml(creation);

    Cache c = getCache();
    assertTrue(c instanceof GemFireCacheImpl);
    c.loadCacheXml(generate(creation));

    Region reg1 = c.getRegion(r1);
    assertNotNull(reg1);
    assertEquals(Scope.LOCAL, reg1.getAttributes().getScope());
    assertFalse(reg1.getAttributes().getEarlyAck());
    assertTrue(reg1.getAttributes().getMulticastEnabled());
    assertFalse(reg1.getAttributes().getCloningEnabled());

    // changing Clonned setting
    reg1.getAttributesMutator().setCloningEnabled(true);
    assertTrue(reg1.getAttributes().getCloningEnabled());

    reg1.getAttributesMutator().setCloningEnabled(false);
    assertFalse(reg1.getAttributes().getCloningEnabled());

    // for sub region - a child attribute should be inherited
    String sub = "subRegion";
    RegionAttributesCreation attrsSub = new RegionAttributesCreation(creation);
    attrsSub.setScope(Scope.LOCAL);
    reg1.createSubregion(sub, attrsSub);
    Region subRegion = reg1.getSubregion(sub);
    assertFalse(subRegion.getAttributes().getCloningEnabled());
    subRegion.getAttributesMutator().setCloningEnabled(true);
    assertTrue(subRegion.getAttributes().getCloningEnabled());
  }

  /**
   * Tests that a region created with a named attributes set programatically for recovery-delay has
   * the correct attributes.
   */
  @Test
  public void testRecoveryDelayAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(1);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);
    paf.setRecoveryDelay(33);
    paf.setStartupRecoveryDelay(270);

    attrs.setPartitionAttributes(paf.create());

    cache.createRegion("parRoot", attrs);

    Region r = cache.getRegion("parRoot");
    assertEquals(r.getAttributes().getPartitionAttributes().getRedundantCopies(), 1);
    assertEquals(r.getAttributes().getPartitionAttributes().getLocalMaxMemory(), 100);
    assertEquals(r.getAttributes().getPartitionAttributes().getTotalMaxMemory(), 500);
    assertEquals(33, r.getAttributes().getPartitionAttributes().getRecoveryDelay());
    assertEquals(270, r.getAttributes().getPartitionAttributes().getStartupRecoveryDelay());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);
    assertEquals(33, r.getAttributes().getPartitionAttributes().getRecoveryDelay());
    assertEquals(270, r.getAttributes().getPartitionAttributes().getStartupRecoveryDelay());
  }

  /**
   * Tests that a region created with a named attributes set programmatically for recovery-delay has
   * the correct attributes.
   */
  @Test
  public void testDefaultRecoveryDelayAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(1);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);
    attrs.setPartitionAttributes(paf.create());

    cache.createRegion("parRoot", attrs);

    Region r = cache.getRegion("parRoot");
    assertEquals(r.getAttributes().getPartitionAttributes().getRedundantCopies(), 1);
    assertEquals(r.getAttributes().getPartitionAttributes().getLocalMaxMemory(), 100);
    assertEquals(r.getAttributes().getPartitionAttributes().getTotalMaxMemory(), 500);
    assertEquals(-1, r.getAttributes().getPartitionAttributes().getRecoveryDelay());
    assertEquals(0, r.getAttributes().getPartitionAttributes().getStartupRecoveryDelay());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);
    assertEquals(-1, r.getAttributes().getPartitionAttributes().getRecoveryDelay());
    assertEquals(0, r.getAttributes().getPartitionAttributes().getStartupRecoveryDelay());
  }

  /**
   * Test the ResourceManager element's critical-heap-percentage and eviction-heap-percentage
   * attributes
   */
  @Test
  public void testResourceManagerThresholds() throws Exception {
    CacheCreation cache = new CacheCreation();
    final float low = 90.0f;
    final float high = 95.0f;

    Cache c;
    ResourceManagerCreation rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(low);
    rmc.setCriticalHeapPercentage(high);
    cache.setResourceManagerCreation(rmc);
    testXml(cache);
    {
      c = getCache();
      assertEquals(low, c.getResourceManager().getEvictionHeapPercentage(), 0);
      assertEquals(high, c.getResourceManager().getCriticalHeapPercentage(), 0);
    }
    closeCache();

    rmc = new ResourceManagerCreation();
    // Set them to similar values
    rmc.setEvictionHeapPercentage(low);
    rmc.setCriticalHeapPercentage(low + 1);
    cache.setResourceManagerCreation(rmc);
    testXml(cache);
    {
      c = getCache();
      assertEquals(low, c.getResourceManager().getEvictionHeapPercentage(), 0);
      assertEquals(low + 1, c.getResourceManager().getCriticalHeapPercentage(), 0);
    }
    closeCache();

    rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(high);
    rmc.setCriticalHeapPercentage(low);
    cache.setResourceManagerCreation(rmc);
    IgnoredException expectedException = addIgnoredException(
        "Eviction percentage must be less than the critical percentage.");
    try {
      testXml(cache);
      assertTrue(false);
    } catch (IllegalArgumentException ignored) {
    } finally {
      expectedException.remove();
      closeCache();
    }

    // Disable eviction
    rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(0);
    rmc.setCriticalHeapPercentage(low);
    cache.setResourceManagerCreation(rmc);
    testXml(cache);
    {
      c = getCache();
      assertEquals(0f, c.getResourceManager().getEvictionHeapPercentage(), 0);
      assertEquals(low, c.getResourceManager().getCriticalHeapPercentage(), 0);
    }
    closeCache();

    // Disable refusing ops in "red zone"
    rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(low);
    rmc.setCriticalHeapPercentage(0);
    cache.setResourceManagerCreation(rmc);
    testXml(cache);
    {
      c = getCache();
      assertEquals(low, c.getResourceManager().getEvictionHeapPercentage(), 0);
      assertEquals(0f, c.getResourceManager().getCriticalHeapPercentage(), 0);
    }
    closeCache();

    // Disable both
    rmc = new ResourceManagerCreation();
    rmc.setEvictionHeapPercentage(0);
    rmc.setCriticalHeapPercentage(0);
    cache.setResourceManagerCreation(rmc);
    testXml(cache);
    c = getCache();
    assertEquals(0f, c.getResourceManager().getEvictionHeapPercentage(), 0);
    assertEquals(0f, c.getResourceManager().getCriticalHeapPercentage(), 0);
  }

  // A bunch of classes for use in testing the serialization schtuff
  public static class DS1 implements DataSerializable {
    @Override
    public void fromData(DataInput in) {}

    @Override
    public void toData(DataOutput out) {}
  }

  public static class DS2 implements DataSerializable {
    @Override
    public void fromData(DataInput in) {}

    @Override
    public void toData(DataOutput out) {}
  }

  public static class NotDataSerializable implements Serializable {
  }

  public static class GoodSerializer extends DataSerializer {
    public GoodSerializer() {}

    @Override
    public Object fromData(DataInput in) {
      return null;
    }

    @Override
    public int getId() {
      return 101;
    }

    @Override
    public Class[] getSupportedClasses() {
      return new Class[] {DS1.class};
    }

    @Override
    public boolean toData(Object o, DataOutput out) {
      return false;
    }
  }

  public static class BadSerializer extends DataSerializer {
    @Override
    public Object fromData(DataInput in) {
      return null;
    }

    @Override
    public int getId() {
      return 101;
    }

    @Override
    public Class[] getSupportedClasses() {
      return null;
    }

    @Override
    public boolean toData(Object o, DataOutput out) {
      return false;
    }
  }

  @Test
  public void testSerializationRegistration() throws Exception {
    CacheCreation cc = new CacheCreation();
    SerializerCreation sc = new SerializerCreation();

    cc.setSerializerCreation(sc);

    sc.registerInstantiator(DS1.class, 15);
    sc.registerInstantiator(DS2.class, 16);
    sc.registerSerializer(GoodSerializer.class);

    testXml(cc);

    // Now make sure all of the classes were registered....
    assertEquals(15, InternalInstantiator.getClassId(DS1.class));
    assertEquals(16, InternalInstantiator.getClassId(DS2.class));
    assertEquals(GoodSerializer.class, InternalDataSerializer.getSerializer(101).getClass());

    sc = new SerializerCreation();
    sc.registerInstantiator(NotDataSerializable.class, 15);
    closeCache();
    cc.setSerializerCreation(sc);

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      testXml(cc);
      fail("Instantiator should not have registered due to bad class.");
    } catch (Exception ignored) {
    } finally {
      expectedException.remove();
    }

    sc = new SerializerCreation();
    sc.registerSerializer(BadSerializer.class);
    closeCache();
    cc.setSerializerCreation(sc);

    IgnoredException expectedException1 =
        addIgnoredException("While reading Cache XML file");
    try {
      testXml(cc);
      fail("Serializer should not have registered due to bad class.");
    } catch (Exception ignored) {
    } finally {
      expectedException1.remove();
    }
  }

  /**
   * Tests that a region created with a named attributes set programmatically for partition-resolver
   * has the correct attributes.
   */
  @Test
  public void testPartitionedRegionAttributesForCustomPartitioning() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    CacheXMLPartitionResolver partitionResolver = new CacheXMLPartitionResolver();
    Properties params = new Properties();
    params.setProperty("initial-index-value", "1000");
    params.setProperty("secondary-index-value", "5000");
    partitionResolver.init(params);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(1);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);
    paf.setPartitionResolver(partitionResolver);

    attrs.setPartitionAttributes(paf.create());

    cache.createRegion("parRoot", attrs);

    Region r = cache.getRegion("parRoot");
    assertEquals(r.getAttributes().getPartitionAttributes().getRedundantCopies(), 1);
    assertEquals(r.getAttributes().getPartitionAttributes().getLocalMaxMemory(), 100);
    assertEquals(r.getAttributes().getPartitionAttributes().getTotalMaxMemory(), 500);
    assertEquals(r.getAttributes().getPartitionAttributes().getPartitionResolver(),
        partitionResolver);

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);
    assertNotNull(pa.getPartitionResolver().getClass());
    assertEquals(pa.getPartitionResolver(), partitionResolver);
  }

  /**
   * Tests that a cache created with FunctionService and registered functions has correct registered
   * functions.
   */
  @Test
  public void testCacheCreationWithFunctionService() throws Exception {
    CacheCreation cache = new CacheCreation();
    FunctionServiceCreation fsc = new FunctionServiceCreation();
    TestFunction function1 = new TestFunction(true, TestFunction.TEST_FUNCTION2);
    TestFunction function2 = new TestFunction(true, TestFunction.TEST_FUNCTION3);
    TestFunction function3 = new TestFunction(true, TestFunction.TEST_FUNCTION4);
    fsc.registerFunction(function1);
    fsc.registerFunction(function2);
    fsc.registerFunction(function3);
    fsc.create();
    cache.setFunctionServiceCreation(fsc);

    testXml(cache);
    getCache();
    Map<String, Function> functionIdMap = FunctionService.getRegisteredFunctions();
    assertEquals(3, functionIdMap.size());

    assertTrue(function1.equals(functionIdMap.get(function1.getId())));
    assertTrue(function2.equals(functionIdMap.get(function2.getId())));
    assertTrue(function3.equals(functionIdMap.get(function3.getId())));
  }

  /**
   * Tests that a Partitioned Region can be created with a named attributes set programmatically for
   * ExpirationAttributes
   */
  @Test
  public void testPartitionedRegionAttributesForExpiration() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setStatisticsEnabled(true);
    RegionAttributes rootAttrs = null;
    ExpirationAttributes expiration = new ExpirationAttributes(60, ExpirationAction.DESTROY);

    CacheXMLPartitionResolver partitionResolver = new CacheXMLPartitionResolver();
    Properties params = new Properties();
    params.setProperty("initial-index-value", "1000");
    params.setProperty("secondary-index-value", "5000");
    partitionResolver.init(params);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(1);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);
    paf.setPartitionResolver(partitionResolver);

    AttributesFactory fac = new AttributesFactory(attrs);
    fac.setEntryTimeToLive(expiration);
    fac.setEntryIdleTimeout(expiration);

    fac.setPartitionAttributes(paf.create());
    rootAttrs = fac.create();
    cache.createRegion("parRoot", rootAttrs);

    Region r = cache.getRegion("parRoot");
    assertNotNull(r);
    assertEquals(r.getAttributes().getPartitionAttributes().getRedundantCopies(), 1);
    assertEquals(r.getAttributes().getPartitionAttributes().getLocalMaxMemory(), 100);
    assertEquals(r.getAttributes().getPartitionAttributes().getTotalMaxMemory(), 500);
    assertEquals(r.getAttributes().getPartitionAttributes().getPartitionResolver(),
        partitionResolver);

    assertEquals(r.getAttributes().getEntryIdleTimeout().getTimeout(), expiration.getTimeout());
    assertEquals(r.getAttributes().getEntryTimeToLive().getTimeout(), expiration.getTimeout());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);
    assertNotNull(pa.getPartitionResolver().getClass());
    assertEquals(pa.getPartitionResolver(), partitionResolver);

    assertEquals(regionAttrs.getEntryIdleTimeout().getTimeout(), expiration.getTimeout());
    assertEquals(regionAttrs.getEntryTimeToLive().getTimeout(), expiration.getTimeout());
  }

  /**
   * Tests that a Partitioned Region can be created with a named attributes set programmatically for
   * ExpirationAttributes
   */
  @Test
  public void testPartitionedRegionAttributesForEviction() throws Exception {
    final int redundantCopies = 1;
    CacheCreation cache = new CacheCreation();
    if (getGemFireVersion().equals(CacheXml.VERSION_6_0)) {
      ResourceManagerCreation rm = new ResourceManagerCreation();
      rm.setCriticalHeapPercentage(95);
      cache.setResourceManagerCreation(rm);
    }
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setStatisticsEnabled(true);
    RegionAttributes rootAttrs = null;

    ExpirationAttributes expiration = new ExpirationAttributes(60, ExpirationAction.DESTROY);

    CacheXMLPartitionResolver partitionResolver = new CacheXMLPartitionResolver();
    Properties params = new Properties();
    params.setProperty("initial-index-value", "1000");
    params.setProperty("secondary-index-value", "5000");
    partitionResolver.init(params);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(redundantCopies);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);
    paf.setPartitionResolver(partitionResolver);

    AttributesFactory fac = new AttributesFactory(attrs);

    // TODO: Move test back to using LRUHeap when config issues have settled
    // if (getGemFireVersion().equals(CacheXml.GEMFIRE_6_0)) {
    // fac.setEvictionAttributes(EvictionAttributes.createLRUHeapAttributes(null,
    // EvictionAction.OVERFLOW_TO_DISK));
    // } else {
    fac.setEvictionAttributes(
        EvictionAttributes.createLRUMemoryAttributes(100, null, EvictionAction.OVERFLOW_TO_DISK));
    // }

    fac.setEntryTimeToLive(expiration);
    fac.setEntryIdleTimeout(expiration);

    DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
    dwaf.setSynchronous(true);

    fac.setPartitionAttributes(paf.create());
    rootAttrs = fac.create();
    cache.createRegion("parRoot", rootAttrs);

    Region r = cache.getRegion("parRoot");
    assertNotNull(r);
    assertEquals(r.getAttributes().getPartitionAttributes().getRedundantCopies(), redundantCopies);
    assertEquals(r.getAttributes().getPartitionAttributes().getLocalMaxMemory(), 100);
    assertEquals(r.getAttributes().getPartitionAttributes().getTotalMaxMemory(), 500);
    assertEquals(r.getAttributes().getPartitionAttributes().getPartitionResolver(),
        partitionResolver);

    assertEquals(r.getAttributes().getEntryIdleTimeout().getTimeout(), expiration.getTimeout());
    assertEquals(r.getAttributes().getEntryTimeToLive().getTimeout(), expiration.getTimeout());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();
    EvictionAttributes ea = regionAttrs.getEvictionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);
    assertNotNull(pa.getPartitionResolver().getClass());
    assertEquals(pa.getPartitionResolver(), partitionResolver);

    assertEquals(regionAttrs.getEntryIdleTimeout().getTimeout(), expiration.getTimeout());
    assertEquals(regionAttrs.getEntryTimeToLive().getTimeout(), expiration.getTimeout());
    // TODO: Move test back to using LRUHeap when config issues have settled
    // if (getGemFireVersion().equals(CacheXml.GEMFIRE_6_0)) {
    // assertIndexDetailsEquals(ea.getAlgorithm(),EvictionAlgorithm.LRU_HEAP);
    // } else {
    assertEquals(ea.getAlgorithm(), EvictionAlgorithm.LRU_MEMORY);
    // }
    assertEquals(ea.getAction(), EvictionAction.OVERFLOW_TO_DISK);
  }

  @Test
  public void testPartitionedRegionAttributesForCoLocation() throws Exception {
    closeCache();
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation custAttrs = new RegionAttributesCreation(cache);
    RegionAttributesCreation orderAttrs = new RegionAttributesCreation(cache);
    PartitionAttributesFactory custPaf = new PartitionAttributesFactory();
    PartitionAttributesFactory orderPaf = new PartitionAttributesFactory();
    custPaf.setRedundantCopies(1);
    custPaf.setTotalMaxMemory(500);
    custPaf.setLocalMaxMemory(100);
    custAttrs.setPartitionAttributes(custPaf.create());
    cache.createRegion("Customer", custAttrs);

    orderPaf.setRedundantCopies(1);
    orderPaf.setTotalMaxMemory(500);
    orderPaf.setLocalMaxMemory(100);
    orderPaf.setColocatedWith("Customer");
    orderAttrs.setPartitionAttributes(orderPaf.create());
    cache.createRegion("Order", orderAttrs);

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region cust = c.getRegion(SEPARATOR + "Customer");
    assertNotNull(cust);
    Region order = c.getRegion(SEPARATOR + "Order");
    assertNotNull(order);
    String coLocatedRegion = order.getAttributes().getPartitionAttributes().getColocatedWith();
    assertEquals("Customer", coLocatedRegion);
  }

  @Test
  public void testPartitionedRegionAttributesForCoLocation2() throws Exception {
    closeCache();
    setXmlFile(findFile("coLocation.xml"));
    Cache c = getCache();
    assertNotNull(c);
    Region cust = c.getRegion(SEPARATOR + "Customer");
    assertNotNull(cust);
    Region order = c.getRegion(SEPARATOR + "Order");
    assertNotNull(order);

    assertTrue(cust.getAttributes().getPartitionAttributes().getColocatedWith() == null);
    assertTrue(
        order.getAttributes().getPartitionAttributes().getColocatedWith().equals("Customer"));
  }

  @Test
  public void testPartitionedRegionAttributesForMemLruWithoutMaxMem() throws Exception {
    final int redundantCopies = 1;
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setStatisticsEnabled(true);
    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(redundantCopies);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);

    AttributesFactory fac = new AttributesFactory(attrs);
    fac.setEvictionAttributes(
        EvictionAttributes.createLRUMemoryAttributes(null, EvictionAction.LOCAL_DESTROY));
    fac.setPartitionAttributes(paf.create());
    cache.createRegion("parRoot", fac.create());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();
    EvictionAttributes ea = regionAttrs.getEvictionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);

    assertEquals(ea.getAlgorithm(), EvictionAlgorithm.LRU_MEMORY);
    assertEquals(ea.getAction(), EvictionAction.LOCAL_DESTROY);
    assertEquals(ea.getMaximum(), pa.getLocalMaxMemory());
  }

  @Test
  public void testPartitionedRegionAttributesForMemLruWithMaxMem() throws Exception {
    final int redundantCopies = 1;
    final int maxMem = 25;
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setStatisticsEnabled(true);
    PartitionAttributesFactory paf = new PartitionAttributesFactory();
    paf.setRedundantCopies(redundantCopies);
    paf.setTotalMaxMemory(500);
    paf.setLocalMaxMemory(100);

    AttributesFactory fac = new AttributesFactory(attrs);
    fac.setEvictionAttributes(
        EvictionAttributes.createLRUMemoryAttributes(maxMem, null, EvictionAction.LOCAL_DESTROY));
    fac.setPartitionAttributes(paf.create());
    cache.createRegion("parRoot", fac.create());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    PartitionAttributes pa = regionAttrs.getPartitionAttributes();
    EvictionAttributes ea = regionAttrs.getEvictionAttributes();

    assertEquals(pa.getRedundantCopies(), 1);
    assertEquals(pa.getLocalMaxMemory(), 100);
    assertEquals(pa.getTotalMaxMemory(), 500);

    assertEquals(ea.getAlgorithm(), EvictionAlgorithm.LRU_MEMORY);
    assertEquals(ea.getAction(), EvictionAction.LOCAL_DESTROY);
    assertNotSame(ea.getMaximum(), maxMem);
    assertEquals(ea.getMaximum(), pa.getLocalMaxMemory());
  }

  @Test
  public void testReplicatedRegionAttributesForMemLruWithoutMaxMem() throws Exception {
    final int redundantCopies = 1;
    CacheCreation cache = new CacheCreation();

    AttributesFactory fac = new AttributesFactory();
    fac.setDataPolicy(DataPolicy.REPLICATE);
    fac.setEvictionAttributes(
        EvictionAttributes.createLRUMemoryAttributes(null, EvictionAction.OVERFLOW_TO_DISK));
    cache.createRegion("parRoot", fac.create());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    EvictionAttributes ea = regionAttrs.getEvictionAttributes();

    assertEquals(ea.getAlgorithm(), EvictionAlgorithm.LRU_MEMORY);
    assertEquals(ea.getAction(), EvictionAction.OVERFLOW_TO_DISK);
    assertEquals(ea.getMaximum(), EvictionAttributes.DEFAULT_MEMORY_MAXIMUM);
  }

  @Test
  public void testReplicatedRegionAttributesForMemLruWithMaxMem() throws Exception {
    final int redundantCopies = 1;
    final int maxMem = 25;
    CacheCreation cache = new CacheCreation();

    AttributesFactory fac = new AttributesFactory();
    fac.setDataPolicy(DataPolicy.REPLICATE);
    fac.setEvictionAttributes(EvictionAttributes.createLRUMemoryAttributes(maxMem, null,
        EvictionAction.OVERFLOW_TO_DISK));
    cache.createRegion("parRoot", fac.create());

    testXml(cache);

    Cache c = getCache();
    assertNotNull(c);

    Region region = c.getRegion("parRoot");
    assertNotNull(region);

    RegionAttributes regionAttrs = region.getAttributes();
    EvictionAttributes ea = regionAttrs.getEvictionAttributes();
    assertEquals(ea.getAlgorithm(), EvictionAlgorithm.LRU_MEMORY);
    assertEquals(ea.getAction(), EvictionAction.OVERFLOW_TO_DISK);
    assertEquals(ea.getMaximum(), maxMem);
  }

  /**
   * Tests the groups subelement on bridge-server.
   */
  @Test
  public void testDefaultCacheServerGroups() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    bs.setGroups(CacheServer.DEFAULT_GROUPS);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(CacheServer.DEFAULT_GROUPS, server.getGroups());
  }

  @Test
  public void testOneCacheServerGroups() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    String[] groups = new String[] {"group1"};
    bs.setGroups(groups);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(Arrays.asList(groups), Arrays.asList(server.getGroups()));
  }

  @Test
  public void testTwoCacheServerGroups() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    String[] groups = new String[] {"group1", "group2"};
    bs.setGroups(groups);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(Arrays.asList(groups), Arrays.asList(server.getGroups()));
  }

  @Test
  public void testDefaultCacheServerBindAddress() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(CacheServer.DEFAULT_BIND_ADDRESS, server.getBindAddress());
  }

  @Test
  public void testCacheServerBindAddress() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    final String BA = ALIAS1;
    bs.setBindAddress(BA);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(BA, server.getBindAddress());
  }

  @Test
  public void testCacheServerHostnameForClients() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer bs = cache.addCacheServer();
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    final String BA = ALIAS1;
    bs.setBindAddress(BA);
    bs.setHostnameForClients("clientHostName");
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(BA, server.getBindAddress());
    assertEquals("clientHostName", server.getHostnameForClients());
  }

  @Test
  public void testTwoConnectionPools() throws Exception {
    getSystem();
    CacheCreation cache = new CacheCreation();
    PoolFactory f = cache.createPoolFactory();
    f.addLocator(ALIAS2, 3777).create("mypool");
    f.reset().addLocator(ALIAS1, 3888).create("mypool2");
    try {
      f.create("mypool");
      fail("expected IllegalStateException");
    } catch (IllegalStateException ignored) {
    }
    try {
      f.create("mypool2");
      fail("expected IllegalStateException");
    } catch (IllegalStateException ignored) {
    }
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setPoolName("mypool");
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    Region r = c.getRegion("rootNORMAL");
    assertNotNull(r);
    assertEquals("mypool", r.getAttributes().getPoolName());
    Pool cp = PoolManager.find("mypool");
    assertNotNull(cp);
    assertEquals(0, cp.getServers().size());
    assertEquals(1, cp.getLocators().size());
    assertEquals(createINSA(ALIAS2, 3777), cp.getLocators().get(0));
    cp = PoolManager.find("mypool2");
    assertNotNull(cp);
    assertEquals(0, cp.getServers().size());
    assertEquals(1, cp.getLocators().size());
    assertEquals(createINSA(ALIAS1, 3888), cp.getLocators().get(0));
  }

  @Test
  public void testNoConnectionPools() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setPoolName("mypool");
    cache.createVMRegion("rootNORMAL", attrs);
    IgnoredException expectedException = addIgnoredException(
        String.format("The connection pool %s has not been created",
            "mypool"));
    try {
      testXml(cache);
      fail("expected IllegalStateException");
    } catch (IllegalStateException ignored) {
    } finally {
      expectedException.remove();
    }
  }

  @Test
  public void testAlreadyExistingPool() throws Exception {
    getSystem();
    PoolFactoryImpl f = (PoolFactoryImpl) PoolManager.createFactory();
    f.setStartDisabled(true).addLocator(ALIAS2, 12345).create("mypool");
    try {
      // now make sure declarative cache can't create the same pool
      CacheCreation cache = new CacheCreation();
      cache.createPoolFactory().addLocator(ALIAS2, 12345).create("mypool");
      IgnoredException expectedException = addIgnoredException(
          String.format("A pool named %s already exists", "mypool"));
      try {
        testXml(cache);
        fail("expected IllegalStateException");
      } catch (IllegalStateException ignored) {
      } finally {
        expectedException.remove();
      }
    } finally {
      PoolManager.close();
    }
  }

  @Test
  public void testDynamicRegionFactoryConnectionPool() throws Exception {
    addIgnoredException("Connection reset");
    addIgnoredException("SocketTimeoutException");
    addIgnoredException("ServerConnectivityException");
    addIgnoredException("Socket Closed");
    getSystem();
    VM vm0 = Host.getHost(0).getVM(0);
    final int port = getRandomAvailableTCPPort();
    vm0.invoke(new SerializableCallable("Create cache server") {
      @Override
      public Object call() throws IOException {
        DynamicRegionFactory.get().open();
        Cache cache = getCache();
        CacheServer bridge = cache.addCacheServer();
        bridge.setPort(port);
        bridge.setNotifyBySubscription(true);
        bridge.start();
        return null;
      }
    });
    CacheCreation cache = new CacheCreation();
    cache.createPoolFactory().addServer(NetworkUtils.getServerHostName(vm0.getHost()), port)
        .setSubscriptionEnabled(true).create("connectionPool");
    cache.setDynamicRegionFactoryConfig(
        new DynamicRegionFactory.Config(null, "connectionPool", false, false));
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    cache.createRegion("root", attrs);
    // note that testXml can't check if they are same because enabling
    // dynamic regions causes a meta region to be produced.
    testXml(cache, false);
    assertEquals(false, DynamicRegionFactory.get().getConfig().getRegisterInterest());
    assertEquals(false, DynamicRegionFactory.get().getConfig().getPersistBackup());
    assertEquals(true, DynamicRegionFactory.get().isOpen());
    assertEquals(null, DynamicRegionFactory.get().getConfig().getDiskDir());
    assertEquals("connectionPool", DynamicRegionFactory.get().getConfig().getPoolName());
    Region dr = getCache().getRegion("__DynamicRegions");
    if (dr != null) {
      dr.localDestroyRegion();
    }
  }

  /**
   * Tests the client subscription attributes ({@code eviction-policy}, {@code capacity} and
   * {@code overflow-directory}) related to client subscription config in gemfire cache-server
   * framework
   *
   * @since GemFire 5.7
   */
  @Test
  public void testBridgeAttributesRelatedToHAOverFlow() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setMessageSyncInterval(3445);
    CacheServer bs = cache.addCacheServer();
    ClientSubscriptionConfig csc = bs.getClientSubscriptionConfig();
    csc.setEvictionPolicy("entry");
    cache.getLogger().config("EvictionPolicy : " + csc.getEvictionPolicy());
    csc.setCapacity(501);
    cache.getLogger().config("EvictionCapacity : " + csc.getCapacity());
    csc.setOverflowDirectory("overFlow");
    cache.getLogger().config("EvictionOverflowDirectory : " + csc.getOverflowDirectory());
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    ClientSubscriptionConfig chaqf = server.getClientSubscriptionConfig();
    assertEquals("entry", chaqf.getEvictionPolicy());
    assertEquals(501, chaqf.getCapacity());
    assertEquals("overFlow", chaqf.getOverflowDirectory());
  }

  @Test
  public void testBridgeLoadProbe() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer server = cache.addCacheServer();
    server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    server.setLoadProbe(new MyLoadProbe());

    testXml(cache);

    Cache c = getCache();
    server = c.getCacheServers().get(0);
    assertEquals(MyLoadProbe.class, server.getLoadProbe().getClass());
  }

  @Test
  public void testLoadPollInterval() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheServer server = cache.addCacheServer();
    server.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    server.setLoadPollInterval(12345);

    testXml(cache);

    Cache c = getCache();
    server = c.getCacheServers().get(0);
    assertEquals(12345, server.getLoadPollInterval());
  }

  public static class MyLoadProbe extends ServerLoadProbeAdapter implements Declarable {
    @Override
    public ServerLoad getLoad(ServerMetrics metrics) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MyLoadProbe;
    }
  }

  public static class Expiry1 implements CustomExpiry, Declarable {
    @Override
    public ExpirationAttributes getExpiry(Entry entry) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public void close() {}
  }

  public static class Expiry2 implements CustomExpiry, Declarable {
    @Override
    public ExpirationAttributes getExpiry(Entry entry) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public void close() {}
  }

  public static class Expiry3 implements CustomExpiry, Declarable {
    @Override
    public ExpirationAttributes getExpiry(Entry entry) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public void close() {}
  }

  public static class Expiry4 implements CustomExpiry, Declarable {
    @Override
    public ExpirationAttributes getExpiry(Entry entry) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public void close() {}
  }

  public static class Expiry5 implements CustomExpiry, Declarable2 {
    @Override
    public ExpirationAttributes getExpiry(Entry entry) {
      return null;
    }

    @Override
    public void init(Properties props) {}

    @Override
    public void close() {}

    @Override
    public Properties getConfig() {
      Properties p = new Properties();
      p.put("prop1", "val1");
      p.put("prop2", "val2");
      return p;
    }
  }

  /**
   * Test both customEntryIdleTime and customEntryTimeToLife
   */
  @Test
  public void testCustomEntryXml() throws Exception {
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_NO_ACK);

    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);

    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
      attrs.setInitialCapacity(142);
      attrs.setLoadFactor(42.42f);
      attrs.setStatisticsEnabled(true);
      attrs.setCustomEntryIdleTimeout(new Expiry1());
      attrs.setCustomEntryTimeToLive(new Expiry5());

      root.createSubregion("one", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_ACK);
      attrs.setInitialCapacity(242);
      attrs.setStatisticsEnabled(true);
      attrs.setCustomEntryIdleTimeout(new Expiry2());

      Region region = root.createSubregion("two", attrs);

      {
        attrs = new RegionAttributesCreation(cache);
        attrs.setScope(Scope.DISTRIBUTED_ACK);
        attrs.setLoadFactor(43.43f);
        attrs.setStatisticsEnabled(true);
        attrs.setCustomEntryIdleTimeout(new Expiry3());
        attrs.setCustomEntryTimeToLive(new Expiry4());

        region.createSubregion("three", attrs);
      }
    }

    testXml(cache);
  }

  @Test
  public void testPreloadDataPolicy() throws Exception {
    CacheCreation cache = new CacheCreation();

    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.NORMAL);
      cache.createRegion("rootNORMAL", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.NORMAL);
      attrs.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
      cache.createRegion("rootNORMAL_ALL", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setMirrorType(MirrorType.KEYS_VALUES);
      cache.createRegion("rootREPLICATE", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      cache.createRegion("rootPERSISTENT_REPLICATE", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.EMPTY);
      cache.createRegion("rootEMPTY", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.EMPTY);
      attrs.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
      cache.createRegion("rootEMPTY_ALL", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.PRELOADED);
      attrs.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
      cache.createRegion("rootPRELOADED_ALL", attrs);
    }

    testXml(cache);
  }

  /**
   * Test EnableSubscriptionConflation region attribute
   *
   * @since GemFire 5.7
   */
  @Test
  public void testEnableSubscriptionConflationAttribute() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEnableSubscriptionConflation(true);
    cache.createRegion("root", attrs);
    testXml(cache);
    assertEquals(true, cache.getRegion("root").getAttributes().getEnableSubscriptionConflation());
  }

  /**
   * Tests that a region created with a named attributes has the correct attributes.
   */
  @Test
  public void testPartitionedRegionXML() throws Exception {
    setXmlFile(findFile("partitionedRegion51.xml"));
    final String regionName = "pRoot";

    Cache cache = getCache();
    Region region = cache.getRegion(regionName);
    assertNotNull(region);

    Host host = Host.getHost(0);
    final VM vm0 = host.getVM(0);
    final VM vm1 = host.getVM(1);

    CacheSerializableRunnable init =
        new CacheSerializableRunnable("initUsingPartitionedRegionXML") {
          @Override
          public void run2() throws CacheException {
            final Cache c;
            try {
              lonerDistributedSystem = false;
              c = getCache();
            } finally {
              lonerDistributedSystem = true;
            }
            Region r = c.getRegion(regionName);
            assertNotNull(r);
            RegionAttributes attrs = r.getAttributes();
            assertNotNull(attrs.getPartitionAttributes());

            PartitionAttributes pa = attrs.getPartitionAttributes();
            assertEquals(pa.getRedundantCopies(), 1);
            assertEquals(pa.getLocalMaxMemory(), 32);
            assertEquals(pa.getTotalMaxMemory(), 96);
            assertEquals(pa.getTotalNumBuckets(), 119);

            r = c.getRegion("bug37905");
            assertTrue("region should have been an instance of PartitionedRegion but was not",
                r instanceof PartitionedRegion);
          }
        };

    init.run2();
    vm0.invoke(init);
    vm1.invoke(init);
    vm0.invoke(new CacheSerializableRunnable("putUsingPartitionedRegionXML1") {
      @Override
      public void run2() throws CacheException {
        final String val = "prValue0";
        final Integer key = 10;
        Cache c = getCache();
        Region r = c.getRegion(regionName);
        assertNotNull(r);
        r.put(key, val);
        assertEquals(val, r.get(key));
      }
    });
    vm1.invoke(new CacheSerializableRunnable("putUsingPartitionedRegionXML2") {
      @Override
      public void run2() throws CacheException {
        final String val = "prValue1";
        final Integer key = 14;
        Cache c = getCache();
        Region r = c.getRegion(regionName);
        assertNotNull(r);
        r.put(key, val);
        assertEquals(val, r.get(key));
      }
    });
  }

  /**
   * Tests the {@code message-sync-interval} attribute of attribute is related to HA of
   * client-queues in gemfire ca framework. This attribute is the frequency at which a messent by
   * the primary cache-server node to all the secondary cache-server nodes to remove the events
   * which have already been dispatched from the queue
   */
  @Test
  public void testMessageSyncInterval() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setMessageSyncInterval(123);
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    assertEquals(123, c.getMessageSyncInterval());
  }

  /**
   * Tests the bridge-server attributes ({@code maximum-message-count} and
   * {@code message-time-to-live}) related to HA of client-queues in gemfire cache-server framework
   */
  @Test
  public void testBridgeAttributesRelatedToClientQueuesHA() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setMessageSyncInterval(3445);
    CacheServer bs = cache.addCacheServer();
    bs.setMaximumMessageCount(12345);
    bs.setMessageTimeToLive(56789);
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
    Cache c = getCache();
    assertNotNull(c);
    CacheServer server = cache.getCacheServers().iterator().next();
    assertNotNull(server);
    assertEquals(12345, server.getMaximumMessageCount());
    assertEquals(56789, server.getMessageTimeToLive());
  }

  /**
   * Tests that a region created with a named attributes has the correct attributes.
   *
   * This tests currently fails due to (what seem to me as) limitations in the XML generator and the
   * comparison of the XML. I have run this test by hand and looked at the generated XML and there
   * were no significant problems, however because of the limitations, I am disabling this test, but
   * leaving the functionality for future comparisons (by hand of course).
   */
  @Test
  public void testPartitionedRegionInstantiation() {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    PartitionAttributesFactory paf = new PartitionAttributesFactory();

    paf.setLocalMaxMemory(4).setTotalNumBuckets(17).setTotalMaxMemory(8);
    attrs.setPartitionAttributes(paf.create());
    cache.createRegion("pRoot", attrs);
  }

  /**
   * Tests the bridge-server attributes ({@code max-threads}
   */
  @Test
  public void testBridgeMaxThreads() throws Exception {
    CacheCreation cache = new CacheCreation();

    CacheServer bs = cache.addCacheServer();
    bs.setMaxThreads(37);
    bs.setMaxConnections(999);
    bs.setPort(AvailablePortHelper.getRandomAvailableTCPPort());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setDataPolicy(DataPolicy.NORMAL);
    cache.createVMRegion("rootNORMAL", attrs);
    testXml(cache);
  }

  /**
   * Tests that loading cache XML with multi-cast set will set the multi-cast
   */
  @Test
  public void testRegionMulticastSetViaCacheXml() throws Exception {
    final String rNameBase = getUniqueName();
    final String r1 = rNameBase + "1";
    final String r2 = rNameBase + "2";
    final String r3 = rNameBase + "3";

    // Setting multi-cast via nested region attributes
    CacheCreation creation = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.LOCAL);
    attrs.setEarlyAck(false);
    attrs.setMulticastEnabled(true);
    creation.createRegion(r1, attrs);

    // Setting multi-cast via named region attributes
    final String attrId = "region_attrs_with_multicast";
    attrs = new RegionAttributesCreation(creation);
    attrs.setId(attrId);
    attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
    attrs.setEarlyAck(false);
    attrs.setMulticastEnabled(true);
    creation.setRegionAttributes(attrs.getId(), attrs);
    attrs = new RegionAttributesCreation(creation);
    attrs.setRefid(attrId);
    creation.createRegion(r3, attrs);

    testXml(creation);

    creation = new CacheCreation();
    attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setEarlyAck(false);
    attrs.setMulticastEnabled(true);
    creation.createRegion(r2, attrs);

    Cache c = getCache();
    assertTrue(c instanceof GemFireCacheImpl);
    c.loadCacheXml(generate(creation));

    {
      Region reg1 = c.getRegion(r1);
      assertNotNull(reg1);
      assertEquals(Scope.LOCAL, reg1.getAttributes().getScope());
      assertFalse(reg1.getAttributes().getEarlyAck());
      assertTrue(reg1.getAttributes().getMulticastEnabled());
    }

    {
      Region reg2 = c.getRegion(r2);
      assertNotNull(reg2);
      assertEquals(Scope.DISTRIBUTED_ACK, reg2.getAttributes().getScope());
      assertFalse(reg2.getAttributes().getEarlyAck());
      assertTrue(reg2.getAttributes().getMulticastEnabled());
    }

    {
      Region reg3 = c.getRegion(r3);
      assertNotNull(reg3);
      assertEquals(Scope.DISTRIBUTED_NO_ACK, reg3.getAttributes().getScope());
      assertFalse(reg3.getAttributes().getEarlyAck());
      assertTrue(reg3.getAttributes().getMulticastEnabled());
    }
  }

  @Test
  public void testRollOplogs() throws Exception {
    CacheCreation cache = new CacheCreation();
    // Set properties for Asynch writes

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setSynchronous(true);
      dwaf.setRollOplogs(true);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("sync", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setTimeInterval(123L);
      dwaf.setBytesThreshold(456L);
      dwaf.setRollOplogs(false);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("async", attrs);
    }

    testXml(cache);
  }

  @Test
  public void testMaxOplogSize() throws Exception {
    CacheCreation cache = new CacheCreation();
    // Set properties for Asynch writes

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setSynchronous(true);
      dwaf.setMaxOplogSize(1);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("sync", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setTimeInterval(123L);
      dwaf.setBytesThreshold(456L);
      dwaf.setMaxOplogSize(1);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("async", attrs);
    }

    testXml(cache);
  }

  @Test
  public void testDataPolicy() throws Exception {
    CacheCreation cache = new CacheCreation();

    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.NORMAL);
      cache.createRegion("rootNORMAL", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.NORMAL);
      attrs.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
      cache.createRegion("rootNORMAL_ALL", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setMirrorType(MirrorType.KEYS_VALUES);
      cache.createRegion("rootREPLICATE", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      cache.createRegion("rootPERSISTENT_REPLICATE", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.EMPTY);
      cache.createRegion("rootEMPTY", attrs);
    }
    {
      RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
      attrs.setDataPolicy(DataPolicy.EMPTY);
      attrs.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
      cache.createRegion("rootEMPTY_ALL", attrs);
    }

    testXml(cache);
  }

  /**
   * These properties, if any, will be added to the properties used for getSystem calls
   */
  protected Properties xmlProps = null;

  @Override
  public Properties getDistributedSystemProperties() {
    Properties props = super.getDistributedSystemProperties();
    if (xmlProps != null) {
      for (final Map.Entry<Object, Object> objectObjectEntry : xmlProps.entrySet()) {
        Map.Entry entry = (Map.Entry) objectObjectEntry;
        String key = (String) entry.getKey();
        String value = (String) entry.getValue();
        props.setProperty(key, value);
      }
    }
    return props;
  }

  /**
   * Test xml support of MembershipAttributes.
   */
  @Test
  public void testMembershipAttributes() throws Exception {
    final String MY_ROLES = "Foo, Bip, BAM";
    final String[][] roles = new String[][] {{"Foo"}, {"Bip", "BAM"}};

    final LossAction[] policies =
        (LossAction[]) LossAction.VALUES.toArray(new LossAction[LossAction.VALUES.size()]);

    final ResumptionAction[] actions = (ResumptionAction[]) ResumptionAction.VALUES
        .toArray(new ResumptionAction[ResumptionAction.VALUES.size()]);

    CacheCreation cache = new CacheCreation();

    // for each policy, try each action and each role...
    for (int policy = 0; policy < policies.length; policy++) {
      for (int action = 0; action < actions.length; action++) {
        for (int role = 0; role < roles.length; role++) {
          String[] theRoles = roles[role];
          LossAction thePolicy = policies[policy];
          ResumptionAction theAction = actions[action];

          // if (theRoles.length == 0 && (thePolicy != LossAction.NONE || theAction !=
          // ResumptionAction.NONE

          RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
          MembershipAttributes ra = new MembershipAttributes(theRoles, thePolicy, theAction);
          attrs.setMembershipAttributes(ra);
          String region = "rootMEMBERSHIP_ATTRIBUTES_" + policy + "_" + action + "_" + role;
          cache.createRegion(region, attrs);
        }
      }
    }

    {
      // make our system play the roles used by this test so the create regions
      // will not think the a required role is missing
      Properties config = new Properties();
      config.setProperty(ROLES, MY_ROLES);
      xmlProps = config;
    }
    DistributedRegion.ignoreReconnect = true;
    try {
      testXml(cache);
    } finally {
      xmlProps = null;
      try {
        preTearDown();
      } finally {
        DistributedRegion.ignoreReconnect = false;
      }
    }
  }

  /**
   * Tests multiple cache listeners on one region
   *
   * @since GemFire 5.0
   */
  @Test
  public void testMultipleCacheListener() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    CacheListener l1 = new MyTestCacheListener();
    CacheListener l2 = new MySecondTestCacheListener();
    attrs.addCacheListener(l1);
    attrs.addCacheListener(l2);

    cache.createRegion("root", attrs);

    testXml(cache);
    {
      Cache c = getCache();
      Region r = c.getRegion("root");
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      AttributesMutator am = r.getAttributesMutator();
      am.removeCacheListener(l2);
      assertEquals(Arrays.asList(l1),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.removeCacheListener(l1);
      assertEquals(Arrays.asList(),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.addCacheListener(l1);
      assertEquals(Arrays.asList(l1),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.addCacheListener(l1);
      assertEquals(Arrays.asList(l1),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.addCacheListener(l2);
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.removeCacheListener(l1);
      assertEquals(Arrays.asList(l2),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.removeCacheListener(l1);
      assertEquals(Arrays.asList(l2),
          Arrays.asList(r.getAttributes().getCacheListeners()));
      am.initCacheListeners(new CacheListener[] {l1, l2});
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(r.getAttributes().getCacheListeners()));
    }
  }

  /**
   * A {@code CacheListener} that is {@code Declarable}, but not {@code Declarable2}.
   */
  public static class MySecondTestCacheListener extends TestCacheListener implements Declarable {

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MySecondTestCacheListener;
    }
  }

  @Test
  public void testHeapLRUEviction() throws Exception {
    final String name = getUniqueName();
    beginCacheXml();
    AttributesFactory factory = new AttributesFactory();
    factory.setScope(Scope.LOCAL);
    EvictionAttributes ev =
        EvictionAttributes.createLRUHeapAttributes(null, EvictionAction.OVERFLOW_TO_DISK);
    factory.setEvictionAttributes(ev);
    // RegionAttributes atts = factory.create();
    createRegion(name, factory.create());
    finishCacheXml(temporaryFolder.getRoot(), getUniqueName(), getUseSchema(),
        getGemFireVersion());
    Region r = getRootRegion().getSubregion(name);

    EvictionAttributes hlea = r.getAttributes().getEvictionAttributes();
    assertEquals(EvictionAction.OVERFLOW_TO_DISK, hlea.getAction());
  }

  /**
   * Tests multiple transaction listeners
   *
   * @since GemFire 5.0
   */
  @Test
  public void testMultipleTXListener() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
    TransactionListener l1 = new MyTestTransactionListener();
    TransactionListener l2 = new MySecondTestTransactionListener();
    txMgrCreation.addListener(l1);
    txMgrCreation.addListener(l2);
    cache.addCacheTransactionManagerCreation(txMgrCreation);
    testXml(cache);
    {
      CacheTransactionManager tm = getCache().getCacheTransactionManager();
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(tm.getListeners()));
      tm.removeListener(l2);
      assertEquals(Arrays.asList(l1), Arrays.asList(tm.getListeners()));
      tm.removeListener(l1);
      assertEquals(Arrays.asList(), Arrays.asList(tm.getListeners()));
      tm.addListener(l1);
      assertEquals(Arrays.asList(l1), Arrays.asList(tm.getListeners()));
      tm.addListener(l1);
      assertEquals(Arrays.asList(l1), Arrays.asList(tm.getListeners()));
      tm.addListener(l2);
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(tm.getListeners()));
      tm.removeListener(l1);
      assertEquals(Arrays.asList(l2), Arrays.asList(tm.getListeners()));
      tm.removeListener(l1);
      assertEquals(Arrays.asList(l2), Arrays.asList(tm.getListeners()));
      tm.initListeners(new TransactionListener[] {l1, l2});
      assertEquals(Arrays.asList(l1, l2),
          Arrays.asList(tm.getListeners()));
    }
  }

  /**
   * A {@code TransactionListener} that is {@code Declarable}, but not {@code Declarable2}.
   */
  public static class MySecondTestTransactionListener extends TestTransactionListener
      implements Declarable {

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MySecondTestTransactionListener;
    }
  }

  private void setBridgeAttributes(CacheServer bridge1) {
    bridge1.setPort(0);
    bridge1.setMaxConnections(100);
    bridge1.setMaximumTimeBetweenPings(12345);
    bridge1.setNotifyBySubscription(true);
    bridge1.setSocketBufferSize(98765);
  }

  /**
   * Tests that named region attributes are registered when the cache is created.
   */
  @Test
  public void testRegisteringNamedRegionAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs;

    String id1 = "id1";
    attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setMirrorType(MirrorType.KEYS);
    cache.setRegionAttributes(id1, attrs);

    String id2 = "id2";
    attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
    attrs.setMirrorType(MirrorType.KEYS_VALUES);
    attrs.setConcurrencyLevel(15);
    cache.setRegionAttributes(id2, attrs);

    String id3 = "id3";
    attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.LOCAL);
    attrs.setValueConstraint(Integer.class);
    cache.setRegionAttributes(id3, attrs);

    testXml(cache);
  }

  /**
   * Tests that a region created with a named attributes has the correct attributes.
   */
  @Test
  public void testNamedAttributes() throws Exception {
    setXmlFile(findFile("namedAttributes.xml"));

    Class keyConstraint = String.class;
    Class valueConstraint = Integer.class;
    String id = "id1";
    String regionName = "root";

    Cache cache = getCache();
    RegionAttributes attrs = cache.getRegionAttributes(id);
    assertEquals(keyConstraint, attrs.getKeyConstraint());
    assertEquals(valueConstraint, attrs.getValueConstraint());
    assertEquals(45, attrs.getEntryIdleTimeout().getTimeout());
    assertEquals(ExpirationAction.INVALIDATE, attrs.getEntryIdleTimeout().getAction());

    Region region = cache.getRegion(regionName);
    assertNotNull(region);

    attrs = region.getAttributes();
    assertEquals(keyConstraint, attrs.getKeyConstraint());
    assertEquals(valueConstraint, attrs.getValueConstraint());
    assertEquals(45, attrs.getEntryIdleTimeout().getTimeout());
    assertEquals(ExpirationAction.INVALIDATE, attrs.getEntryIdleTimeout().getAction());

    // Make sure that attributes can be "overridden"
    Region subregion = region.getSubregion("subregion");
    assertNotNull(subregion);

    attrs = subregion.getAttributes();
    assertEquals(keyConstraint, attrs.getKeyConstraint());
    assertEquals(Long.class, attrs.getValueConstraint());
    assertEquals(90, attrs.getEntryIdleTimeout().getTimeout());
    assertEquals(ExpirationAction.DESTROY, attrs.getEntryIdleTimeout().getAction());

    // Make sure that a named region attributes used in a region
    // declaration is registered
    assertNotNull(cache.getRegionAttributes("id2"));
  }

  /**
   * Tests that trying to parse an XML file that declares a region whose attributes refer to an
   * unknown named region attributes throws an {@link IllegalStateException}.
   */
  @Test
  public void testUnknownNamedAttributes() throws Exception {
    setXmlFile(findFile("unknownNamedAttributes.xml"));

    IgnoredException expectedException = addIgnoredException(
        "Cannot reference non-existing region attributes named");
    try {
      getCache();
      fail("Should have thrown an IllegalStateException");

    } catch (IllegalStateException ex) {
      // pass...
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests to make sure that we cannot create the same region multiple times in a {@code cache.xml}
   * file.
   */
  @Test
  public void testCreateSameRegionTwice() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    String name = "root";

    cache.createRegion(name, attrs);

    try {
      cache.createRegion(name, attrs);
      fail("Should have thrown a RegionExistsException");

    } catch (RegionExistsException ex) {
      // pass...
    }

    setXmlFile(findFile("sameRootRegion.xml"));

    addIgnoredException("While reading Cache XML file");
    addIgnoredException("org.apache.geode.cache.RegionExistsException");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      Throwable cause = ex.getCause();
      assertTrue(cause instanceof SAXException);
      cause = ((SAXException) cause).getException();
      if (!(cause instanceof RegionExistsException)) {
        Assert.fail("Expected a RegionExistsException, not a " + cause.getClass().getName(), cause);
      }
    } finally {
      IgnoredException.removeAllExpectedExceptions();
    }
  }

  /**
   * Tests to make sure that we cannot create the same subregion multiple times in a
   * {@code cache.xml} file.
   */
  @Test
  public void testCreateSameSubregionTwice() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    String name = getUniqueName();

    Region root = cache.createRegion("root", attrs);

    root.createSubregion(name, attrs);

    try {
      root.createSubregion(name, attrs);
      fail("Should have thrown a RegionExistsException");

    } catch (RegionExistsException ex) {
      // pass...
    }

    setXmlFile(findFile("sameSubregion.xml"));

    addIgnoredException("While reading Cache XML file");
    addIgnoredException("org.apache.geode.cache.RegionExistsException");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      Throwable cause = ex.getCause();
      assertTrue(cause instanceof SAXException);
      cause = ((SAXException) cause).getException();
      if (!(cause instanceof RegionExistsException)) {
        Assert.fail("Expected a RegionExistsException, not a " + cause.getClass().getName(), cause);
      }
    } finally {
      IgnoredException.removeAllExpectedExceptions();
    }
  }

  /**
   * Generates XML from the given {@code CacheCreation} and returns an {@code InputStream} for
   * reading that XML.
   */
  public InputStream generate(CacheCreation creation) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    final String version = getGemFireVersion();

    PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos), true);
    CacheXmlGenerator.generate(creation, pw, getUseSchema(), version);
    pw.close();

    byte[] bytes = baos.toByteArray();
    return new ByteArrayInputStream(bytes);
  }

  /**
   * Tests that loading cache XML effects mutable cache attributes.
   */
  @Test
  public void testModifyCacheAttributes() throws Exception {
    boolean copyOnRead1 = false;
    boolean isServer1 = true;
    int lockLease1 = 123;
    int lockTimeout1 = 345;
    int searchTimeout1 = 567;

    CacheCreation creation = new CacheCreation();
    creation.setCopyOnRead(copyOnRead1);
    creation.setIsServer(isServer1);
    creation.setLockLease(lockLease1);
    creation.setLockTimeout(lockTimeout1);
    creation.setSearchTimeout(searchTimeout1);

    testXml(creation);

    Cache cache = getCache();
    assertEquals(copyOnRead1, cache.getCopyOnRead());
    assertEquals(isServer1, cache.isServer());
    assertEquals(lockLease1, cache.getLockLease());
    assertEquals(lockTimeout1, cache.getLockTimeout());
    assertEquals(searchTimeout1, cache.getSearchTimeout());

    boolean copyOnRead2 = true;
    boolean isServer2 = false;
    int lockLease2 = 234;
    int lockTimeout2 = 456;
    int searchTimeout2 = 678;

    creation = new CacheCreation();
    creation.setCopyOnRead(copyOnRead2);
    creation.setIsServer(isServer2);
    creation.setLockLease(lockLease2);
    creation.setLockTimeout(lockTimeout2);
    creation.setSearchTimeout(searchTimeout2);

    cache.loadCacheXml(generate(creation));

    assertEquals(copyOnRead2, cache.getCopyOnRead());
    assertEquals(isServer2, cache.isServer());
    assertEquals(lockLease2, cache.getLockLease());
    assertEquals(lockTimeout2, cache.getLockTimeout());
    assertEquals(searchTimeout2, cache.getSearchTimeout());
  }

  /**
   * Tests that loading cache XML can create a region.
   */
  @Test
  public void testAddRegionViaCacheXml() throws Exception {
    CacheCreation creation = new CacheCreation();

    testXml(creation);

    Cache cache = getCache();
    assertTrue(cache.rootRegions().isEmpty());

    creation = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.GLOBAL);
    attrs.setKeyConstraint(Integer.class);
    attrs.setCacheListener(new MyTestCacheListener());
    Region root = creation.createRegion("root", attrs);

    attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.LOCAL);
    attrs.setEarlyAck(true);
    attrs.setValueConstraint(String.class);
    Region subregion = root.createSubregion("subregion", attrs);

    cache.loadCacheXml(generate(creation));

    root = cache.getRegion("root");
    assertNotNull(root);
    assertEquals(Scope.GLOBAL, root.getAttributes().getScope());
    assertEquals(Integer.class, root.getAttributes().getKeyConstraint());
    assertTrue(root.getAttributes().getCacheListener() instanceof MyTestCacheListener);

    subregion = root.getSubregion("subregion");
    assertNotNull(subregion);
    assertEquals(Scope.LOCAL, subregion.getAttributes().getScope());
    assertTrue(subregion.getAttributes().getEarlyAck());
    assertFalse(subregion.getAttributes().getMulticastEnabled());
    assertEquals(String.class, subregion.getAttributes().getValueConstraint());

    // Create a subregion of a region that already exists

    creation = new CacheCreation();
    attrs = new RegionAttributesCreation(creation);
    root = creation.createRegion("root", attrs);

    attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.DISTRIBUTED_ACK);
    attrs.setEarlyAck(false);
    attrs.setValueConstraint(Long.class);
    Region subregion2 = root.createSubregion("subregion2", attrs);

    cache.loadCacheXml(generate(creation));

    subregion2 = root.getSubregion("subregion2");
    assertNotNull(subregion2);
    assertEquals(Scope.DISTRIBUTED_ACK, subregion2.getAttributes().getScope());
    assertTrue(!subregion2.getAttributes().getEarlyAck());
    assertEquals(Long.class, subregion2.getAttributes().getValueConstraint());
  }

  /**
   * Tests that loading cache XML can modify a region.
   */
  @Test
  public void testModifyRegionViaCacheXml() throws Exception {
    CacheCreation creation = new CacheCreation();

    int timeout1a = 123;
    ExpirationAction action1a = ExpirationAction.LOCAL_DESTROY;
    int timeout1b = 456;
    ExpirationAction action1b = ExpirationAction.DESTROY;

    RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
    attrs.setStatisticsEnabled(true);
    attrs.setEntryIdleTimeout(new ExpirationAttributes(timeout1a, action1a));
    Region root = creation.createRegion("root", attrs);

    attrs = new RegionAttributesCreation(creation);
    attrs.setStatisticsEnabled(true);
    attrs.setEntryIdleTimeout(new ExpirationAttributes(timeout1b, action1b));
    Region subregion = root.createSubregion("subregion", attrs);

    testXml(creation);

    Cache cache = getCache();

    root = cache.getRegion("root");
    assertEquals(timeout1a, root.getAttributes().getEntryIdleTimeout().getTimeout());
    assertEquals(action1a, root.getAttributes().getEntryIdleTimeout().getAction());

    subregion = root.getSubregion("subregion");
    assertEquals(timeout1b, subregion.getAttributes().getEntryIdleTimeout().getTimeout());
    assertEquals(action1b, subregion.getAttributes().getEntryIdleTimeout().getAction());

    creation = new CacheCreation();

    int timeout2a = 234;
    ExpirationAction action2a = ExpirationAction.LOCAL_INVALIDATE;
    int timeout2b = 567;
    ExpirationAction action2b = ExpirationAction.INVALIDATE;

    attrs = new RegionAttributesCreation(creation);
    attrs.setStatisticsEnabled(true);
    attrs.setEntryIdleTimeout(new ExpirationAttributes(timeout2a, action2a));
    attrs.setCacheListener(new MyTestCacheListener());
    root = creation.createRegion("root", attrs);

    attrs = new RegionAttributesCreation(creation);
    attrs.setStatisticsEnabled(true);
    attrs.setEntryIdleTimeout(new ExpirationAttributes(timeout2b, action2b));
    subregion = root.createSubregion("subregion", attrs);

    cache.loadCacheXml(generate(creation));

    root = cache.getRegion("root");
    subregion = root.getSubregion("subregion");

    assertEquals(timeout2a, root.getAttributes().getEntryIdleTimeout().getTimeout());
    assertEquals(action2a, root.getAttributes().getEntryIdleTimeout().getAction());
    assertTrue(root.getAttributes().getCacheListener() instanceof MyTestCacheListener);

    assertEquals(timeout2b, subregion.getAttributes().getEntryIdleTimeout().getTimeout());
    assertEquals(action2b, subregion.getAttributes().getEntryIdleTimeout().getAction());
  }

  /**
   * Tests that loading cache XML can add/update entries to a region.
   */
  @Test
  public void testAddEntriesViaCacheXml() throws Exception {
    String key1 = "KEY1";
    String value1 = "VALUE1";

    CacheCreation creation = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.LOCAL);

    Region root = creation.createRegion("root", attrs);
    root.put(key1, value1);

    testXml(creation);

    Cache cache = getCache();
    root = cache.getRegion("root");
    assertEquals(1, root.entrySet(false).size());
    assertEquals(value1, root.get(key1));

    creation = new CacheCreation();

    attrs = new RegionAttributesCreation(creation);
    attrs.setScope(Scope.LOCAL);

    String value2 = "VALUE2";
    String key2 = "KEY2";
    String value3 = "VALUE3";

    root = creation.createRegion("root", attrs);
    root.put(key1, value2);
    root.put(key2, value3);

    cache.loadCacheXml(generate(creation));

    root = cache.getRegion("root");
    assertEquals(2, root.entrySet(false).size());
    assertEquals(value2, root.get(key1));
    assertEquals(value3, root.get(key2));
  }

  /**
   * Test EnableBridgeConflation region attribute
   *
   * @since GemFire 4.2
   */
  @Test
  public void testEnableBridgeConflationAttribute() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEnableBridgeConflation(true);
    cache.createRegion("root", attrs);
    testXml(cache);
    assertEquals(true, cache.getRegion("root").getAttributes().getEnableBridgeConflation());
  }

  /**
   * Test EnableAsyncConflation region attribute
   *
   * @since GemFire 4.2
   */
  @Test
  public void testEnableAsyncConflationAttribute() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEnableAsyncConflation(true);
    cache.createRegion("root", attrs);
    testXml(cache);
    assertEquals(true, cache.getRegion("root").getAttributes().getEnableAsyncConflation());
  }

  /**
   * @since GemFire 4.3
   */
  @Test
  public void testDynamicRegionFactoryDefault() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setDynamicRegionFactoryConfig(new DynamicRegionFactory.Config());
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    cache.createRegion("root", attrs);
    // note that testXml can't check if they are same because enabling
    // dynamic regions causes a meta region to be produced.
    testXml(cache, false);
    assertEquals(true, DynamicRegionFactory.get().getConfig().getRegisterInterest());
    assertEquals(true, DynamicRegionFactory.get().getConfig().getPersistBackup());
    assertEquals(true, DynamicRegionFactory.get().isOpen());
    assertEquals(null, DynamicRegionFactory.get().getConfig().getDiskDir());
    Region dr = getCache().getRegion("__DynamicRegions");
    if (dr != null) {
      dr.localDestroyRegion();
    }
  }

  @Test
  public void testDynamicRegionFactoryNonDefault() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setDynamicRegionFactoryConfig(
        new DynamicRegionFactory.Config(null, null, false, false));
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    cache.createRegion("root", attrs);
    // note that testXml can't check if they are same because enabling
    // dynamic regions causes a meta region to be produced.
    testXml(cache, false);
    assertEquals(false, DynamicRegionFactory.get().getConfig().getRegisterInterest());
    assertEquals(false, DynamicRegionFactory.get().getConfig().getPersistBackup());
    assertEquals(true, DynamicRegionFactory.get().isOpen());
    assertEquals(null, DynamicRegionFactory.get().getConfig().getDiskDir());
    Region dr = getCache().getRegion("__DynamicRegions");
    if (dr != null) {
      dr.localDestroyRegion();
    }
  }

  /**
   * @since GemFire 4.3
   */
  @Test
  public void testDynamicRegionFactoryDiskDir() throws Exception {
    CacheCreation cache = new CacheCreation();
    File f = new File("diskDir");
    f.mkdirs();
    cache.setDynamicRegionFactoryConfig(new DynamicRegionFactory.Config(f, null, true, true));
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    cache.createRegion("root", attrs);
    // note that testXml can't check if they are same because enabling
    // dynamic regions causes a meta region to be produced.
    testXml(cache, false);
    assertEquals(true, DynamicRegionFactory.get().isOpen());
    assertEquals(f.getAbsoluteFile(), DynamicRegionFactory.get().getConfig().getDiskDir());
    Region dr = getCache().getRegion("__DynamicRegions");
    if (dr != null) {
      dr.localDestroyRegion();
    }
  }

  /**
   * Tests the cache server attribute
   *
   * @since GemFire 4.0
   */
  @Test
  public void testServer() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setIsServer(true);
    assertTrue(cache.isServer());

    testXml(cache);
  }

  /**
   * Tests declarative cache servers
   *
   * @since GemFire 4.0
   */
  @Test
  public void testBridgeServers() throws Exception {
    CacheCreation cache = new CacheCreation();

    CacheServer bridge1 = cache.addCacheServer();
    setBridgeAttributes(bridge1);

    CacheServer bridge2 = cache.addCacheServer();
    setBridgeAttributes(bridge2);

    testXml(cache);
  }

  /**
   * Tests the is-lock-grantor attribute in xml.
   */
  @Test
  public void testIsLockGrantorAttribute() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    attrs.setLockGrantor(true);
    attrs.setScope(Scope.GLOBAL);
    attrs.setMirrorType(MirrorType.KEYS_VALUES);

    cache.createRegion("root", attrs);

    testXml(cache);
    assertEquals(true, cache.getRegion("root").getAttributes().isLockGrantor());
  }

  /**
   * Tests a cache listener with no parameters
   *
   * @since GemFire 4.0
   */
  @Test
  public void testTransactionListener() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
    txMgrCreation.setListener(new MyTestTransactionListener());
    cache.addCacheTransactionManagerCreation(txMgrCreation);
    testXml(cache);
  }

  /**
   * Tests transaction manager with no listener
   *
   * @since GemFire 4.0
   */
  @Test
  public void testCacheTransactionManager() throws Exception {
    CacheCreation cache = new CacheCreation();
    CacheTransactionManagerCreation txMgrCreation = new CacheTransactionManagerCreation();
    cache.addCacheTransactionManagerCreation(txMgrCreation);
    testXml(cache);
  }

  /**
   * Tests the value constraints region attribute that was added in GemFire 4.0.
   *
   * @since GemFire 4.1
   */
  @Test
  public void testConstrainedValues() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setValueConstraint(String.class);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests creating a cache with a non-existent XML file
   */
  @Test
  public void testNonExistentFile() {
    // System.out.println("testNonExistentFile - start: " + System.currentTimeMillis());
    File nonExistent = new File(getName() + ".xml");
    nonExistent.delete();
    // System.out.println("testNonExistentFile - deleted: " + System.currentTimeMillis());
    setXmlFile(nonExistent);
    // System.out.println("testNonExistentFile - set: " + System.currentTimeMillis());

    IgnoredException expectedException = addIgnoredException(
        String.format("Declarative Cache XML file/resource %s does not exist.",
            nonExistent.getPath()));
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      // System.out.println("testNonExistentFile - caught: " + System.currentTimeMillis());
      // pass...
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests creating a cache with a XML file that is a directory
   */
  @Test
  public void testXmlFileIsDirectory() {
    File dir = new File(getName() + "dir");
    dir.mkdirs();
    dir.deleteOnExit();
    setXmlFile(dir);

    IgnoredException expectedException = addIgnoredException(
        String.format("Declarative XML file %s is not a file.", dir));
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      // pass...
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests creating a cache with the default lock-timeout, lock-lease, and search-timeout.
   */
  @Test
  public void testDefaultCache() throws Exception {
    CacheCreation cache = new CacheCreation();

    testXml(cache);
  }

  /**
   * Tests creating a cache with non-default lock-timeout, lock-lease, and search-timeout.
   */
  @Test
  public void testNonDefaultCache() throws Exception {
    CacheCreation cache = new CacheCreation();
    cache.setLockTimeout(42);
    cache.setLockLease(43);
    cache.setSearchTimeout(44);

    if (getGemFireVersion().compareTo(CacheXml.VERSION_4_0) >= 0) {
      cache.setCopyOnRead(true);
    }

    testXml(cache);
  }

  /**
   * Tests creating a cache with entries defined in the root region
   */
  @Test
  public void testEntriesInRootRegion() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionCreation root =
        (RegionCreation) cache.createRegion("root", new RegionAttributesCreation(cache));
    root.put("KEY1", "VALUE1");
    root.put("KEY2", "VALUE2");
    root.put("KEY3", "VALUE3");

    testXml(cache);
  }

  /**
   * Tests creating a cache whose keys are constrained
   */
  @Test
  public void testConstrainedKeys() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setKeyConstraint(String.class);
    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests creating a cache with a various {@link ExpirationAttributes}.
   */
  @Test
  public void testExpirationAttriubutes() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setStatisticsEnabled(true);

    {
      ExpirationAttributes expire = new ExpirationAttributes(42, ExpirationAction.INVALIDATE);
      attrs.setRegionTimeToLive(expire);
    }

    {
      ExpirationAttributes expire = new ExpirationAttributes(43, ExpirationAction.DESTROY);
      attrs.setRegionIdleTimeout(expire);
    }

    {
      ExpirationAttributes expire = new ExpirationAttributes(44, ExpirationAction.LOCAL_INVALIDATE);
      attrs.setEntryTimeToLive(expire);
    }

    {
      ExpirationAttributes expire = new ExpirationAttributes(45, ExpirationAction.LOCAL_DESTROY);
      attrs.setEntryIdleTimeout(expire);
    }

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests a cache loader an interesting combination of declarables
   */
  @Test
  public void testCacheLoaderWithDeclarables() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    CacheLoaderWithDeclarables loader = new CacheLoaderWithDeclarables();
    attrs.setCacheLoader(loader);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests a cache writer with no parameters
   */
  @Test
  public void testCacheWriter() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    CacheWriter writer = new MyTestCacheWriter();
    attrs.setCacheWriter(writer);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests a cache listener with no parameters
   */
  @Test
  public void testCacheListener() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    CacheListener listener = new MyTestCacheListener();
    attrs.setCacheListener(listener);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests a region with non-default region attributes
   */
  @Test
  public void testNonDefaultRegionAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
    attrs.setMirrorType(MirrorType.KEYS_VALUES);
    attrs.setInitialCapacity(142);
    attrs.setLoadFactor(42.42f);
    attrs.setStatisticsEnabled(false);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests parsing a malformed XML file
   */
  @Test
  public void testMalformed() throws Exception {
    setXmlFile(findFile("malformed.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      assertTrue(ex.getCause() instanceof SAXException);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests parsing an XML file with a bad integer
   */
  @Test
  public void testBadInt() throws Exception {
    setXmlFile(findFile("badInt.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      Throwable cause = ex.getCause();
      assertNotNull("Expected a cause", cause);
      assertTrue("Didn't expect cause:" + cause + " (a " + cause.getClass().getName() + ")",
          cause instanceof NumberFormatException);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests parsing an XML file with a bad float
   */
  @Test
  public void testBadFloat() throws Exception {
    setXmlFile(findFile("badFloat.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      assertTrue(ex.getCause() instanceof NumberFormatException);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests parsing an XML file with a bad scope. This error should be caught by the XML parser.
   */
  @Test
  public void testBadScope() throws Exception {
    setXmlFile(findFile("badScope.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      assertTrue(ex.getCause() instanceof SAXException);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests parsing an XML file with a non-existent key constraint class.
   */
  @Test
  public void testBadKeyConstraintClass() throws Exception {
    setXmlFile(findFile("badKeyConstraintClass.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      assertTrue(ex.getCause() instanceof ClassNotFoundException);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests parsing an XML file that specifies a cache listener that is not {@link Declarable}.
   */
  @Test
  public void testCallbackNotExplicitlyDeclarableIsStillOK() throws Exception {
    setXmlFile(findFile("callbackNotDeclarable.xml"));

    getCache();
  }

  /**
   * Tests parsing an XML file that specifies a cache listener whose constructor throws an
   * {@linkplain AssertionError exception}.
   */
  @Test
  public void testCallbackWithException() throws Exception {
    setXmlFile(findFile("callbackWithException.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      if (!(ex.getCause() instanceof AssertionError)) {
        throw ex;
      }
    } finally {
      expectedException.remove();
    }

  }

  /**
   * Tests parsing an XML file that specifies a cache listener that is not a {@code CacheLoader}.
   */
  @Test
  public void testLoaderNotLoader() throws Exception {
    setXmlFile(findFile("loaderNotLoader.xml"));

    IgnoredException expectedException =
        addIgnoredException("While reading Cache XML file");
    try {
      getCache();
      fail("Should have thrown a CacheXmlException");

    } catch (CacheXmlException ex) {
      Throwable cause = ex.getCause();
      assertNull("Didn't expect a " + cause, cause);
    } finally {
      expectedException.remove();
    }
  }

  /**
   * Tests nested regions
   */
  @Test
  public void testNestedRegions() throws Exception {
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setScope(Scope.DISTRIBUTED_NO_ACK);

    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);

    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_NO_ACK);
      attrs.setMirrorType(MirrorType.KEYS_VALUES);
      attrs.setInitialCapacity(142);
      attrs.setLoadFactor(42.42f);
      attrs.setStatisticsEnabled(false);

      root.createSubregion("one", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      attrs.setScope(Scope.DISTRIBUTED_ACK);
      attrs.setMirrorType(MirrorType.KEYS);
      attrs.setInitialCapacity(242);

      Region region = root.createSubregion("two", attrs);

      {
        attrs = new RegionAttributesCreation(cache);
        attrs.setScope(Scope.GLOBAL);
        attrs.setLoadFactor(43.43f);

        region.createSubregion("three", attrs);
      }
    }

    testXml(cache);
  }

  /**
   * Tests whether or not XML attributes can appear in any order. See bug 30050.
   */
  @Test
  public void testAttributesUnordered() throws Exception {
    setXmlFile(findFile("attributesUnordered.xml"));
    getCache();
  }

  /**
   * Tests disk directories
   */
  @Test
  public void testDiskDirs() throws Exception {
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    File[] dirs = new File[] {new File(getUniqueName() + "-dir1"),
        new File(getUniqueName() + "-dir2")};
    for (final File dir : dirs) {
      dir.mkdirs();
      dir.deleteOnExit();
    }

    int[] diskSizes = {DiskWriteAttributesImpl.DEFAULT_DISK_DIR_SIZE,
        DiskWriteAttributesImpl.DEFAULT_DISK_DIR_SIZE};
    attrs.setDiskDirsAndSize(dirs, diskSizes);
    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests the {@code overflowThreshold} and {@code persistBackup} related attributes
   */
  @Test
  public void testOverflowAndBackup() throws Exception {
    CacheCreation cache = new CacheCreation();

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setMirrorType(MirrorType.KEYS_VALUES);
    attrs.setPersistBackup(true);

    cache.createRegion("root", attrs);

    testXml(cache);
  }

  /**
   * Tests {@code DiskWriteAttributes}
   */
  @Test
  public void testDiskWriteAttributes() throws Exception {
    CacheCreation cache = new CacheCreation();
    // Set properties for Asynch writes

    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);

    RegionCreation root = (RegionCreation) cache.createRegion("root", attrs);

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setSynchronous(true);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("sync", attrs);
    }

    {
      attrs = new RegionAttributesCreation(cache);
      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory();
      dwaf.setTimeInterval(123L);
      dwaf.setBytesThreshold(456L);
      attrs.setDiskWriteAttributes(dwaf.create());
      root.createSubregion("async", attrs);
    }

    testXml(cache);
  }

  /**
   * Tests to make sure that the example cache.xml file in the API documentation conforms to the
   * DTD.
   *
   * @since GemFire 3.2.1
   */
  @Test
  @Ignore // TODO: why is testExampleCacheXmlFile @Ignored?
  public void testExampleCacheXmlFile() throws Exception {
    // Check for old example files
    String dirName = "examples_" + getGemFireVersion();
    File dir = null;
    try {
      dir = findFile(dirName);
    } catch (AssertionError e) {
      // ignore, no directory.
    }
    if (dir != null && dir.exists()) {
      File[] xmlFiles = dir.listFiles((dir1, name) -> name.endsWith(".xml"));
      assertTrue("No XML files in " + dirName, xmlFiles.length > 0);
      for (File xmlFile : xmlFiles) {
        LogWriterUtils.getLogWriter().info("Parsing " + xmlFile);

        FileInputStream fis = new FileInputStream(xmlFile);
        CacheXmlParser.parse(fis);
      }

    } else {

      File example = new File(createTempFileFromResource(getClass(),
          "/org/apache/geode/cache/doc-files/example-cache.xml").getAbsolutePath());
      FileInputStream fis = new FileInputStream(example);
      CacheXmlParser.parse(fis);

      File example2 = new File(createTempFileFromResource(getClass(),
          "/org/apache/geode/cache/doc-files/example2-cache.xml").getAbsolutePath());
      fis = new FileInputStream(example2);
      CacheXmlParser.parse(fis);

      File example3 = new File(createTempFileFromResource(getClass(),
          "/org/apache/geode/cache/doc-files/example3-cache.xml").getAbsolutePath());
      fis = new FileInputStream(example3);
      CacheXmlParser.parse(fis);
    }
  }

  @Test
  public void testEvictionLRUEntryAttributes() throws Exception {
    final String rName = getUniqueName();
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEvictionAttributes(
        EvictionAttributes.createLRUEntryAttributes(80, EvictionAction.LOCAL_DESTROY));
    cache.createRegion(rName, attrs);
    testXml(cache);
  }

  public static class EvictionObjectSizer implements ObjectSizer, Declarable2 {
    Properties props = new Properties();

    @Override
    public int sizeof(Object o) {
      return 1;
    }

    @Override
    public Properties getConfig() {
      if (null == props) {
        props = new Properties();
      }
      props.setProperty("EvictionObjectSizerColor", "blue");
      return props;
    }

    @Override
    public void init(Properties props) {
      this.props = props;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof EvictionObjectSizer)) {
        return false;
      }
      EvictionObjectSizer other = (EvictionObjectSizer) obj;
      return props.equals(other.props);
    }
  }

  @Test
  public void testEvictionLRUMemoryAttributes() throws Exception {
    final String rName = getUniqueName();
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEvictionAttributes(
        EvictionAttributes.createLRUMemoryAttributes(10, new EvictionObjectSizer()));
    cache.createRegion(rName, attrs);
    testXml(cache);
  }

  @Test
  public void testEvictionLRUHeapAttributes() throws Exception {
    final String rName = getUniqueName();
    CacheCreation cache = new CacheCreation();
    RegionAttributesCreation attrs = new RegionAttributesCreation(cache);
    attrs.setEvictionAttributes(EvictionAttributes
        .createLRUHeapAttributes(new EvictionObjectSizer(), EvictionAction.LOCAL_DESTROY));
    cache.createRegion(rName, attrs);
    testXml(cache);
  }


  /**
   * A cache listener that is not {@link Declarable}
   *
   * @see #testCallbackNotExplicitlyDeclarableIsStillOK()
   */
  public static class NotDeclarableCacheListener extends TestCacheListener {
    // empty
  }

  public static class AssertionError extends RuntimeException {
    public AssertionError() {
      super("Test Exception");
    }
  }

  /**
   * A cache listener whose constructor throws an exception
   *
   * @see #testCallbackWithException()
   */
  public static class ExceptionalCacheListener extends TestCacheListener {

    public ExceptionalCacheListener() {
      throw new AssertionError();
    }
  }

  /**
   * A {@code CacheListener} that is {@code Declarable}, but not {@code Declarable2}.
   */
  public static class MyTestCacheListener extends TestCacheListener implements Declarable {

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MyTestCacheListener;
    }
  }

  /**
   * A {@code CacheWriter} that is {@code Declarable}, but not {@code Declarable2}.
   */
  public static class MyTestCacheWriter extends TestCacheWriter implements Declarable {

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MyTestCacheWriter;
    }
  }

  /**
   * A {@code TransactionListener} that is {@code Declarable}, but not {@code Declarable2}.
   */
  public static class MyTestTransactionListener extends TestTransactionListener
      implements Declarable {

    @Override
    public void init(Properties props) {}

    @Override
    public boolean equals(Object o) {
      return o instanceof MyTestTransactionListener;
    }
  }

  /**
   * A {@code CacheLoader} that is {@code Declarable} and has some interesting parameters.
   */
  public static class CacheLoaderWithDeclarables implements CacheLoader, Declarable2 {

    /** This loader's properties */
    private final Properties props;

    /** Was this declarable initialized */
    private boolean initialized = false;

    /**
     * Creates a new loader and initializes its properties
     */
    public CacheLoaderWithDeclarables() {
      props = new Properties();
      props.put("KEY1", "VALUE1");
      props.put("KEY2", new TestDeclarable());
    }

    /**
     * Returns whether or not this {@code Declarable} was initialized.
     */
    public boolean isInitialized() {
      return initialized;
    }

    @Override
    public void init(Properties props) {
      initialized = true;
      assertEquals(this.props, props);
    }

    @Override
    public Properties getConfig() {
      return props;
    }

    @Override
    public Object load(LoaderHelper helper) throws CacheLoaderException {

      fail("Loader shouldn't be invoked");
      return null;
    }

    public boolean equals(Object o) {
      if (o instanceof CacheLoaderWithDeclarables) {
        CacheLoaderWithDeclarables other = (CacheLoaderWithDeclarables) o;
        return props.equals(other.props);

      } else {
        return false;
      }
    }

    @Override
    public void close() {}

  }

  public static class TestDeclarable implements Declarable {
    @Override
    public void init(Properties props) {}

    public boolean equals(Object o) {
      return o instanceof TestDeclarable;
    }
  }

}
