/* 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.CourseOverGroundStatisticData; import dk.dma.ais.abnormal.stat.db.data.StatisticData; import dk.dma.ais.abnormal.util.Categorizer; 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 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 org.junit.Assert.assertEquals; public class CourseOverGroundStatisticTest { final JUnit4Mockery context = new JUnit4Mockery(); EventEmittingTracker trackingService; AppStatisticsService statisticsService; StatisticDataRepository statisticsRepository; Track track; CellChangedEvent event; CourseOverGroundStatistic 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 beforeTest() { // 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.setProperty(Track.CELL_ID, 5674365784L); track.update(packets[0]); track.update(packets[1]); event = new CellChangedEvent(track, null); statistic = new CourseOverGroundStatistic(statisticsService, trackingService, statisticsRepository); assertEquals(3, Categorizer.mapShipTypeToCategory(track.getShipType())); assertEquals(7, Categorizer.mapCourseOverGroundToCategory(track.getCourseOverGround())); } @Test public void testNewShipCountIsCreated() { // Setup expectations final ArgumentCaptor<StatisticData> statistics = ArgumentCaptor.forClass(StatisticData.class); context.checking(new Expectations() {{ oneOf(trackingService).registerSubscriber(statistic); ignoring(statisticsService).incStatisticStatistics(with(CourseOverGroundStatistic.STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics.getMatcher())); }}); // Execute statistic.start(); statistic.onCellIdChanged(event); // Main assertations CourseOverGroundStatisticData capturedStatisticData = (CourseOverGroundStatisticData) statistics.getCapturedObject(); context.assertIsSatisfied(); TreeMap<Integer, TreeMap<Integer, TreeMap<Integer, HashMap<String, Integer>>>> data = capturedStatisticData.getData(); assertEquals(1, data.size()); // Assert one statistic recorded int shipTypeBucket = data.firstKey(); assertEquals(3, shipTypeBucket); int shipSizeBucket = data.get(shipTypeBucket).firstKey(); assertEquals(3, shipSizeBucket); int cogBucket = data.get(shipTypeBucket).get(shipSizeBucket).firstKey(); assertEquals(7, cogBucket); int numberOfStats = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).size(); assertEquals(1, numberOfStats); String statName = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).keySet().iterator().next(); Object statValue = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).get(statName); assertEquals(Integer.class, statValue.getClass()); assertEquals(1, statValue); // Other assertations now we're here assertEquals(CourseOverGroundStatisticData.class, statistics.getCapturedObject().getClass()); assertEquals("type", capturedStatisticData.getMeaningOfKey1()); assertEquals("size", capturedStatisticData.getMeaningOfKey2()); assertEquals(TreeMap.class, statistics.getCapturedObject().getData().getClass()); assertEquals(CourseOverGroundStatisticData.STAT_SHIP_COUNT, statName); } @Test public void testExistingShipCountIsUpdated() { final CourseOverGroundStatisticData existingStatisticData = CourseOverGroundStatisticData.create(); existingStatisticData.setValue(3-1, 3-1, 7-1, CourseOverGroundStatisticData.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(CourseOverGroundStatistic.STATISTIC_NAME), with(any(String.class))); oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); will(returnValue(null)); oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics1.getMatcher())); oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID))); will(returnValue(existingStatisticData)); oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.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(CourseOverGroundStatistic.STATISTIC_NAME, statistics2.getCapturedObject().getStatisticName()); assertEquals(CourseOverGroundStatisticData.class, statistics2.getCapturedObject().getClass()); CourseOverGroundStatisticData capturedStatisticData = (CourseOverGroundStatisticData) statistics2.getCapturedObject(); assertEquals("type", capturedStatisticData.getMeaningOfKey1()); assertEquals("size", capturedStatisticData.getMeaningOfKey2()); assertEquals(TreeMap.class, statistics2.getCapturedObject().getData().getClass()); TreeMap<Integer, TreeMap<Integer, TreeMap<Integer, HashMap<String, Integer>>>> data = capturedStatisticData.getData(); assertEquals(1, data.size()); // Assert one statistic recorded int shipTypeBucket = data.firstKey(); assertEquals(3, shipTypeBucket); int shipSizeBucket = data.get(shipTypeBucket).firstKey(); assertEquals(3, shipSizeBucket); int cogBucket = data.get(shipTypeBucket).get(shipSizeBucket).firstKey(); assertEquals(7, cogBucket); int numberOfStatsForShipTypeAndShipSize = data.get(shipTypeBucket).get(shipSizeBucket).size(); assertEquals(1, numberOfStatsForShipTypeAndShipSize); String statName = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).keySet().iterator().next(); assertEquals(CourseOverGroundStatisticData.STAT_SHIP_COUNT, statName); Object statValue = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).get(statName); assertEquals(2, statValue); } }