package org.epics.archiverappliance.retrieval.postprocessor;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.Event;
import org.epics.archiverappliance.EventStream;
import org.epics.archiverappliance.PVCaPut;
import org.epics.archiverappliance.SIOCSetup;
import org.epics.archiverappliance.TomcatSetup;
import org.epics.archiverappliance.common.TimeUtils;
import org.epics.archiverappliance.config.ConfigServiceForTests;
import org.epics.archiverappliance.retrieval.client.RawDataRetrievalAsEventStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
/**
* This tests various post processors using sample data generated from within Matlab
* We change an ai record using various values generated from within Matlab and then make various postprocessor calls and compare with values we got from Matlab
* @author mshankar
*
*/
public class VariousPostProcessorTest {
private static Logger logger = Logger.getLogger(VariousPostProcessorTest.class.getName());
TomcatSetup tomcatSetup = new TomcatSetup();
SIOCSetup siocSetup = new SIOCSetup();
WebDriver driver;
String pvName = "UnitTestNoNamingConvention:inactive1";
// These values were generated from Matlab.
double[] sampleValues = new double[] { 0.1349, -2.3312, 1.2507, 1.5754, -1.2929, 3.3818, 3.3783, 0.9247, 1.6546, 1.3493, 0.6266, 2.4516, -0.1766, 5.3664, 0.7272, 1.2279, 3.1335, 1.1186, 0.8087, -0.6647, 1.5888, -1.6724, 2.4286, 4.2471, -0.3836, 2.7160, 3.5080, -2.1875, -1.8819, 2.1423, 0.2002, 2.3800, 2.6312, 2.4238, 3.5805, 2.3372, 3.3817, -1.4049, 0.9604, 0.6866, -2.2082, 1.5146, -1.1129, 3.8303, -0.6102, 2.0575, 1.4386, -0.8438, -3.3413, 0.8816, -1.0213, 2.2289, 2.0155, 4.3849, 2.1826, -0.2872, 1.7607, -1.0182, 0.9610, 0.9036, 1.0001, 0.3643, 3.1900, -2.7480, 1.8564, 2.7913, 2.4619, 2.1557, 1.0806, 2.3542, 2.1378, 0.4887, 0.2451, 0.4082, -1.9503, 0.5320, 1.2369, 1.6296, 3.8870, 0.2981, 2.2465, 2.5981, 2.8818, -0.9842, 1.4241, 1.4758, -1.0155, -0.4841, 3.1646, 0.7370, 1.7798, 1.1760, -0.2709, -0.1191, 1.8873, -0.8998, 2.5624, 2.1379, -0.6434, 0.4688, Float.NaN };
double expectedMean = 1.0959;
double expectedMedian = 1.2324;
double expectedStd = 1.7370;
double expectedJitter = 1.5851;
double expectedVariance = 3.0172;
@Before
public void setUp() throws Exception {
FileUtils.deleteDirectory(new File(ConfigServiceForTests.getDefaultShortTermFolder() + File.separator + "UnitTestNoNamingConvention"));
FileUtils.deleteDirectory(new File(ConfigServiceForTests.getDefaultPBTestFolder() + File.separator + "UnitTestNoNamingConvention"));
if(!System.getenv().containsKey("ARCHAPPL_SHORT_TERM_FOLDER") && !System.getProperties().containsKey("ARCHAPPL_SHORT_TERM_FOLDER")) {
System.getProperties().put("ARCHAPPL_SHORT_TERM_FOLDER", ConfigServiceForTests.getDefaultShortTermFolder());
}
if(!System.getenv().containsKey("ARCHAPPL_MEDIUM_TERM_FOLDER") && !System.getProperties().containsKey("ARCHAPPL_MEDIUM_TERM_FOLDER")) {
System.getProperties().put("ARCHAPPL_MEDIUM_TERM_FOLDER", ConfigServiceForTests.getDefaultPBTestFolder());
}
siocSetup.startSIOCWithDefaultDB();
tomcatSetup.setUpWebApps(this.getClass().getSimpleName());
driver = new FirefoxDriver();
}
@After
public void tearDown() throws Exception {
driver.quit();
tomcatSetup.tearDown();
siocSetup.stopSIOC();
FileUtils.deleteDirectory(new File(ConfigServiceForTests.getDefaultShortTermFolder() + File.separator + "UnitTestNoNamingConvention"));
FileUtils.deleteDirectory(new File(ConfigServiceForTests.getDefaultPBTestFolder() + File.separator + "UnitTestNoNamingConvention"));
}
@Test
public void testPostProcessors() throws Exception {
driver.get("http://localhost:17665/mgmt/ui/index.html");
WebElement pvstextarea = driver.findElement(By.id("archstatpVNames"));
String pvNameToArchive = pvName;
pvstextarea.sendKeys(pvNameToArchive);
WebElement archiveButton = driver.findElement(By.id("archstatArchive"));
logger.debug("About to submit");
archiveButton.click();
// We have to wait for a few minutes here as it does take a while for the workflow to complete.
Thread.sleep(5*60*1000);
WebElement checkStatusButton = driver.findElement(By.id("archstatCheckStatus"));
checkStatusButton.click();
Thread.sleep(2*1000);
WebElement statusPVName = driver.findElement(By.cssSelector("#archstatsdiv_table tr:nth-child(1) td:nth-child(1)"));
String pvNameObtainedFromTable = statusPVName.getText();
assertTrue("PV Name is not " + pvNameToArchive + "; instead we get " + pvNameObtainedFromTable, pvNameToArchive.equals(pvNameObtainedFromTable));
WebElement statusPVStatus = driver.findElement(By.cssSelector("#archstatsdiv_table tr:nth-child(1) td:nth-child(2)"));
String pvArchiveStatusObtainedFromTable = statusPVStatus.getText();
String expectedPVStatus = "Being archived";
assertTrue("Expecting PV archive status to be " + expectedPVStatus + "; instead it is " + pvArchiveStatusObtainedFromTable, expectedPVStatus.equals(pvArchiveStatusObtainedFromTable));
// Change the values for the PV
logger.info("Changing pv " + pvName + " and generating " + sampleValues.length + " values");
new PVCaPut().caPutValues(pvName,sampleValues);
Thread.sleep(3*1000);
testRetrievalCount(pvName, sampleValues);
testRetrievalCount("mean_432000(" + pvName + ")", new double[] {expectedMean});
testRetrievalCount("median_432000(" + pvName + ")", new double[] {expectedMedian});
testRetrievalCount("std_432000(" + pvName + ")", new double[] {expectedStd});
testRetrievalCount("jitter_432000(" + pvName + ")", new double[] {expectedJitter});
testRetrievalCount("variance_432000(" + pvName + ")", new double[] {expectedVariance});
}
private void testRetrievalCount(String pvName, double[] expectedValues) throws IOException {
RawDataRetrievalAsEventStream rawDataRetrieval = new RawDataRetrievalAsEventStream("http://localhost:" + ConfigServiceForTests.RETRIEVAL_TEST_PORT+ "/retrieval/data/getData.raw");
Timestamp end = TimeUtils.plusDays(TimeUtils.now(), 1);
Timestamp start = TimeUtils.minusDays(end, 2);
try(EventStream stream = rawDataRetrieval.getDataForPVS(new String[] { pvName}, start, end, null)) {
long previousEpochSeconds = 0;
int eventCount = 0;
// We are making sure that the stream we get back has times in sequential order...
if(stream != null) {
double previousValue = 0.0;
for(Event e : stream) {
long actualSeconds = e.getEpochSeconds();
assertTrue(actualSeconds >= previousEpochSeconds);
previousEpochSeconds = actualSeconds;
if(eventCount == expectedValues.length) {
assertTrue("We are probably running this test on a day that generates two values for the bin size. In this case, we make sure the two values are the same",
e.getSampleValue().getValue().doubleValue() == previousValue);
continue;
}
assertTrue("Expecting " + expectedValues.length + " got " + eventCount + " for pv " + pvName, eventCount < expectedValues.length);
// We check for approx values only.
if(Double.isNaN(expectedValues[eventCount])) {
assertTrue("Got " + e.getSampleValue().getValue().doubleValue() + " expecting " + expectedValues[eventCount] + " at " + eventCount,
Double.isNaN(e.getSampleValue().getValue().doubleValue()));
} else {
assertTrue("Got " + e.getSampleValue().getValue().doubleValue() + " expecting " + expectedValues[eventCount] + " at " + eventCount,
Math.abs(Math.abs(e.getSampleValue().getValue().doubleValue()) - Math.abs(expectedValues[eventCount])) < 0.001);
}
previousValue = e.getSampleValue().getValue().doubleValue();
eventCount++;
}
}
assertTrue("Expecting " + expectedValues.length + " got " + eventCount + " for pv " + pvName, eventCount == expectedValues.length);
}
}
}