/* *************************************************************************************** * 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.example.stockticker; import com.espertech.esper.client.Configuration; import com.espertech.esper.client.EPServiceProvider; import com.espertech.esper.client.EPServiceProviderManager; import com.espertech.esper.client.time.TimerControlEvent; import com.espertech.esper.example.stockticker.eventbean.LimitAlert; import com.espertech.esper.example.stockticker.eventbean.PriceLimit; import com.espertech.esper.example.stockticker.eventbean.StockTick; import com.espertech.esper.example.stockticker.monitor.StockTickerMonitor; import com.espertech.esper.example.stockticker.monitor.StockTickerResultListener; import junit.framework.TestCase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestStockTickerSimple extends TestCase { private StockTickerResultListener listener; private EPServiceProvider epService; protected void setUp() throws Exception { listener = new StockTickerResultListener(); Configuration configuration = new Configuration(); configuration.addEventType("PriceLimit", PriceLimit.class.getName()); configuration.addEventType("StockTick", StockTick.class.getName()); epService = EPServiceProviderManager.getProvider("TestStockTickerSimple", configuration); // To reduce logging noise and get max performance epService.getEPRuntime().sendEvent(new TimerControlEvent(TimerControlEvent.ClockType.CLOCK_EXTERNAL)); } public void testStockTicker() throws Exception { log.info(".testStockTicker"); new StockTickerMonitor(epService, listener); performEventFlowTest(); performBoundaryTest(); } public void performEventFlowTest() { final String STOCK_NAME = "IBM.N"; final double STOCK_PRICE = 50; final double LIMIT_PERCENT = 10; final double LIMIT_PERCENT_LARGE = 20; final String USER_ID_ONE = "junit"; final String USER_ID_TWO = "jack"; final String USER_ID_THREE = "anna"; final double STOCK_PRICE_WITHIN_LIMIT_LOW = 46.0; final double STOCK_PRICE_OUTSIDE_LIMIT_LOW = 44.9; final double STOCK_PRICE_WITHIN_LIMIT_HIGH = 51.0; final double STOCK_PRICE_OUTSIDE_LIMIT_HIGH = 55.01; log.debug(".testEvents"); listener.clearMatched(); // Set a limit sendEvent(new PriceLimit(USER_ID_ONE, STOCK_NAME, LIMIT_PERCENT)); assertTrue(listener.getSize() == 0); // First stock ticker sets the initial price sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE)); // Go within the limit, expect no response sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_LOW)); assertTrue(listener.getSize() == 0); // Go outside the limit, expect an event sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_LOW)); sleep(500); assertTrue(listener.getSize() == 1); listener.clearMatched(); // Go within the limit, expect no response sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_HIGH)); assertTrue(listener.getSize() == 0); // Go outside the limit, expect an event sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_HIGH)); sleep(500); assertTrue(listener.getSize() == 1); LimitAlert alert = (LimitAlert) listener.getMatchEvents().get(0); listener.clearMatched(); assertTrue(alert.getInitialPrice() == STOCK_PRICE); assertTrue(alert.getPriceLimit().getUserId().equals(USER_ID_ONE)); assertTrue(alert.getPriceLimit().getStockSymbol().equals(STOCK_NAME)); assertTrue(alert.getPriceLimit().getLimitPct() == LIMIT_PERCENT); assertTrue(alert.getTick().getStockSymbol().equals(STOCK_NAME)); assertTrue(alert.getTick().getPrice() == STOCK_PRICE_OUTSIDE_LIMIT_HIGH); // Set a new limit for the same stock // With the new limit none of these should fire sendEvent(new PriceLimit(USER_ID_ONE, STOCK_NAME, LIMIT_PERCENT_LARGE)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_LOW)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_LOW)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_HIGH)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_HIGH)); sleep(500); assertTrue(listener.getSize() == 0); // Set a smaller limit for another couple of users sendEvent(new PriceLimit(USER_ID_TWO, STOCK_NAME, LIMIT_PERCENT)); sendEvent(new PriceLimit(USER_ID_THREE, STOCK_NAME, LIMIT_PERCENT_LARGE)); // Set limit back to original limit, send same prices, expect exactly 2 event sendEvent(new PriceLimit(USER_ID_ONE, STOCK_NAME, LIMIT_PERCENT)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_LOW)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_LOW)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_WITHIN_LIMIT_HIGH)); sendEvent(new StockTick(STOCK_NAME, STOCK_PRICE_OUTSIDE_LIMIT_HIGH)); sleep(500); log.info(".performEventFlowTest listSize=" + listener.getSize()); assertTrue(listener.getSize() == 4); } public void performBoundaryTest() { final String STOCK_NAME = "BOUNDARY_TEST"; listener.clearMatched(); sendEvent(new PriceLimit("junit", STOCK_NAME, 25.0)); sendEvent(new StockTick(STOCK_NAME, 46.0)); sendEvent(new StockTick(STOCK_NAME, 46.0 - 11.5)); sendEvent(new StockTick(STOCK_NAME, 46.0 + 11.5)); sleep(500); assertTrue(listener.getSize() == 0); sendEvent(new StockTick(STOCK_NAME, 46.0 - 11.5001)); sendEvent(new StockTick(STOCK_NAME, 46.0 + 11.5001)); sleep(500); assertTrue(listener.getSize() == 2); } private void sleep(int msec) { try { Thread.sleep(msec); } catch (InterruptedException e) { log.error("Interrupted: {}", e.getMessage(), e); } } private void sendEvent(Object theEvent) { epService.getEPRuntime().sendEvent(theEvent); } private static final Logger log = LoggerFactory.getLogger(TestStockTickerSimple.class); }