package org.epics.archiverappliance.retrieval.postprocessor;
import static org.junit.Assert.assertTrue;
import java.sql.Timestamp;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.Event;
import org.epics.archiverappliance.common.TimeUtils;
import org.epics.archiverappliance.common.YearSecondTimestamp;
import org.epics.archiverappliance.config.ArchDBRTypes;
import org.epics.archiverappliance.config.PVTypeInfo;
import org.epics.archiverappliance.data.ScalarValue;
import org.epics.archiverappliance.engine.membuf.ArrayListEventStream;
import org.epics.archiverappliance.retrieval.CallableEventStream;
import org.epics.archiverappliance.retrieval.RemotableEventStreamDesc;
import org.epics.archiverappliance.retrieval.postprocessors.Mean;
import org.epics.archiverappliance.utils.simulation.SimulationEvent;
import org.junit.Test;
/**
* The SummaryStatsPostProcessor provides the framework code for computing average, sigma etc on the server side.
* This tests the framework itself; specifically, it tests that binning works as expected and fills all the bins.
* The ArchiveViewer relies on this behavior to implement formulae.
* @author mshankar
*
*/
public class SummaryStatsPostProcessorTest {
private static Logger logger = Logger.getLogger(SummaryStatsPostProcessorTest.class.getName());
private String pvName = "Test_SummaryStats1";
/**
* Generate data from Jun 1 for a couple of months; one every two days.
* Ask for summary with a bin of one day and different periods and see that we get appropriate results.
* @throws Exception
*/
@Test
public void testBeforeAndAfter() throws Exception {
short currentYear = TimeUtils.getCurrentYear();
int totalDays = 60;
YearSecondTimestamp startOfSamples = TimeUtils.convertToYearSecondTimestamp(TimeUtils.convertFromISO8601String(currentYear + "-06-01T10:00:00.000Z"));
for(int sampleIntervalInHours = 3; sampleIntervalInHours < 24*4; sampleIntervalInHours+=3) {
int totSamples = totalDays*24/sampleIntervalInHours;
logger.info("Creating " + totSamples + " samples " + sampleIntervalInHours + " hours apart");
ArrayListEventStream testData = new ArrayListEventStream(0, new RemotableEventStreamDesc(ArchDBRTypes.DBR_SCALAR_DOUBLE, pvName, currentYear));
for(int s = 0; s < totSamples; s++) {
testData.add(new SimulationEvent(startOfSamples.getSecondsintoyear() + s*sampleIntervalInHours*60*60, currentYear, ArchDBRTypes.DBR_SCALAR_DOUBLE, new ScalarValue<Double>((double) s)));
}
{
Mean meanProcessor = new Mean();
meanProcessor.initialize("mean_"+24*60*60, pvName);
Timestamp start = TimeUtils.convertFromISO8601String(currentYear + "-06-03T10:00:00.000Z");
Timestamp end = TimeUtils.convertFromISO8601String(currentYear + "-06-23T10:00:00.000Z");
meanProcessor.estimateMemoryConsumption(pvName, new PVTypeInfo(pvName, ArchDBRTypes.DBR_SCALAR_DOUBLE, true, 1), start, end, null);
meanProcessor.wrap(CallableEventStream.makeOneStreamCallable(testData, null, false)).call();
int eventCount = 0;
Timestamp previousTimeStamp = TimeUtils.convertFromYearSecondTimestamp(startOfSamples);
for(Event e : meanProcessor.getConsolidatedEventStream()) {
logger.debug(TimeUtils.convertToISO8601String(e.getEventTimeStamp()) + "=" + e.getSampleValue().toString());
Timestamp eventTs = e.getEventTimeStamp();
assertTrue("Event timestamp " + TimeUtils.convertToISO8601String(eventTs) + " is the same or after previous timestamp " + TimeUtils.convertToISO8601String(previousTimeStamp),
eventTs.after(previousTimeStamp));
previousTimeStamp = eventTs;
eventCount++;
}
assertTrue("Expected around 21 events got " + eventCount, eventCount >= 19 && eventCount <= 22);
}
// Test where we are missing the starting bin.
{
Mean meanProcessor = new Mean();
meanProcessor.initialize("mean_"+24*60*60, pvName);
Timestamp start = TimeUtils.convertFromISO8601String(currentYear + "-06-04T10:00:00.000Z");
Timestamp end = TimeUtils.convertFromISO8601String(currentYear + "-06-23T10:00:00.000Z");
meanProcessor.estimateMemoryConsumption(pvName, new PVTypeInfo(pvName, ArchDBRTypes.DBR_SCALAR_DOUBLE, true, 1), start, end, null);
meanProcessor.wrap(CallableEventStream.makeOneStreamCallable(testData, null, false)).call();
int eventCount = 0;
Timestamp previousTimeStamp = TimeUtils.convertFromYearSecondTimestamp(startOfSamples);
for(Event e : meanProcessor.getConsolidatedEventStream()) {
logger.debug(TimeUtils.convertToISO8601String(e.getEventTimeStamp()) + "=" + e.getSampleValue().toString());
Timestamp eventTs = e.getEventTimeStamp();
assertTrue("Event timestamp " + TimeUtils.convertToISO8601String(eventTs) + " is the same or after previous timestamp " + TimeUtils.convertToISO8601String(previousTimeStamp),
eventTs.after(previousTimeStamp));
previousTimeStamp = eventTs;
eventCount++;
}
assertTrue("Expected around 20 events got " + eventCount, eventCount >= 17 && eventCount <= 22);
}
// Test where we are missing data in the start.
{
Mean meanProcessor = new Mean();
meanProcessor.initialize("mean_"+24*60*60, pvName);
Timestamp start = TimeUtils.convertFromISO8601String(currentYear + "-05-21T10:00:00.000Z");
Timestamp end = TimeUtils.convertFromISO8601String(currentYear + "-06-21T10:00:00.000Z");
meanProcessor.estimateMemoryConsumption(pvName, new PVTypeInfo(pvName, ArchDBRTypes.DBR_SCALAR_DOUBLE, true, 1), start, end, null);
meanProcessor.wrap(CallableEventStream.makeOneStreamCallable(testData, null, false)).call();
int eventCount = 0;
Timestamp previousTimeStamp = start;
for(Event e : meanProcessor.getConsolidatedEventStream()) {
logger.debug(TimeUtils.convertToISO8601String(e.getEventTimeStamp()) + "=" + e.getSampleValue().toString());
Timestamp eventTs = e.getEventTimeStamp();
assertTrue("Event timestamp " + TimeUtils.convertToISO8601String(eventTs) + " is the same or after previous timestamp " + TimeUtils.convertToISO8601String(previousTimeStamp),
eventTs.after(previousTimeStamp));
previousTimeStamp = eventTs;
eventCount++;
}
assertTrue("Expected around 21 events got " + eventCount, eventCount >= 17 && eventCount <= 23);
}
}
}
}