blob: a6f0b7b540dd9ed50d5661742cfa3067012526e0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.statistics;
import static org.apache.geode.internal.statistics.StatArchiveFormat.NANOS_PER_MILLI;
import static org.apache.geode.internal.statistics.StatUtils.findResourceInsts;
import static org.apache.geode.internal.statistics.TestStatArchiveWriter.WRITER_INITIAL_DATE_MILLIS;
import static org.apache.geode.internal.statistics.TestStatArchiveWriter.WRITER_PREVIOUS_TIMESTAMP_NANOS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
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 org.apache.geode.StatisticDescriptor;
import org.apache.geode.Statistics;
import org.apache.geode.StatisticsType;
import org.apache.geode.internal.statistics.StatArchiveReader.ResourceInst;
import org.apache.geode.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(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());
}
}
}