/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.regression.view;
import com.espertech.esper.client.*;
import com.espertech.esper.client.scopetest.EPAssertionUtil;
import com.espertech.esper.client.scopetest.SupportUpdateListener;
import com.espertech.esper.client.time.CurrentTimeEvent;
import com.espertech.esper.client.util.DateTime;
import com.espertech.esper.core.service.EPServiceProviderSPI;
import com.espertech.esper.metrics.instrumentation.InstrumentationHelper;
import com.espertech.esper.supportregression.bean.SupportBean;
import com.espertech.esper.supportregression.bean.SupportBeanTimestamp;
import com.espertech.esper.supportregression.bean.SupportMarketDataBean;
import com.espertech.esper.supportregression.client.SupportConfigFactory;
import com.espertech.esper.supportregression.util.SupportMessageAssertUtil;
import com.espertech.esper.util.EventRepresentationChoice;
import junit.framework.TestCase;
import java.util.*;
public class TestViewGroupWin extends TestCase
{
private static String SYMBOL_CISCO = "CSCO.O";
private static String SYMBOL_IBM = "IBM.N";
private static String SYMBOL_GE = "GE.N";
private EPServiceProvider epService;
private SupportUpdateListener listener;
private SupportUpdateListener priceLast3StatsListener;
private SupportUpdateListener priceAllStatsListener;
private SupportUpdateListener volumeLast3StatsListener;
private SupportUpdateListener volumeAllStatsListener;
public void setUp()
{
listener = new SupportUpdateListener();
priceLast3StatsListener = new SupportUpdateListener();
priceAllStatsListener = new SupportUpdateListener();
volumeLast3StatsListener = new SupportUpdateListener();
volumeAllStatsListener = new SupportUpdateListener();
epService = EPServiceProviderManager.getDefaultProvider(SupportConfigFactory.getConfiguration());
epService.initialize();
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName());}
}
protected void tearDown() throws Exception {
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();}
priceLast3StatsListener = null;
priceAllStatsListener = null;
volumeLast3StatsListener = null;
volumeAllStatsListener = null;
listener = null;
}
public void testObjectArrayEvent() {
String[] fields = "p1,sp2".split(",");
epService.getEPAdministrator().getConfiguration().addEventType("MyOAEvent", new String[] {"p1","p2"}, new Object[] {String.class, int.class});
epService.getEPAdministrator().createEPL("select p1,sum(p2) as sp2 from MyOAEvent#groupwin(p1)#length(2)").addListener(listener);
epService.getEPRuntime().sendEvent(new Object[] {"A", 10}, "MyOAEvent");
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 10});
epService.getEPRuntime().sendEvent(new Object[] {"B", 11}, "MyOAEvent");
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"B", 21});
epService.getEPRuntime().sendEvent(new Object[] {"A", 12}, "MyOAEvent");
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 33});
epService.getEPRuntime().sendEvent(new Object[] {"A", 13}, "MyOAEvent");
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[] {"A", 36});
}
public void testSelfJoin() {
// ESPER-528
epService.getEPAdministrator().createEPL(EventRepresentationChoice.MAP.getAnnotationText() + " create schema Product (product string, productsize int)");
epService.getEPRuntime().sendEvent(new CurrentTimeEvent(0));
String query =
" @Hint('reclaim_group_aged=1,reclaim_group_freq=1') select Product.product as product, Product.productsize as productsize from Product unidirectional" +
" left outer join Product#time(3 seconds)#groupwin(product,productsize)#size PrevProduct on Product.product=PrevProduct.product and Product.productsize=PrevProduct.productsize" +
" having PrevProduct.size<2";
epService.getEPAdministrator().createEPL(query);
// Set to larger number of executions and monitor memory
for (int i = 0; i < 10; i++) {
sendProductNew("The id of this product is deliberately very very long so that we can use up more memory per instance of this event sent into Esper " + i, i);
epService.getEPRuntime().sendEvent(new CurrentTimeEvent(i * 100));
//if (i % 2000 == 0) {
// System.out.println("i=" + i + "; Allocated: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "; Free: " + Runtime.getRuntime().freeMemory() / 1024 / 1024);
//}
}
}
private void sendProductNew(String product, int size) {
Map<String, Object> theEvent = new HashMap<String, Object>();
theEvent.put("product", product);
theEvent.put("productsize", size);
epService.getEPRuntime().sendEvent(theEvent, "Product");
}
public void testReclaimTimeWindow()
{
sendTimer(0);
epService.getEPAdministrator().getConfiguration().addEventType("SupportBean", SupportBean.class);
epService.getEPAdministrator().createEPL("@Hint('reclaim_group_aged=30,reclaim_group_freq=5') " +
"select longPrimitive, count(*) from SupportBean#groupwin(theString)#time(3000000)");
for (int i = 0; i < 10; i++)
{
SupportBean theEvent = new SupportBean(Integer.toString(i), i);
epService.getEPRuntime().sendEvent(theEvent);
}
EPServiceProviderSPI spi = (EPServiceProviderSPI) epService;
int handleCountBefore = spi.getSchedulingService().getScheduleHandleCount();
assertEquals(10, handleCountBefore);
sendTimer(1000000);
epService.getEPRuntime().sendEvent(new SupportBean("E1", 1));
int handleCountAfter = spi.getSchedulingService().getScheduleHandleCount();
assertEquals(1, handleCountAfter);
}
private void sendTimer(long timeInMSec)
{
CurrentTimeEvent theEvent = new CurrentTimeEvent(timeInMSec);
EPRuntime runtime = epService.getEPRuntime();
runtime.sendEvent(theEvent);
}
public void testReclaimAgedHint() {
if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest();} // exclude from test, too much data
epService.getEPRuntime().sendEvent(new CurrentTimeEvent(0));
epService.getEPAdministrator().getConfiguration().addEventType("SupportBean", SupportBean.class);
String epl = "@Hint('reclaim_group_aged=5,reclaim_group_freq=1') " +
"select * from SupportBean#groupwin(theString)#keepall";
EPStatement stmt = epService.getEPAdministrator().createEPL(epl);
int maxSlots = 10;
int maxEventsPerSlot = 1000;
for (int timeSlot = 0; timeSlot < maxSlots; timeSlot++) {
epService.getEPRuntime().sendEvent(new CurrentTimeEvent(timeSlot * 1000 + 1));
for (int i = 0; i < maxEventsPerSlot; i++) {
epService.getEPRuntime().sendEvent(new SupportBean("E" + timeSlot, 0));
}
}
EventBean[] iterator = EPAssertionUtil.iteratorToArray(stmt.iterator());
assertTrue(iterator.length <= 6 * maxEventsPerSlot);
}
public void testInvalidGroupByNoChild()
{
String stmtText = "select avg(price), symbol from " + SupportMarketDataBean.class.getName() + "#length(100)#groupwin(symbol)";
try
{
epService.getEPAdministrator().createEPL(stmtText);
}
catch (EPStatementException ex)
{
SupportMessageAssertUtil.assertMessage(ex, "Error starting statement: Invalid use of the 'groupwin' view, the view requires one or more child views to group, or consider using the group-by clause [");
}
}
public void testStats()
{
EPAdministrator epAdmin = epService.getEPAdministrator();
String filter = "select * from " + SupportMarketDataBean.class.getName();
EPStatement priceLast3Stats = epAdmin.createEPL(filter + "#groupwin(symbol)#length(3)#uni(price) order by symbol asc");
priceLast3Stats.addListener(priceLast3StatsListener);
EPStatement volumeLast3Stats = epAdmin.createEPL(filter + "#groupwin(symbol)#length(3)#uni(volume) order by symbol asc");
volumeLast3Stats.addListener(volumeLast3StatsListener);
EPStatement priceAllStats = epAdmin.createEPL(filter + "#groupwin(symbol)#uni(price) order by symbol asc");
priceAllStats.addListener(priceAllStatsListener);
EPStatement volumeAllStats = epAdmin.createEPL(filter + "#groupwin(symbol)#uni(volume) order by symbol asc");
volumeAllStats.addListener(volumeAllStatsListener);
Vector<Map<String, Object>> expectedList = new Vector<Map<String, Object>>();
for (int i = 0; i < 3; i++)
{
expectedList.add(new HashMap<String, Object>());
}
sendEvent(SYMBOL_CISCO, 25, 50000);
sendEvent(SYMBOL_CISCO, 26, 60000);
sendEvent(SYMBOL_IBM, 10, 8000);
sendEvent(SYMBOL_IBM, 10.5, 8200);
sendEvent(SYMBOL_GE, 88, 1000);
EPAssertionUtil.assertPropsPerRow(priceLast3StatsListener.getLastNewData(), makeMap(SYMBOL_GE, 88));
EPAssertionUtil.assertPropsPerRow(priceAllStatsListener.getLastNewData(), makeMap(SYMBOL_GE, 88));
EPAssertionUtil.assertPropsPerRow(volumeLast3StatsListener.getLastNewData(), makeMap(SYMBOL_GE, 1000));
EPAssertionUtil.assertPropsPerRow(volumeAllStatsListener.getLastNewData(), makeMap(SYMBOL_GE, 1000));
sendEvent(SYMBOL_CISCO, 27, 70000);
sendEvent(SYMBOL_CISCO, 28, 80000);
EPAssertionUtil.assertPropsPerRow(priceAllStatsListener.getLastNewData(), makeMap(SYMBOL_CISCO, 26.5d));
EPAssertionUtil.assertPropsPerRow(volumeAllStatsListener.getLastNewData(), makeMap(SYMBOL_CISCO, 65000d));
EPAssertionUtil.assertPropsPerRow(priceLast3StatsListener.getLastNewData(), makeMap(SYMBOL_CISCO, 27d));
EPAssertionUtil.assertPropsPerRow(volumeLast3StatsListener.getLastNewData(), makeMap(SYMBOL_CISCO, 70000d));
sendEvent(SYMBOL_IBM, 11, 8700);
sendEvent(SYMBOL_IBM, 12, 8900);
EPAssertionUtil.assertPropsPerRow(priceAllStatsListener.getLastNewData(), makeMap(SYMBOL_IBM, 10.875d));
EPAssertionUtil.assertPropsPerRow(volumeAllStatsListener.getLastNewData(), makeMap(SYMBOL_IBM, 8450d));
EPAssertionUtil.assertPropsPerRow(priceLast3StatsListener.getLastNewData(), makeMap(SYMBOL_IBM, 11d + 1 / 6d));
EPAssertionUtil.assertPropsPerRow(volumeLast3StatsListener.getLastNewData(), makeMap(SYMBOL_IBM, 8600d));
sendEvent(SYMBOL_GE, 85.5, 950);
sendEvent(SYMBOL_GE, 85.75, 900);
sendEvent(SYMBOL_GE, 89, 1250);
sendEvent(SYMBOL_GE, 86, 1200);
sendEvent(SYMBOL_GE, 85, 1150);
double averageGE = (88d + 85.5d + 85.75d + 89d + 86d + 85d) / 6d;
EPAssertionUtil.assertPropsPerRow(priceAllStatsListener.getLastNewData(), makeMap(SYMBOL_GE, averageGE));
EPAssertionUtil.assertPropsPerRow(volumeAllStatsListener.getLastNewData(), makeMap(SYMBOL_GE, 1075d));
EPAssertionUtil.assertPropsPerRow(priceLast3StatsListener.getLastNewData(), makeMap(SYMBOL_GE, 86d + 2d / 3d));
EPAssertionUtil.assertPropsPerRow(volumeLast3StatsListener.getLastNewData(), makeMap(SYMBOL_GE, 1200d));
// Check iterator results
expectedList.get(0).put("symbol", SYMBOL_CISCO);
expectedList.get(0).put("average", 26.5d);
expectedList.get(1).put("symbol", SYMBOL_GE);
expectedList.get(1).put("average", averageGE);
expectedList.get(2).put("symbol", SYMBOL_IBM);
expectedList.get(2).put("average", 10.875d);
EPAssertionUtil.assertPropsPerRow(priceAllStats.iterator(), expectedList);
expectedList.get(0).put("symbol", SYMBOL_CISCO);
expectedList.get(0).put("average", 27d);
expectedList.get(1).put("symbol", SYMBOL_GE);
expectedList.get(1).put("average", 86d + 2d/3d);
expectedList.get(2).put("symbol", SYMBOL_IBM);
expectedList.get(2).put("average", 11d + 1/6d);
EPAssertionUtil.assertPropsPerRow(priceLast3Stats.iterator(), expectedList);
}
public void testLengthWindowGrouped()
{
String stmtText = "select symbol, price from " + SupportMarketDataBean.class.getName() + "#groupwin(symbol)#length(2)";
EPStatement stmt = epService.getEPAdministrator().createEPL(stmtText);
SupportUpdateListener listener = new SupportUpdateListener();
stmt.addListener(listener);
sendEvent("IBM", 100);
}
public void testExpressionGrouped() {
epService.getEPAdministrator().getConfiguration().addEventType(SupportBeanTimestamp.class);
EPStatement stmt = epService.getEPAdministrator().createEPL("select irstream * from SupportBeanTimestamp#groupwin(timestamp.getDayOfWeek())#length(2)");
stmt.addListener(listener);
epService.getEPRuntime().sendEvent(new SupportBeanTimestamp("E1", DateTime.parseDefaultMSec("2002-01-01T09:0:00.000")));
epService.getEPRuntime().sendEvent(new SupportBeanTimestamp("E2", DateTime.parseDefaultMSec("2002-01-08T09:0:00.000")));
epService.getEPRuntime().sendEvent(new SupportBeanTimestamp("E3", DateTime.parseDefaultMSec("2002-01-015T09:0:00.000")));
assertEquals(1, listener.getDataListsFlattened().getSecond().length);
}
public void testCorrel()
{
// further math tests can be found in the view unit test
EPAdministrator admin = epService.getEPAdministrator();
admin.getConfiguration().addEventType("Market", SupportMarketDataBean.class);
EPStatement statement = admin.createEPL("select * from Market#groupwin(symbol)#length(1000000)#correl(price, volume, feed)");
SupportUpdateListener listener = new SupportUpdateListener();
statement.addListener(listener);
assertEquals(Double.class, statement.getEventType().getPropertyType("correlation"));
String[] fields = new String[] {"symbol", "correlation", "feed"};
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("ABC", 10.0, 1000L, "f1"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"ABC", Double.NaN, "f1"});
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("DEF", 1.0, 2L, "f2"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"DEF", Double.NaN, "f2"});
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("DEF", 2.0, 4L, "f3"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"DEF", 1.0, "f3"});
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("ABC", 20.0, 2000L, "f4"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"ABC", 1.0, "f4"});
}
public void testLinest()
{
// further math tests can be found in the view unit test
EPAdministrator admin = epService.getEPAdministrator();
admin.getConfiguration().addEventType("Market", SupportMarketDataBean.class);
EPStatement statement = admin.createEPL("select * from Market#groupwin(symbol)#length(1000000)#linest(price, volume, feed)");
SupportUpdateListener listener = new SupportUpdateListener();
statement.addListener(listener);
assertEquals(Double.class, statement.getEventType().getPropertyType("slope"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YIntercept"));
assertEquals(Double.class, statement.getEventType().getPropertyType("XAverage"));
assertEquals(Double.class, statement.getEventType().getPropertyType("XStandardDeviationPop"));
assertEquals(Double.class, statement.getEventType().getPropertyType("XStandardDeviationSample"));
assertEquals(Double.class, statement.getEventType().getPropertyType("XSum"));
assertEquals(Double.class, statement.getEventType().getPropertyType("XVariance"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YAverage"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YStandardDeviationPop"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YStandardDeviationSample"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YSum"));
assertEquals(Double.class, statement.getEventType().getPropertyType("YVariance"));
assertEquals(Long.class, statement.getEventType().getPropertyType("dataPoints"));
assertEquals(Long.class, statement.getEventType().getPropertyType("n"));
assertEquals(Double.class, statement.getEventType().getPropertyType("sumX"));
assertEquals(Double.class, statement.getEventType().getPropertyType("sumXSq"));
assertEquals(Double.class, statement.getEventType().getPropertyType("sumXY"));
assertEquals(Double.class, statement.getEventType().getPropertyType("sumY"));
assertEquals(Double.class, statement.getEventType().getPropertyType("sumYSq"));
String[] fields = new String[] {"symbol", "slope", "YIntercept", "feed"};
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("ABC", 10.0, 50000L, "f1"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"ABC", Double.NaN, Double.NaN, "f1"});
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("DEF", 1.0, 1L, "f2"));
EventBean theEvent = listener.assertOneGetNewAndReset();
EPAssertionUtil.assertProps(theEvent, fields, new Object[]{"DEF", Double.NaN, Double.NaN, "f2"});
assertEquals(1d, theEvent.get("XAverage"));
assertEquals(0d, theEvent.get("XStandardDeviationPop"));
assertEquals(Double.NaN, theEvent.get("XStandardDeviationSample"));
assertEquals(1d, theEvent.get("XSum"));
assertEquals(Double.NaN, theEvent.get("XVariance"));
assertEquals(1d, theEvent.get("YAverage"));
assertEquals(0d, theEvent.get("YStandardDeviationPop"));
assertEquals(Double.NaN, theEvent.get("YStandardDeviationSample"));
assertEquals(1d, theEvent.get("YSum"));
assertEquals(Double.NaN, theEvent.get("YVariance"));
assertEquals(1L, theEvent.get("dataPoints"));
assertEquals(1L, theEvent.get("n"));
assertEquals(1d, theEvent.get("sumX"));
assertEquals(1d, theEvent.get("sumXSq"));
assertEquals(1d, theEvent.get("sumXY"));
assertEquals(1d, theEvent.get("sumY"));
assertEquals(1d, theEvent.get("sumYSq"));
// above computed values tested in more detail in RegressionBean test
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("DEF", 2.0, 2L, "f3"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"DEF", 1.0, 0.0, "f3"});
epService.getEPRuntime().sendEvent(new SupportMarketDataBean("ABC", 11.0, 50100L, "f4"));
EPAssertionUtil.assertProps(listener.assertOneGetNewAndReset(), fields, new Object[]{"ABC", 100.0, 49000.0, "f4"});
}
private void sendEvent(String symbol, double price)
{
sendEvent(symbol, price, -1);
}
private void sendEvent(String symbol, double price, long volume)
{
SupportMarketDataBean theEvent = new SupportMarketDataBean(symbol, price, volume, "");
epService.getEPRuntime().sendEvent(theEvent);
}
private List<Map<String, Object>> makeMap(String symbol, double average)
{
Map<String, Object> result = new HashMap<String, Object>();
result.put("symbol", symbol);
result.put("average", average);
ArrayList<Map<String, Object>> vec = new ArrayList<Map<String, Object>>();
vec.add(result);
return vec;
}
}