GEODE-1782: include start timestamp in stat resource equals * stat resources with different time stamps should not be equal
* StatArchiveWithConsecutiveResourceInstGenerator generates gfs with multiple stat resources of same name but different times * StatArchiveWithConsecutiveResourceInstIntegrationTest confirms existence of bug GEODE-1782: StatArchiveReader ignores later stats resource with same name as closed stats resource * ResourceInstTest verifies the underlying issue and fix in StatArchiveReader.ResourceInst.equals and the fix Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/bac2e4eb Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/bac2e4eb Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/bac2e4eb Branch: refs/heads/feature/GEODE-420 Commit: bac2e4eb6c12f9cca2a8ab7cffbf58bb380af19a Parents: 750996a Author: Kirk Lund <[email protected]> Authored: Mon Aug 15 18:35:45 2016 -0700 Committer: Kirk Lund <[email protected]> Committed: Wed Aug 17 16:45:40 2016 -0700 ---------------------------------------------------------------------- .../internal/statistics/StatArchiveReader.java | 3 + .../internal/statistics/ResourceInstTest.java | 84 +++++++ ...iveWithConsecutiveResourceInstGenerator.java | 223 +++++++++++++++++++ ...ithConsecutiveResourceInstGeneratorTest.java | 55 +++++ ...hConsecutiveResourceInstIntegrationTest.java | 108 +++++++++ .../gemfire/internal/statistics/StatUtils.java | 102 +++++++++ ...thConsecutiveResourceInstIntegrationTest.gfs | Bin 0 -> 1924 bytes 7 files changed, 575 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatArchiveReader.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatArchiveReader.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatArchiveReader.java index 12637bc..e597b83 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatArchiveReader.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatArchiveReader.java @@ -2672,6 +2672,9 @@ public class StatArchiveReader implements StatArchiveFormat { return false; } else if (!type.equals(other.type)) return false; + if (this.firstTSidx != other.firstTSidx) { + return false; + } return true; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/ResourceInstTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/ResourceInstTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/ResourceInstTest.java new file mode 100644 index 0000000..9b697bd --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/ResourceInstTest.java @@ -0,0 +1,84 @@ +/* + * 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.assertj.core.api.Assertions.*; +import static org.mockito.MockitoAnnotations.*; + +import java.lang.reflect.Field; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.Mock; + +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.ResourceInst; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.ResourceType; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.StatArchiveFile; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Unit tests for {@link ResourceInst}. + * + * <p>Confirms ResourceInst equals change to fix GEODE-1782. + * + * <p>GEODE-1782: StatArchiveReader ignores later stats resource with same name as closed stats resource + * + * @since Geode 1.0 + */ +@Category(UnitTest.class) +public class ResourceInstTest { + + @Mock + private StatArchiveFile archive1; + @Mock + private StatArchiveFile archive2; + @Mock + private ResourceType resourceType; + + @Before + public void setUp() throws Exception { + initMocks(this); + } + + @Test + public void sameFirstTSidxEquals() throws Exception { + ResourceInst resourceInst1 = new ResourceInst(this.archive1, 0, "name", 0, this.resourceType, false); + setFirstTSidx(resourceInst1, 1); + ResourceInst resourceInst2 = new ResourceInst(this.archive1, 0, "name", 0, this.resourceType, false); + setFirstTSidx(resourceInst2, 1); + + assertThat(resourceInst1).isEqualTo(resourceInst2); + } + + @Test + public void differentFirstTSidxIsNotEqual() throws Exception { + ResourceInst resourceInst1 = new ResourceInst(this.archive1, 0, "name", 0, this.resourceType, false); + setFirstTSidx(resourceInst1, 1); + ResourceInst resourceInst2 = new ResourceInst(this.archive1, 0, "name", 0, this.resourceType, false); + setFirstTSidx(resourceInst2, 2); + + assertThat(resourceInst1).isNotEqualTo(resourceInst2); + } + + private void setFirstTSidx(ResourceInst resourceInst, int value) throws IllegalAccessException, NoSuchFieldException { + Field field = ResourceInst.class.getDeclaredField("firstTSidx"); + field.setAccessible(true); + field.setInt(resourceInst, value); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGenerator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGenerator.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGenerator.java new file mode 100644 index 0000000..972e6702 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGenerator.java @@ -0,0 +1,223 @@ +/* + * 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.internal.statistics.StatArchiveFormat.NANOS_PER_MILLI; +import static com.gemstone.gemfire.internal.statistics.StatUtils.*; +import static com.gemstone.gemfire.internal.statistics.TestStatArchiveWriter.*; +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.logging.log4j.LogManager; +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.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import com.gemstone.gemfire.StatisticDescriptor; +import com.gemstone.gemfire.Statistics; +import com.gemstone.gemfire.StatisticsType; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.ResourceInst; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.StatValue; + +/** + * Generates the stat archive file that is committed under src/test/resources + * for {@link StatArchiveWithConsecutiveResourceInstIntegrationTest} to load. + * + * <p>The generated gfs file is used to confirm GEODE-1782 and its fix. + * + * @since Geode 1.0 + */ +public class StatArchiveWithConsecutiveResourceInstGenerator { + + private static final Logger logger = LogManager.getLogger(); + + protected static final String STATS_TYPE_NAME = "TestStats"; + protected static final String STATS_SPEC_STRING = ":" + STATS_TYPE_NAME; + + protected static final String TEST_NAME = StatArchiveWithConsecutiveResourceInstIntegrationTest.class.getSimpleName(); + protected static final String ARCHIVE_FILE_NAME = TEST_NAME + ".gfs"; + + private File dir; + private Map<String,String> statisticTypes; + private Map<String,Map<String,Number>> allStatistics; + protected String archiveFileName; + + private TestStatisticsManager manager; + private TestStatisticsSampler sampler; + private SampleCollector sampleCollector; + private StatArchiveWriter writer; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUpGenerator() throws Exception { + this.statisticTypes = new HashMap<>(); + this.allStatistics = new HashMap<>(); + this.dir = this.temporaryFolder.getRoot(); + this.archiveFileName = new File(this.dir.getAbsolutePath(), ARCHIVE_FILE_NAME).getAbsolutePath(); + + this.manager = new TestStatisticsManager(1, getUniqueName(), WRITER_INITIAL_DATE_MILLIS); + StatArchiveDescriptor archiveDescriptor = new StatArchiveDescriptor.Builder() + .setArchiveName(this.archiveFileName) + .setSystemId(1) + .setSystemStartTime(WRITER_INITIAL_DATE_MILLIS - 2000) + .setSystemDirectoryPath(TEST_NAME) + .setProductDescription(TEST_NAME) + .build(); + this.writer = new TestStatArchiveWriter(archiveDescriptor); + this.sampler = new TestStatisticsSampler(manager); + this.sampleCollector = new SampleCollector(sampler); + this.sampleCollector.addSampleHandler(this.writer); + } + + @After + public void tearDown() throws Exception { + StatisticsTypeFactoryImpl.clear(); + } + + @Test + public void generateStatArchiveFile() throws Exception { + + long sampleTimeNanos = WRITER_PREVIOUS_TIMESTAMP_NANOS + NANOS_PER_MILLI*1000; + + // 1) create statistics + + StatisticsType type = createStatisticsType(STATS_TYPE_NAME, "description of " + STATS_TYPE_NAME); + Statistics statistics1 = createStatistics(type, STATS_TYPE_NAME + "1", 1); + + // 2) sample changing stat + + for (int i = 0; i < 100; i++) { + incInt(statistics1, "stat", 1); + this.sampleCollector.sample(sampleTimeNanos += (1000 * NANOS_PER_MILLI)); + } + + // 3) close statistics + + statistics1.close(); + + // 4) recreate statistics + + Statistics statistics2 = createStatistics(type, STATS_TYPE_NAME + "1", 1); + + // 5) sample changing stat again + + for (int i = 0; i < 100; i++) { + incInt(statistics2, "stat", 1); + this.sampleCollector.sample(sampleTimeNanos += (1000 * NANOS_PER_MILLI)); + } + + // close the writer + + this.writer.close(); + + // validate that stat archive file exists + + File actual = new File(this.archiveFileName); + assertTrue(actual.exists()); + + // validate content of stat archive file using StatArchiveReader + + StatArchiveReader reader = new StatArchiveReader(new File[]{actual}, null, false); + + // compare all resourceInst values against what was printed above + + for (final Iterator iter = reader.getResourceInstList().iterator(); iter.hasNext();) { + StatArchiveReader.ResourceInst ri = (StatArchiveReader.ResourceInst) iter.next(); + String resourceName = ri.getName(); + assertNotNull(resourceName); + + 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++) { + final 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.01); + } + } + + validateArchiveFile(); + } + + protected void validateArchiveFile() throws IOException { + final File archiveFile = new File(this.archiveFileName); + assertTrue(archiveFile.exists()); + + logger.info("ArchiveFile: {}", archiveFile.getAbsolutePath()); + logger.info("ArchiveFile length: {}", archiveFile.length()); + + for (ResourceInst resourceInst: findResourceInsts(archiveFile, STATS_SPEC_STRING)) { + logger.info("ResourceInst: {}", resourceInst); + } + } + + private String getUniqueName() { + return StatArchiveWithConsecutiveResourceInstGenerator.class + "_" + this.testName.getMethodName(); + } + + private StatisticsType createStatisticsType(final String name, final String description) { + StatisticDescriptor[] descriptors = new StatisticDescriptor[] { + manager.createIntCounter("stat", "description of stat", "units"), + }; + return manager.createType(name, description, descriptors); + } + + private Statistics createStatistics(final StatisticsType type, final String textId, final long numericId) { + return manager.createAtomicStatistics(type, textId, 1); + } + + private void incInt(Statistics statistics, String stat, int value) { + assertFalse(statistics.isClosed()); + Map<String,Number> statValues = this.allStatistics.get(statistics.getTextId()); + if (statValues == null) { + statValues = new HashMap<>(); + this.allStatistics.put(statistics.getTextId(), statValues); + } + 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()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGeneratorTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGeneratorTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGeneratorTest.java new file mode 100644 index 0000000..1e4554e --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstGeneratorTest.java @@ -0,0 +1,55 @@ +/* + * 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.internal.statistics.StatUtils.*; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +/** + * Compares the output results of {@link StatArchiveWithConsecutiveResourceInstGenerator} against the saved stat + * archive file in src/test/resources that is used by {@link StatArchiveWithConsecutiveResourceInstIntegrationTest}. + * + * @since Geode 1.0 + */ +@Category(IntegrationTest.class) +public class StatArchiveWithConsecutiveResourceInstGeneratorTest extends StatArchiveWithConsecutiveResourceInstGenerator { + + private File expectedStatArchiveFile; + + @Before + public void setUpGeneratorTest() throws Exception { + URL url = getClass().getResource(ARCHIVE_FILE_NAME); + File testFolder = this.temporaryFolder.newFolder(getClass().getSimpleName()); + this.expectedStatArchiveFile = new File(testFolder, ARCHIVE_FILE_NAME); + FileUtils.copyURLToFile(url, this.expectedStatArchiveFile); + } + + @Override + protected void validateArchiveFile() throws IOException { + compareStatArchiveFiles(this.expectedStatArchiveFile, new File(this.archiveFileName)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.java new file mode 100644 index 0000000..e272fec --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.java @@ -0,0 +1,108 @@ +/* + * 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.internal.statistics.StatArchiveWithConsecutiveResourceInstGenerator.*; +import static org.assertj.core.api.Assertions.*; + +import java.io.File; +import java.net.URL; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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.internal.SystemAdmin.StatSpec; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.ResourceInst; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.StatValue; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +/** + * Confirms existence of GEODE-1782 and its fix. + * + * <p>GEODE-1782: StatArchiveReader ignores later stats resource with same name as closed stats resource + * + * @since Geode 1.0 + */ +@Category(IntegrationTest.class) +public class StatArchiveWithConsecutiveResourceInstIntegrationTest { + + private static final Logger logger = LogManager.getLogger(); + + private File archiveFile; + private StatSpec statSpec; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + URL url = getClass().getResource(ARCHIVE_FILE_NAME); + this.archiveFile = this.temporaryFolder.newFile(ARCHIVE_FILE_NAME); + FileUtils.copyURLToFile(url, archiveFile); + + this.statSpec = new StatSpec(STATS_SPEC_STRING); + + // precondition + assertThat(this.archiveFile).exists(); + } + + @Test + public void readingFourActiveCacheClientUpdaterStatsWithReaderMatchSpec() throws Exception { + StatArchiveReader reader = new StatArchiveReader(new File[] {this.archiveFile}, new StatSpec[] {this.statSpec }, true); + + Set<ResourceInst> resourceInstList = new HashSet<>(); + for (StatValue statValue: reader.matchSpec(this.statSpec)) { + for (int i = 0; i < statValue.getResources().length; i++) { + resourceInstList.add(statValue.getResources()[i]); + } + } + + assertThat(resourceInstList.size()).isEqualTo(2); + } + + @Test + public void readingFourActiveCacheClientUpdaterStatsWithReader() throws Exception { + StatArchiveReader reader = new StatArchiveReader(new File[] {this.archiveFile}, new StatSpec[]{this.statSpec }, true); + + Set<ResourceInst> resourceInstList = new HashSet<>(); + for (Iterator<ResourceInst> it = reader.getResourceInstList().iterator(); it.hasNext();) { + resourceInstList.add(it.next()); + } + + assertThat(resourceInstList.size()).isEqualTo(2); + } + + private void printResourceInsts(Set<ResourceInst> resourceInstList) { + for (ResourceInst resourceInst : resourceInstList) { + logger.info(this.testName.getMethodName() + ":ResourceInst: {}", resourceInst); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatUtils.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatUtils.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatUtils.java new file mode 100644 index 0000000..1ffbd6f --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/statistics/StatUtils.java @@ -0,0 +1,102 @@ +/* + * 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.assertj.core.api.Assertions.*; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; + +import com.gemstone.gemfire.internal.SystemAdmin.StatSpec; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.ResourceInst; +import com.gemstone.gemfire.internal.statistics.StatArchiveReader.StatValue; + +/** + * @since Geode 1.0 + */ +public class StatUtils { + + /** + * final File expectedStatArchiveFile = new File(TestUtil.getResourcePath(getClass(), "StatArchiveWriterReaderJUnitTest_" + this.testName.getMethodName() + "_expected.gfs")); + */ + public static void compareStatArchiveFiles(final File expectedStatArchiveFile, final File actualStatArchiveFile) throws IOException { + assertThat(expectedStatArchiveFile).exists(); + assertThat(actualStatArchiveFile.length()).isEqualTo(expectedStatArchiveFile.length()); + + assertThat(readBytes(actualStatArchiveFile)).isEqualTo(readBytes(expectedStatArchiveFile)); + } + + public static Set<ResourceInst> findResourceInsts(final File archiveFile, final String specString) throws IOException { + Set<ResourceInst> resourceInsts = new HashSet<>(); + + if (StringUtils.isNotEmpty(specString)) { + addResourceInstsToSet(archiveFile, specString, resourceInsts); + } else { + addResourceInstsToSet(archiveFile, resourceInsts); + } + + return resourceInsts; + } + + private static void addResourceInstsToSet(final File archiveFile, final Set<ResourceInst> resourceInsts) throws IOException { + StatArchiveReader reader = new StatArchiveReader(new File[] {archiveFile}, new StatSpec[]{}, true); + + for (Iterator<ResourceInst> it = reader.getResourceInstList().iterator(); it.hasNext();) { + resourceInsts.add(it.next()); + } + } + + private static void addResourceInstsToSet(final File archiveFile, final String specString, final Set<ResourceInst> resourceInsts) throws IOException { + StatSpec statSpec = new StatSpec(specString); + + StatArchiveReader reader = new StatArchiveReader(new File[] { archiveFile }, new StatSpec[] { statSpec }, true); + StatValue[] statValues = reader.matchSpec(statSpec); + + for (StatValue statValue : statValues) { + for (ResourceInst resourceInst : statValue.getResources()) { + resourceInsts.add(resourceInst); + } + } + } + + private static byte[] readBytes(File file) throws IOException { + int byteCount = (int)file.length(); + + byte[] input = new byte[byteCount]; + + URL url = file.toURL(); + assertThat(url).isNotNull(); + + InputStream is = url.openStream(); + assertThat(is).isNotNull(); + + BufferedInputStream bis = new BufferedInputStream(is); + int bytesRead = bis.read(input); + bis.close(); + + assertThat(bytesRead).isEqualTo(byteCount); + return input; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/bac2e4eb/geode-core/src/test/resources/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.gfs ---------------------------------------------------------------------- diff --git a/geode-core/src/test/resources/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.gfs b/geode-core/src/test/resources/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.gfs new file mode 100644 index 0000000..943f6d9 Binary files /dev/null and b/geode-core/src/test/resources/com/gemstone/gemfire/internal/statistics/StatArchiveWithConsecutiveResourceInstIntegrationTest.gfs differ
