/** * Global Sensor Networks (GSN) Source Code * Copyright (c) 2006-2016, Ecole Polytechnique Federale de Lausanne (EPFL) * * This file is part of GSN. * * GSN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GSN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GSN. If not, see <http://www.gnu.org/licenses/>. * * File: src/ch/epfl/gsn/beans/windowing/TestWindowing2.java * * @author gsn_devs * @author Ali Salehi * @author Mehdi Riahi * @author Timotee Maret * */ package ch.epfl.gsn.beans.windowing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.Serializable; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import ch.epfl.gsn.Main; import ch.epfl.gsn.VirtualSensor; import ch.epfl.gsn.VirtualSensorInitializationFailedException; import ch.epfl.gsn.beans.AddressBean; import ch.epfl.gsn.beans.DataField; import ch.epfl.gsn.beans.InputStream; import ch.epfl.gsn.beans.StreamElement; import ch.epfl.gsn.beans.StreamSource; import ch.epfl.gsn.beans.VSensorConfig; import ch.epfl.gsn.beans.windowing.SQLViewQueryRewriter; import ch.epfl.gsn.beans.windowing.WindowType; import ch.epfl.gsn.storage.DataEnumerator; import ch.epfl.gsn.storage.StorageManager; import ch.epfl.gsn.storage.StorageManagerFactory; import ch.epfl.gsn.vsensor.BridgeVirtualSensor; import ch.epfl.gsn.wrappers.AbstractWrapper; public class TestWindowing2 { public static class WrapperForTest2 extends AbstractWrapper { @Override public void dispose() { } @Override public DataField[] getOutputFormat() { return new DataField[] {}; } @Override public String getWrapperName() { return "WrapperForTest2"; } @Override public boolean initialize() { setUsingRemoteTimestamp(true); return true; } @Override public Boolean postStreamElement(StreamElement streamElement) { return super.postStreamElement(streamElement); } } private WrapperForTest2 wrapper = new WrapperForTest2(); private static StorageManager sm = null;//StorageManager.getInstance(); private AddressBean[] addressing = new AddressBean[] { new AddressBean("wrapper-for-test") }; @BeforeClass public static void setUpBeforeClass() throws Exception { // Mysql //DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //sm = StorageManagerFactory.getInstance("com.mysql.jdbc.Driver", "mehdi", "mehdi", "jdbc:mysql://localhost/gsntest", Main.DEFAULT_MAX_DB_CONNECTIONS); //h2 DriverManager.registerDriver(new org.h2.Driver()); sm = StorageManagerFactory.getInstance("org.hsqldb.jdbcDriver", "sa", "", "jdbc:hsqldb:mem:.", Main.DEFAULT_MAX_DB_CONNECTIONS); // sqlserver // DriverManager.registerDriver(new net.sourceforge.jtds.jdbc.Driver()); // sm = StorageManagerFactory.getInstance("net.sourceforge.jtds.jdbc.Driver", "mehdi", "mehdi", // "jdbc:jtds:sqlserver://172.16.4.121:10101/gsntest;cachemetadata=true;prepareSQL=3", Main.DEFAULT_MAX_DB_CONNECTIONS); } @Before public void setup() throws SQLException { sm.executeCreateTable(wrapper.getDBAliasInStr(), new DataField[] {},true); wrapper.setActiveAddressBean(new AddressBean("system-time")); assertTrue(wrapper.initialize()); } @After public void teardown() throws SQLException { sm.executeDropTable(wrapper.getDBAliasInStr()); } /** * Testing time-based slide on each tuple (remote time-based) */ @Test public void testTimeBasedWindow1() throws SQLException, VirtualSensorInitializationFailedException { InputStream is = new InputStream(); is.setQuery("select * from mystream"); StreamSource ss = new StreamSource().setAlias("mystream").setAddressing(addressing).setSqlQuery("select * from wrapper") .setRawHistorySize("2s").setInputStream(is); ss.setSamplingRate(1); is.setSources(new StreamSource[] { ss }); assertTrue(ss.validate()); ss.setWrapper(wrapper); VSensorConfig config = new VSensorConfig(); config.setName("testvs"); config.setMainClass(new BridgeVirtualSensor().getClass().getName()); config.setInputStreams(new InputStream[] { is }); config.setStorageHistorySize("10"); config.setOutputStructure(new DataField[] {}); config.setFileName("dummy-vs-file"); assertTrue(config.validate()); VirtualSensor pool = new VirtualSensor(config); is.setPool(pool); if (sm.tableExists(config.getName())) sm.executeDropTable(config.getName()); sm.executeCreateTable(config.getName(), config.getOutputStructure(),true); // Mappings.addVSensorInstance ( pool ); pool.start(); assertTrue(is.validate()); assertTrue(ss.rewrite(is.getQuery()).indexOf(ss.getUIDStr().toString()) > 0); assertEquals(ss.getWindowingType(), WindowType.TIME_BASED_SLIDE_ON_EACH_TUPLE); assertTrue(SQLViewQueryRewriter.class.isAssignableFrom(ss.getQueryRewriter().getClass())); assertTrue(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL().toString().toLowerCase().indexOf("mod") < 0); StringBuilder query = new StringBuilder(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL()); print(query.toString()); long time = System.currentTimeMillis(); wrapper.postStreamElement(createStreamElement(time)); Connection conn = sm.getConnection(); ResultSet rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertFalse(rs.next()); StringBuilder vsQuery = new StringBuilder("select * from ").append(config.getName()); StringBuilder sb = new StringBuilder("SELECT timed from ").append(SQLViewQueryRewriter.VIEW_HELPER_TABLE).append(" where UID='") .append(ss.getUIDStr()).append("'"); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), time); long time1 = time + 1000; wrapper.postStreamElement(createStreamElement(time1)); long time2 = time + 2500; wrapper.postStreamElement(createStreamElement(time2)); DataEnumerator dm = sm.executeQuery(query, true); rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertTrue(rs.next()); assertFalse(rs.next()); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time2); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time1); assertFalse(dm.hasMoreElements()); wrapper.removeListener(ss); } /** * Testing time-based window-slide (remote time-based) */ @Test public void testTimeBasedWindow2() throws SQLException, VirtualSensorInitializationFailedException { InputStream is = new InputStream(); is.setQuery("select * from mystream"); StreamSource ss = new StreamSource().setAlias("mystream").setAddressing(addressing).setSqlQuery("select * from wrapper") .setRawHistorySize("3s").setRawSlideValue("2s").setInputStream(is); ss.setSamplingRate(1); is.setSources(new StreamSource[] { ss }); assertTrue(ss.validate()); ss.setWrapper(wrapper); VSensorConfig config = new VSensorConfig(); config.setName("testvs"); config.setMainClass(new BridgeVirtualSensor().getClass().getName()); config.setInputStreams(new InputStream[] { is }); config.setStorageHistorySize("10"); config.setOutputStructure(new DataField[] {}); config.setFileName("dummy-vs-file"); assertTrue(config.validate()); VirtualSensor pool = new VirtualSensor(config); is.setPool(pool); if (sm.tableExists(config.getName())) sm.executeDropTable(config.getName()); sm.executeCreateTable(config.getName(), config.getOutputStructure(),true); // Mappings.addVSensorInstance ( pool ); pool.start(); assertTrue(is.validate()); assertTrue(ss.rewrite(is.getQuery()).indexOf(ss.getUIDStr().toString()) > 0); assertEquals(ss.getWindowingType(), WindowType.TIME_BASED); assertTrue(SQLViewQueryRewriter.class.isAssignableFrom(ss.getQueryRewriter().getClass())); assertTrue(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL().toString().toLowerCase().indexOf("mod") < 0); StringBuilder query = new StringBuilder(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL()); print(query.toString()); long time = System.currentTimeMillis() + 2000; wrapper.postStreamElement(createStreamElement(time)); Connection conn = sm.getConnection(); ResultSet rs = sm.executeQueryWithResultSet(query,conn); assertFalse(rs.next()); StringBuilder vsQuery = new StringBuilder("select * from ").append(config.getName()); StringBuilder sb = new StringBuilder("SELECT timed from ").append(SQLViewQueryRewriter.VIEW_HELPER_TABLE).append(" where UID='") .append(ss.getUIDStr()).append("'"); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), -1L); long time1 = time + 1500; wrapper.postStreamElement(createStreamElement(time1)); long time2 = time + 3800; wrapper.postStreamElement(createStreamElement(time2)); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), time2); long time3 = time + 4200; wrapper.postStreamElement(createStreamElement(time3)); DataEnumerator dm = sm.executeQuery(query, true); rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertTrue(rs.next()); assertFalse(rs.next()); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time2); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time1); assertFalse(dm.hasMoreElements()); long time4 = time + 5800; wrapper.postStreamElement(createStreamElement(time4)); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), time4); dm = sm.executeQuery(query, true); rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertTrue(rs.next()); assertTrue(rs.next()); assertFalse(rs.next()); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time4); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time3); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time2); assertFalse(dm.hasMoreElements()); wrapper.removeListener(ss); } /** * Testing tuple-based-win-time-based-slide */ @Test public void testTimeBasedWindow3() throws SQLException, VirtualSensorInitializationFailedException { InputStream is = new InputStream(); is.setQuery("select * from mystream"); StreamSource ss = new StreamSource().setAlias("mystream").setAddressing(addressing).setSqlQuery("select * from wrapper") .setRawHistorySize("2").setRawSlideValue("2s").setInputStream(is); ss.setSamplingRate(1); is.setSources(new StreamSource[] { ss }); assertTrue(ss.validate()); ss.setWrapper(wrapper); VSensorConfig config = new VSensorConfig(); config.setName("testvs"); config.setMainClass(new BridgeVirtualSensor().getClass().getName()); config.setInputStreams(new InputStream[] { is }); config.setStorageHistorySize("10"); config.setOutputStructure(new DataField[] {}); config.setFileName("dummy-vs-file"); assertTrue(config.validate()); VirtualSensor pool = new VirtualSensor(config); is.setPool(pool); if (sm.tableExists(config.getName())) sm.executeDropTable(config.getName()); sm.executeCreateTable(config.getName(), config.getOutputStructure(),true); // Mappings.addVSensorInstance ( pool ); pool.start(); assertTrue(is.validate()); assertTrue(ss.rewrite(is.getQuery()).indexOf(ss.getUIDStr().toString()) > 0); assertEquals(ss.getWindowingType(), WindowType.TUPLE_BASED_WIN_TIME_BASED_SLIDE); assertTrue(SQLViewQueryRewriter.class.isAssignableFrom(ss.getQueryRewriter().getClass())); assertTrue(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL().toString().toLowerCase().indexOf("mod") < 0); StringBuilder query = new StringBuilder(((SQLViewQueryRewriter) ss.getQueryRewriter()).createViewSQL()); print(query.toString()); long time = System.currentTimeMillis() + 2000; wrapper.postStreamElement(createStreamElement(time)); Connection conn = sm.getConnection(); ResultSet rs = sm.executeQueryWithResultSet(query,conn); assertFalse(rs.next()); StringBuilder vsQuery = new StringBuilder("select * from ").append(config.getName()); StringBuilder sb = new StringBuilder("SELECT timed from ").append(SQLViewQueryRewriter.VIEW_HELPER_TABLE).append(" where UID='") .append(ss.getUIDStr()).append("'"); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), -1L); long time1 = time + 1500; wrapper.postStreamElement(createStreamElement(time1)); long time2 = time + 2500; wrapper.postStreamElement(createStreamElement(time2)); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), time2); long time3 = time + 3500; wrapper.postStreamElement(createStreamElement(time3)); DataEnumerator dm = sm.executeQuery(query, true); rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertTrue(rs.next()); assertFalse(rs.next()); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time2); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time1); assertFalse(dm.hasMoreElements()); long time4 = time + 4600; wrapper.postStreamElement(createStreamElement(time4)); rs = sm.executeQueryWithResultSet(sb,conn); assertTrue(rs.next()); assertEquals(rs.getLong(1), time4); dm = sm.executeQuery(query, true); rs = sm.executeQueryWithResultSet(query,conn); assertTrue(rs.next()); assertTrue(rs.next()); assertFalse(rs.next()); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time4); assertTrue(dm.hasMoreElements()); assertEquals(dm.nextElement().getTimeStamp(), time3); assertFalse(dm.hasMoreElements()); wrapper.removeListener(ss); } private StreamElement createStreamElement(long timed) { return new StreamElement(new DataField[] {}, new Serializable[] {}, timed); } public static void print(String query) { System.out.println(query); } }