You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/08/16 16:45:15 UTC
[2/2] incubator-geode git commit: GEODE-1782: stat resources with
different time stamps should not be equal
GEODE-1782: 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 reso
urce with same name as closed stats resource
* ResourceInstTest verifies the underlying issue 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/bcf3487a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/bcf3487a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/bcf3487a
Branch: refs/heads/feature/GEODE-1781
Commit: bcf3487aa13b85515827e550123d9925f0e1a272
Parents: 6a9444a
Author: Kirk Lund <kl...@apache.org>
Authored: Mon Aug 15 18:35:45 2016 -0700
Committer: Kirk Lund <kl...@apache.org>
Committed: Tue Aug 16 09:26:30 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/bcf3487a/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/bcf3487a/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/bcf3487a/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/bcf3487a/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/bcf3487a/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/bcf3487a/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/bcf3487a/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