/* 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.analyzer.behaviour;
import com.google.common.eventbus.Subscribe;
import dk.dma.ais.abnormal.analyzer.behaviour.events.AbnormalEventLower;
import dk.dma.ais.abnormal.analyzer.behaviour.events.AbnormalEventMaintain;
import dk.dma.ais.abnormal.analyzer.behaviour.events.AbnormalEventRaise;
import dk.dma.ais.abnormal.event.db.domain.CourseOverGroundEvent;
import dk.dma.ais.tracker.eventEmittingTracker.EventEmittingTracker;
import dk.dma.ais.tracker.eventEmittingTracker.EventEmittingTrackerImpl;
import dk.dma.ais.tracker.eventEmittingTracker.Track;
import dk.dma.enav.model.geometry.Position;
import dk.dma.enav.model.geometry.grid.Grid;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class BehaviourManagerImplTest {
private JUnit4Mockery context;
private EventEmittingTracker trackingService;
private BehaviourManagerImpl behaviourManager;
private Track track;
private EventBusSubscriber testSubscriber;
@Before
public void setUp() {
context = new JUnit4Mockery();
trackingService = new EventEmittingTrackerImpl(Grid.createSize(200));
behaviourManager = new BehaviourManagerImpl(trackingService);
track = new Track(12345678);
track.update(1234567890L, Position.create(56, 12), 45.0f, 10.1f, 45.0f);
testSubscriber = new EventBusSubscriber();
behaviourManager.registerSubscriber(testSubscriber);
}
@Test
public void noCogEventRaisedForPurelyNormalBehaviour() {
for (int i=0; i<1000; i++) {
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
}
@Test
public void cogEventRaisedWhenThresholdReached() {
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
for (int i=0; i<BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD - 1; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
@Test
public void cogEventIsRaisedAndMaintained() {
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
for (int i=0; i<BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD - 1; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
for (int i=1; i<100; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(i, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
}
@Test
public void cogEventLoweredAfterNConsecutiveNormalBehaviours() {
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
for (int i=0; i<BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(i == BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD - 1 ? 1:0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
for (int i=1; i<100; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(i, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
int i;
for (i=0; i<BehaviourManagerImpl.LOWER_EVENT_SCORE_THRESHOLD-1; i++) {
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(100+i, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(100+i-1, testSubscriber.numAbnormalEventMaintain);
assertEquals(1, testSubscriber.numAbnormalEventLower);
}
@Test
public void scoreIsResetWhenAbnormalEventReceived() {
assertEquals(0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
// Raise event
for (int i=0; i<BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(i == BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD-1 ? 1:0, testSubscriber.numAbnormalEventRaise);
assertEquals(0, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
// A few normal behaviours observed (but not enough to lower event)
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(1, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(2, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
// Then a new abnormal event is received
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(3, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
// Now we require the full no. of consective normal behaviours to lower event
for (int i=0; i<BehaviourManagerImpl.LOWER_EVENT_SCORE_THRESHOLD-1; i++) {
System.out.println("i:" + i);
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(4+i, testSubscriber.numAbnormalEventMaintain);
assertEquals(0, testSubscriber.numAbnormalEventLower);
}
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
assertEquals(1, testSubscriber.numAbnormalEventRaise);
assertEquals(4 + BehaviourManagerImpl.LOWER_EVENT_SCORE_THRESHOLD - 1 - 1, testSubscriber.numAbnormalEventMaintain);
assertEquals(1, testSubscriber.numAbnormalEventLower);
}
@Test
public void testEventCertainty() {
EventCertainty eventCertainty;
assertEquals(0, ((EventEmittingTrackerImpl) behaviourManager.trackingService).getNumberOfTracks());
//
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.LOWERED, eventCertainty);
// Raise event
for (int i=0; i<BehaviourManagerImpl.RAISE_EVENT_SCORE_THRESHOLD - 1; i++) {
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.UNCERTAIN, eventCertainty);
}
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.RAISED, eventCertainty);
// Raise again
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.RAISED, eventCertainty);
// Make us a bit uncertain
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.UNCERTAIN, eventCertainty);
// Reassure us
behaviourManager.abnormalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.RAISED, eventCertainty);
// Now we require the full no. of consective normal behaviours to lower event
for (int i=0; i<BehaviourManagerImpl.LOWER_EVENT_SCORE_THRESHOLD-1; i++) {
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.UNCERTAIN, eventCertainty);
}
behaviourManager.normalBehaviourDetected(CourseOverGroundEvent.class, track);
eventCertainty = (EventCertainty) track.getNewestTrackingReport().getProperty(BehaviourManagerImpl.getEventCertaintyKey(CourseOverGroundEvent.class));
System.out.println(eventCertainty);
assertEquals(EventCertainty.LOWERED, eventCertainty);
}
public final class EventBusSubscriber {
int numAbnormalEventRaise = 0;
int numAbnormalEventMaintain = 0;
int numAbnormalEventLower = 0;
EventCertainty eventCertainty;
@Subscribe
public void onAbnormalEventRaise(AbnormalEventRaise event) {
numAbnormalEventRaise++;
eventCertainty = event.getEventCertainty();
}
@Subscribe
public void onAbnormalEventMaintain(AbnormalEventMaintain event) {
numAbnormalEventMaintain++;
eventCertainty = event.getEventCertainty();
}
@Subscribe
public void onAbnormalEventLower(AbnormalEventLower event) {
numAbnormalEventLower++;
eventCertainty = event.getEventCertainty();
}
}
}