You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/02/22 00:43:40 UTC
geode git commit: GEODE-2514: add new tests for statistics archive
rolling and removal
Repository: geode
Updated Branches:
refs/heads/feature/GEODE-2514 [created] d6ca901f7
GEODE-2514: add new tests for statistics archive rolling and removal
* add MainWithChildrenRollingFileHandlerIntegrationTest
* add StatArchiveHandlerIntegrationTest
* expand DiskSpaceLimitIntegrationTest
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/d6ca901f
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/d6ca901f
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/d6ca901f
Branch: refs/heads/feature/GEODE-2514
Commit: d6ca901f7f225c331e54c6ad7d300a9139a39ffb
Parents: c6b941f
Author: Kirk Lund <kl...@apache.org>
Authored: Tue Feb 21 13:09:24 2017 -0800
Committer: Kirk Lund <kl...@apache.org>
Committed: Tue Feb 21 13:40:50 2017 -0800
----------------------------------------------------------------------
.../io/MainWithChildrenRollingFileHandler.java | 6 +-
.../internal/statistics/StatArchiveHandler.java | 6 +-
...ildrenRollingFileHandlerIntegrationTest.java | 96 ++++++++
.../DiskSpaceLimitIntegrationTest.java | 245 ++++++++++++++++++-
.../StatArchiveHandlerIntegrationTest.java | 243 ++++++++++++++++++
5 files changed, 582 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/d6ca901f/geode-core/src/main/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandler.java b/geode-core/src/main/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandler.java
index 20d1c4f..11d10af 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandler.java
@@ -206,7 +206,11 @@ public class MainWithChildrenRollingFileHandler implements RollingFileHandler {
return tmp;
}
- private Pattern getFilePattern(String name) {
+ Pattern getFilePattern(String name) {
+ if (name == null || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Name must not be empty");
+ }
+
int extIdx = name.lastIndexOf('.');
String ext = "";
if (extIdx != -1) {
http://git-wip-us.apache.org/repos/asf/geode/blob/d6ca901f/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
index 3eb9730..03b0f89 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
@@ -446,7 +446,7 @@ public class StatArchiveHandler implements SampleHandler {
* @return the modified archive file name to use; it is modified by applying mainArchiveId and
* archiveId to the name for supporting file rolling
*/
- private File getRollingArchiveName(File archive, boolean archiveClosed) {
+ File getRollingArchiveName(File archive, boolean archiveClosed) {
if (mainArchiveId != -1) {
// leave mainArchiveId as is. Bump archiveId.
} else {
@@ -538,7 +538,7 @@ public class StatArchiveHandler implements SampleHandler {
return result;
}
- private void initMainArchiveId(File archive) {
+ void initMainArchiveId(File archive) {
if (mainArchiveId != -1) {
// already initialized
return;
@@ -598,7 +598,7 @@ public class StatArchiveHandler implements SampleHandler {
* @return the modified archive file name to use; it is modified by applying the next main id if
* any files in the dir already have a main id in the file name
*/
- private File getRenameArchiveName(File archive) {
+ File getRenameArchiveName(File archive) {
File dir = archive.getAbsoluteFile().getParentFile();
int previousMainId = this.rollingFileHandler.calcNextMainId(dir, false);
if (previousMainId == 0) {
http://git-wip-us.apache.org/repos/asf/geode/blob/d6ca901f/geode-core/src/test/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandlerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandlerIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandlerIntegrationTest.java
new file mode 100644
index 0000000..5ea77c4
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/io/MainWithChildrenRollingFileHandlerIntegrationTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.io;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.regex.Pattern;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class MainWithChildrenRollingFileHandlerIntegrationTest {
+
+ private String name;
+ private MainWithChildrenRollingFileHandler handler;
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void before() throws Exception {
+ this.name = this.testName.getMethodName();
+ this.handler = new MainWithChildrenRollingFileHandler();
+ }
+
+ @Test
+ public void getFilePattern_matchesFilesWithBothIds() throws Exception {
+ Pattern pattern = this.handler.getFilePattern(this.name);
+
+ assertThat(pattern).isNotNull();
+ assertThat(pattern.matcher(this.name).matches()).isFalse();
+ assertThat(pattern.matcher(this.name + "-01-01").matches()).isTrue();
+ assertThat(pattern.matcher(this.name + "-01-02").matches()).isTrue();
+ assertThat(pattern.matcher(this.name + "-02-01").matches()).isTrue();
+ assertThat(pattern.matcher(this.name + "-01").matches()).isFalse();
+ assertThat(pattern.matcher(this.name + "0101").matches()).isFalse();
+ assertThat(pattern.matcher(this.name + "--").matches()).isFalse();
+
+ // TODO: revisit these to determine if behavior should change
+ assertThat(pattern.matcher(this.name + "-01-01-01").matches()).isFalse();
+ assertThat(pattern.matcher(this.name + ".01-01-01").matches()).isFalse();
+ }
+
+ @Test
+ public void getFilePattern_withNumbers_matchesFiles() throws Exception {
+ this.name = "a1s2d3f4_cache1_statistics";
+ Pattern pattern = this.handler.getFilePattern(this.name);
+
+ assertThat(pattern).isNotNull();
+ assertThat(pattern.matcher(this.name + "-01-41").matches()).isTrue();
+ }
+
+ @Test
+ public void getFilePattern_withHyphens_matchesFiles() throws Exception {
+ this.name = "a1s2d3f4_cache1-statistics";
+ Pattern pattern = this.handler.getFilePattern(this.name);
+
+ assertThat(pattern).isNotNull();
+ assertThat(pattern.matcher(this.name + "-01-41").matches()).isTrue();
+ }
+
+ @Test
+ public void getFilePattern_empty_throwsIllegalArgumentException() throws Exception {
+ this.name = "";
+
+ assertThatThrownBy(() -> this.handler.getFilePattern(this.name))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void getFilePattern_null_throwsIllegalArgumentException() throws Exception {
+ this.name = null;
+
+ assertThatThrownBy(() -> this.handler.getFilePattern(this.name))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/geode/blob/d6ca901f/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java
index 1702d9a..5d94fa0 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java
@@ -14,8 +14,10 @@
*/
package org.apache.geode.internal.statistics;
+import static java.lang.String.valueOf;
import static java.util.concurrent.TimeUnit.MINUTES;
-import static org.apache.commons.io.FileUtils.moveFileToDirectory;
+import static org.apache.commons.io.FileUtils.*;
+import static org.apache.commons.lang.StringUtils.leftPad;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -37,9 +39,14 @@ import org.junit.rules.TestName;
import java.io.File;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.TimeoutException;
@Category(IntegrationTest.class)
+@SuppressWarnings("unused")
public class DiskSpaceLimitIntegrationTest {
private static final long FILE_SIZE_LIMIT = 256;
@@ -48,6 +55,8 @@ public class DiskSpaceLimitIntegrationTest {
private File dir;
private File dirOfDeletedFiles;
+ private String name;
+
private String archiveFileName;
private LocalStatisticsFactory factory;
@@ -55,9 +64,14 @@ public class DiskSpaceLimitIntegrationTest {
private StatisticsType statisticsType;
private Statistics statistics;
+ private RollingFileHandler testRollingFileHandler;
+ private MainWithChildrenRollingFileHandler mainWithChildrenRollingFileHandler;
+
private SampleCollector sampleCollector;
private StatArchiveHandlerConfig config;
+ private long initTimeStamp;
+
private NanoTimer timer = new NanoTimer();
private long nanosTimeStamp;
@@ -69,10 +83,10 @@ public class DiskSpaceLimitIntegrationTest {
@Before
public void setUp() throws Exception {
this.dir = this.temporaryFolder.getRoot();
- this.dirOfDeletedFiles = this.temporaryFolder.newFolder("deleted");
- this.archiveFileName =
- new File(this.dir, this.testName.getMethodName() + ".gfs").getAbsolutePath();
+ this.name = this.testName.getMethodName();
+
+ this.archiveFileName = new File(this.dir, this.name + ".gfs").getAbsolutePath();
this.factory = new LocalStatisticsFactory(null);
this.statisticDescriptors = new StatisticDescriptor[] {
@@ -93,11 +107,12 @@ public class DiskSpaceLimitIntegrationTest {
.thenReturn(this.temporaryFolder.getRoot().getAbsolutePath());
when(this.config.getProductDescription()).thenReturn(this.testName.getMethodName());
- RollingFileHandler rollingFileHandler = new TestableRollingFileHandler();
+ this.testRollingFileHandler = new TestableRollingFileHandler();
+ this.mainWithChildrenRollingFileHandler = new MainWithChildrenRollingFileHandler();
this.sampleCollector = new SampleCollector(sampler);
- this.sampleCollector.initialize(this.config, NanoTimer.getTime(), rollingFileHandler);
+ this.initTimeStamp = NanoTimer.getTime();
this.timer.reset();
this.nanosTimeStamp = this.timer.getLastResetTime() - getNanoRate();
}
@@ -109,6 +124,9 @@ public class DiskSpaceLimitIntegrationTest {
@Test
public void zeroKeepsAllFiles() throws Exception {
+ this.dirOfDeletedFiles = this.temporaryFolder.newFolder("deleted");
+ this.sampleCollector.initialize(this.config, this.initTimeStamp, this.testRollingFileHandler);
+
when(this.config.getArchiveDiskSpaceLimit()).thenReturn(0L);
sampleUntilFileExists(archiveFile(1));
sampleUntilFileExists(archiveFile(2));
@@ -118,6 +136,9 @@ public class DiskSpaceLimitIntegrationTest {
@Test
public void aboveZeroDeletesOldestFile() throws Exception {
+ this.dirOfDeletedFiles = this.temporaryFolder.newFolder("deleted");
+ this.sampleCollector.initialize(this.config, this.initTimeStamp, this.testRollingFileHandler);
+
when(this.config.getArchiveDiskSpaceLimit()).thenReturn(DISK_SPACE_LIMIT);
sampleUntilFileExists(archiveFile(1));
sampleUntilFileExists(archiveFile(2));
@@ -138,6 +159,118 @@ public class DiskSpaceLimitIntegrationTest {
assertThat(everExisted(archiveFile(1))).isTrue();
}
+ @Test
+ public void aboveZeroDeletesPreviousFiles() throws Exception {
+ assertThat(numberOfFiles(this.dir)).as("Unexpected files: " + listFiles(this.dir)).isEqualTo(0);
+
+ int oldMainId = 1;
+ int newMainId = 2;
+
+ int numberOfPreviousFiles = 100;
+ int numberOfLines = 100;
+ createPreviousFiles(oldMainId, numberOfPreviousFiles, numberOfLines);
+ assertThat(numberOfFiles(this.dir)).as("Missing files: " + listFiles(this.dir))
+ .isEqualTo(numberOfPreviousFiles);
+
+ for (int childId = 1; childId <= numberOfPreviousFiles; childId++) {
+ assertThat(archiveFile(oldMainId, childId)).exists();
+ }
+
+ // current archive file does not exist yet
+ assertThat(archiveFile()).doesNotExist();
+
+ // rolling files for mainId 2 do not exist yet
+ assertThat(markerFile(newMainId)).doesNotExist();
+ assertThat(archiveFile(newMainId, 1)).doesNotExist();
+
+ when(this.config.getArchiveDiskSpaceLimit())
+ .thenReturn(sizeOfDirectory(this.dir) / numberOfPreviousFiles);
+
+ this.sampleCollector.initialize(this.config, this.initTimeStamp,
+ this.mainWithChildrenRollingFileHandler);
+
+ assertThat(archiveFile()).exists().hasParent(this.dir);
+ assertThat(markerFile(newMainId)).exists().hasParent(this.dir).hasBinaryContent(new byte[0]);
+
+ assertThat(archiveFile(newMainId, 1)).doesNotExist();
+
+ sampleNumberOfTimes(1);
+
+ sampleUntilFileExists(archiveFile(newMainId, 1));
+ assertThat(archiveFile(newMainId, 1)).exists();
+
+ // this might be a brittle assertion... ok to delete if following for-block-assertion passes
+ assertThat(numberOfFiles(this.dir)).as("Unexpected files: " + listFiles(this.dir)).isEqualTo(2);
+
+ for (int childId = 1; childId <= numberOfPreviousFiles; childId++) {
+ assertThat(archiveFile(oldMainId, childId)).doesNotExist();
+ }
+ }
+
+ @Test
+ public void aboveZeroDeletesPreviousFiles_nameWithHyphen() throws Exception {
+ this.name = "psin8p724_cache1-statistics";
+ this.archiveFileName = new File(this.dir, this.name + ".gfs").getAbsolutePath();
+ when(this.config.getArchiveFileName()).thenReturn(new File(this.archiveFileName));
+
+ assertThat(numberOfFiles(this.dir)).as("Unexpected files: " + listFiles(this.dir)).isEqualTo(0);
+
+ int oldMainId = 1;
+ int newMainId = 2;
+
+ int numberOfPreviousFiles = 100;
+ int numberOfLines = 100;
+ createPreviousFiles(oldMainId, numberOfPreviousFiles, numberOfLines);
+ assertThat(numberOfFiles(this.dir)).as("Missing files: " + listFiles(this.dir))
+ .isEqualTo(numberOfPreviousFiles);
+
+ for (int childId = 1; childId <= numberOfPreviousFiles; childId++) {
+ assertThat(archiveFile(oldMainId, childId)).exists();
+ }
+
+ // current archive file does not exist yet
+ assertThat(archiveFile()).doesNotExist();
+
+ // rolling files for mainId 2 do not exist yet
+ assertThat(markerFile(newMainId)).doesNotExist();
+ assertThat(archiveFile(newMainId, 1)).doesNotExist();
+
+ when(this.config.getArchiveDiskSpaceLimit())
+ .thenReturn(sizeOfDirectory(this.dir) / numberOfPreviousFiles);
+
+ this.sampleCollector.initialize(this.config, this.initTimeStamp,
+ this.mainWithChildrenRollingFileHandler);
+
+ assertThat(archiveFile()).exists().hasParent(this.dir);
+ assertThat(markerFile(newMainId)).exists().hasParent(this.dir).hasBinaryContent(new byte[0]);
+
+ assertThat(archiveFile(newMainId, 1)).doesNotExist();
+
+ sampleNumberOfTimes(1);
+
+ sampleUntilFileExists(archiveFile(newMainId, 1));
+ assertThat(archiveFile(newMainId, 1)).exists();
+
+ // this might be a brittle assertion... ok to delete if following for-block-assertion passes
+ assertThat(numberOfFiles(this.dir)).as("Unexpected files: " + listFiles(this.dir)).isEqualTo(2);
+
+ for (int childId = 1; childId <= numberOfPreviousFiles; childId++) {
+ assertThat(archiveFile(oldMainId, childId)).doesNotExist();
+ }
+ }
+
+ private void sampleNumberOfTimes(final int value) throws InterruptedException {
+ long minutes = 1;
+ long timeout = System.nanoTime() + MINUTES.toNanos(minutes);
+ int count = 0;
+ do {
+ sample(advanceNanosTimeStamp());
+ count++;
+ Thread.sleep(10);
+ } while (count < value && System.nanoTime() < timeout);
+ System.out.println("Sampled " + count + " times.");
+ }
+
private void sampleUntilFileExists(final File file)
throws InterruptedException, TimeoutException {
long minutes = 1;
@@ -203,9 +336,102 @@ public class DiskSpaceLimitIntegrationTest {
return 1000; // 1 second
}
- private File archiveFile(final int child) {
- return new File(this.dir,
- this.testName.getMethodName() + "-01-" + String.format("%02d", child) + ".gfs");
+ private File archiveFile() {
+ return archiveFile(archiveName());
+ }
+
+ private String archiveName() {
+ return this.name;
+ }
+
+ private File archiveFile(final String name) {
+ return new File(this.dir, name + ".gfs");
+ }
+
+ private File archiveFile(final int childId) {
+ return archiveFile(1, childId);
+ }
+
+ private File archiveFile(final int mainId, final int childId) {
+ return archiveFile(archiveName(), mainId, childId);
+ }
+
+ private File archiveFile(final String name, final int mainId, final int childId) {
+ return new File(this.dir, archiveName(name, mainId, childId) + ".gfs");
+ }
+
+ private String archiveName(final int mainId, final int childId) {
+ return archiveName(archiveName(), mainId, childId);
+ }
+
+ private String archiveName(final String name, final int mainId, final int childId) {
+ return name + "-" + formatId(mainId) + "-" + formatId(childId);
+ }
+
+ private File markerFile(final int mainId) {
+ return markerFile(archiveName(), mainId);
+ }
+
+ private File markerFile(final String name, final int mainId) {
+ return new File(this.dir, markerName(name, mainId));
+ }
+
+ private String markerName(final int mainId) {
+ return markerName(archiveName(), mainId);
+ }
+
+ private String markerName(final String name, final int mainId) {
+ return archiveName(name, mainId, 0) + ".marker";
+ }
+
+ private String formatId(final int id) {
+ return String.format("%02d", id);
+ }
+
+ private List<File> listFiles(final File dir) {
+ return Arrays.asList(dir.listFiles());
+ }
+
+ private int numberOfFiles(final File dir) {
+ return dir.listFiles().length;
+ }
+
+ private void createPreviousFiles(final int mainId, final int fileCount, final int lineCount)
+ throws IOException {
+ createPreviousFiles(this.name, mainId, fileCount, lineCount);
+ }
+
+ private void createPreviousFiles(final String name, final int mainId, final int fileCount,
+ final int lineCount) throws IOException {
+ int childId = 1;
+ List<String> lines = lines(lineCount);
+ for (int i = 0; i < fileCount; i++) {
+ File file = createFile(name, mainId, childId);
+ writeFile(file, lines);
+ childId++;
+ }
+ }
+
+ private File createFile(final String name, final int mainId, final int childId) {
+ File file = new File(this.dir, name + "-" + leftPad(valueOf(mainId), 2, "0") + "-"
+ + leftPad(valueOf(childId), 2, "0") + ".gfs");
+ return file;
+ }
+
+ private void writeFile(final File file, final List<String> lines) throws IOException {
+ PrintWriter writer = new PrintWriter(file, "UTF-8");
+ for (String line : lines) {
+ writer.println(line);
+ }
+ writer.close();
+ }
+
+ private List<String> lines(final int lineCount) {
+ List<String> lines = new ArrayList<>();
+ for (int i = 0; i < lineCount; i++) {
+ lines.add(this.testName.getMethodName());
+ }
+ return lines;
}
/**
@@ -222,5 +448,4 @@ public class DiskSpaceLimitIntegrationTest {
}
}
}
-
}
http://git-wip-us.apache.org/repos/asf/geode/blob/d6ca901f/geode-core/src/test/java/org/apache/geode/internal/statistics/StatArchiveHandlerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/statistics/StatArchiveHandlerIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/statistics/StatArchiveHandlerIntegrationTest.java
new file mode 100644
index 0000000..ca5993c
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/StatArchiveHandlerIntegrationTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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.statistics;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.io.IOException;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+import org.apache.geode.internal.io.MainWithChildrenRollingFileHandler;
+import org.apache.geode.internal.io.RollingFileHandler;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+/**
+ * Tests behavior that interacts with file system.
+ */
+@Category(IntegrationTest.class)
+@RunWith(JUnitParamsRunner.class)
+public class StatArchiveHandlerIntegrationTest {
+
+ private File dir;
+ private String ext;
+ private String name;
+ private File archive;
+
+ private StatArchiveHandlerConfig mockConfig;
+ private SampleCollector mockCollector;
+ private RollingFileHandler rollingFileHandler;
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void setUp() throws Exception {
+ this.dir = this.temporaryFolder.getRoot();
+
+ this.ext = ".gfs";
+ this.name = this.testName.getMethodName();
+ this.archive = new File(this.dir, this.name + this.ext);
+
+ this.mockConfig = mock(StatArchiveHandlerConfig.class);
+ this.mockCollector = mock(SampleCollector.class);
+ this.rollingFileHandler = new MainWithChildrenRollingFileHandler();
+ }
+
+ @Test
+ @Parameters({"false,false,false", "false,false,true", "false,true,false", "false,true,true",
+ "true,false,false", "true,false,true", "true,true,false", "true,true,true"})
+ public void getRollingArchiveName_withEmptyDir_createsFirstIds(final boolean archiveExists,
+ final boolean archiveClosed, final boolean initMainId) throws Exception {
+ if (archiveExists) {
+ this.archive.createNewFile();
+ }
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ if (initMainId) {
+ handler.initMainArchiveId(this.archive);
+ }
+
+ File file = handler.getRollingArchiveName(this.archive, archiveClosed);
+
+ assertThat(file).hasParent(this.dir).hasName(this.name + formatIds(1, 1) + this.ext);
+ }
+
+ @Test
+ @Parameters({"1,1,false,false", "1,1,false,true", "1,1,true,false", "1,1,true,true",
+ "1,10,false,false", "1,10,false,true", "1,10,true,false", "1,10,true,true",
+ "10,1,false,false", "10,1,false,true", "10,1,true,false", "10,1,true,true",
+ "10,10,false,false", "10,10,false,true", "10,10,true,false", "10,10,true,true"})
+ public void getRollingArchiveName_withOldArchives_rollsChildId(final int mainCount,
+ final int childCount, final boolean archiveExists, final boolean archiveClosed)
+ throws Exception {
+ createEmptyArchiveFiles(this.dir, this.name, this.ext, mainCount, childCount);
+ if (archiveExists) {
+ this.archive.createNewFile();
+ }
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+
+ File file = handler.getRollingArchiveName(this.archive, archiveClosed);
+
+ assertThat(file).hasParent(this.dir)
+ .hasName(this.name + formatIds(mainCount, childCount + 1) + this.ext);
+ }
+
+ @Test
+ public void initMainArchiveId_withEmptyDir_createsMainId_createsFirstMarker() throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+
+ handler.initMainArchiveId(this.archive);
+
+ assertThat(new File(this.dir, this.name + formatIds(1, 0) + ".marker")).exists();
+ }
+
+ @Test
+ @Parameters({"1,1", "1,10", "10,1", "10,10"})
+ public void initMainArchiveId_withOldArchives_rollsMainId_rollsMarker(final int mainCount,
+ final int childCount) throws Exception {
+ createEmptyArchiveFiles(this.dir, this.name, this.ext, mainCount, childCount);
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+
+ handler.initMainArchiveId(this.archive);
+
+ assertThat(new File(this.dir, this.name + formatIds(mainCount + 1, 0) + ".marker")).exists();
+ }
+
+ @Test
+ public void getRenameArchiveName_withEmptyDir_createsFirstIds() throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).isNotNull().isEqualTo(new File(this.dir, this.name + "-01-01" + this.ext));
+ }
+
+ @Test
+ public void getRenameArchiveName_withExtraneousIds_withEmptyDir_appendsIds() throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ this.archive = new File(this.dir, this.name + "-01-01" + this.ext);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).hasParent(this.dir).hasName(this.name + "-01-01-01-01" + this.ext);
+ }
+
+ @Test
+ public void getRenameArchiveName_withExtraneousDots_withEmptyDir_appendsIds() throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ this.archive = new File(this.dir, this.name + ".test.test" + this.ext);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).hasParent(this.dir).hasName(this.name + ".test.test-01-01" + this.ext);
+ }
+
+ @Test
+ public void getRenameArchiveName_withExtraneousUnderscores_withEptyDir_appendsIds()
+ throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ this.archive = new File(this.dir, this.name + "_test_test" + this.ext);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).hasParent(this.dir).hasName(this.name + "_test_test-01-01" + this.ext);
+ }
+
+ @Test
+ public void getRenameArchiveName_withExtraneousHyphens_withEmptyDir_appendsIds()
+ throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ this.archive = new File(this.dir, this.name + "-test-test" + this.ext);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).hasParent(this.dir).hasName(this.name + "-test-test-01-01" + this.ext);
+ }
+
+ @Test
+ @Parameters({"1,1", "1,10", "10,1", "10,10"})
+ public void getRenameArchiveName_withOldArchives_rollsMainId(final int mainCount,
+ final int childCount) throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ createEmptyArchiveFiles(this.dir, this.name, this.ext, mainCount, childCount);
+
+ File renamed = handler.getRenameArchiveName(this.archive);
+
+ assertThat(renamed).doesNotExist().hasParent(this.dir)
+ .hasName(this.name + formatIds(mainCount + 1, 1) + this.ext);
+ }
+
+ @Test
+ public void getRenameArchiveName_withNullArchive_throwsNullPointerException() throws Exception {
+ StatArchiveHandler handler =
+ new StatArchiveHandler(this.mockConfig, this.mockCollector, this.rollingFileHandler);
+ File archive = null;
+
+ assertThatThrownBy(() -> handler.getRenameArchiveName(archive))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ /**
+ * Returns mainId and childId formatted like "-01-01"
+ */
+ private String formatIds(final int mainId, final int childId) {
+ return "-" + formatId(mainId) + "-" + formatId(childId);
+ }
+
+ /**
+ * Returns id formatted like "01"
+ */
+ private String formatId(final int id) {
+ return String.format("%02d", id);
+ }
+
+ /**
+ * Creates empty archive files like dir/name-mainId-childId.ext. Returns greatest mainId.
+ */
+ private int createEmptyArchiveFiles(final File dir, final String name, final String ext,
+ final int mainCount, final int childCount) throws IOException {
+ int mainId = 1;
+ for (; mainId <= mainCount; mainId++) {
+ for (int childId = 1; childId <= childCount; childId++) {
+ File existing = new File(dir, name + formatIds(mainId, childId) + ext);
+ existing.createNewFile();
+ }
+ }
+ return mainId - 1;
+ }
+}