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 2016/10/26 20:22:28 UTC
incubator-geode git commit: GEODE-2012: always write stat types to
archive [Forced Update!]
Repository: incubator-geode
Updated Branches:
refs/heads/feature/GEODE-2012 5ab02de6c -> 040a2e6c0 (forced update)
GEODE-2012: always write stat types to archive
* write additional tests for stat archive rolling
* expose bug GEODE-2012 in StatTypesAreRolledOverRegressionTest
* fix failure in StatTypesAreRolledOverRegressionTest
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/040a2e6c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/040a2e6c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/040a2e6c
Branch: refs/heads/feature/GEODE-2012
Commit: 040a2e6c05179b4b2cda3418d478a8c7a83bcacd
Parents: 56917a2
Author: Kirk Lund <kl...@apache.org>
Authored: Wed Oct 26 13:11:08 2016 -0700
Committer: Kirk Lund <kl...@apache.org>
Committed: Wed Oct 26 13:11:08 2016 -0700
----------------------------------------------------------------------
.../org/apache/geode/internal/NanoTimer.java | 6 +-
.../geode/internal/i18n/LocalizedStrings.java | 2 +-
.../internal/statistics/HostStatSampler.java | 35 +++-
.../internal/statistics/SampleCollector.java | 10 +-
.../internal/statistics/SimpleStatSampler.java | 7 +-
.../internal/statistics/StatArchiveWriter.java | 4 +-
.../concurrent/StoppableCountDownLatch.java | 5 +
.../DiskSpaceLimitIntegrationTest.java | 137 +++++++++++++
.../FileSizeLimitIntegrationTest.java | 125 +++++++++++
.../StatTypesAreRolledOverRegressionTest.java | 205 +++++++++++++++++++
10 files changed, 516 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/NanoTimer.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/NanoTimer.java b/geode-core/src/main/java/org/apache/geode/internal/NanoTimer.java
index e8c1145..67e0bb1 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/NanoTimer.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/NanoTimer.java
@@ -41,7 +41,7 @@ package org.apache.geode.internal;
* </pre>
*
*/
-public final class NanoTimer {
+public class NanoTimer {
public static final long NANOS_PER_MILLISECOND = 1000000;
@@ -76,7 +76,7 @@ public final class NanoTimer {
/**
* For unit testing
*/
- NanoTimer(TimeService ts) {
+ protected NanoTimer(TimeService ts) {
this.timeService = ts;
this.lastResetTime = ts.getTime();
this.constructionTime = this.lastResetTime;
@@ -174,7 +174,7 @@ public final class NanoTimer {
/**
* Allows unit tests to insert a deterministic clock for testing.
*/
- interface TimeService {
+ public interface TimeService {
/**
* Returns the current time.
*/
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
index 7d762b8..aa00b73 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/i18n/LocalizedStrings.java
@@ -664,7 +664,7 @@ public class LocalizedStrings {
public static final StringId ManagerLogWriter_COULD_NOT_DELETE_INACTIVE__0___1_ = new StringId(1794, "Could not delete inactive {0} \"{1}\".");
public static final StringId ManagerLogWriter_COULD_NOT_FREE_SPACE_IN_0_DIRECTORY_THE_SPACE_USED_IS_1_WHICH_EXCEEDS_THE_CONFIGURED_LIMIT_OF_2 = new StringId(1795, "Could not free space in {0} directory. The space used is {1} which exceeds the configured limit of {2}.");
- public static final StringId ManagerLogWriter_DELETED_INACTIVE__0___1_ = new StringId(1797, "Deleted inactive {0} \"{1}\".");
+ public static final StringId ManagerLogWriter_DELETED_INACTIVE__0___1_ = new StringId(1797, "Deleted inactive {0} \"{1}\".");
public static final StringId ManagerLogWriter_SWITCHING_TO_LOG__0 = new StringId(1798, "Switching to log {0}");
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
index 020b5ab..588bcf8 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
@@ -85,16 +85,25 @@ public abstract class HostStatSampler
private final CancelCriterion stopper;
private final CallbackSampler callbackSampler;
+
+ private final NanoTimer timer;
protected HostStatSampler(CancelCriterion stopper,
StatSamplerStats samplerStats) {
+ this(stopper, samplerStats, new NanoTimer());
+ }
+
+ protected HostStatSampler(CancelCriterion stopper,
+ StatSamplerStats samplerStats,
+ NanoTimer timer) {
this.stopper = stopper;
this.statSamplerInitializedLatch = new StoppableCountDownLatch(this.stopper, 1);
this.samplerStats = samplerStats;
this.fileSizeLimitInKB = Boolean.getBoolean(TEST_FILE_SIZE_LIMIT_IN_KB_PROPERTY);
this.callbackSampler = new CallbackSampler(stopper, samplerStats);
+ this.timer = timer;
}
-
+
public final StatSamplerStats getStatSamplerStats() {
return this.samplerStats;
}
@@ -169,8 +178,6 @@ public abstract class HostStatSampler
*/
@Override
public final void run() {
- NanoTimer timer = new NanoTimer();
-
final boolean isDebugEnabled_STATISTICS = logger.isTraceEnabled(LogMarker.STATISTICS);
if (isDebugEnabled_STATISTICS) {
logger.trace(LogMarker.STATISTICS, "HostStatSampler started");
@@ -180,7 +187,7 @@ public abstract class HostStatSampler
initSpecialStats();
this.sampleCollector = new SampleCollector(this);
- this.sampleCollector.initialize(this, NanoTimer.getTime());
+ this.sampleCollector.initialize(this, timer.getTime());
this.statSamplerInitializedLatch.countDown();
latchCountedDown = true;
@@ -195,7 +202,7 @@ public abstract class HostStatSampler
}
final long nanosBeforeSleep = timer.getLastResetTime();
final long nanosToDelay = nanosLastTimeStamp + getNanoRate();
- delay(timer, nanosToDelay);
+ delay(nanosToDelay);
nanosLastTimeStamp = timer.getLastResetTime();
if (!stopRequested() && isSamplingEnabled()) {
final long nanosTimeStamp = timer.getLastResetTime();
@@ -366,11 +373,20 @@ public abstract class HostStatSampler
* @since GemFire 7.0
*/
public final boolean waitForInitialization(long ms) throws InterruptedException {
- return this.statSamplerInitializedLatch.await(ms);
+ return awaitInitialization(ms, TimeUnit.MILLISECONDS);
}
-
+
+ /**
+ * Awaits the initialization of special statistics.
+ *
+ * @see #initSpecialStats
+ */
+ public final boolean awaitInitialization(final long timeout, final TimeUnit unit) throws InterruptedException {
+ return this.statSamplerInitializedLatch.await(timeout, unit);
+ }
+
public final void changeArchive(File newFile) {
- this.sampleCollector.changeArchive(newFile, NanoTimer.getTime());
+ this.sampleCollector.changeArchive(newFile, timer.getTime());
}
/**
@@ -473,10 +489,9 @@ public abstract class HostStatSampler
}
/**
- * @param timer a NanoTimer used to compute the elapsed delay
* @param nanosToDelay the timestamp to delay until it is the current time
*/
- private void delay(NanoTimer timer, final long nanosToDelay) throws InterruptedException {
+ private void delay(final long nanosToDelay) throws InterruptedException {
timer.reset();
long now = timer.getLastResetTime();
long remainingNanos = nanosToDelay - now;
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java
index 68430a1..428e83c 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java
@@ -366,7 +366,7 @@ public class SampleCollector {
}
// notify unmarked/new handlers but not marked/old handlers
- notifyNewHandlersOfResources(handlers, this.resourceInstMap.values());
+ notifyNewHandlersOfResources(handlers, this.resourceTypeMap.values(), this.resourceInstMap.values());
}
private ResourceType getResourceType(List<MarkableSampleHandler> handlers,
@@ -478,8 +478,7 @@ public class SampleCollector {
}
}
- private void notifyNewHandlersOfResources(List<MarkableSampleHandler> handlers,
- Collection<ResourceInstance> resources) {
+ private void notifyNewHandlersOfResources(List<MarkableSampleHandler> handlers, Collection<ResourceType> types, Collection<ResourceInstance> resources) {
final boolean isDebugEnabled_STATISTICS = logger.isTraceEnabled(LogMarker.STATISTICS);
if (isDebugEnabled_STATISTICS) {
logger.trace(LogMarker.STATISTICS, "SampleCollector#notifyNewHandlersOfResources ri.size()={}", resources.size());
@@ -498,6 +497,11 @@ public class SampleCollector {
// allocatedResourceInstance...
handler.allocatedResourceInstance(resourceInstance);
}
+ for (ResourceType resourceType : types) {
+ if (!allocatedResourceTypes.contains(resourceType)) {
+ handler.allocatedResourceType(resourceType);
+ }
+ }
handler.mark();
count++;
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/statistics/SimpleStatSampler.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/SimpleStatSampler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/SimpleStatSampler.java
index 50f49a7..ebf15cf 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/SimpleStatSampler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/SimpleStatSampler.java
@@ -21,6 +21,7 @@ import java.io.File;
import org.apache.logging.log4j.Logger;
import org.apache.geode.CancelCriterion;
+import org.apache.geode.internal.NanoTimer;
import org.apache.geode.internal.i18n.LocalizedStrings;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.logging.log4j.LocalizedMessage;
@@ -57,7 +58,11 @@ public class SimpleStatSampler extends HostStatSampler {
private final StatisticsManager sm;
public SimpleStatSampler(CancelCriterion stopper, StatisticsManager sm) {
- super(stopper, new StatSamplerStats(sm, sm.getId()));
+ this(stopper, sm, new NanoTimer());
+ }
+
+ public SimpleStatSampler(CancelCriterion stopper, StatisticsManager sm, NanoTimer timer) {
+ super(stopper, new StatSamplerStats(sm, sm.getId()), timer);
this.sm = sm;
logger.info(LogMarker.STATISTICS, LocalizedMessage.create(LocalizedStrings.SimpleStatSampler_STATSSAMPLERATE_0, getSampleRate()));
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java
index b8f44e2..cbd1538 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java
@@ -150,7 +150,7 @@ public class StatArchiveWriter implements StatArchiveFormat, SampleHandler {
}
}
- @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification="Best effort attempt to delete a GFS file without any samples.")
+ @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification="Best effort attempt to delete a GFS file without any samples.")
private static void deleteFileIfPossible(File file) {
file.delete();
}
@@ -270,7 +270,7 @@ public class StatArchiveWriter implements StatArchiveFormat, SampleHandler {
}
}
- @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification="This is only for debugging and there is never more than one instance being traced because there is only one stat sampler.")
+ @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification="This is only for debugging and there is never more than one instance being traced because there is only one stat sampler.")
public void allocatedResourceInstance(ResourceInstance statResource) {
if (logger.isTraceEnabled(LogMarker.STATISTICS)) {
logger.trace(LogMarker.STATISTICS, "StatArchiveWriter#allocatedResourceInstance statResource={}", statResource);
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/StoppableCountDownLatch.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/StoppableCountDownLatch.java b/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/StoppableCountDownLatch.java
index 1f0ac34..a3052078 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/StoppableCountDownLatch.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/StoppableCountDownLatch.java
@@ -77,6 +77,11 @@ public class StoppableCountDownLatch {
return latch.await(msTimeout, TimeUnit.MILLISECONDS);
}
+ public boolean await(final long timeout, final TimeUnit unit) throws InterruptedException {
+ stopper.checkCancelInProgress(null);
+ return latch.await(timeout, unit);
+ }
+
public synchronized void countDown() {
latch.countDown();
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/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
new file mode 100644
index 0000000..8c6bd8a
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/DiskSpaceLimitIntegrationTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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 java.util.concurrent.TimeUnit.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.After;
+import org.junit.Before;
+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.junit.rules.TestName;
+
+import org.apache.geode.StatisticDescriptor;
+import org.apache.geode.Statistics;
+import org.apache.geode.StatisticsType;
+import org.apache.geode.internal.NanoTimer;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class DiskSpaceLimitIntegrationTest {
+
+ private static final long FILE_SIZE_LIMIT = 1024*1;
+ private static final long DISK_SPACE_LIMIT = Long.MAX_VALUE;
+
+ private File dir;
+ private String archiveFileName;
+
+ private LocalStatisticsFactory factory;
+ private StatisticDescriptor[] statisticDescriptors;
+ private StatisticsType statisticsType;
+ private Statistics statistics;
+
+ private SampleCollector sampleCollector;
+ private StatArchiveHandlerConfig config;
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void setUp() throws Exception {
+ this.dir = this.temporaryFolder.getRoot();
+ this.archiveFileName = new File(this.dir, this.testName.getMethodName() + ".gfs").getAbsolutePath();
+
+ this.factory = new LocalStatisticsFactory(null);
+ this.statisticDescriptors = new StatisticDescriptor[] {
+ this.factory.createIntCounter("stat1", "description of stat1", "units", true),
+ };
+ this.statisticsType = factory.createType("statisticsType1", "statisticsType1", this.statisticDescriptors);
+ this.statistics = factory.createAtomicStatistics(this.statisticsType, "statistics1", 1);
+
+ StatisticsSampler sampler = mock(StatisticsSampler.class);
+ when(sampler.getStatistics()).thenReturn(this.factory.getStatistics());
+
+ this.config = mock(StatArchiveHandlerConfig.class);
+ when(this.config.getArchiveFileName()).thenReturn(new File(this.archiveFileName));
+ when(this.config.getArchiveFileSizeLimit()).thenReturn(FILE_SIZE_LIMIT);
+ when(this.config.getSystemId()).thenReturn(1L);
+ when(this.config.getSystemStartTime()).thenReturn(System.currentTimeMillis());
+ when(this.config.getSystemDirectoryPath()).thenReturn(this.temporaryFolder.getRoot().getAbsolutePath());
+ when(this.config.getProductDescription()).thenReturn(this.testName.getMethodName());
+ when(this.config.getArchiveDiskSpaceLimit()).thenReturn(DISK_SPACE_LIMIT);
+
+ this.sampleCollector = new SampleCollector(sampler);
+ this.sampleCollector.initialize(this.config, NanoTimer.getTime());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatisticsTypeFactoryImpl.clear();
+ }
+
+ @Test
+ public void zeroKeepsAllFiles() throws Exception {
+ when(this.config.getArchiveDiskSpaceLimit()).thenReturn(0L);
+ sampleUntilFileExists(archiveFile(1));
+ sampleUntilFileExists(archiveFile(2));
+ assertThat(archiveFile(1)).exists();
+ assertThat(archiveFile(2)).exists();
+ }
+
+ @Test
+ public void sameKeepsOneFile() throws Exception {
+ when(this.config.getArchiveDiskSpaceLimit()).thenReturn(FILE_SIZE_LIMIT*2);
+ sampleUntilFileExists(archiveFile(1));
+ sampleUntilFileExists(archiveFile(2));
+ assertThat(archiveFile(1)).doesNotExist();
+ assertThat(archiveFile(2)).exists();
+ }
+
+ private File archiveFile(final int child) {
+ return new File(this.dir, this.testName.getMethodName() + "-01-" +String.format("%02d", child) + ".gfs");
+ }
+
+ private void sampleUntilFileExists(final File file) throws InterruptedException, TimeoutException {
+ long end = System.nanoTime() + MINUTES.toNanos(1);
+ while (!file.exists() && System.nanoTime() < end) {
+ sample();
+ }
+ if (!file.exists()) {
+ throw new TimeoutException("File " + file + " does not exist within " + 1 + " " + MINUTES);
+ }
+ }
+
+ private void sample() {
+ getSampleCollector().sample(System.nanoTime());
+ }
+
+ private SampleCollector getSampleCollector() {
+ return this.sampleCollector;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/test/java/org/apache/geode/internal/statistics/FileSizeLimitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/statistics/FileSizeLimitIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/internal/statistics/FileSizeLimitIntegrationTest.java
new file mode 100644
index 0000000..5a56e4d
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/FileSizeLimitIntegrationTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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 java.util.concurrent.TimeUnit.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.After;
+import org.junit.Before;
+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.junit.rules.TestName;
+
+import org.apache.geode.StatisticDescriptor;
+import org.apache.geode.Statistics;
+import org.apache.geode.StatisticsType;
+import org.apache.geode.internal.NanoTimer;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class FileSizeLimitIntegrationTest {
+
+ private static final long FILE_SIZE_LIMIT = 1024*1;
+
+ private File dir;
+ private String archiveFileName;
+
+ private LocalStatisticsFactory factory;
+ private StatisticDescriptor[] statisticDescriptors;
+ private StatisticsType statisticsType;
+ private Statistics statistics;
+
+ private SampleCollector sampleCollector;
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void setUp() throws Exception {
+ this.dir = this.temporaryFolder.getRoot();
+ this.archiveFileName = new File(this.dir, this.testName.getMethodName() + ".gfs").getAbsolutePath();
+
+ this.factory = new LocalStatisticsFactory(null);
+ this.statisticDescriptors = new StatisticDescriptor[] {
+ this.factory.createIntCounter("stat1", "description of stat1", "units", true),
+ };
+ this.statisticsType = factory.createType("statisticsType1", "statisticsType1", this.statisticDescriptors);
+ this.statistics = factory.createAtomicStatistics(this.statisticsType, "statistics1", 1);
+
+ StatisticsSampler sampler = mock(StatisticsSampler.class);
+ when(sampler.getStatistics()).thenReturn(this.factory.getStatistics());
+
+ StatArchiveHandlerConfig config = mock(StatArchiveHandlerConfig.class);
+ when(config.getArchiveFileName()).thenReturn(new File(this.archiveFileName));
+ when(config.getArchiveFileSizeLimit()).thenReturn(FILE_SIZE_LIMIT);
+ when(config.getSystemId()).thenReturn(1L);
+ when(config.getSystemStartTime()).thenReturn(System.currentTimeMillis());
+ when(config.getSystemDirectoryPath()).thenReturn(this.temporaryFolder.getRoot().getAbsolutePath());
+ when(config.getProductDescription()).thenReturn(this.testName.getMethodName());
+ when(config.getArchiveDiskSpaceLimit()).thenReturn(0L);
+
+ this.sampleCollector = new SampleCollector(sampler);
+ this.sampleCollector.initialize(config, NanoTimer.getTime());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatisticsTypeFactoryImpl.clear();
+ }
+
+ private File archiveFile(final int child) {
+ return new File(this.dir, this.testName.getMethodName() + "-01-" +String.format("%02d", child) + ".gfs");
+ }
+
+ @Test
+ public void rollsWhenLimitIsReached() throws Exception { // TODO: add test to assert size is correct
+ sampleUntilFileExists(archiveFile(1));
+ sampleUntilFileExists(archiveFile(2));
+ assertThat(archiveFile(1)).exists();
+ assertThat(archiveFile(2)).exists();
+ }
+
+ private void sampleUntilFileExists(final File file) throws InterruptedException, TimeoutException {
+ long end = System.nanoTime() + MINUTES.toNanos(1);
+ while (!file.exists() && System.nanoTime() < end) {
+ sample();
+ }
+ if (!file.exists()) {
+ throw new TimeoutException("File " + file + " does not exist within " + 1 + " " + MINUTES);
+ }
+ }
+
+ private void sample() {
+ getSampleCollector().sample(System.nanoTime());
+ }
+
+ private SampleCollector getSampleCollector() {
+ return this.sampleCollector;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/040a2e6c/geode-core/src/test/java/org/apache/geode/internal/statistics/StatTypesAreRolledOverRegressionTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/statistics/StatTypesAreRolledOverRegressionTest.java b/geode-core/src/test/java/org/apache/geode/internal/statistics/StatTypesAreRolledOverRegressionTest.java
new file mode 100644
index 0000000..63c22db
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/StatTypesAreRolledOverRegressionTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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 java.util.concurrent.TimeUnit.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.After;
+import org.junit.Before;
+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.junit.rules.TestName;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import org.apache.geode.StatisticDescriptor;
+import org.apache.geode.Statistics;
+import org.apache.geode.StatisticsType;
+import org.apache.geode.internal.NanoTimer;
+import org.apache.geode.internal.statistics.StatArchiveReader.ResourceInst;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class StatTypesAreRolledOverRegressionTest {
+
+ private static final long FILE_SIZE_LIMIT = 1024*1;
+
+ private File dir;
+ private String archiveFileName;
+
+ private LocalStatisticsFactory factory;
+ private StatisticDescriptor[] statisticDescriptors;
+ private StatisticsType statisticsType;
+ private Statistics statistics;
+
+ private SampleCollector sampleCollector;
+
+ private NanoTimer timer = new NanoTimer();
+ private long nanosTimeStamp;
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+ @Rule
+ public TestName testName = new TestName();
+
+ @Before
+ public void setUp() throws Exception {
+ this.dir = this.temporaryFolder.getRoot();
+ this.archiveFileName = new File(this.dir, this.testName.getMethodName() + ".gfs").getAbsolutePath();
+
+ this.factory = new LocalStatisticsFactory(null);
+ this.statisticDescriptors = new StatisticDescriptor[] {
+ this.factory.createIntCounter("stat1", "description of stat1", "units", true),
+ };
+ this.statisticsType = factory.createType("statisticsType1", "statisticsType1", this.statisticDescriptors);
+ this.statistics = factory.createAtomicStatistics(this.statisticsType, "statistics1", 1);
+
+ Answer<Statistics[]> statisticsAnswer = new Answer<Statistics[]>() {
+ public Statistics[] answer(InvocationOnMock invocation) throws Throwable {
+ return factory.getStatistics();
+ }
+ };
+
+ Answer<Integer> modCountAnswer = new Answer<Integer>() {
+ public Integer answer(InvocationOnMock invocation) throws Throwable {
+ return factory.getStatListModCount();
+ }
+ };
+
+ StatisticsSampler sampler = mock(StatisticsSampler.class);
+ when(sampler.getStatistics()).thenAnswer(statisticsAnswer);
+ when(sampler.getStatisticsModCount()).thenAnswer(modCountAnswer);
+
+ StatArchiveHandlerConfig config = mock(StatArchiveHandlerConfig.class);
+ when(config.getArchiveFileName()).thenReturn(new File(this.archiveFileName));
+ when(config.getArchiveFileSizeLimit()).thenReturn(FILE_SIZE_LIMIT);
+ when(config.getSystemId()).thenReturn(1L);
+ when(config.getSystemStartTime()).thenReturn(System.currentTimeMillis());
+ when(config.getSystemDirectoryPath()).thenReturn(this.temporaryFolder.getRoot().getAbsolutePath());
+ when(config.getProductDescription()).thenReturn(this.testName.getMethodName());
+ when(config.getArchiveDiskSpaceLimit()).thenReturn(0L);
+
+ this.sampleCollector = new SampleCollector(sampler);
+ this.sampleCollector.initialize(config, this.timer.getTime());
+
+ this.timer.reset();
+ this.nanosTimeStamp = this.timer.getLastResetTime() - getNanoRate();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ StatisticsTypeFactoryImpl.clear();
+ }
+
+ @Test
+ public void closedInstanceShouldHaveTypeInRolledArchives() throws Exception {
+ // initial state
+ verifyStatisticsTypeIsInArchiveFile(archiveFile(), 0);
+
+ // one sample
+ sample(advanceNanosTimeStamp());
+ verifyStatisticsTypeIsInArchiveFile(archiveFile(), 1);
+
+ // close stats
+ this.statistics.close();
+
+ assertThat(archiveFile(1)).doesNotExist();
+
+ // cause roll
+ sampleUntilFileExists(archiveFile(1));
+
+ sample(advanceNanosTimeStamp());
+ verifyStatisticsTypeIsInArchiveFile(archiveFile(), 0);
+
+ this.statistics = factory.createAtomicStatistics(this.statisticsType, "statistics1", 2);
+
+ sample(advanceNanosTimeStamp());
+ verifyStatisticsTypeIsInArchiveFile(archiveFile(), 1); // should be corrupt?
+
+ }
+
+ private void verifyStatisticsTypeIsInArchiveFile(final File archiveFile, final int expectedResources) throws IOException {
+ StatArchiveReader reader = new StatArchiveReader(new File[]{ archiveFile }, null, false);
+
+ // compare all resourceInst values against what was printed above
+
+ List<ResourceInst> resources = reader.getResourceInstList();
+ if (expectedResources > 0) {
+ assertThat(resources).hasAtLeastOneElementOfType(ResourceInst.class);
+ }
+
+ for (ResourceInst resourceInstance : resources) {
+ if (resourceInstance == null) continue;
+ assertThat(resourceInstance.getName()).isNotNull();
+ assertThat(resourceInstance.getType()).isNotNull();
+ assertThat(resourceInstance.getType().getName()).isEqualTo(this.statisticsType.getName());
+ }
+ }
+
+ private void sampleUntilFileExists(final File file) throws InterruptedException, TimeoutException {
+ long timeout = System.nanoTime() + MINUTES.toNanos(1);
+ int count = 0;
+ do {
+ sample(advanceNanosTimeStamp());
+ count++;
+ } while (!file.exists() && System.nanoTime() < timeout);
+ if (!file.exists()) {
+ throw new TimeoutException("File " + file + " does not exist within " + 1 + " " + MINUTES);
+ }
+ }
+
+ private void sample(final long time) {
+ getSampleCollector().sample(time);
+ }
+
+ private SampleCollector getSampleCollector() {
+ return this.sampleCollector;
+ }
+
+ private File archiveFile(final int child) {
+ return new File(this.dir, this.testName.getMethodName() + "-01-" +String.format("%02d", child) + ".gfs");
+ }
+
+ private File archiveFile() {
+ return new File(this.archiveFileName);
+ }
+
+ private long advanceNanosTimeStamp() {
+ this.nanosTimeStamp += getNanoRate();
+ return this.nanosTimeStamp;
+ }
+
+ private long getNanoRate() {
+ return NanoTimer.millisToNanos(getSampleRate());
+ }
+
+ private long getSampleRate() {
+ return 1000; // 1 second
+ }
+}