This is an automated email from the ASF dual-hosted git repository.

klund pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 755eaaa  GEODE-4929: Add ability for tests to overide the default 
DiskDirs (#1701)
755eaaa is described below

commit 755eaaa56685a185de56e1bdc3c33d04ad4420dc
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Fri Mar 30 09:37:33 2018 -0700

    GEODE-4929: Add ability for tests to overide the default DiskDirs (#1701)
    
    * System property geode.defaultDiskDirs is used to specify some dir
      other than "."
    * DiskDirRule can be used by IntegrationTests
    * DistributedDiskDirRule can be used by DistributedTests
    * Update BucketRegionSizeWithOverflowRegressionTest to use
      DistributedDiskDirRule
---
 .../org/apache/geode/cache/AttributesFactory.java  |  12 +-
 .../geode/internal/cache/DiskStoreAttributes.java  |   3 +-
 .../apache/geode/internal/cache/LocalRegion.java   |   3 +-
 .../cache/persistence/DefaultDiskDirs.java         |  38 +++
 .../internal/cache/xmlcache/CacheXmlGenerator.java |   3 +-
 .../geode/internal/lang/SystemPropertyHelper.java  |  21 ++
 ...a => PRAccessorWithOverflowRegressionTest.java} |  29 +--
 .../DefaultDiskDirsIntegrationTest.java            |  47 ++++
 .../cache/persistence/DefaultDiskDirsTest.java     |  50 ++++
 .../test/dunit/rules/DistributedDiskDirRule.java   | 275 +++++++++++++++++++++
 .../apache/geode/test/junit/rules/DiskDirRule.java | 188 ++++++++++++++
 .../junit/rules/DescribedExternalResource.java     |  23 +-
 .../serializable/SerializableTemporaryFolder.java  |   8 +-
 .../rules/serializable/SerializableTestName.java   |   2 +-
 14 files changed, 656 insertions(+), 46 deletions(-)

diff --git 
a/geode-core/src/main/java/org/apache/geode/cache/AttributesFactory.java 
b/geode-core/src/main/java/org/apache/geode/cache/AttributesFactory.java
index f9f07bf..64e427a 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/AttributesFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/AttributesFactory.java
@@ -34,6 +34,7 @@ import org.apache.geode.internal.cache.EvictionAttributesImpl;
 import org.apache.geode.internal.cache.PartitionAttributesImpl;
 import org.apache.geode.internal.cache.PartitionedRegionHelper;
 import org.apache.geode.internal.cache.UserSpecifiedRegionAttributes;
+import org.apache.geode.internal.cache.persistence.DefaultDiskDirs;
 import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 
@@ -1541,18 +1542,15 @@ public class AttributesFactory<K, V> {
     boolean publisher = false;
     boolean enableAsyncConflation = false;
     boolean enableSubscriptionConflation = false;
-    @SuppressWarnings("deprecation")
     DiskWriteAttributes diskWriteAttributes = 
DiskWriteAttributesImpl.getDefaultSyncInstance();
-    File[] diskDirs = DiskStoreFactory.DEFAULT_DISK_DIRS;
-    int[] diskSizes = new int[] {DiskStoreFactory.DEFAULT_DISK_DIR_SIZE}; // 
10* 1024 MB }
+    File[] diskDirs = DefaultDiskDirs.getDefaultDiskDirs();
+    int[] diskSizes = DiskStoreFactory.DEFAULT_DISK_DIR_SIZES;
     boolean indexMaintenanceSynchronous = true;
-    PartitionAttributes partitionAttributes = null; // new 
PartitionAttributes();
+    PartitionAttributes partitionAttributes = null;
     MembershipAttributes membershipAttributes = new MembershipAttributes();
     SubscriptionAttributes subscriptionAttributes = new 
SubscriptionAttributes();
     boolean multicastEnabled = false;
-    EvictionAttributesImpl evictionAttributes = new EvictionAttributesImpl(); 
// TODO need to
-                                                                              
// determine the
-                                                                              
// constructor
+    EvictionAttributesImpl evictionAttributes = new EvictionAttributesImpl();
     String poolName = null;
     String diskStoreName = null;
     boolean diskSynchronous = DEFAULT_DISK_SYNCHRONOUS;
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreAttributes.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreAttributes.java
index 90b48c9..f5965e2 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreAttributes.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/DiskStoreAttributes.java
@@ -23,6 +23,7 @@ import java.util.UUID;
 
 import org.apache.geode.cache.DiskStore;
 import org.apache.geode.cache.DiskStoreFactory;
+import org.apache.geode.internal.cache.persistence.DefaultDiskDirs;
 
 /**
  * Creates an attribute object for DiskStore.
@@ -61,7 +62,7 @@ public class DiskStoreAttributes implements Serializable, 
DiskStore {
     this.timeInterval = DiskStoreFactory.DEFAULT_TIME_INTERVAL;
     this.writeBufferSize = DiskStoreFactory.DEFAULT_WRITE_BUFFER_SIZE;
     this.queueSize = DiskStoreFactory.DEFAULT_QUEUE_SIZE;
-    this.diskDirs = DiskStoreFactory.DEFAULT_DISK_DIRS;
+    this.diskDirs = DefaultDiskDirs.getDefaultDiskDirs();
     this.diskDirSizes = DiskStoreFactory.DEFAULT_DISK_DIR_SIZES;
     this.diskUsageWarningPct = 
DiskStoreFactory.DEFAULT_DISK_USAGE_WARNING_PERCENTAGE;
     this.diskUsageCriticalPct = 
DiskStoreFactory.DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE;
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java 
b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
index a1ae0a5..f12f1af 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
@@ -186,6 +186,7 @@ import 
org.apache.geode.internal.cache.execute.ServerToClientFunctionResultSende
 import org.apache.geode.internal.cache.ha.ThreadIdentifier;
 import org.apache.geode.internal.cache.partitioned.Bucket;
 import 
org.apache.geode.internal.cache.partitioned.RedundancyAlreadyMetException;
+import org.apache.geode.internal.cache.persistence.DefaultDiskDirs;
 import org.apache.geode.internal.cache.persistence.DiskExceptionHandler;
 import org.apache.geode.internal.cache.persistence.DiskRecoveryStore;
 import org.apache.geode.internal.cache.persistence.DiskRegionView;
@@ -7526,7 +7527,7 @@ public class LocalRegion extends AbstractRegion 
implements LoaderHelperFactory,
    */
   private boolean useDefaultDiskStore() {
     assert getDiskStoreName() == null;
-    if (!Arrays.equals(getDiskDirs(), DiskStoreFactory.DEFAULT_DISK_DIRS)) {
+    if (!Arrays.equals(getDiskDirs(), DefaultDiskDirs.getDefaultDiskDirs())) {
       return false;
     }
     if (!Arrays.equals(getDiskDirSizes(), 
DiskStoreFactory.DEFAULT_DISK_DIR_SIZES)) {
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirs.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirs.java
new file mode 100644
index 0000000..991e4c7
--- /dev/null
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirs.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.internal.cache.persistence;
+
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.DEFAULT_DISK_DIRS_PROPERTY;
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.getProductStringProperty;
+
+import java.io.File;
+import java.util.Optional;
+
+public class DefaultDiskDirs {
+
+  static File[] DEFAULT_DISK_DIRS_VALUE = new File[] {new File(".")};
+
+  public static File[] getDefaultDiskDirs() {
+    Optional<String> value = 
getProductStringProperty(DEFAULT_DISK_DIRS_PROPERTY);
+    if (value.isPresent()) {
+      String diskDirs = value.get();
+      return new File[] {new File(diskDirs)};
+    } else {
+      return DEFAULT_DISK_DIRS_VALUE;
+    }
+  }
+}
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGenerator.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGenerator.java
index 1bdb64c..58832d2 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGenerator.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlGenerator.java
@@ -123,6 +123,7 @@ import org.apache.geode.internal.cache.PartitionedRegion;
 import org.apache.geode.internal.cache.control.MemoryThresholds;
 import org.apache.geode.internal.cache.extension.Extensible;
 import org.apache.geode.internal.cache.extension.Extension;
+import org.apache.geode.internal.cache.persistence.DefaultDiskDirs;
 import org.apache.geode.internal.i18n.LocalizedStrings;
 import org.apache.geode.internal.size.SizeClassOnceObjectSizer;
 import org.apache.geode.management.internal.configuration.utils.XmlConstants;
@@ -1140,7 +1141,7 @@ public class CacheXmlGenerator extends CacheXml 
implements XMLReader {
         File[] diskDirs = ds.getDiskDirs();
         int[] diskSizes = ds.getDiskDirSizes();
         if (diskDirs != null && diskDirs.length > 0) {
-          if (generateDefaults() || !Arrays.equals(diskDirs, 
DiskStoreFactory.DEFAULT_DISK_DIRS)
+          if (generateDefaults() || !Arrays.equals(diskDirs, 
DefaultDiskDirs.getDefaultDiskDirs())
               || !Arrays.equals(diskSizes, 
DiskStoreFactory.DEFAULT_DISK_DIR_SIZES)) {
             handler.startElement("", DISK_DIRS, DISK_DIRS, EMPTY);
             for (int i = 0; i < diskDirs.length; i++) {
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/lang/SystemPropertyHelper.java
 
b/geode-core/src/main/java/org/apache/geode/internal/lang/SystemPropertyHelper.java
index 5208044..fc2551d 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/lang/SystemPropertyHelper.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/lang/SystemPropertyHelper.java
@@ -59,6 +59,8 @@ public class SystemPropertyHelper {
 
   public static final String EARLY_ENTRY_EVENT_SERIALIZATION = 
"earlyEntryEventSerialization";
 
+  public static final String DEFAULT_DISK_DIRS_PROPERTY = "defaultDiskDirs";
+
   /**
    * This method will try to look up "geode." and "gemfire." versions of the 
system property. It
    * will check and prefer "geode." setting first, then try to check 
"gemfire." setting.
@@ -71,6 +73,13 @@ public class SystemPropertyHelper {
     return property != null ? Optional.of(Boolean.parseBoolean(property)) : 
Optional.empty();
   }
 
+  /**
+   * This method will try to look up "geode." and "gemfire." versions of the 
system property. It
+   * will check and prefer "geode." setting first, then try to check 
"gemfire." setting.
+   *
+   * @param name system property name set in Geode
+   * @return an Optional containing the Integer value of the system property
+   */
   public static Optional<Integer> getProductIntegerProperty(String name) {
     Integer propertyValue = Integer.getInteger(GEODE_PREFIX + name);
     if (propertyValue == null) {
@@ -84,6 +93,18 @@ public class SystemPropertyHelper {
     }
   }
 
+  /**
+   * This method will try to look up "geode." and "gemfire." versions of the 
system property. It
+   * will check and prefer "geode." setting first, then try to check 
"gemfire." setting.
+   *
+   * @param name system property name set in Geode
+   * @return an Optional containing the String value of the system property
+   */
+  public static Optional<String> getProductStringProperty(String name) {
+    String property = getProperty(name);
+    return property != null ? Optional.of(property) : Optional.empty();
+  }
+
   private static String getProperty(String name) {
     String property = getGeodeProperty(name);
     return property != null ? property : getGemfireProperty(name);
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionSizeWithOverflowRegressionTest.java
 
b/geode-core/src/test/java/org/apache/geode/internal/cache/PRAccessorWithOverflowRegressionTest.java
similarity index 79%
rename from 
geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionSizeWithOverflowRegressionTest.java
rename to 
geode-core/src/test/java/org/apache/geode/internal/cache/PRAccessorWithOverflowRegressionTest.java
index 807966c..efb0f02 100644
--- 
a/geode-core/src/test/java/org/apache/geode/internal/cache/BucketRegionSizeWithOverflowRegressionTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/cache/PRAccessorWithOverflowRegressionTest.java
@@ -25,20 +25,18 @@ import java.io.File;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.cache.AttributesFactory;
 import org.apache.geode.cache.DataPolicy;
-import org.apache.geode.cache.DiskStoreFactory;
 import org.apache.geode.cache.PartitionAttributesFactory;
 import org.apache.geode.cache.Region;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.cache.CacheTestCase;
+import org.apache.geode.test.dunit.rules.DistributedDiskDirRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
-import 
org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
 import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
 
 /**
@@ -46,13 +44,9 @@ import 
org.apache.geode.test.junit.rules.serializable.SerializableTestName;
  *
  * <p>
  * TRAC #42055: a pr accessor configured for OverflowToDisk fails during 
creation because of disk
- *
- * <p>
- * TRAC #42055 also mentions delta so we should add test(s) for delta as well. 
<br>
- * TODO: Test that the bucket size does not go negative when we fault out and 
in a delta object.
  */
 @Category(DistributedTest.class)
-public class BucketRegionSizeWithOverflowRegressionTest extends CacheTestCase {
+public class PRAccessorWithOverflowRegressionTest extends CacheTestCase {
 
   private static final int ENTRIES_COUNT = 1;
 
@@ -64,10 +58,10 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
   private VM accessor;
 
   @Rule
-  public SerializableTemporaryFolder temporaryFolder = new 
SerializableTemporaryFolder();
+  public SerializableTestName testName = new SerializableTestName();
 
   @Rule
-  public SerializableTestName testName = new SerializableTestName();
+  public DistributedDiskDirRule diskDirsRule = new DistributedDiskDirRule();
 
   @Before
   public void setUp() throws Exception {
@@ -75,8 +69,9 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
     accessor = getHost(0).getVM(1);
 
     uniqueName = getClass().getSimpleName() + "_" + testName.getMethodName();
-    datastoreDiskDir = temporaryFolder.newFolder(uniqueName + 
"_datastore_disk");
-    accessorDiskDir = temporaryFolder.newFolder(uniqueName + "_accessor_disk");
+
+    datastoreDiskDir = diskDirsRule.getDiskDirFor(datastore);
+    accessorDiskDir = diskDirsRule.getDiskDirFor(accessor);
 
     datastore.invoke(() -> createDataStore());
     accessor.invoke(() -> createAccessor());
@@ -87,7 +82,6 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
     disconnectAllFromDS();
   }
 
-  @Ignore("GEODE-4929")
   @Test
   public void testPROverflow() throws Exception {
     accessor.invoke(() -> {
@@ -104,7 +98,6 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
     datastore.invoke(() -> {
       PartitionedRegion partitionedRegion = (PartitionedRegion) 
getCache().getRegion(uniqueName);
       assertThat(getCache().getRegion(uniqueName).size()).isEqualTo(2);
-      
assertThat(getCache().getRegion(uniqueName).size()).isGreaterThanOrEqualTo(0);
       
assertThat(partitionedRegion.getDataStore().getAllLocalBucketIds()).hasSize(2);
     });
 
@@ -117,12 +110,8 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
   }
 
   private void createDataStore() {
-    DiskStoreFactory dsf = getCache().createDiskStoreFactory();
-    dsf.setDiskDirs(new File[] {datastoreDiskDir});
-
     AttributesFactory af = new AttributesFactory();
     af.setDataPolicy(DataPolicy.PARTITION);
-    af.setDiskStoreName(dsf.create(uniqueName).getName());
     af.setEvictionAttributes(createLRUEntryAttributes(ENTRIES_COUNT, 
OVERFLOW_TO_DISK));
     af.setPartitionAttributes(new PartitionAttributesFactory().create());
 
@@ -130,15 +119,11 @@ public class BucketRegionSizeWithOverflowRegressionTest 
extends CacheTestCase {
   }
 
   private void createAccessor() {
-    DiskStoreFactory dsf = getCache().createDiskStoreFactory();
-    dsf.setDiskDirs(new File[] {accessorDiskDir});
-
     PartitionAttributesFactory<Integer, TestDelta> paf = new 
PartitionAttributesFactory<>();
     paf.setLocalMaxMemory(0);
 
     AttributesFactory<Integer, TestDelta> af = new AttributesFactory<>();
     af.setDataPolicy(DataPolicy.PARTITION);
-    af.setDiskStoreName(dsf.create(uniqueName).getName());
     af.setEvictionAttributes(createLRUEntryAttributes(ENTRIES_COUNT, 
OVERFLOW_TO_DISK));
     af.setPartitionAttributes(paf.create());
 
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsIntegrationTest.java
 
b/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsIntegrationTest.java
new file mode 100644
index 0000000..aadda75
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsIntegrationTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.internal.cache.persistence;
+
+import static 
org.apache.geode.internal.cache.persistence.DefaultDiskDirs.getDefaultDiskDirs;
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.DEFAULT_DISK_DIRS_PROPERTY;
+import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class DefaultDiskDirsIntegrationTest {
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Test
+  public void getDefaultDiskDirsReturnsOverriddenValue() {
+    System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY,
+        temporaryFolder.getRoot().getAbsolutePath());
+    
assertThat(getDefaultDiskDirs()[0]).exists().isEqualTo(temporaryFolder.getRoot());
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsTest.java
 
b/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsTest.java
new file mode 100644
index 0000000..c445bca
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/internal/cache/persistence/DefaultDiskDirsTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.internal.cache.persistence;
+
+import static 
org.apache.geode.internal.cache.persistence.DefaultDiskDirs.DEFAULT_DISK_DIRS_VALUE;
+import static 
org.apache.geode.internal.cache.persistence.DefaultDiskDirs.getDefaultDiskDirs;
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.DEFAULT_DISK_DIRS_PROPERTY;
+import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class DefaultDiskDirsTest {
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+  @Test
+  public void getDefaultDiskDirsReturnsTheDefault() throws Exception {
+    assertThat(getDefaultDiskDirs()).isEqualTo(DEFAULT_DISK_DIRS_VALUE);
+  }
+
+  @Test
+  public void getDefaultDiskDirsReturnsOverriddenValue() {
+    System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY, 
"/FullyQualifiedPath");
+    assertThat(getDefaultDiskDirs()).isEqualTo(new File[] {new 
File("/FullyQualifiedPath")});
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDiskDirRule.java
 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDiskDirRule.java
new file mode 100644
index 0000000..1ada67b
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDiskDirRule.java
@@ -0,0 +1,275 @@
+/*
+ * 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.test.dunit.rules;
+
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.DEFAULT_DISK_DIRS_PROPERTY;
+import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.getProductStringProperty;
+import static org.apache.geode.test.dunit.Host.getHost;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+import org.junit.runner.Description;
+
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.junit.rules.DiskDirRule;
+import 
org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestRule;
+
+/**
+ * JUnit Rule that overrides the default DiskDirs directory in all DUnit VMs 
(except for the hidden
+ * Locator VM). Internally, SerializableTemporaryFolder and 
SerializableTestName are used by this
+ * rule to define the directory locations and names.
+ *
+ * <p>
+ * You may either pass in instances of SerializableTemporaryFolder and 
SerializableTestName from
+ * the test or the DistributedDiskDirRule will create its own instances. 
Either way, it will invoke
+ * SerializableTemporaryFolder.before and 
SerializableTestName.starting(Description). If the test
+ * provides its own instances of these rules defined, please do not annotate 
these instances with
+ * {@code @Rule}.
+ *
+ * <p>
+ * Each JVM will have its own default DiskDirs directory in which that JVM 
will create the default
+ * disk store (if one is created). Each DiskDir name is defined as:
+ *
+ * <pre>
+ * "VM" + VM.getCurrentVMNum() + "-" + testClass + "_" + 
testName.getMethodName() + "-diskDirs"
+ * </pre>
+ *
+ * Using DistributedDiskDirRule will produce unique DiskDirs for each DUnit VM 
including the main
+ * controller VM (-1) but not the locator VM (-2):
+ *
+ * <pre>
+ * /var/folders/28/m__9dv1906n60kmz7t71wm680000gn/T/junit1766147044000254810
+ *     VM-1-PRAccessorWithOverflowRegressionTest_testPROverflow-diskDirs
+ *     VM0-PRAccessorWithOverflowRegressionTest_testPROverflow-diskDirs
+ *     VM1-PRAccessorWithOverflowRegressionTest_testPROverflow-diskDirs
+ *     VM2-PRAccessorWithOverflowRegressionTest_testPROverflow-diskDirs
+ *     VM3-PRAccessorWithOverflowRegressionTest_testPROverflow-diskDirs
+ * </pre>
+ *
+ * <p>
+ * Example of test using DistributedDiskDirRule:
+ *
+ * <pre>
+ * {@literal @}Category(DistributedTest.class)
+ * public class PRAccessorWithOverflowRegressionTest extends CacheTestCase {
+ *
+ *     {@literal @}Rule
+ *     public DistributedDiskDirRule diskDirsRule = new 
DistributedDiskDirRule();
+ * </pre>
+ */
+@SuppressWarnings("serial,unused")
+public class DistributedDiskDirRule extends DiskDirRule implements 
SerializableTestRule {
+
+  private static volatile DistributedDiskDirRuleData data;
+
+  private final SerializableTemporaryFolder temporaryFolder;
+  private final SerializableTestName testName;
+  private final RemoteInvoker invoker;
+
+  private volatile int beforeVmCount;
+
+  public DistributedDiskDirRule() {
+    this(new Builder());
+  }
+
+  public DistributedDiskDirRule(SerializableTemporaryFolder temporaryFolder) {
+    this(new Builder().temporaryFolder(temporaryFolder));
+  }
+
+  public DistributedDiskDirRule(SerializableTestName testName) {
+    this(new Builder().testName(testName));
+  }
+
+  public DistributedDiskDirRule(SerializableTemporaryFolder temporaryFolder,
+      SerializableTestName testName) {
+    this(new Builder().temporaryFolder(temporaryFolder).testName(testName));
+  }
+
+  public DistributedDiskDirRule(Builder builder) {
+    this(builder.fillIn(), new RemoteInvoker());
+  }
+
+  protected DistributedDiskDirRule(Builder builder, RemoteInvoker invoker) {
+    super(builder.initializeHelperRules, null, null);
+    temporaryFolder = builder.temporaryFolder;
+    testName = builder.testName;
+    this.invoker = invoker;
+  }
+
+  public File getDiskDirFor(VM vm) {
+    return new File(vm.invoke(() -> System.getProperty(GEODE_PREFIX + 
DEFAULT_DISK_DIRS_PROPERTY)));
+  }
+
+  @Override
+  protected void before(Description description) throws Exception {
+    beforeVmCount = getVMCount();
+
+    if (initializeHelperRules) {
+      initializeHelperRules(description);
+    }
+
+    invoker.invokeInEveryVMAndController(() -> doBefore(this, description));
+  }
+
+  @Override
+  protected void initializeHelperRules(Description description) throws 
Exception {
+    if (temporaryFolder != null) {
+      Method method = TemporaryFolder.class.getDeclaredMethod(BEFORE);
+      method.setAccessible(true);
+      method.invoke(temporaryFolder);
+    }
+
+    if (testName != null) {
+      Method method = TestName.class.getDeclaredMethod(STARTING, 
Description.class);
+      method.setAccessible(true);
+      method.invoke(testName, description);
+    }
+  }
+
+  @Override
+  protected void after(Description description) {
+    assertThat(getVMCount()).isEqualTo(beforeVmCount);
+
+    invoker.invokeInEveryVMAndController(() -> doAfter());
+  }
+
+  @Override
+  protected String getDiskDirName(String testClass) {
+    return "VM" + VM.getCurrentVMNum() + "-" + testClass + "_" + 
testName.getMethodName()
+        + "-diskDirs";
+  }
+
+  private void doBefore(DistributedDiskDirRule diskDirRule, Description 
description)
+      throws Exception {
+    data = new DistributedDiskDirRuleData(diskDirRule);
+
+    Optional<String> value = 
getProductStringProperty(DEFAULT_DISK_DIRS_PROPERTY);
+    value.ifPresent(s -> data.setOriginalValue(s));
+
+    File diskDir = 
data.temporaryFolder().newFolder(getDiskDirName(getTestClassName(description)));
+
+    System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY, 
diskDir.getAbsolutePath());
+  }
+
+  private void doAfter() {
+    if (data.originalValue() == null) {
+      System.clearProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY);
+    } else {
+      System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY, 
data.originalValue());
+    }
+  }
+
+  private int getVMCount() {
+    try {
+      return getHost(0).getVMCount();
+    } catch (IllegalArgumentException e) {
+      throw new IllegalStateException("DUnit VMs have not been launched");
+    }
+  }
+
+  /**
+   * Data for DistributedDiskDirRule for each DUnit child VM.
+   */
+  private static class DistributedDiskDirRuleData {
+    private final SerializableTemporaryFolder temporaryFolder;
+    private final SerializableTestName testName;
+
+    private volatile String originalValue;
+
+    DistributedDiskDirRuleData(DistributedDiskDirRule diskDirRule) {
+      this(diskDirRule.temporaryFolder, diskDirRule.testName);
+    }
+
+    private DistributedDiskDirRuleData(SerializableTemporaryFolder 
temporaryFolder,
+        SerializableTestName testName) {
+      this.temporaryFolder = temporaryFolder;
+      this.testName = testName;
+    }
+
+    SerializableTemporaryFolder temporaryFolder() {
+      return temporaryFolder;
+    }
+
+    SerializableTestName testName() {
+      return testName;
+    }
+
+    String originalValue() {
+      return originalValue;
+    }
+
+    void setOriginalValue(String originalValue) {
+      this.originalValue = originalValue;
+    }
+  }
+
+  /**
+   * Builds an instance of DistributedDiskDirRule
+   */
+  public static class Builder {
+    private boolean initializeHelperRules = true;
+    private SerializableTemporaryFolder temporaryFolder;
+    private SerializableTestName testName;
+
+    public Builder() {
+      // nothing
+    }
+
+    /**
+     * Specify false to disable initializing SerializableTemporaryFolder and 
SerializableTestName
+     * during DistributedDiskDirRule initialization. If this is enabled then 
do NOT annotate these
+     * helper rules in the test or combine them with RuleChain or RuleList. 
Default value is true.
+     */
+    public Builder initializeHelperRules(boolean value) {
+      initializeHelperRules = value;
+      return this;
+    }
+
+    public Builder temporaryFolder(SerializableTemporaryFolder 
temporaryFolder) {
+      this.temporaryFolder = temporaryFolder;
+      return this;
+    }
+
+    public Builder testName(SerializableTestName testName) {
+      this.testName = testName;
+      return this;
+    }
+
+    public DistributedDiskDirRule build() {
+      fillIn();
+      return new DistributedDiskDirRule(this);
+    }
+
+    private Builder fillIn() {
+      if (temporaryFolder == null) {
+        temporaryFolder = new SerializableTemporaryFolder();
+      }
+      if (testName == null) {
+        testName = new SerializableTestName();
+      }
+      return this;
+    }
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/rules/DiskDirRule.java 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/DiskDirRule.java
new file mode 100644
index 0000000..bbeec89
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/DiskDirRule.java
@@ -0,0 +1,188 @@
+/*
+ * 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.test.junit.rules;
+
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.DEFAULT_DISK_DIRS_PROPERTY;
+import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
+import static 
org.apache.geode.internal.lang.SystemPropertyHelper.getProductStringProperty;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Optional;
+
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+import org.junit.runner.Description;
+
+@SuppressWarnings("unused")
+public class DiskDirRule extends DescribedExternalResource {
+
+  protected static final String BEFORE = "before";
+  protected static final String AFTER = "after";
+  protected static final String STARTING = "starting";
+
+  protected final boolean initializeHelperRules;
+
+  private final TemporaryFolder temporaryFolder;
+  private final TestName testName;
+
+  private String originalValue;
+
+  public DiskDirRule(TemporaryFolder temporaryFolder) {
+    this(new Builder().temporaryFolder(temporaryFolder));
+  }
+
+  public DiskDirRule(TestName testName) {
+    this(new Builder().testName(testName));
+  }
+
+  public DiskDirRule(TemporaryFolder temporaryFolder, TestName testName) {
+    this(new Builder().temporaryFolder(temporaryFolder).testName(testName));
+  }
+
+  public DiskDirRule(Builder builder) {
+    this(builder.initializeHelperRules, builder.temporaryFolder, 
builder.testName);
+  }
+
+  protected DiskDirRule() {
+    this(false, null, null);
+  }
+
+  protected DiskDirRule(boolean initializeHelperRules, TemporaryFolder 
temporaryFolder,
+      TestName testName) {
+    this.initializeHelperRules = initializeHelperRules;
+    this.temporaryFolder = temporaryFolder;
+    this.testName = testName;
+  }
+
+  @Override
+  protected void before(Description description) throws Exception {
+    Optional<String> value = 
getProductStringProperty(DEFAULT_DISK_DIRS_PROPERTY);
+    value.ifPresent(s -> originalValue = s);
+
+    if (initializeHelperRules) {
+      initializeHelperRules(description);
+    }
+
+    File diskDir =
+        
temporaryFolder.newFolder(getDiskDirName(getDiskDirName(description.getClassName())));
+
+    System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY, 
diskDir.getAbsolutePath());
+  }
+
+  protected void initializeHelperRules(Description description) throws 
Exception {
+    if (temporaryFolder != null) {
+      Method method = TemporaryFolder.class.getDeclaredMethod(BEFORE);
+      method.setAccessible(true);
+      method.invoke(temporaryFolder);
+    }
+
+    if (testName != null) {
+      Method method = TestName.class.getDeclaredMethod(STARTING, 
Description.class);
+      method.setAccessible(true);
+      method.invoke(testName, description);
+    }
+  }
+
+  @Override
+  protected void after(Description description) {
+    if (originalValue == null) {
+      System.clearProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY);
+    } else {
+      System.setProperty(GEODE_PREFIX + DEFAULT_DISK_DIRS_PROPERTY, 
originalValue);
+    }
+  }
+
+  protected String getDiskDirName(String testClass) {
+    return testClass + "_" + testName.getMethodName() + "-diskDirs";
+  }
+
+  protected String getTestClassName(Description description) {
+    return description.getTestClass().getSimpleName();
+  }
+
+  protected void invokeTemporaryFolderBefore(TemporaryFolder temporaryFolder) {
+    if (temporaryFolder != null) {
+      invoke(TemporaryFolder.class, temporaryFolder, BEFORE);
+    }
+  }
+
+  protected void invokeTestNameBefore(TestName testName) {
+    if (testName != null) {
+      invoke(TestName.class, testName, BEFORE);
+    }
+  }
+
+  protected <V> V invoke(Class<?> targetClass, Object targetInstance, String 
methodName) {
+    try {
+      Method method = targetClass.getDeclaredMethod(methodName);
+      method.setAccessible(true);
+      return (V) method.invoke(targetInstance);
+    } catch (IllegalAccessException | InvocationTargetException | 
NoSuchMethodException e) {
+      throw new Error(e);
+    }
+  }
+
+  /**
+   * Builds an instance of DiskDirRule
+   */
+  public static class Builder {
+    private boolean initializeHelperRules = true;
+    private TemporaryFolder temporaryFolder;
+    private TestName testName;
+
+    public Builder() {
+      // nothing
+    }
+
+    /**
+     * Specify false to disable initializing TemporaryFolder and TestName 
during DiskDirRule
+     * initialization. If this is enabled then do NOT annotate these helper 
rules in the test or
+     * combine them with RuleChain or RuleList. Default value is true.
+     */
+    public Builder initializeHelperRules(boolean value) {
+      initializeHelperRules = value;
+      return this;
+    }
+
+    public Builder temporaryFolder(TemporaryFolder temporaryFolder) {
+      this.temporaryFolder = temporaryFolder;
+      return this;
+    }
+
+    public Builder testName(TestName testName) {
+      this.testName = testName;
+      return this;
+    }
+
+    public DiskDirRule build() {
+      fillIn();
+      return new DiskDirRule(this);
+    }
+
+    private Builder fillIn() {
+      if (temporaryFolder == null) {
+        temporaryFolder = new TemporaryFolder();
+      }
+      if (testName == null) {
+        testName = new TestName();
+      }
+      return this;
+    }
+  }
+}
diff --git 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
index f8d4668..106c713 100644
--- 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
+++ 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
@@ -19,16 +19,19 @@ import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 /**
- * this class extends the capability of JUnit's ExternalResource in that it 
provides a Description
- * object in the before and after methods, so that the implementation would 
have access to the
- * annotation of the test methods
+ * A base class for Rules that require {@code Description} to set up an 
external resource before
+ * a test and tear it down afterward. {@code DescribedExternalResource} is 
similar to
+ * {@code ExternalResource} but includes {@code Description} as a parameter to 
both {@code before}
+ * and {@code after}.
+ *
+ * <p>
+ * {@code Description} allows the implementation to have access to the test 
class, its annotations
+ * and information about JUnit lifecycle.
  */
 public abstract class DescribedExternalResource implements TestRule {
-  public Statement apply(Statement base, Description description) {
-    return statement(base, description);
-  }
 
-  private Statement statement(final Statement base, final Description 
description) {
+  @Override
+  public Statement apply(Statement base, Description description) {
     return new Statement() {
       @Override
       public void evaluate() throws Throwable {
@@ -42,18 +45,18 @@ public abstract class DescribedExternalResource implements 
TestRule {
     };
   }
 
-
   /**
    * Override to set up your specific external resource.
    *
-   * @throws Throwable if setup fails (which will disable {@code after}
+   * @throws Throwable if setup fails (which will prevent the invocation of 
{@code after})
    */
   protected void before(Description description) throws Throwable {
     // do nothing
   }
 
   /**
-   * Override to tear down your specific external resource.
+   * Override to tear down your specific external resource. Note: 
ExternalResource after
+   * does not include {@code throws Throwable}.
    */
   protected void after(Description description) throws Throwable {
     // do nothing
diff --git 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTemporaryFolder.java
 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTemporaryFolder.java
index 3d55336..a7cf565 100755
--- 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTemporaryFolder.java
+++ 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTemporaryFolder.java
@@ -14,8 +14,10 @@
  */
 package org.apache.geode.test.junit.rules.serializable;
 
-import static 
org.apache.geode.test.junit.rules.serializable.FieldSerializationUtils.*;
-import static 
org.apache.geode.test.junit.rules.serializable.FieldsOfTemporaryFolder.*;
+import static 
org.apache.geode.test.junit.rules.serializable.FieldSerializationUtils.readField;
+import static 
org.apache.geode.test.junit.rules.serializable.FieldSerializationUtils.writeField;
+import static 
org.apache.geode.test.junit.rules.serializable.FieldsOfTemporaryFolder.FIELD_FOLDER;
+import static 
org.apache.geode.test.junit.rules.serializable.FieldsOfTemporaryFolder.FIELD_PARENT_FOLDER;
 
 import java.io.File;
 import java.io.InvalidObjectException;
@@ -25,7 +27,7 @@ import java.io.Serializable;
 import org.junit.rules.TemporaryFolder;
 
 /**
- * Serializable subclass of {@link org.junit.rules.TemporaryFolder 
TemporaryFolder}. Instance
+ * Serializable subclass of {@link TemporaryFolder TemporaryFolder}. Instance
  * variables of TemporaryFolder are serialized by reflection.
  */
 public class SerializableTemporaryFolder extends TemporaryFolder implements 
SerializableTestRule {
diff --git 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTestName.java
 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTestName.java
index 437ca17..bb3436d 100755
--- 
a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTestName.java
+++ 
b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableTestName.java
@@ -25,7 +25,7 @@ import org.junit.rules.TestName;
 import org.junit.runner.Description;
 
 /**
- * Serializable subclass of {@link org.junit.rules.TestName TestName}. All 
instance variables of
+ * Serializable subclass of {@link TestName TestName}. All instance variables 
of
  * {@code TestName} are serialized by reflection.
  */
 public class SerializableTestName extends TestName implements 
SerializableTestRule {

-- 
To stop receiving notification emails like this one, please contact
kl...@apache.org.

Reply via email to