bug4713: implemented fix for comment 9; tests locally green

Change-Id: I9466ad6d383bc2072f18cb5ca278eaeb73a48fe3
This commit is contained in:
Axel Uhl
2018-08-09 17:17:53 +02:00
parent 8c408527cd
commit 6dbbbb1834
3 changed files with 43 additions and 13 deletions
@@ -30,7 +30,8 @@ public abstract class RaceLogAnalyzerTest<AnalyzerType extends RaceLogAnalyzer<?
protected abstract AnalyzerType createAnalyzer(RaceLog raceLog); protected abstract AnalyzerType createAnalyzer(RaceLog raceLog);
protected static <T extends RaceLogEvent> T createEvent(Class<T> type, long milliseconds) { protected static <T extends RaceLogEvent> T createEvent(Class<T> type, long milliseconds) {
return createEvent(/* priority */ 0, type, milliseconds); final T result = createEvent(/* priority */ 0, type, milliseconds);
return result;
} }
protected static <T extends RaceLogEvent> T createEvent(int priority, Class<T> type, long milliseconds) { protected static <T extends RaceLogEvent> T createEvent(int priority, Class<T> type, long milliseconds) {
@@ -24,6 +24,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartProcedureChangedEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl; import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl; import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
@@ -76,25 +77,33 @@ public class RaceStatusAnalyzerTest extends PassAwareRaceLogAnalyzerTest<RaceSta
@Test @Test
public void testMostRecent() { public void testMostRecent() {
RaceLogRaceStatusEvent event1 = createEvent(RaceLogRaceStatusEvent.class, 1); LogEventAuthorImpl author = new LogEventAuthorImpl("author", 0);
when(event1.getNextStatus()).thenReturn(RaceLogRaceStatus.FINISHING); RaceLogRaceStatusEvent event1 = new RaceLogRaceStatusEventImpl(
RaceLogRaceStatusEvent event2 = createEvent(RaceLogRaceStatusEvent.class, 2); new MillisecondsTimePoint(1), author, /* passId */ 1, RaceLogRaceStatus.FINISHING);
when(event2.getNextStatus()).thenReturn(RaceLogRaceStatus.FINISHED); RaceLogRaceStatusEvent event2 = new RaceLogRaceStatusEventImpl(
doAnswer(new StatusVisitorAnswer()).when(event2).accept(any(RaceLogEventVisitor.class)); new MillisecondsTimePoint(2), author, /* passId */ 1, RaceLogRaceStatus.FINISHED);
raceLog.add(event1); raceLog.add(event1);
raceLog.add(event2); raceLog.add(event2);
assertEquals(event2.getNextStatus(), analyzer.analyze().getA()); assertEquals(event2.getNextStatus(), analyzer.analyze().getA());
} }
@Test
public void testFinishingWithFinishedInFuture() {
now = new MillisecondsTimePoint(2);
LogEventAuthorImpl author = new LogEventAuthorImpl("author", 0);
RaceLogRaceStatusEvent event1 = new RaceLogRaceStatusEventImpl(
new MillisecondsTimePoint(1), author, /* passId */ 1, RaceLogRaceStatus.FINISHING);
RaceLogRaceStatusEvent event2 = new RaceLogRaceStatusEventImpl(
new MillisecondsTimePoint(3), author, /* passId */ 1, RaceLogRaceStatus.FINISHED);
raceLog.add(event1);
raceLog.add(event2);
assertEquals(event1.getNextStatus(), analyzer.analyze().getA());
}
@Test @Test
public void testStartphaseNotYetActive() { public void testStartphaseNotYetActive() {
when(racingProcedure.isStartphaseActive(any(TimePoint.class), any(TimePoint.class))).thenReturn(false);
RaceLogStartTimeEvent event = createStartTimeEvent(MillisecondsTimePoint.now().plus(20000).asMillis(), true); RaceLogStartTimeEvent event = createStartTimeEvent(MillisecondsTimePoint.now().plus(20000).asMillis(), true);
raceLog.add(event); raceLog.add(event);
assertEquals(RaceLogRaceStatus.SCHEDULED, analyzer.analyze().getA()); assertEquals(RaceLogRaceStatus.SCHEDULED, analyzer.analyze().getA());
} }
@@ -1,5 +1,9 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl; package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
@@ -49,6 +53,8 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<Pair<RaceLogRaceStatus,
this.racingProcedure = racingProcedure; this.racingProcedure = racingProcedure;
} }
private static final Set<RaceLogRaceStatus> statusTypesToIgnoreIfEventNotValidYet = new HashSet<>(Arrays.asList(
new RaceLogRaceStatus[] { RaceLogRaceStatus.FINISHED, RaceLogRaceStatus.FINISHING }));
@Override @Override
protected Pair<RaceLogRaceStatus, TimePoint> performAnalysis() { protected Pair<RaceLogRaceStatus, TimePoint> performAnalysis() {
ArrayListNavigableSet<RaceLogRaceStatusEvent> statusEvents = new ArrayListNavigableSet<>( ArrayListNavigableSet<RaceLogRaceStatusEvent> statusEvents = new ArrayListNavigableSet<>(
@@ -60,10 +66,24 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<Pair<RaceLogRaceStatus,
} }
final TimePoint now = clock.now(); final TimePoint now = clock.now();
final EventDispatcher eventDispatcher = new EventDispatcher(now, racingProcedure); final EventDispatcher eventDispatcher = new EventDispatcher(now, racingProcedure);
Set<RaceLogRaceStatus> statusesToIgnore = new HashSet<>();
RaceLogRaceStatus result = RaceLogRaceStatus.UNSCHEDULED; RaceLogRaceStatus result = RaceLogRaceStatus.UNSCHEDULED;
for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) { for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) {
// consider race log status events that are valid already at the time point we use as "now" // We need to read across a not yet valid FINISHED event and record that other FINISHED
if (!event.getLogicalTimePoint().after(now)) { // events need to be ignored; if we find a not yet valid FINISHING event, ignore further FINISHING
// events; but dispatch all other events (particularly start-related events) to the dispatcher:
final boolean dispatch;
if (statusTypesToIgnoreIfEventNotValidYet.contains(event.getNextStatus())) {
if (event.getLogicalTimePoint().after(now)) { // event not valid yet
statusesToIgnore.add(event.getNextStatus()); // but ignore events of same status with lesser relevance
dispatch = false;
} else {
dispatch = true;
}
} else {
dispatch = true;
}
if (dispatch) {
event.accept(eventDispatcher); event.accept(eventDispatcher);
result = eventDispatcher.nextStatus; result = eventDispatcher.nextStatus;
break; break;