http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerJUnitTest.java deleted file mode 100755 index e16eeaf..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerJUnitTest.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal; - -import static org.junit.Assert.*; - -import java.io.File; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.logging.log4j.Logger; -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 com.gemstone.gemfire.CancelCriterion; -import com.gemstone.gemfire.StatisticDescriptor; -import com.gemstone.gemfire.Statistics; -import com.gemstone.gemfire.StatisticsType; -import com.gemstone.gemfire.internal.StatArchiveReader.StatValue; -import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.util.StopWatch; -import com.gemstone.gemfire.test.junit.categories.IntegrationTest; - -/** - * @since GemFire 7.0 - */ -@Category(IntegrationTest.class) -public class StatSamplerJUnitTest { - - private static final Logger logger = LogService.getLogger(); - - private Map<String,String> statisticTypes; - private Map<String,Map<String,Number>> allStatistics; - - @Rule - public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); - - @Rule - public TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Rule - public TestName testName = new TestName(); - - @Before - public void setUp() { - this.statisticTypes = new HashMap<String,String>(); - this.allStatistics = new HashMap<String,Map<String,Number>>(); - } - - @After - public void tearDown() { - this.statisticTypes = null; - this.allStatistics = null; - StatisticsTypeFactoryImpl.clear(); - StatArchiveWriter.clearTraceFilter(); - } - - private String getName() { - return getClass().getSimpleName() + "_" + testName.getMethodName(); - } - - @Test - public void testStatSampler() throws Exception { - StatArchiveWriter.setTraceFilter("st1_1", "ST1"); - - File folder = temporaryFolder.newFolder(); - String archiveFileName = folder.getAbsolutePath() + File.separator + getName() + ".gfs"; - - System.setProperty("stats.log-level", "config"); - System.setProperty("stats.disable", "false"); - System.setProperty("stats.name", getName()); - System.setProperty("stats.archive-file", archiveFileName); - System.setProperty("stats.file-size-limit", "0"); - System.setProperty("stats.disk-space-limit", "0"); - System.setProperty("stats.sample-rate", "100"); - - final CancelCriterion stopper = new CancelCriterion() { - public String cancelInProgress() { - return null; - } - public RuntimeException generateCancelledException(Throwable e) { - return null; - } - }; - final LocalStatisticsFactory factory = new LocalStatisticsFactory(stopper); - final StatisticDescriptor[] statsST1 = new StatisticDescriptor[] { - factory.createDoubleCounter("double_counter_1", "d1", "u1"), - factory.createDoubleCounter("double_counter_2", "d2", "u2", true), - factory.createDoubleGauge( "double_gauge_3", "d3", "u3"), - factory.createDoubleGauge( "double_gauge_4", "d4", "u4", false), - factory.createIntCounter( "int_counter_5", "d5", "u5"), - factory.createIntCounter( "int_counter_6", "d6", "u6", true), - factory.createIntGauge( "int_gauge_7", "d7", "u7"), - factory.createIntGauge( "int_gauge_8", "d8", "u8", false), - factory.createLongCounter( "long_counter_9", "d9", "u9"), - factory.createLongCounter( "long_counter_10", "d10", "u10", true), - factory.createLongGauge( "long_gauge_11", "d11", "u11"), - factory.createLongGauge( "long_gauge_12", "d12", "u12", false), - factory.createLongGauge( "sampled_long", "d13", "u13", false), - factory.createIntGauge( "sampled_int", "d14", "u14", false), - factory.createDoubleGauge( "sampled_double", "d15", "u15", false) - }; - final StatisticsType ST1 = factory.createType("ST1", "ST1", statsST1); - final Statistics st1_1 = factory.createAtomicStatistics(ST1, "st1_1", 1); - st1_1.setIntSupplier("sampled_int", () -> 5); - getOrCreateExpectedValueMap(st1_1).put("sampled_int", 5); - st1_1.setLongSupplier("sampled_long", () -> 6); - getOrCreateExpectedValueMap(st1_1).put("sampled_long", 6); - st1_1.setDoubleSupplier("sampled_double", () -> 7.0); - getOrCreateExpectedValueMap(st1_1).put("sampled_double", 7.0); - - boolean done = false; - - Statistics[] samplerStatsInstances = factory.findStatisticsByTextId("statSampler"); - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 4000; done = (samplerStatsInstances != null && samplerStatsInstances.length > 0)) { - Thread.sleep(10); - samplerStatsInstances = factory.findStatisticsByTextId("statSampler"); - } - - assertTrue("Waiting for statSampler stats", done); - - samplerStatsInstances = factory.findStatisticsByTextId("statSampler"); - assertNotNull(samplerStatsInstances); - assertEquals(1, samplerStatsInstances.length); - final Statistics samplerStats = samplerStatsInstances[0]; - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_gauge_3", 3); - incInt(st1_1, "int_counter_5", 5); - incInt(st1_1, "int_gauge_7", 7); - incLong(st1_1, "long_counter_9", 9); - incLong(st1_1, "long_gauge_11", 11); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", 1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", 1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", -1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", -1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", -1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", 1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", 1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - waitForStatSample(samplerStats); - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_gauge_3", 3); - incInt(st1_1, "int_counter_5", 5); - incInt(st1_1, "int_gauge_7", 7); - incLong(st1_1, "long_counter_9", 9); - incLong(st1_1, "long_gauge_11", 11); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", 1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", 1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", -1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", -1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", -1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - - incDouble(st1_1, "double_counter_1", 1); - incDouble(st1_1, "double_counter_2", 1); - incDouble(st1_1, "double_gauge_3", 1); - incDouble(st1_1, "double_gauge_4", 1); - incInt(st1_1, "int_counter_5", 1); - incInt(st1_1, "int_counter_6", 1); - incInt(st1_1, "int_gauge_7", 1); - incInt(st1_1, "int_gauge_8", 1); - incLong(st1_1, "long_counter_9", 1); - incLong(st1_1, "long_counter_10", 1); - incLong(st1_1, "long_gauge_11", 1); - incLong(st1_1, "long_gauge_12", 1); - - waitForStatSample(samplerStats); - - factory.close(); - - final File archiveFile = new File(System.getProperty("stats.archive-file")); - assertTrue(archiveFile.exists()); - final StatArchiveReader reader = new StatArchiveReader( - new File[]{archiveFile}, null, false); - - List resources = reader.getResourceInstList(); - for (Iterator iter = resources.iterator(); iter.hasNext();) { - StatArchiveReader.ResourceInst ri = (StatArchiveReader.ResourceInst) iter.next(); - String resourceName = ri.getName(); - assertNotNull(resourceName); - - if (!resourceName.equals("st1_1")) { - logger.info("testStatSampler skipping {}", resourceName); - continue; - } - - String expectedStatsType = this.statisticTypes.get(resourceName); - assertNotNull(expectedStatsType); - assertEquals(expectedStatsType, ri.getType().getName()); - - Map<String,Number> expectedStatValues = this.allStatistics.get(resourceName); - assertNotNull(expectedStatValues); - - StatValue[] statValues = ri.getStatValues(); - for (int i = 0; i < statValues.length; i++) { - String statName = ri.getType().getStats()[i].getName(); - assertNotNull(statName); - assertNotNull(expectedStatValues.get(statName)); - - assertEquals(statName, statValues[i].getDescriptor().getName()); - - statValues[i].setFilter(StatValue.FILTER_NONE); - //double[] rawSnapshots = statValues[i].getRawSnapshots(); - assertEquals("Value " + i + " for " + statName + " is wrong: " + expectedStatValues, - expectedStatValues.get(statName).doubleValue(), - statValues[i].getSnapshotsMostRecent(), - 0); - } - } - } - - private void waitForStatSample(final Statistics samplerStats) throws InterruptedException { - int startSampleCount = samplerStats.getInt("sampleCount"); - boolean done = false; - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 3000; done = (samplerStats.getInt("sampleCount") > startSampleCount)) { - Thread.sleep(10); - } - assertTrue("Waiting for statSampler sampleCount to increment", done); - } - - private void incDouble(Statistics statistics, String stat, double value) { - assertFalse(statistics.isClosed()); - Map<String, Number> statValues = getOrCreateExpectedValueMap(statistics); - statistics.incDouble(stat, value); - statValues.put(stat, statistics.getDouble(stat)); - if (this.statisticTypes.get(statistics.getTextId()) == null) { - this.statisticTypes.put(statistics.getTextId(), statistics.getType().getName()); - } - } - - private void incInt(Statistics statistics, String stat, int value) { - assertFalse(statistics.isClosed()); - Map<String, Number> statValues = getOrCreateExpectedValueMap(statistics); - statistics.incInt(stat, value); - statValues.put(stat, statistics.getInt(stat)); - if (this.statisticTypes.get(statistics.getTextId()) == null) { - this.statisticTypes.put(statistics.getTextId(), statistics.getType().getName()); - } - } - - private Map<String, Number> getOrCreateExpectedValueMap(final Statistics statistics) { - Map<String,Number> statValues = this.allStatistics.get(statistics.getTextId()); - if (statValues == null) { - statValues = new HashMap<String,Number>(); - this.allStatistics.put(statistics.getTextId(), statValues); - } - return statValues; - } - - private void incLong(Statistics statistics, String stat, long value) { - assertFalse(statistics.isClosed()); - Map<String, Number> statValues = getOrCreateExpectedValueMap(statistics); - statistics.incLong(stat, value); - statValues.put(stat, statistics.getLong(stat)); - if (this.statisticTypes.get(statistics.getTextId()) == null) { - this.statisticTypes.put(statistics.getTextId(), statistics.getType().getName()); - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerTestCase.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerTestCase.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerTestCase.java deleted file mode 100755 index 819a79c..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/StatSamplerTestCase.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal; - -import static org.junit.Assert.*; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.logging.log4j.Logger; - -import com.gemstone.gemfire.Statistics; -import com.gemstone.gemfire.StatisticsType; -import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.util.StopWatch; - -/** - * Integration TestCase for StatSampler. - * - * @since GemFire 7.0 - */ -public abstract class StatSamplerTestCase { - protected static final Logger logger = LogService.getLogger(); - - protected abstract StatisticsManager getStatisticsManager(); - - protected int getStatListModCount() { - return getStatisticsManager().getStatListModCount(); - } - - protected List<Statistics> getStatsList() { - return getStatisticsManager().getStatsList(); - } - - protected static void waitForFileToExist(final File file, final long millis, final long sleep) { - boolean done = false; - try { - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < millis; done = (file.exists())) { - Thread.sleep(sleep); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - assertTrue("Waiting for file to exist: " + file, done); - } - - protected static void waitForFileToDelete(final File file, final long millis, final long sleep) { - boolean done = false; - try { - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < millis; done = (!file.exists())) { - Thread.sleep(sleep); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - assertTrue("Waiting for file to be deleted: " + file, done); - } - - protected static void waitForExpectedStatValue(final Statistics statSamplerStats, final String statName, final int expectedStatValue, final long millis, final long sleep) { - boolean done = false; - try { - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < millis; done = (statSamplerStats.getInt(statName) >= expectedStatValue)) { - Thread.sleep(sleep); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - assertTrue("Waiting for " + statName + " >= " + expectedStatValue, done); - } - - protected static void waitForStatSample(final Statistics statSamplerStats, final int samples, final long millis, final long sleep) { - waitForExpectedStatValue(statSamplerStats, "sampleCount", samples, millis, sleep); - } - - protected static void assertStatValueDoesNotChange(final Statistics statSamplerStats, final String statName, final int expectedStatValue, final long millis, final long sleep) { - boolean done = false; - try { - for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < millis; done = (statSamplerStats.getInt(statName) != expectedStatValue)) { - Thread.sleep(sleep); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - assertFalse("Waiting to assert that " + statName + " does not change from " + expectedStatValue, done); - } - - protected static class AllStatistics { - - private final HostStatSampler statSampler; - private final Map<StatisticsType, Set<Statistics>> allStatistics; - - protected AllStatistics(HostStatSampler statSampler) throws InterruptedException { - this.statSampler = statSampler; - this.allStatistics = initAllStatistics(); - } - - private Map<StatisticsType, Set<Statistics>> initAllStatistics() throws InterruptedException { - assertTrue(this.statSampler.waitForInitialization(5000)); - - Map<StatisticsType, Set<Statistics>> statsTypeToStats = new HashMap<StatisticsType, Set<Statistics>>(); - Statistics[] stats = this.statSampler.getStatistics(); - for (int i = 0; i < stats.length; i++) { - StatisticsType statsType = stats[i].getType(); - Set<Statistics> statsSet = statsTypeToStats.get(statsType); - if (statsSet == null) { - statsSet = new HashSet<Statistics>(); - statsSet.add(stats[i]); - statsTypeToStats.put(statsType, statsSet); - } else { - statsSet.add(stats[i]); - } - } - return statsTypeToStats; - } - - protected boolean containsStatisticsType(StatisticsType type) { - throw new UnsupportedOperationException("TODO"); - } - - protected boolean containsStatisticsType(String typeName) throws InterruptedException { - for (StatisticsType statType : this.allStatistics.keySet()) { - if (statType.getName().equals(typeName)) { - return true; - } - } - return false; - } - - protected boolean containsStatistics(Statistics statistics) { - throw new UnsupportedOperationException("TODO"); - } - - protected boolean containsStatistics(String instanceName) throws InterruptedException { - for (StatisticsType statType : this.allStatistics.keySet()) { - for (Statistics statistics : this.allStatistics.get(statType)) { - if (statistics.getTextId().equals(instanceName)) { - return true; - } - } - } - return false; - } - - /** - * Statistics[0]: typeName=StatSampler instanceName=statSampler - * Statistics[1]: typeName=VMStats instanceName=vmStats - * Statistics[2]: typeName=VMMemoryUsageStats instanceName=vmHeapMemoryStats - * Statistics[3]: typeName=VMMemoryUsageStats instanceName=vmNonHeapMemoryStats - * Statistics[4]: typeName=VMMemoryPoolStats instanceName=Code Cache-Non-heap memory - * Statistics[5]: typeName=VMMemoryPoolStats instanceName=PS Eden Space-Heap memory - * Statistics[6]: typeName=VMMemoryPoolStats instanceName=PS Survivor Space-Heap memory - * Statistics[7]: typeName=VMMemoryPoolStats instanceName=PS Old Gen-Heap memory - * Statistics[8]: typeName=VMMemoryPoolStats instanceName=PS Perm Gen-Non-heap memory - * Statistics[9]: typeName=VMGCStats instanceName=PS Scavenge - * Statistics[10]: typeName=VMGCStats instanceName=PS MarkSweep - * Statistics[11]: typeName=LinuxSystemStats instanceName=kuwait.gemstone.com - * Statistics[12]: typeName=LinuxProcessStats instanceName=javaApp0-proc - */ - protected void dumpStatistics() throws InterruptedException { - Statistics[] stats = this.statSampler.getStatistics(); - for (int i = 0; i < stats.length; i++) { - logger.info("Statistics[{}]: typeName={} instanceName={}", i, stats[i].getType().getName(), stats[i].getTextId()); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/lru/LRUClockJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/lru/LRUClockJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/lru/LRUClockJUnitTest.java index 16b7ac5..7e24d0c 100755 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/lru/LRUClockJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/lru/LRUClockJUnitTest.java @@ -39,7 +39,7 @@ import com.gemstone.gemfire.cache.EvictionAction; import com.gemstone.gemfire.cache.EvictionAlgorithm; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.distributed.DistributedSystem; -import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl; +import com.gemstone.gemfire.internal.statistics.StatisticsTypeFactoryImpl; import com.gemstone.gemfire.internal.cache.InternalRegionArguments; import com.gemstone.gemfire.internal.cache.PlaceHolderDiskRegion; import com.gemstone.gemfire.test.junit.categories.IntegrationTest; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java index 93bef98..bf5a176 100755 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java @@ -23,7 +23,7 @@ import com.gemstone.gemfire.distributed.internal.DistributionConfig; import com.gemstone.gemfire.distributed.internal.DistributionStats; import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; import com.gemstone.gemfire.distributed.internal.InternalLocator; -import com.gemstone.gemfire.internal.LocalStatisticsFactory; +import com.gemstone.gemfire.internal.statistics.LocalStatisticsFactory; import com.gemstone.gemfire.test.junit.categories.UnitTest; import org.junit.Rule; import org.junit.Test; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerJUnitTest.java deleted file mode 100644 index 47bfc58..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerJUnitTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal.statistics; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import java.util.Arrays; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import com.gemstone.gemfire.CancelCriterion; -import com.gemstone.gemfire.Statistics; -import com.gemstone.gemfire.internal.StatSamplerStats; -import com.gemstone.gemfire.internal.StatisticsImpl; -import com.gemstone.gemfire.internal.StatisticsManager; -import com.gemstone.gemfire.test.junit.categories.UnitTest; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -@Category(UnitTest.class) -@RunWith(MockitoJUnitRunner.class) -public class CallbackSamplerJUnitTest { - @Mock - CancelCriterion cancelCriterion; - @Mock - StatSamplerStats statSamplerStats; - @Mock - StatisticsManager statisticsManager; - @Mock - ScheduledExecutorService executorService; - private CallbackSampler sampler; - - @Before - public void createSampler() { - sampler = new CallbackSampler(cancelCriterion, statSamplerStats); - } - - @Test - public void taskShouldSampleStatistics() { - Runnable sampleTask = invokeStartAndGetTask(); - - StatisticsImpl stats1 = mock(StatisticsImpl.class); - StatisticsImpl stats2 = mock(StatisticsImpl.class); - when(stats1.invokeSuppliers()).thenReturn(3); - when(stats2.invokeSuppliers()).thenReturn(2); - when(stats1.getSupplierCount()).thenReturn(7); - when(stats2.getSupplierCount()).thenReturn(8); - when(statisticsManager.getStatsList()).thenReturn(Arrays.asList(stats1, stats2)); - sampleTask.run(); - verify(statSamplerStats).setSampleCallbacks(eq(15)); - verify(statSamplerStats).incSampleCallbackErrors(5); - verify(statSamplerStats).incSampleCallbackDuration(anyLong()); - } - - @Test - public void stopShouldStopExecutor() { - sampler.start(executorService, statisticsManager, 1, TimeUnit.MILLISECONDS); - sampler.stop(); - verify(executorService).shutdown(); - } - - @Test - public void cancelCriterionShouldStopExecutor() { - Runnable sampleTask = invokeStartAndGetTask(); - when(cancelCriterion.isCancelInProgress()).thenReturn(Boolean.TRUE); - sampleTask.run(); - verify(executorService).shutdown(); - } - - private Runnable invokeStartAndGetTask() { - sampler.start(executorService, statisticsManager, 1, TimeUnit.MILLISECONDS); - ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); - verify(executorService).scheduleAtFixedRate(runnableCaptor.capture(), eq(1L), eq(1L), eq(TimeUnit.MILLISECONDS)); - return runnableCaptor.getValue(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerTest.java new file mode 100644 index 0000000..fd442bb --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/CallbackSamplerTest.java @@ -0,0 +1,98 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.gemstone.gemfire.CancelCriterion; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Unit tests for {@link CallbackSampler}. + */ +@Category(UnitTest.class) +@RunWith(MockitoJUnitRunner.class) +public class CallbackSamplerTest { + + @Mock + CancelCriterion cancelCriterion; + @Mock + StatSamplerStats statSamplerStats; + @Mock + StatisticsManager statisticsManager; + @Mock + ScheduledExecutorService executorService; + + private CallbackSampler sampler; + + @Before + public void createSampler() { + sampler = new CallbackSampler(cancelCriterion, statSamplerStats); + } + + @Test + public void taskShouldSampleStatistics() { + Runnable sampleTask = invokeStartAndGetTask(); + + StatisticsImpl stats1 = mock(StatisticsImpl.class); + StatisticsImpl stats2 = mock(StatisticsImpl.class); + when(stats1.invokeSuppliers()).thenReturn(3); + when(stats2.invokeSuppliers()).thenReturn(2); + when(stats1.getSupplierCount()).thenReturn(7); + when(stats2.getSupplierCount()).thenReturn(8); + when(statisticsManager.getStatsList()).thenReturn(Arrays.asList(stats1, stats2)); + sampleTask.run(); + verify(statSamplerStats).setSampleCallbacks(eq(15)); + verify(statSamplerStats).incSampleCallbackErrors(5); + verify(statSamplerStats).incSampleCallbackDuration(anyLong()); + } + + @Test + public void stopShouldStopExecutor() { + sampler.start(executorService, statisticsManager, 1, TimeUnit.MILLISECONDS); + sampler.stop(); + verify(executorService).shutdown(); + } + + @Test + public void cancelCriterionShouldStopExecutor() { + Runnable sampleTask = invokeStartAndGetTask(); + when(cancelCriterion.isCancelInProgress()).thenReturn(Boolean.TRUE); + sampleTask.run(); + verify(executorService).shutdown(); + } + + private Runnable invokeStartAndGetTask() { + sampler.start(executorService, statisticsManager, 1, TimeUnit.MILLISECONDS); + ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + verify(executorService).scheduleAtFixedRate(runnableCaptor.capture(), eq(1L), eq(1L), eq(TimeUnit.MILLISECONDS)); + return runnableCaptor.getValue(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsIntegrationTest.java new file mode 100644 index 0000000..76763de --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsIntegrationTest.java @@ -0,0 +1,271 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Properties; +import java.util.Random; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +import com.gemstone.gemfire.StatisticDescriptor; +import com.gemstone.gemfire.Statistics; +import com.gemstone.gemfire.StatisticsFactory; +import com.gemstone.gemfire.StatisticsType; +import com.gemstone.gemfire.distributed.DistributedSystem; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +/** + * Integration tests for {@link Statistics} as implemented by {@link DistributedSystem}. + */ +@Category(IntegrationTest.class) +public class DistributedSystemStatisticsIntegrationTest { + + private DistributedSystem system; + + private String statName1; + private String statName2; + private String statName3; + private String[] statNames; + + private Random random; + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + Properties props = new Properties(); + props.setProperty(MCAST_PORT, "0"); + props.setProperty(LOCATORS, ""); + props.setProperty(NAME, getUniqueName()); + + this.system = DistributedSystem.connect(props); + + this.statName1 = "one"; + this.statName2 = "two"; + this.statName3 = "three"; + this.statNames = new String[] { statName1, statName2, statName3 }; + + this.random = new Random(); + } + + @After + public void tearDown() throws Exception { + this.system.disconnect(); + this.system = null; + } + + /** + * Tests {@code int} statistics + */ + @Test + public void testIntStatistics() { + Statistics stats = setUpIntStatistics(3); + + for (int j = 0; j < this.statNames.length; j++) { + String statName = this.statNames[j]; + for (int i = 0; i < 10; i++) { + stats.setInt(statName, i); + stats.incInt(statName, 1); + assertThat(stats.getInt(statName)).isEqualTo(i + 1); + } + } + } + + /** + * Tests {@code long} statistics + */ + @Test + public void testLongStatistics() { + Statistics stats = setUpLongStatistics(3); + + // Set/get some random long values + for (int i = 0; i < 100; i++) { + for (int j = 0; j < this.statNames.length; j++) { + String statName = this.statNames[j]; + long value = this.random.nextLong(); + stats.setLong(statName, value); + assertThat(stats.getLong(statName)).isEqualTo(value); + } + } + + // Increment by some random values + for (int i = 0; i < 100; i++) { + for (int j = 0; j < this.statNames.length; j++) { + String statName = this.statNames[j]; + long inc = this.random.nextLong(); + long before = stats.getLong(statName); + stats.incLong(statName, inc); + assertThat(stats.getLong(statName)).isEqualTo(before + inc); + } + } + } + + /** + * Tests {@code double} statistics + */ + @Test + public void testDoubleStatistics() { + Statistics stats = setUpDoubleStatistics(3); + + // Set/get some random double values + for (int i = 0; i < 100; i++) { + for (int j = 0; j < this.statNames.length; j++) { + String statName = this.statNames[j]; + double value = this.random.nextDouble(); + stats.setDouble(statName, value); + assertThat(stats.getDouble(statName)).isEqualTo(value); + } + } + + // Increment by some random values + for (int i = 0; i < 100; i++) { + for (int j = 0; j < this.statNames.length; j++) { + String statName = this.statNames[j]; + double inc = this.random.nextDouble(); + double before = stats.getDouble(statName); + stats.incDouble(statName, inc); + assertThat(stats.getDouble(statName)).isEqualTo(before + inc); + } + } + } + + /** + * Tests that accessing an {@code int} stat throws the appropriate exceptions. + */ + @Test + public void testAccessingIntStat() { + Statistics stats = setUpIntStatistics(1); + + assertThat(stats.getInt(this.statName1)).isEqualTo(0); + assertThatThrownBy(() -> stats.getDouble(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.getLong(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.setInt(this.statName1, 4); + assertThatThrownBy(() -> stats.setDouble(this.statName1, 4.0)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.setLong(this.statName1, 4L)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.incInt(this.statName1, 4); + assertThatThrownBy(() -> stats.incDouble(this.statName1, 4.0)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.incLong(this.statName1, 4L)).isExactlyInstanceOf(IllegalArgumentException.class); + } + + /** + * Tests that accessing a {@code long} stat throws the appropriate exceptions. + */ + @Test + public void testAccessingLongStat() { + Statistics stats = setUpLongStatistics(1); + + assertThat(stats.getLong(this.statName1)).isEqualTo(0L); + assertThatThrownBy(() -> stats.getDouble(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.getInt(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.setLong(this.statName1, 4L); + assertThatThrownBy(() -> stats.setDouble(this.statName1, 4.0)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.setInt(this.statName1, 4)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.incLong(this.statName1, 4L); + assertThatThrownBy(() -> stats.incDouble(this.statName1, 4.0)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.incInt(this.statName1, 4)).isExactlyInstanceOf(IllegalArgumentException.class); + } + + /** + * Tests that accessing an {@code double} stat throws the appropriate exceptions. + */ + @Test + public void testAccessingDoubleStat() { + Statistics stats = setUpDoubleStatistics(1); + + assertThat(stats.getDouble(this.statName1)).isEqualTo(0.0); + assertThatThrownBy(() -> stats.getInt(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.getLong(this.statName1)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.setDouble(this.statName1, 4.0); + assertThatThrownBy(() -> stats.setInt(this.statName1, 4)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.setLong(this.statName1, 4L)).isExactlyInstanceOf(IllegalArgumentException.class); + + stats.incDouble(this.statName1, 4.0); + assertThatThrownBy(() -> stats.incInt(this.statName1, 4)).isExactlyInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> stats.incLong(this.statName1, 4L)).isExactlyInstanceOf(IllegalArgumentException.class); + } + + private StatisticsFactory factory() { + return this.system; + } + + private Statistics setUpIntStatistics(final int count) { + String[] descriptions = new String[] {"ONE", "TWO", "THREE"}; + StatisticDescriptor[] descriptors = new StatisticDescriptor[count]; + for (int i = 0; i < count; i++) { + descriptors[i] = factory().createIntGauge(this.statNames[i], descriptions[i], "x"); + } + + StatisticsType type = factory().createType(getUniqueName(), "", descriptors); + Statistics stats = factory().createStatistics(type, "Display"); + + for (int i = 0; i < count; i++) { + stats.setInt(this.statNames[i], 0); + } + return stats; + } + + private Statistics setUpLongStatistics(final int count) { + String[] descriptions = new String[] {"ONE", "TWO", "THREE"}; + StatisticDescriptor[] descriptors = new StatisticDescriptor[count]; + for (int i = 0; i < count; i++) { + descriptors[i] = factory().createLongGauge(this.statNames[i], descriptions[i], "x"); + } + + StatisticsType type = factory().createType(getUniqueName(), "", descriptors); + Statistics stats = factory().createStatistics(type, "Display"); + + for (int i = 0; i < count; i++) { + stats.setLong(this.statNames[i], 0L); + } + return stats; + } + + private Statistics setUpDoubleStatistics(final int count) { + String[] descriptions = new String[] {"ONE", "TWO", "THREE"}; + StatisticDescriptor[] descriptors = new StatisticDescriptor[count]; + for (int i = 0; i < count; i++) { + descriptors[i] = factory().createDoubleGauge(this.statNames[i], descriptions[i], "x"); + } + + StatisticsType type = factory().createType(getUniqueName(), "", descriptors); + Statistics stats = factory().createStatistics(type, "Display"); + + for (int i = 0; i < count; i++) { + stats.setDouble(this.statNames[i], 0.0); + } + return stats; + } + + private String getUniqueName() { + return getClass().getSimpleName() + "_" + this.testName.getMethodName(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsTypeIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsTypeIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsTypeIntegrationTest.java new file mode 100644 index 0000000..a87dd52 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/DistributedSystemStatisticsTypeIntegrationTest.java @@ -0,0 +1,90 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Properties; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +import com.gemstone.gemfire.StatisticDescriptor; +import com.gemstone.gemfire.StatisticsFactory; +import com.gemstone.gemfire.StatisticsType; +import com.gemstone.gemfire.distributed.DistributedSystem; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +/** + * Integration tests for {@link StatisticsType} as implemented by {@link DistributedSystem}. + */ +@Category(IntegrationTest.class) +public class DistributedSystemStatisticsTypeIntegrationTest { + + private DistributedSystem system; + private StatisticsType type; + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + Properties props = new Properties(); + props.setProperty(MCAST_PORT, "0"); + props.setProperty(LOCATORS, ""); + props.setProperty(NAME, getUniqueName()); + this.system = DistributedSystem.connect(props); + + StatisticDescriptor[] stats = { + factory().createIntGauge("test", "TEST", "ms") + }; + + this.type = factory().createType(getUniqueName(), "TEST", stats); + } + + @After + public void tearDown() throws Exception { + this.system.disconnect(); + this.system = null; + } + + @Test + public void testNameToIdUnknownStatistic() { + assertThat(type.nameToId("test")).isEqualTo(0); + assertThatThrownBy(() -> type.nameToId("Fred")).isExactlyInstanceOf(IllegalArgumentException.class); + } + + @Test + public void testNameToDescriptorUnknownStatistic() { + assertThat(type.nameToDescriptor("test").getName()).isEqualTo("test"); + assertThatThrownBy(() -> type.nameToDescriptor("Fred")).isExactlyInstanceOf(IllegalArgumentException.class); + } + + private String getUniqueName() { + return getClass().getSimpleName() + "_" + this.testName.getMethodName(); + } + + private StatisticsFactory factory() { + return this.system; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/GemFireStatSamplerIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/GemFireStatSamplerIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/GemFireStatSamplerIntegrationTest.java new file mode 100644 index 0000000..ff7c34d --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/GemFireStatSamplerIntegrationTest.java @@ -0,0 +1,612 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.junit.Assert.*; +import static org.junit.Assume.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.logging.log4j.Logger; +import org.junit.After; +import org.junit.Assert; +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 com.gemstone.gemfire.Statistics; +import com.gemstone.gemfire.StatisticsType; +import com.gemstone.gemfire.distributed.DistributedSystem; +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; +import com.gemstone.gemfire.internal.GemFireVersion; +import com.gemstone.gemfire.internal.PureJavaMode; +import com.gemstone.gemfire.internal.SocketCreator; +import com.gemstone.gemfire.internal.cache.control.HeapMemoryMonitor; +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.internal.statistics.GemFireStatSampler.LocalStatListenerImpl; +import com.gemstone.gemfire.internal.statistics.platform.OsStatisticsFactory; +import com.gemstone.gemfire.internal.statistics.platform.ProcessStats; +import com.gemstone.gemfire.internal.stats50.VMStats50; +import com.gemstone.gemfire.internal.util.StopWatch; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +/** + * Integration tests for {@link GemFireStatSampler}. + * + * @since GemFire 7.0 + */ +@Category(IntegrationTest.class) +public class GemFireStatSamplerIntegrationTest extends StatSamplerTestCase { + + private static final Logger logger = LogService.getLogger(); + + private static final int STAT_SAMPLE_RATE = 1000; + + private DistributedSystem system; + private File testDir; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + this.testDir = this.temporaryFolder.getRoot(); + assertTrue(this.testDir.exists()); + } + + /** + * Removes the loner DistributedSystem at the end of each test. + */ + @After + public void tearDown() throws Exception { + System.clearProperty(GemFireStatSampler.TEST_FILE_SIZE_LIMIT_IN_KB_PROPERTY); + disconnect(); + } + + /** + * Tests the majority of getters and the basic functionality of the sampler. + * + * This test is skipped when running on Windows 7 because ProcessStats is not created for this OS. See #45395. + */ + @Test + public void testBasics() throws Exception { + final String osName = System.getProperty("os.name", "unknown"); + assumeFalse(osName.equals("Windows 7")); + + connect(createGemFireProperties()); + + GemFireStatSampler statSampler = getGemFireStatSampler(); + assertTrue(statSampler.waitForInitialization(5000)); + + assertEquals(0, statSampler.getArchiveFileSizeLimit()); + assertEquals(0, statSampler.getArchiveDiskSpaceLimit()); + assertEquals(STAT_SAMPLE_RATE, statSampler.getSampleRate()); + assertEquals(true, statSampler.isSamplingEnabled()); + + int statsCount = statSampler.getStatisticsManager().getStatisticsCount(); + + assertEquals(statsCount, statSampler.getStatisticsModCount()); + assertEquals(statsCount, statSampler.getStatisticsManager().getStatisticsCount()); + assertEquals(statsCount, statSampler.getStatistics().length); + + Assert.assertEquals(getStatisticsManager().getId(), statSampler.getSystemId()); + assertTrue(statSampler.getSystemStartTime() < System.currentTimeMillis()); + Assert.assertEquals(SocketCreator.getHostName(SocketCreator.getLocalHost()), + statSampler.getSystemDirectoryPath()); + + AllStatistics allStats = new AllStatistics(statSampler); + + VMStatsContract vmStats = statSampler.getVMStats(); + assertNotNull(vmStats); + assertTrue(vmStats instanceof VMStats50); + /* NOTE: VMStats50 is not an instance of Statistics but instead its + * instance contains 3 instances of Statistics: + * 1) vmStats + * 2) heapMemStats + * 3) nonHeapMemStats + */ + + Method getProcessStats = getGemFireStatSampler().getClass().getMethod("getProcessStats"); + assertNotNull(getProcessStats); + + ProcessStats processStats = statSampler.getProcessStats(); + if (osName.equals("SunOS")) { + assertNotNull(processStats); + assertTrue(PureJavaMode.osStatsAreAvailable()); + assertTrue(allStats.containsStatisticsType("SolarisProcessStats")); + assertTrue(allStats.containsStatisticsType("SolarisSystemStats")); + } else if (osName.startsWith("Windows")) { + // fails on Windows 7: 45395 "ProcessStats are not created on Windows 7" + assertNotNull("ProcessStats were not created on " + osName, processStats); + assertTrue(PureJavaMode.osStatsAreAvailable()); + assertTrue(allStats.containsStatisticsType("WindowsProcessStats")); + assertTrue(allStats.containsStatisticsType("WindowsSystemStats")); + } else if (osName.startsWith("Linux")) { + assertNotNull(processStats); + assertTrue(PureJavaMode.osStatsAreAvailable()); + assertTrue(allStats.containsStatisticsType("LinuxProcessStats")); + assertTrue(allStats.containsStatisticsType("LinuxSystemStats")); + } else if (osName.equals("Mac OS X")) { + assertNull(processStats); + assertFalse(PureJavaMode.osStatsAreAvailable()); + assertFalse(allStats.containsStatisticsType("OSXProcessStats")); + assertFalse(allStats.containsStatisticsType("OSXSystemStats")); + } else { + assertNull(processStats); + } + + String productDesc = statSampler.getProductDescription(); + assertTrue(productDesc.contains(GemFireVersion.getGemFireVersion())); + assertTrue(productDesc.contains(GemFireVersion.getBuildId())); + assertTrue(productDesc.contains(GemFireVersion.getSourceDate())); + } + + /** + * Tests that the configured archive file is created and exists. + */ + @Test + public void testArchiveFileExists() throws Exception { + final String dir = this.testDir.getAbsolutePath(); + final String archiveFileName = dir + File.separator + this.testName.getMethodName() + ".gfs"; + + final File archiveFile1 = new File(dir + File.separator + this.testName.getMethodName() + ".gfs"); + + Properties props = createGemFireProperties(); + props.setProperty(STATISTIC_ARCHIVE_FILE, archiveFileName); + connect(props); + + GemFireStatSampler statSampler = getGemFireStatSampler(); + assertTrue(statSampler.waitForInitialization(5000)); + + final File archiveFile = statSampler.getArchiveFileName(); + assertNotNull(archiveFile); + assertEquals(archiveFile1, archiveFile); + + waitForFileToExist(archiveFile, 5000, 10); + + assertTrue("File name incorrect: archiveFile.getName()=" + archiveFile.getName() + + " archiveFile.getAbsolutePath()=" + archiveFile.getAbsolutePath() + + " getCanonicalPath()" + archiveFile.getCanonicalPath(), + archiveFileName.contains(archiveFile.getName())); + } + + /** + * Tests the statistics sample rate within an acceptable margin of error. + */ + @Test + public void testSampleRate() throws Exception { + connect(createGemFireProperties()); + + GemFireStatSampler statSampler = getGemFireStatSampler(); + assertTrue(statSampler.waitForInitialization(5000)); + + assertEquals(STAT_SAMPLE_RATE, statSampler.getSampleRate()); + + assertTrue(getStatisticsManager().getStatListModCount() > 0); + + List<Statistics> statistics = getStatisticsManager().getStatsList(); + assertNotNull(statistics); + assertTrue(statistics.size() > 0); + + StatisticsType statSamplerType = getStatisticsManager().findType("StatSampler"); + Statistics[] statsArray = getStatisticsManager().findStatisticsByType(statSamplerType); + assertEquals(1, statsArray.length); + + final Statistics statSamplerStats = statsArray[0]; + final int initialSampleCount = statSamplerStats.getInt("sampleCount"); + final int expectedSampleCount = initialSampleCount + 2; + + waitForExpectedStatValue(statSamplerStats, "sampleCount", expectedSampleCount, 5000, 10); + } + + /** + * Adds a LocalStatListener for an individual stat. Validates that it + * receives notifications. Removes the listener and validates that it + * was in fact removed and no longer receives notifications. + */ + @Test + public void testLocalStatListener() throws Exception { + connect(createGemFireProperties()); + + GemFireStatSampler statSampler = getGemFireStatSampler(); + assertTrue(statSampler.waitForInitialization(5000)); + + Method getLocalListeners = getGemFireStatSampler().getClass().getMethod("getLocalListeners"); + assertNotNull(getLocalListeners); + + Method addLocalStatListener = getGemFireStatSampler().getClass().getMethod("addLocalStatListener", LocalStatListener.class, Statistics.class, String.class); + assertNotNull(addLocalStatListener); + + Method removeLocalStatListener = getGemFireStatSampler().getClass().getMethod("removeLocalStatListener", LocalStatListener.class); + assertNotNull(removeLocalStatListener); + + // validate that there are no listeners + assertTrue(statSampler.getLocalListeners().isEmpty()); + + // add a listener for sampleCount stat in StatSampler statistics + StatisticsType statSamplerType = getStatisticsManager().findType("StatSampler"); + Statistics[] statsArray = getStatisticsManager().findStatisticsByType(statSamplerType); + assertEquals(1, statsArray.length); + + final Statistics statSamplerStats = statsArray[0]; + final String statName = "sampleCount"; + final AtomicInteger sampleCountValue = new AtomicInteger(0); + final AtomicInteger sampleCountChanged = new AtomicInteger(0); + + LocalStatListener listener = new LocalStatListener() { + public void statValueChanged(double value) { + sampleCountValue.set((int)value); + sampleCountChanged.incrementAndGet(); + } + }; + + statSampler.addLocalStatListener(listener, statSamplerStats, statName); + assertTrue(statSampler.getLocalListeners().size() == 1); + + // there's a level of indirection here and some protected member fields + LocalStatListenerImpl lsli = (LocalStatListenerImpl) + statSampler.getLocalListeners().iterator().next(); + assertEquals("sampleCount", lsli.stat.getName()); + + // wait for the listener to update 4 times + final int expectedChanges = 4; + boolean done = false; + try { + for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 5000; done = (sampleCountChanged.get() >= expectedChanges)) { + Thread.sleep(10); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + assertTrue("Waiting for sampleCountChanged >= " + expectedChanges, done); + + // validate that the listener fired and updated the value + assertTrue(sampleCountValue.get() > 0); + assertTrue(sampleCountChanged.get() >= expectedChanges); + + // remove the listener + statSampler.removeLocalStatListener(listener); + final int expectedSampleCountValue = sampleCountValue.get(); + final int expectedSampleCountChanged = sampleCountChanged.get(); + + // validate that there are no listeners now + assertTrue(statSampler.getLocalListeners().isEmpty()); + + // wait for 2 stat samples to occur + waitForStatSample(statSamplerStats, expectedSampleCountValue, 5000, 10); + + // validate that the listener did not fire + assertEquals(expectedSampleCountValue, sampleCountValue.get()); + assertEquals(expectedSampleCountChanged, sampleCountChanged.get()); + } + + /** + * Invokes stop() and then validates that the sampler did in fact stop. + */ + @Test + public void testStop() throws Exception { + connect(createGemFireProperties()); + + GemFireStatSampler statSampler = getGemFireStatSampler(); + assertTrue(statSampler.waitForInitialization(5000)); + + // validate the stat sampler is running + StatisticsType statSamplerType = getStatisticsManager().findType("StatSampler"); + Statistics[] statsArray = getStatisticsManager().findStatisticsByType(statSamplerType); + assertEquals(1, statsArray.length); + + final Statistics statSamplerStats = statsArray[0]; + final int initialSampleCount = statSamplerStats.getInt("sampleCount"); + final int expectedSampleCount = initialSampleCount + 2; + + waitForStatSample(statSamplerStats, expectedSampleCount, 20000, 10); + + // stop the stat sampler + statSampler.stop(); + + // validate the stat sampler has stopped + final int stoppedSampleCount = statSamplerStats.getInt("sampleCount"); + + // the following should timeout rather than complete + assertStatValueDoesNotChange(statSamplerStats, "sampleCount", stoppedSampleCount, 5000, 10); + + assertEquals(stoppedSampleCount, statSamplerStats.getInt("sampleCount")); + } + + /** + * Verifies that archive rolling works correctly when archive-file-size-limit + * is specified. + */ + @Test + public void testArchiveRolling() throws Exception { + final String dirName = this.testDir.getAbsolutePath() + File.separator + this.testName; + new File(dirName).mkdirs(); + final String archiveFileName = dirName + File.separator + this.testName + ".gfs"; + + final File archiveFile = new File(archiveFileName); + final File archiveFile1 = new File(dirName + File.separator + this.testName + "-01-01.gfs"); + final File archiveFile2 = new File(dirName + File.separator + this.testName + "-01-02.gfs"); + final File archiveFile3 = new File(dirName + File.separator + this.testName + "-01-03.gfs"); + + // set the system property to use KB instead of MB for file size + System.setProperty(HostStatSampler.TEST_FILE_SIZE_LIMIT_IN_KB_PROPERTY, "true"); + Properties props = createGemFireProperties(); + props.setProperty(ARCHIVE_FILE_SIZE_LIMIT, "1"); + props.setProperty(ARCHIVE_DISK_SPACE_LIMIT, "0"); + props.setProperty(STATISTIC_ARCHIVE_FILE, archiveFileName); + connect(props); + + assertTrue(getGemFireStatSampler().waitForInitialization(5000)); + + boolean done = false; + try { + for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 4000; done = (getSampleCollector() != null && getSampleCollector().getStatArchiveHandler() != null)) { + Thread.sleep(10); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + assertTrue("Waiting for getSampleCollector().getStatArchiveHandler() to not be null", done); + + StatArchiveHandler statArchiveHandler = getSampleCollector().getStatArchiveHandler(); + StatArchiveHandlerConfig config = statArchiveHandler.getStatArchiveHandlerConfig(); + assertEquals(1 * 1024, config.getArchiveFileSizeLimit()); + + waitForFileToExist(archiveFile, 4000, 10); + waitForFileToExist(archiveFile1, 4000, 10); + waitForFileToExist(archiveFile2, 4000, 10); + waitForFileToExist(archiveFile3, 4000, 10); + } + + /** + * Verifies that archive removal works correctly when archive-disk-space-limit + * is specified. + */ + @Test + public void testArchiveRemoval() throws Exception { + final String dirName = this.testDir.getAbsolutePath();// + File.separator + this.testName; + new File(dirName).mkdirs(); + final String archiveFileName = dirName + File.separator + this.testName + ".gfs"; + + final File archiveFile = new File(archiveFileName); + final File archiveFile1 = new File(dirName + File.separator + this.testName + "-01-01.gfs"); + final File archiveFile2 = new File(dirName + File.separator + this.testName + "-01-02.gfs"); + final File archiveFile3 = new File(dirName + File.separator + this.testName + "-01-03.gfs"); + final File archiveFile4 = new File(dirName + File.separator + this.testName + "-01-04.gfs"); + + final int sampleRate = 1000; + + // set the system property to use KB instead of MB for file size + System.setProperty(HostStatSampler.TEST_FILE_SIZE_LIMIT_IN_KB_PROPERTY, "true"); + Properties props = createGemFireProperties(); + props.setProperty(STATISTIC_ARCHIVE_FILE, archiveFileName); + props.setProperty(ARCHIVE_FILE_SIZE_LIMIT, "1"); + props.setProperty(ARCHIVE_DISK_SPACE_LIMIT, "12"); + props.setProperty(STATISTIC_SAMPLE_RATE, String.valueOf(sampleRate)); + connect(props); + + assertTrue(getGemFireStatSampler().waitForInitialization(5000)); + + boolean exists1 = false; + boolean exists2 = false; + boolean exists3 = false; + boolean exists4 = false; + boolean exists = false; + boolean done = false; + try { + for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 10*sampleRate;) { + exists1 = exists1 || archiveFile1.exists(); + exists2 = exists2 || archiveFile2.exists(); + exists3 = exists3 || archiveFile3.exists(); + exists4 = exists4 || archiveFile4.exists(); + exists = exists || archiveFile.exists(); + done = exists1 && exists2 && exists3 && exists4 && exists; + if (!done) { + Thread.sleep(10); + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + assertTrue("Waiting for archive files to exist:" + + " exists1=" + exists1 + + " exists2=" + exists2 + + " exists3=" + exists3 + + " exists4=" + exists4 + + " exists=" + exists, done); + + waitForFileToDelete(archiveFile1, 10*sampleRate, 10); + } + + @Test + public void testLocalStatListenerRegistration() throws Exception { + connect(createGemFireProperties()); + + final GemFireStatSampler statSampler = getGemFireStatSampler(); + statSampler.waitForInitialization(5000); + + final AtomicBoolean flag = new AtomicBoolean(false); + final LocalStatListener listener = new LocalStatListener(){ + public void statValueChanged(double value) { + flag.set(true); + } + }; + + final String tenuredPoolName = HeapMemoryMonitor.getTenuredMemoryPoolMXBean().getName(); + logger.info("TenuredPoolName: {}", tenuredPoolName); + + final List<Statistics> list = ((StatisticsManager)this.system).getStatsList(); + assertFalse(list.isEmpty()); + + boolean done = false; + try { + for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 5000;) { + Thread.sleep(10); + int i=0; + synchronized (list) { + for (Object obj : list) { + ++i; + logger.info("List:{}:{}", i, obj); + if (obj instanceof StatisticsImpl) { + StatisticsImpl si = (StatisticsImpl)obj; + logger.info("stat:{}", si.getTextId()); + if (si.getTextId().contains(tenuredPoolName)) { + statSampler.addLocalStatListener(listener, si, "currentUsedMemory"); + done = true; + } + } + } + } + //done = false; + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + assertTrue("Waiting for " + tenuredPoolName + " statistics to be added to create listener for", done); + + assertTrue("expected at least one stat listener, found " + + statSampler.getLocalListeners().size(), + statSampler.getLocalListeners().size() > 0); + + long maxTenuredMemory = HeapMemoryMonitor.getTenuredMemoryPoolMXBean() + .getUsage().getMax(); + + //byte[] bytes = new byte[1024 * 1024 * 10]; + byte[] bytes = new byte[(int)(maxTenuredMemory*0.01)]; + Arrays.fill(bytes, Byte.MAX_VALUE); + + done = false; + try { + for (StopWatch time = new StopWatch(true); !done && time.elapsedTimeMillis() < 5000; done = (flag.get())) { + Thread.sleep(10); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + assertTrue("Waiting for listener to set flag to true", done); + } + + @Override + protected StatisticsManager getStatisticsManager() { + return (InternalDistributedSystem)this.system; + } + + protected OsStatisticsFactory getOsStatisticsFactory() { + return (InternalDistributedSystem)this.system; + } + + private GemFireStatSampler getGemFireStatSampler() { + return ((InternalDistributedSystem)this.system).getStatSampler(); + } + + private SampleCollector getSampleCollector() { + return getGemFireStatSampler().getSampleCollector(); + } + + private Properties createGemFireProperties() { + Properties props = new Properties(); + props.setProperty(STATISTIC_SAMPLING_ENABLED, "true"); // TODO: test true/false + props.setProperty(ENABLE_TIME_STATISTICS, "true"); // TODO: test true/false + props.setProperty(STATISTIC_SAMPLE_RATE, String.valueOf(STAT_SAMPLE_RATE)); + props.setProperty(ARCHIVE_FILE_SIZE_LIMIT, "0"); + props.setProperty(ARCHIVE_DISK_SPACE_LIMIT, "0"); + props.setProperty(MCAST_PORT, "0"); + props.setProperty(LOCATORS, ""); + return props; + } + + /** + * Creates a fresh loner DistributedSystem for each test. Note + * that the DistributedSystem is the StatisticsManager/Factory/etc. + */ + @SuppressWarnings("deprecation") + private void connect(Properties props) { + this.system = DistributedSystem.connect(props); + } + + @SuppressWarnings("deprecation") + private void disconnect() { + if (this.system != null) { + this.system.disconnect(); + this.system = null; + } + } + +// public static class AsyncInvoker { +// public static AsyncInvocation invokeAsync(Runnable r) { +// return invokeAsync(r, "run", new Object[0]); +// } +// public static AsyncInvocation invokeAsync(Callable c) { +// return invokeAsync(c, "call", new Object[0]); +// } +// public static AsyncInvocation invokeAsync( +// final Object o, final String methodName, final Object[] args) { +// AsyncInvocation ai = +// new AsyncInvocation(o, methodName, new Runnable() { +// public void run() { +// MethExecutorResult result = +// MethExecutor.executeObject(o, methodName, args); +// if (result.exceptionOccurred()) { +// throw new AsyncInvocationException(result.getException()); +// } +// AsyncInvocation.setReturnValue(result.getResult()); +// } +// }); +// ai.start(); +// return ai; +// } +// +// public static class AsyncInvocationException extends RuntimeException { +// private static final long serialVersionUID = -5522299018650622945L; +// /** +// * Creates a new <code>AsyncInvocationException</code>. +// */ +// public AsyncInvocationException(String message) { +// super(message); +// } +// +// /** +// * Creates a new <code>AsyncInvocationException</code> that was +// * caused by a given exception +// */ +// public AsyncInvocationException(String message, Throwable thr) { +// super(message, thr); +// } +// +// /** +// * Creates a new <code>AsyncInvocationException</code> that was +// * caused by a given exception +// */ +// public AsyncInvocationException(Throwable thr) { +// super(thr.getMessage(), thr); +// } +// } +// } +}