Merge branch 'master' into bug3934

# Conflicts:
#	java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/FixLoaderAndTracker.java
#	java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/RegattaLogDeviceMappings.java
#	java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/impl/GPSFixStoreImpl.java
This commit is contained in:
Steffen Schaefer committed 2017-01-09 10:34:20 +01:00
commit 6231ef0cfa
478 files changed
+79716 -4510

No files matched your search

@@ -2,7 +2,9 @@ package com.sap.sailing.domain.racelogtracking.test;
import static com.sap.sse.common.Util.size;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.UUID;
import org.junit.After;
@@ -11,14 +13,20 @@ import org.junit.Before;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
@@ -26,12 +34,19 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockDeviceAndSessionIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
@@ -61,13 +76,17 @@ public class AbstractGPSFixStoreTest {
service = new RacingEventServiceImpl(null, null, serviceFinderFactory);
raceLog = new RaceLogImpl("racelog");
regattaLog = new RegattaLogImpl("regattalog");
dropPersistedData();
store = new MongoSensorFixStoreImpl(service.getMongoObjectFactory(), service.getDomainObjectFactory(),
serviceFinderFactory);
}
@After
public void after() {
dropPersistedData();
}
private void dropPersistedData() {
MongoObjectFactoryImpl mongoOF = (MongoObjectFactoryImpl) service.getMongoObjectFactory();
mongoOF.getGPSFixCollection().drop();
mongoOF.getGPSFixMetadataCollection().drop();
@@ -76,8 +95,9 @@ public class AbstractGPSFixStoreTest {
}
protected void map(RegattaLog regattaLog, Competitor comp, DeviceIdentifier device, long from, long to) {
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
comp, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(MillisecondsTimePoint.now(),
MillisecondsTimePoint.now(), author, UUID.randomUUID(), comp, device, new MillisecondsTimePoint(from),
new MillisecondsTimePoint(to)));
}
protected void map(Competitor comp, DeviceIdentifier device, long from, long to) {
@@ -85,8 +105,25 @@ public class AbstractGPSFixStoreTest {
}
protected void map(Mark mark, DeviceIdentifier device, long from, long to) {
regattaLog.add(new RegattaLogDeviceMarkMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
mark, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
regattaLog.add(new RegattaLogDeviceMarkMappingEventImpl(MillisecondsTimePoint.now(),
MillisecondsTimePoint.now(), author, UUID.randomUUID(), mark, device, new MillisecondsTimePoint(from),
new MillisecondsTimePoint(to)));
}
protected void defineMarksOnRegattaLog(Mark... marks) {
for (int i = 0; i < marks.length; i++) {
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(i + 1), author,
new MillisecondsTimePoint(1), 0, marks[i]));
}
}
protected DynamicTrackedRaceImpl createDynamicTrackedRace(BoatClass boatClass, RaceDefinition raceDefinition) {
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* startDate */ null, /* endDate */null, null, null, "a", null));
return new DynamicTrackedRaceImpl(regatta, raceDefinition, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogResolver.class));
}
protected void testNumberOfRawFixes(Track<?> track, long expected) {
@@ -78,7 +78,7 @@ public class CreateAndTrackWithRaceLogTest {
@Before
public void setup() {
service = new RacingEventServiceImpl(true, new MockSmartphoneImeiServiceFinderFactory());
service = new RacingEventServiceImpl(/* clearPersistentCompetitorStore */ true, new MockSmartphoneImeiServiceFinderFactory(), /* restoreTrackedRaces */ false);
sensorFixStore = service.getSensorFixStore();
service.getMongoObjectFactory().getDatabase().dropDatabase();
author = service.getServerAuthor();
@@ -113,7 +113,7 @@ public class CreateAndTrackWithRaceLogTest {
Exception {
RaceColumn column = leaderboard.getRaceColumnByName(columnName);
exception.expect(NotDenotedForRaceLogTrackingException.class);
adapter.startTracking(service, leaderboard, column, fleet);
adapter.startTracking(service, leaderboard, column, fleet, /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false);
}
private void testSize(Track<?> track, int expected) {
@@ -184,7 +184,7 @@ public class CreateAndTrackWithRaceLogTest {
raceLog.add(new RaceLogRegisterCompetitorEventImpl(t(), author, 0, comp1));
raceLog.add(new RaceLogStartOfTrackingEventImpl(t(0), author, /* passId */ 0));
// start tracking
adapter.startTracking(service, leaderboard, column, fleet);
adapter.startTracking(service, leaderboard, column, fleet, /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false);
// now there is a tracked race
@@ -226,7 +226,7 @@ public class CreateAndTrackWithRaceLogTest {
raceLog.add(new RaceLogStartOfTrackingEventImpl(t(0), author, /* passId */ 0));
// start tracking
adapter.startTracking(service, leaderboard, column, fleet);
adapter.startTracking(service, leaderboard, column, fleet, /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ false);
// now there is a trackedrace
TrackedRace race = column.getTrackedRace(fleet);
@@ -0,0 +1,145 @@
package com.sap.sailing.domain.racelogtracking.test.impl;
import static org.mockito.Mockito.mock;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import org.junit.Before;
import org.junit.Test;
import com.mongodb.MongoException;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.persistence.PersistenceFactory;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.EmptySensorFixStore;
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.impl.fixtracker.RaceLogFixTrackerManager;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.DynamicTrack;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sse.common.Timed;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RaceLogFixTrackerManagerTest {
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
protected final DeviceIdentifier deviceTest = new SmartphoneImeiIdentifier("b");
protected RaceLog raceLog;
protected RaceLog raceLog2;
protected RegattaLog regattaLog;
protected SensorFixStore store;
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null,
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
protected final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
private DynamicTrackedRace trackedRace;
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
return new GPSFixMovingImpl(new DegreePosition(lat, lng), new MillisecondsTimePoint(millis),
new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
}
@Before
public void setUp() throws UnknownHostException, MongoException {
raceLog = new RaceLogImpl("racelog");
raceLog2 = new RaceLogImpl("racelog2");
regattaLog = new RegattaLogImpl("regattalog");
store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(),
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory);
Course course = new CourseImpl("course",
Arrays.asList(new Waypoint[] { new WaypointImpl(mark), new WaypointImpl(mark2) }));
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp));
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* startDate */ null, /* endDate */null, null, null, "a", null));
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogResolver.class));
}
/**
* Bug 4001: A {@link ConcurrentModificationException} was thrown when stopping tracking for a race with multiple
* attached RaceLogs.
*/
@Test
public void testThatNoExceptionIsThrownWhenStoppingTrackingForRaceWithMultipleRaceLogs_bug4001() {
trackedRace.attachRegattaLog(regattaLog);
trackedRace.attachRaceLog(raceLog);
trackedRace.attachRaceLog(raceLog2);
RaceLogFixTrackerManager raceLogFixTrackerManager = new RaceLogFixTrackerManager(trackedRace,
EmptySensorFixStore.INSTANCE, new SensorFixMapperFactory() {
@Override
public <FixT extends Timed, TrackT extends DynamicTrack<FixT>> SensorFixMapper<FixT, TrackT, Competitor> createCompetitorMapper(
Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
throw new IllegalArgumentException("Unknown event type");
}
});
raceLogFixTrackerManager.stop(false);
}
/**
* Bug 4001: A {@link ConcurrentModificationException} was thrown when stopping tracking for a race with multiple
* attached RaceLogs.
*/
@Test
public void testThatNoExceptionIsThrownWhenStoppingTrackingWhenAddingSecondRaceLogWhileAlreadyTracking_bug4001() {
trackedRace.attachRegattaLog(regattaLog);
trackedRace.attachRaceLog(raceLog);
RaceLogFixTrackerManager raceLogFixTrackerManager = new RaceLogFixTrackerManager(trackedRace,
EmptySensorFixStore.INSTANCE, new SensorFixMapperFactory() {
@Override
public <FixT extends Timed, TrackT extends DynamicTrack<FixT>> SensorFixMapper<FixT, TrackT, Competitor> createCompetitorMapper(
Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
throw new IllegalArgumentException("Unknown event type");
}
});
trackedRace.attachRaceLog(raceLog2);
raceLogFixTrackerManager.stop(false);
}
}
@@ -1,50 +1,50 @@
package com.sap.sailing.domain.racelogtracking.test.impl;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEndOfTrackingEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartOfTrackingEventImpl;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.impl.fixtracker.FixLoaderAndTracker;
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.Timed;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.TimeRangeImpl;
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
private static final Logger logger = Logger.getLogger(TrackedRaceLoadsFixesTest.class.getName());
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
private final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
private final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null,
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
private final Course course = new CourseImpl("course", Arrays.asList(new WaypointImpl(mark), new WaypointImpl(mark2)));
private final RaceDefinition raceDefinition = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp, comp2));
@Rule
public Timeout TrackedRaceLoadsFixesTestTimeout = new Timeout(3 * 60 * 1000);
@@ -52,15 +52,8 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
@Test
public void doesRaceLoadOnlyBetweenStartAndEndOfTracking() throws TransformationException,
NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
DeviceIdentifier markDevice = new SmartphoneImeiIdentifier("imei2");
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
new WaypointImpl(mark2) }));
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
defineMarksOnRegattaLog(mark, mark2);
map(comp, device, 0, 10000);
map(mark, markDevice, 0, 10000);
@@ -71,13 +64,7 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
store.storeFix(markDevice, createFix(1100, 10, 20, 30, 40));
store.storeFix(markDevice, createFix(2100, 10, 20, 30, 40));
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
null, /* endDate */null, null, null, "a", null));
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
final DynamicTrackedRaceImpl trackedRace = createDynamicTrackedRace(boatClass, raceDefinition);
trackedRace.setStartOfTrackingReceived(new MillisecondsTimePoint(1000));
trackedRace.setEndOfTrackingReceived(new MillisecondsTimePoint(2000));
new FixLoaderAndTracker(trackedRace, store, null);
@@ -100,16 +87,9 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
@Test
public void areFixesStoredInDb() throws TransformationException, NoCorrespondingServiceRegisteredException,
InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
defineMarksOnRegattaLog(mark, mark2);
DeviceIdentifier device2 = new SmartphoneImeiIdentifier("imei2");
DeviceIdentifier device3 = new SmartphoneImeiIdentifier("imei3");
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
new WaypointImpl(mark2) }));
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp, comp2));
map(comp, device, 0, 20000);
map(comp2, device2, 0, 600);
@@ -127,12 +107,7 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
store.storeFix(device, createFix(i + 1000, 10, 20, 30, 40));
}
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* startDate */ null, /* endDate */null, null, null, "a", null));
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
DynamicTrackedRace trackedRace = createDynamicTrackedRace(boatClass, raceDefinition);
new FixLoaderAndTracker(trackedRace, store, null);
@@ -145,17 +120,228 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark2), 1);
}
@Test
public void testFixesForCompetitorsAreNotLoadedIfMappingDoesNotIntersectWithTrackingInterval()
throws InterruptedException {
testFixes(/* start of tracking */ 200, /* end of tracking */ 300, /* mappings and fixes */ () -> {
map(comp, device, 0, 100);
store.storeFix(device, createFix(10, 10, 20, 30, 40));
store.storeFix(device, createFix(20, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> testNumberOfRawFixes(trackedRace.getTrack(comp), 0));
}
@Test
public void testFixesForCompetitorsAreLoadedIfMappingDoesIntersectWithTrackingIntervalFixesWithinIntersectionOnly()
throws InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings and fixes */ () -> {
map(comp, device, 0, 200);
store.storeFix(device, createFix(50, 10, 20, 30, 40));
store.storeFix(device, createFix(150, 10, 20, 30, 40));
store.storeFix(device, createFix(250, 10, 20, 30, 40));
map(comp, device, 350, 500);
store.storeFix(device, createFix(400, 10, 20, 30, 40));
store.storeFix(device, createFix(450, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> testNumberOfRawFixes(trackedRace.getTrack(comp), 1));
}
@Test
public void testAddingMappingLoadsFixesPreviouslyNotCovered() throws InterruptedException {
testFixes(/* start of tracking */ 10, /* end of tracking */ 500, /* mappings and fixes */ () -> {
map(comp, device, 0, 200);
map(comp, device, 300, 400);
store.storeFix(device, createFix(50, 10, 20, 30, 40)); // in first mapping
store.storeFix(device, createFix(150, 10, 20, 30, 40)); // in first mapping
store.storeFix(device, createFix(250, 10, 20, 30, 40)); // outside both mappings
store.storeFix(device, createFix(350, 10, 20, 30, 40)); // in second mapping
}, /* tests and expectations */ trackedRace -> {
testNumberOfRawFixes(trackedRace.getTrack(comp), 3);
map(comp, device, 0, 500); // covers fix at 250ms; assert that only that fix is loaded
try {
trackedRace.waitForLoadingToFinish();
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception waiting for loading to finish", e);
}
testNumberOfRawFixes(trackedRace.getTrack(comp), 4);
});
}
@Test
public void testAddingMappingDoesNotLoadFixesAlreadyCoveredByExistingMapping() throws InterruptedException {
testFixes(/* start of tracking */ 10, /* end of tracking */ 500, /* mappings and fixes */ () -> {
map(comp, device, 0, 200);
map(comp, device, 300, 400);
store.storeFix(device, createFix(50, 10, 20, 30, 40)); // in first mapping
store.storeFix(device, createFix(150, 10, 20, 30, 40)); // in first mapping
store.storeFix(device, createFix(250, 10, 20, 30, 40)); // outside both mappings
store.storeFix(device, createFix(350, 10, 20, 30, 40)); // in second mapping
}, /* tests and expectations */ trackedRace -> {
map(comp, device, 0, 500); // covers fix at 250ms
try {
trackedRace.waitForLoadingToFinish();
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception waiting for loading to finish", e);
}
store.storeFix(device, createFix(400, 10, 20, 30, 40)); // in third mapping
testNumberOfRawFixes(trackedRace.getTrack(comp), 5);
});
}
/** Regression test for bug 4008 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4008 */
@Test
public void testFixesForMarkAreLoadedIfMappingDoesNotIntersectWithTrackingInterval() throws InterruptedException {
testFixes(/* start of tracking */ 200, /* end of tracking */ 300, /* mappings and fixes */ () -> {
map(mark, device, 0, 100);
store.storeFix(device, createFix(10, 10, 20, 30, 40));
store.storeFix(device, createFix(20, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 2));
}
/** Regression test for bug 4008 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4008 */
@Test
public void testFixesForTwoMarksAreLoadedIfMappingsDoNotIntersectWithTrackingInterval()
throws InterruptedException {
testFixes(/* start of tracking */ 400, /* end of tracking */ 500, /* mappings and fixes */ () -> {
map(mark, device, 0, 100);
store.storeFix(device, createFix(50, 10, 20, 30, 40));
map(mark2, device, 200, 300);
store.storeFix(device, createFix(250, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> {
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark2), 1);
});
}
/** Regression test for bug 4008 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4008 */
@Test
public void testFixesForMarkAreLoadedIfMappingDoesIntersectWithTrackingIntervalFixesWithinIntersectionOnly()
throws InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings and fixes */ () -> {
map(mark, device, 0, 200);
store.storeFix(device, createFix(50, 10, 20, 30, 40));
store.storeFix(device, createFix(150, 10, 20, 30, 40));
store.storeFix(device, createFix(250, 10, 20, 30, 40));
map(mark, device, 350, 500);
store.storeFix(device, createFix(400, 10, 20, 30, 40));
store.storeFix(device, createFix(450, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> {
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
/** Regression test for bug 4008 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4008 */
@Test
public void testFixesForMarkAreLoadedIfMappingDoesIntersectWithTrackingIntervalAllFixesBecauseOfNoFixesWithIntersection()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings and fixes */ () -> {
map(mark, device, 0, 200);
store.storeFix(device, createFix(50, 10, 20, 30, 40));
store.storeFix(device, createFix(250, 10, 20, 30, 40));
map(mark, device, 350, 500);
store.storeFix(device, createFix(400, 10, 20, 30, 40));
store.storeFix(device, createFix(450, 10, 20, 30, 40));
}, /* tests and expectations */ trackedRace -> {
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 3);
});
}
@Test
public void testFixForMarkIsAddedIfBeforeTrackingIntervalAndNoOtherFixExists()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 200),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(50, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
@Test
public void testFixForMarkIsAddedIfAfterTrackingIntervalAndNoOtherFixExists()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400), /* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(350, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
@Test
public void testFixForMarkIsAddedIfBeforeTrackingIntervalAndBetterThanAnExistingOne()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(50, 10, 20, 30, 40));
store.storeFix(device, createFix(75, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 2);
});
}
@Test
public void testFixForMarkIsNotAddedIfBeforeTrackingIntervalAndWorseThanAnExistingOne()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(75, 10, 20, 30, 40));
store.storeFix(device, createFix(50, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
@Test
public void testFixForMarkIsAddedIfAfterTrackingIntervalAndBetterThanAnExistingOne()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(375, 10, 20, 30, 40));
store.storeFix(device, createFix(350, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 2);
});
}
@Test
public void testFixForMarkIsNotAddedIfAfterTrackingIntervalAndWorseThanAnExistingOne()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(350, 10, 20, 30, 40));
store.storeFix(device, createFix(375, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
@Test
public void testFixForMarkIsNotAddedIfNotWithinTrackingIntervalAndFixWithinTrackingIntervalExists()
throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
testFixes(/* start of tracking */ 100, /* end of tracking */ 300, /* mappings */ () -> map(mark, device, 0, 400),
/* fixes and tests/expectations */ trackedRace -> {
store.storeFix(device, createFix(200, 10, 20, 30, 40));
store.storeFix(device, createFix(50, 10, 20, 30, 40));
store.storeFix(device, createFix(350, 10, 20, 30, 40));
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
});
}
private void testFixes(long startOfTracking, long endOfTracking, Runnable beforeTrackingStarted,
Consumer<DynamicTrackedRace> afterTrackingStarted) throws InterruptedException {
defineMarksOnRegattaLog(mark, mark2);
raceLog.add(new RaceLogStartOfTrackingEventImpl(new MillisecondsTimePoint(startOfTracking), author, 0));
raceLog.add(new RaceLogEndOfTrackingEventImpl(new MillisecondsTimePoint(endOfTracking), author, 0));
beforeTrackingStarted.run();
DynamicTrackedRace trackedRace = createDynamicTrackedRace(boatClass, raceDefinition);
trackedRace.attachRaceLog(raceLog);
trackedRace.attachRegattaLog(regattaLog);
new FixLoaderAndTracker(trackedRace, store, null);
trackedRace.waitForLoadingToFinish();
afterTrackingStarted.accept(trackedRace);
}
@Test
public void metadataStoredInDb() throws TransformationException, NoCorrespondingServiceRegisteredException {
assertEquals(0, store.getNumberOfFixes(device));
assertEquals(null, store.getTimeRangeCoveredByFixes(device));
map(comp, device, 0, 600);
store.storeFix(device, createFix(100, 10, 20, 30, 40));
store.storeFix(device, createFix(200, 10, 20, 30, 40));
assertEquals(2, store.getNumberOfFixes(device));
assertEquals(TimeRangeImpl.create(100, 200), store.getTimeRangeCoveredByFixes(device));
}