/* * #! * % * Copyright (C) 2014 - 2016 Humboldt-Universität zu Berlin * % * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #_ */ package de.hub.cs.dbis.lrb.operators; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.stubbing.OngoingStubbing; import org.powermock.modules.junit4.PowerMockRunner; import backtype.storm.task.OutputCollector; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import de.hub.cs.dbis.aeolus.testUtils.TestDeclarer; import de.hub.cs.dbis.aeolus.testUtils.TestOutputCollector; import de.hub.cs.dbis.aeolus.utils.TimestampMerger; import de.hub.cs.dbis.lrb.queries.utils.TopologyControl; import de.hub.cs.dbis.lrb.types.internal.AccidentTuple; import de.hub.cs.dbis.lrb.types.internal.StoppedCarTuple; import de.hub.cs.dbis.lrb.util.Constants; /** * @author mjsax */ @RunWith(PowerMockRunner.class) public class AccidentDetectionBoltTest { // @formatter:off // segment size = 5280 with seg_0 = [0..5179] @SuppressWarnings("boxing") private static Integer[][][] timeAndPositions = new Integer[][][] { // vehicle 1 new Integer[][] {new Integer[] {0, 151, 50102, 1}, new Integer[] {0, 181, 50102, -1}, // move new Integer[] {0, 301, 50103, 1}, new Integer[] {0, 331, 50103, 1}, new Integer[] {0, 361, 50103, -1}, // move new Integer[] {0, 481, 50105, 1}, // accident m=9 }, // vehicle 2 new Integer[][] {new Integer[] {0, 185, 50102, 1}, new Integer[] {0, 215, 50102, -1}, // move new Integer[] {0, 425, 50105, 1}, // accident m=8 new Integer[] {0, 455, 50105, 1}, // accident m=8 new Integer[] {0, 485, 50105, -1}, // move }, // vehicle 3 new Integer[][] {new Integer[] {0, 130, 50105, 1}, new Integer[] {0, 160, 50105, 1}, new Integer[] {0, 190, 50105, 1}, new Integer[] {0, 220, 50105, 1}, new Integer[] {0, 250, 50105, 1}, new Integer[] {0, 280, 50105, 1}, new Integer[] {0, 310, 50105, 1}, new Integer[] {0, 340, 50105, 1}, new Integer[] {0, 370, 50105, 1}, new Integer[] {0, 400, 50105, 1}, new Integer[] {0, 430, 50105, 1}, // accident m=8 new Integer[] {0, 460, 50105, 1}, // accident m=8 new Integer[] {0, 490, 50105, -1}, // move } }; // @formatter:on @SuppressWarnings("boxing") @Test public void testExecute() { Tuple tuple = mock(Tuple.class); when(tuple.getSourceStreamId()).thenReturn("streamId"); OngoingStubbing<List<Object>> tupleValueStub = when(tuple.getValues()); int[] m = new int[timeAndPositions.length]; int tupleCount = 0; while(true) { int vid = -1; int minTs = Integer.MAX_VALUE; for(int i = 0; i < timeAndPositions.length; ++i) { if(m[i] < timeAndPositions[i].length) { if(timeAndPositions[i][m[i]][1] < minTs) { minTs = timeAndPositions[i][m[i]][1]; vid = i; } } } if(minTs == Integer.MAX_VALUE) { break; } StoppedCarTuple t = new StoppedCarTuple((vid + 1) * timeAndPositions[vid][m[vid]][3], timeAndPositions[vid][m[vid]][1].shortValue(), 0, timeAndPositions[vid][m[vid]][0].shortValue(), timeAndPositions[vid][m[vid]][2], Constants.EASTBOUND); tupleValueStub = tupleValueStub.thenReturn(t); ++tupleCount; ++m[vid]; } tupleValueStub.thenReturn(null); AccidentDetectionBolt bolt = new AccidentDetectionBolt(); TestOutputCollector collector = new TestOutputCollector(); bolt.prepare(null, null, new OutputCollector(collector)); for(int i = 0; i < tupleCount; ++i) { bolt.execute(tuple); } Tuple flushTuple = mock(Tuple.class); when(flushTuple.getSourceStreamId()).thenReturn(TimestampMerger.FLUSH_STREAM_ID); bolt.execute(flushTuple); List<Values> expectedFlushes = new ArrayList<Values>(); expectedFlushes.add(new Values((short)119)); expectedFlushes.add(new Values((short)179)); expectedFlushes.add(new Values((short)239)); expectedFlushes.add(new Values((short)299)); expectedFlushes.add(new Values((short)359)); expectedFlushes.add(new Values((short)419)); expectedFlushes.add(new Values((short)479)); expectedFlushes.add(new Values((Object)null)); List<Values> expectedResult = new ArrayList<Values>(); expectedResult.add(new AccidentTuple((short)425, 0, (short)9, (short)0)); expectedResult.add(new AccidentTuple((short)430, 0, (short)9, (short)0)); expectedResult.add(new AccidentTuple((short)455, 0, (short)9, (short)0)); expectedResult.add(new AccidentTuple((short)460, 0, (short)9, (short)0)); expectedResult.add(new AccidentTuple((short)481, 0, (short)9, (short)0)); Assert.assertEquals(2, collector.output.size()); Assert.assertEquals(expectedResult, collector.output.get(TopologyControl.ACCIDENTS_STREAM_ID)); Assert.assertEquals(expectedFlushes, collector.output.get(TimestampMerger.FLUSH_STREAM_ID)); } @Test public void testDeclareOutputFields() { AccidentDetectionBolt bolt = new AccidentDetectionBolt(); TestDeclarer declarer = new TestDeclarer(); bolt.declareOutputFields(declarer); Assert.assertEquals(2, declarer.streamIdBuffer.size()); Assert.assertEquals(2, declarer.schemaBuffer.size()); Assert.assertEquals(2, declarer.directBuffer.size()); Assert.assertEquals(TopologyControl.ACCIDENTS_STREAM_ID, declarer.streamIdBuffer.get(0)); Assert.assertEquals(new Fields(TopologyControl.TIMESTAMP_FIELD_NAME, TopologyControl.XWAY_FIELD_NAME, TopologyControl.SEGMENT_FIELD_NAME, TopologyControl.DIRECTION_FIELD_NAME).toList(), declarer.schemaBuffer .get(0).toList()); Assert.assertEquals(new Boolean(false), declarer.directBuffer.get(0)); Assert.assertEquals(TimestampMerger.FLUSH_STREAM_ID, declarer.streamIdBuffer.get(1)); Assert.assertEquals(new Fields("ts").toList(), declarer.schemaBuffer.get(1).toList()); Assert.assertEquals(new Boolean(false), declarer.directBuffer.get(1)); } }