/* Copyright (c) 2011 Danish Maritime Authority * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library. If not, see <http://www.gnu.org/licenses/>. */ package dk.dma.ais.abnormal.stat.statistics; import dk.dma.ais.abnormal.stat.AppStatisticsService; import dk.dma.ais.abnormal.stat.db.StatisticDataRepository; import dk.dma.ais.abnormal.stat.db.data.ShipTypeAndSizeStatisticData; import dk.dma.ais.abnormal.stat.db.data.StatisticData; import dk.dma.ais.packet.AisPacket; import dk.dma.ais.test.helpers.ArgumentCaptor; import dk.dma.ais.tracker.eventEmittingTracker.EventEmittingTracker; import dk.dma.ais.tracker.eventEmittingTracker.Track; import dk.dma.ais.tracker.eventEmittingTracker.events.CellChangedEvent; import dk.dma.enav.model.geometry.Position; import org.jmock.Expectations; import org.jmock.integration.junit4.JUnit4Mockery; import org.junit.Before; import org.junit.Test; import java.util.HashMap; import java.util.TreeMap; import static dk.dma.ais.abnormal.stat.statistics.ShipTypeAndSizeStatistic.STATISTIC_NAME; import static org.junit.Assert.assertEquals; public class ShipTypeAndSizeStatisticTest { final JUnit4Mockery context = new JUnit4Mockery(); EventEmittingTracker trackingService; AppStatisticsService statisticsService; StatisticDataRepository statisticsRepository; Track track; ShipTypeAndSizeStatistic statistic; final String[] NMEA_TEST_STRINGS = { // GatehouseSourceTag [baseMmsi=2190067, country=DK, region=, timestamp=Thu Apr 10 15:30:28 CEST 2014] // [msgId=1, repeat=0, userId=219000606, cog=2010, navStatus=0, pos=(33024811,6011092) = (33024811,6011092), posAcc=1, raim=0, specialManIndicator=0, rot=0, sog=108, spare=0, syncState=1, trueHeading=200, utcSec=60, slotTimeout=6, subMessage=1063] "$PGHP,1,2014,4,10,13,30,28,385,219,,2190067,1,12*26\r\n" + "!BSVDM,1,1,,A,13@ng7P01dPeo6`OOc:onVAp0p@W,0*12", // GatehouseSourceTag [baseMmsi=2190067, country=DK, region=, timestamp=Thu Apr 10 15:30:29 CEST 2014] // [msgId=5, repeat=0, userId=219000606, callsign=OWNM@@@, dest=BOEJDEN-FYNSHAV@@@@@, dimBow=12, dimPort=8, dimStarboard=4, dimStern=58, draught=30, dte=0, eta=67584, imo=8222824, name=FRIGG SYDFYEN@@@@@@@, posType=1, shipType=61, spare=0, version=0] "$PGHP,1,2014,4,10,13,30,29,165,219,,2190067,1,28*22\r\n" + "!BSVDM,2,1,1,A,53@ng7P1uN6PuLpl000I8TLN1=T@ITDp0000000u1Pr844@P07PSiBQ1,0*7B\r\n" + "!BSVDM,2,2,1,A,CcAVCTj0EP00000,2*53" }; final AisPacket[] packets = { AisPacket.from(NMEA_TEST_STRINGS[0]), AisPacket.from(NMEA_TEST_STRINGS[1])}; @Before public void setup() { // Mock dependencies trackingService = context.mock(EventEmittingTracker.class); statisticsService = context.mock(AppStatisticsService.class); statisticsRepository = context.mock(StatisticDataRepository.class); // Setup test data track = new Track(219000606); track.update(packets[0]); track.update(packets[1]); track.setProperty(Track.CELL_ID, 5674365784L); statistic = new ShipTypeAndSizeStatistic(statisticsService, trackingService, statisticsRepository); } @Test public void testNewShipCountIsCreated() { Long oldCellId = null; CellChangedEvent event = new CellChangedEvent(track, oldCellId); // Setup expectations final ArgumentCaptor<StatisticData> statistics = ArgumentCaptor.forClass(StatisticData.class); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); oneOf(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics.getMatcher())); }}); // Execute statistic.start(); statistic.onCellIdChanged(event); // Assert expectations and captured values context.assertIsSatisfied(); // TODO assertEquals(ShipTypeAndSizeStatistic.STATISTIC_NAME, statistics.getCapturedObject().getStatisticName()); assertEquals(ShipTypeAndSizeStatisticData.class, statistics.getCapturedObject().getClass()); ShipTypeAndSizeStatisticData capturedStatisticData = (ShipTypeAndSizeStatisticData) statistics.getCapturedObject(); assertEquals("type", capturedStatisticData.getMeaningOfKey1()); assertEquals("size", capturedStatisticData.getMeaningOfKey2()); assertEquals(TreeMap.class, statistics.getCapturedObject().getData().getClass()); TreeMap<Integer, TreeMap<Integer, HashMap<String,Integer>>> data = capturedStatisticData.getData(); assertEquals(1, data.size()); // Assert one statistic recorded int shipType = data.firstKey(); assertEquals(3, shipType); int shipSize = data.get(shipType).firstKey(); assertEquals(3, shipSize); int numberOfStatsForShipTypeAndShipSize = data.get(shipType).get(shipSize).size(); assertEquals(1, numberOfStatsForShipTypeAndShipSize); String statName = data.get(shipType).get(shipSize).keySet().iterator().next(); assertEquals(ShipTypeAndSizeStatisticData.STAT_SHIP_COUNT, statName); Object statValue = data.get(shipType).get(shipSize).get(statName); assertEquals(Integer.class, statValue.getClass()); assertEquals(1, statValue); } @Test public void testExistingShipCountIsUpdated() { Long oldCellId = null; CellChangedEvent event = new CellChangedEvent(track, oldCellId); // Setup expectations final ShipTypeAndSizeStatisticData existingStatisticData = ShipTypeAndSizeStatisticData.create(); existingStatisticData.setValue(3 - 1 /* -1 because idx counts from zero */, 3 - 1 /* -1 because idx counts from zero */, ShipTypeAndSizeStatisticData.STAT_SHIP_COUNT, 1); final ArgumentCaptor<StatisticData> statistics1 = ArgumentCaptor.forClass(StatisticData.class); final ArgumentCaptor<StatisticData> statistics2 = ArgumentCaptor.forClass(StatisticData.class); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); will(returnValue(null)); oneOf(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics1.getMatcher())); oneOf(statisticsRepository).getStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); will(returnValue(existingStatisticData)); oneOf(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics2.getMatcher())); }}); // Execute statistic.start(); statistic.onCellIdChanged(event); statistic.onCellIdChanged(event); // Assert expectations and captured values context.assertIsSatisfied(); // TODO assertEquals(ShipTypeAndSizeStatistic.STATISTIC_NAME, statistics2.getCapturedObject().getStatisticName()); assertEquals(ShipTypeAndSizeStatisticData.class, statistics2.getCapturedObject().getClass()); ShipTypeAndSizeStatisticData capturedStatisticData = (ShipTypeAndSizeStatisticData) statistics2.getCapturedObject(); assertEquals("type", capturedStatisticData.getMeaningOfKey1()); assertEquals("size", capturedStatisticData.getMeaningOfKey2()); assertEquals(TreeMap.class, statistics2.getCapturedObject().getData().getClass()); TreeMap<Integer, TreeMap<Integer, HashMap<String,Integer>>> data = capturedStatisticData.getData(); assertEquals(1, data.size()); // Assert one statistic recorded int shipType = data.firstKey(); assertEquals(3, shipType); int shipSize = data.get(shipType).firstKey(); assertEquals(3, shipSize); int numberOfStatsForShipTypeAndShipSize = data.get(shipType).get(shipSize).size(); assertEquals(1, numberOfStatsForShipTypeAndShipSize); String statName = data.get(shipType).get(shipSize).keySet().iterator().next(); assertEquals(ShipTypeAndSizeStatisticData.STAT_SHIP_COUNT, statName); Object statValue = data.get(shipType).get(shipSize).get(statName); assertEquals(2, statValue); } @Test public void testDoNotCountTracksWithSogLessThanTwo() { track.update(System.currentTimeMillis(), Position.create(56, 12), 0.0f, 1.99f, 1.99f); Long oldCellId = null; CellChangedEvent event = new CellChangedEvent(track, oldCellId); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(STATISTIC_NAME), with(any(String.class))); never(statisticsRepository).getStatisticData(with(STATISTIC_NAME), with(any(Long.class))); never(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(any(Long.class)), with(any(StatisticData.class))); }}); statistic.start(); statistic.onCellIdChanged(event); // Assert expectations and captured values context.assertIsSatisfied(); } @Test public void testCountTracksWithSogOverTwo() { track.update(System.currentTimeMillis(), Position.create(56, 12), 0.0f, 2.01f, 2.01f); Long oldCellId = null; CellChangedEvent event = new CellChangedEvent(track, oldCellId); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(STATISTIC_NAME), with(any(Long.class))); oneOf(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(any(Long.class)), with(any(StatisticData.class))); }}); statistic.start(); statistic.onCellIdChanged(event); // Assert expectations and captured values context.assertIsSatisfied(); } @Test public void testCountTracksWithNoSog() { //track.setProperty(Track.SPEED_OVER_GROUND, null); Long oldCellId = null; CellChangedEvent event = new CellChangedEvent(track, oldCellId); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(STATISTIC_NAME), with(any(Long.class))); oneOf(statisticsRepository).putStatisticData(with(STATISTIC_NAME), (Long) with(any(Long.class)), with(any(StatisticData.class))); }}); statistic.start(); statistic.onCellIdChanged(event); // Assert expectations and captured values context.assertIsSatisfied(); } }