mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-28 06:47:15 +00:00
failing test case for bug 3648; introduced Speed.travel(Duration)
Change-Id: Ib164a12b0330f8c99251031553866435e82632fe
This commit is contained in:
1 parent
fd348db671
commit
fbd79b6dde
6 files changed
+83
-3
No files matched your search
+6
-1
@@ -16,7 +16,12 @@ public abstract class AbstractSpeedImpl implements Speed {
|
||||
|
||||
@Override
|
||||
public Distance travel(TimePoint t1, TimePoint t2) {
|
||||
return new NauticalMileDistance((t2.asMillis() - t1.asMillis()) / 1000. / 3600. * getKnots());
|
||||
return travel(t1.until(t2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance travel(Duration duration) {
|
||||
return new NauticalMileDistance(duration.asHours() * getKnots());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,6 +60,11 @@ public interface Speed extends Comparable<Speed>, Serializable {
|
||||
public double getStatuteMilesPerHour() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance travel(Duration duration) {
|
||||
return Distance.NULL;
|
||||
}
|
||||
};
|
||||
|
||||
@Statistic(messageKey="", resultDecimals=2)
|
||||
@@ -85,4 +90,6 @@ public interface Speed extends Comparable<Speed>, Serializable {
|
||||
* line" on a sphere) with this speed.
|
||||
*/
|
||||
Duration getDuration(Distance distance);
|
||||
|
||||
Distance travel(Duration duration);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
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.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
* See bug 3648: When a race is loading, cache invalidation is suspended which also affects the distance cache.
|
||||
* However, for the distance cache, during resuming caching operations there was a cache invalidation missing.
|
||||
* This tests, failing before the fix for bug 3648, ensures that this type of invalidation actually happens.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class DistanceCacheInvalidationAfterLoadingFinishedTest extends TrackBasedTest {
|
||||
private Competitor competitor;
|
||||
private DynamicTrackedRace trackedRace;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
competitor = createCompetitor("Test Competitor");
|
||||
trackedRace = createTestTrackedRace("Test Regatta", "Test Race", "505", Collections.singleton(competitor), MillisecondsTimePoint.now());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistanceCalculationWhileLoading() {
|
||||
final TimePoint now = MillisecondsTimePoint.now();
|
||||
trackedRace.updateMarkPassings(competitor, Collections.singleton(new MarkPassingImpl(now, trackedRace.getRace().getCourse().getFirstWaypoint(), competitor)));
|
||||
// no distance traveled yet because there is no fix yet; this may be cached for now
|
||||
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now));
|
||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, /* progress */ 0.1));
|
||||
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))));
|
||||
final Position startPos = new DegreePosition(0, 0);
|
||||
final DegreeBearingImpl bearing = new DegreeBearingImpl(10);
|
||||
final KnotSpeedWithBearingImpl speed = new KnotSpeedWithBearingImpl(10, bearing);
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos, now, speed));
|
||||
final Distance distance = speed.travel(Duration.ONE_SECOND);
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed));
|
||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, /* progress */ 1.0));
|
||||
assertEquals(distance.getMeters(), trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))).getMeters(), 0.000001); // ask 1s after the second fix
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -549,22 +549,26 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends TrackImpl
|
||||
if (!from.before(to)) {
|
||||
result = Distance.NULL;
|
||||
} else {
|
||||
boolean perfectCacheHit = false;
|
||||
lockForRead();
|
||||
try {
|
||||
Util.Pair<TimePoint, Util.Pair<TimePoint, Distance>> bestCacheEntry = getDistanceCache()
|
||||
.getEarliestFromAndDistanceAtOrAfterFrom(from, to);
|
||||
if (bestCacheEntry != null) {
|
||||
perfectCacheHit = true; // potentially a cache hit; but if it doesn't span the full interval, it's not perfect; see below
|
||||
// compute the missing stretches between best cache entry's "from" and our "from" and the cache
|
||||
// entry's "to" and our "to"
|
||||
Distance distanceFromFromToBeginningOfCacheEntry = Distance.NULL;
|
||||
Distance distanceFromEndOfCacheEntryToTo = Distance.NULL;
|
||||
if (!bestCacheEntry.getB().getA().equals(from)) {
|
||||
assert bestCacheEntry.getB().getA().after(from);
|
||||
perfectCacheHit = false;
|
||||
distanceFromFromToBeginningOfCacheEntry = getDistanceTraveledRecursively(from, bestCacheEntry
|
||||
.getB().getA(), recursionDepth + 1);
|
||||
}
|
||||
if (!bestCacheEntry.getA().equals(to)) {
|
||||
assert bestCacheEntry.getA().before(to);
|
||||
perfectCacheHit = false;
|
||||
distanceFromEndOfCacheEntryToTo = getDistanceTraveledRecursively(bestCacheEntry.getA(), to,
|
||||
recursionDepth + 1);
|
||||
}
|
||||
@@ -599,7 +603,7 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends TrackImpl
|
||||
} finally {
|
||||
unlockAfterRead();
|
||||
}
|
||||
if (recursionDepth == 0) {
|
||||
if (!perfectCacheHit && recursionDepth == 0) {
|
||||
getDistanceCache().cache(from, to, result);
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -398,6 +398,10 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
public double getStatuteMilesPerHour() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public Distance travel(Duration duration) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,7 @@ public class MillisecondsDurationImpl implements Duration {
|
||||
|
||||
@Override
|
||||
public double asHours() {
|
||||
return asMillis() / Duration.ONE_HOUR.asMillis();
|
||||
return ((double) asMillis()) / (double) Duration.ONE_HOUR.asMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in new issue
Block a user