bug6127: upgraded domain.test to JUnit5

This commit is contained in:
Axel Uhl
2025-06-05 17:21:27 +02:00
parent 5b2536e9c0
commit 5a3a63f71b
11 changed files with 111 additions and 178 deletions
@@ -7,17 +7,15 @@ import java.io.FileInputStream;
import java.io.IOException;
import org.json.simple.parser.ParseException;
import org.junit.Rule;
import org.junit.jupiter.api.extension.ExtendWith;
import com.sap.sailing.domain.common.orc.ORCCertificate;
@ExtendWith(FailIfNoValidOrcCertificateRule.class)
public abstract class AbstractORCCertificateImporterTest {
protected static final String RESOURCES = "resources/orc/";
@Rule
public FailIfNoValidOrcCertificateRule customIgnoreRule = new FailIfNoValidOrcCertificateRule();
protected void testSimpleLocalFileRead(String fileName, String expectedCertificateId) throws IOException, ParseException {
File fileGER = new File(RESOURCES + fileName);
ORCCertificatesCollection importer = ORCCertificatesImporter.INSTANCE.read(new FileInputStream(fileGER));
@@ -1,16 +1,18 @@
package com.sap.sailing.domain.orc;
import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.StreamSupport;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import com.sap.sailing.domain.common.orc.ORCCertificate;
import com.sap.sailing.domain.orc.ORCPublicCertificateDatabase.CertificateHandle;
@@ -19,7 +21,7 @@ import com.sap.sailing.domain.orc.impl.ORCPublicCertificateDatabaseImpl;
import com.sap.sse.common.Util;
/***
* A IgnoreInvalidOrcCerticatesRule is an implementation of TestRule. This class execution depends on
* An {@link IgnoreInvalidOrcCerticatesRule} execution depends on
* {@link FailIfNoValidOrcCertificates} annotation on any method in a test class containing
* {@link org.junit.rules.TestRule} annotation with current class implementation. When any test class added
* {@link FailIfNoValidOrcCertificateRule} rule then before executing all of it's test method, Junit will execute the
@@ -34,7 +36,7 @@ import com.sap.sse.common.Util;
*
*/
public class FailIfNoValidOrcCertificateRule implements TestRule {
public class FailIfNoValidOrcCertificateRule implements BeforeTestExecutionCallback {
private static final Logger logger = Logger.getLogger(FailIfNoValidOrcCertificateRule.class.getName());
private static final int NUMBER_OF_CERTIFICATES_TO_PROBE = 3;
@@ -70,37 +72,19 @@ public class FailIfNoValidOrcCertificateRule implements TestRule {
logger.info("FailIfNoValidOrcCertificateRule created");
}
public Collection<ORCCertificate> getAvailableCerts() {
public static Collection<ORCCertificate> getAvailableCerts() {
return Collections.unmodifiableCollection(availableCerts);
}
@Override
public Statement apply(Statement base, Description description) {
return new IgnorableStatement(base, description);
}
private class IgnorableStatement extends Statement {
private final Statement base;
private final Description description;
public IgnorableStatement(Statement base, Description description) {
this.base = base;
this.description = description;
}
/***
* This method executes for every test case having {@link TestRule} annotation of
* {@link FailIfNoValidOrcCertificateRule} class. Assume statement at the end of this method evaluates whether
* the test method will execute or be ignored.
*/
@Override
public void evaluate() throws Throwable {
FailIfNoValidOrcCertificates annotation = description.getAnnotation(FailIfNoValidOrcCertificates.class);
if (annotation == null || certificateExists) {
base.evaluate();
} else if (annotation != null) {
logger.warning("No certificates found. Are we at the beginning of a new year (January)? Then this may be okay. Otherwise, please check what's up!");
}
public void beforeTestExecution(ExtensionContext context) {
Optional<AnnotatedElement> testElement = context.getElement();
final boolean hasAnnotation = testElement
.map(el -> el.isAnnotationPresent(FailIfNoValidOrcCertificates.class))
.orElse(false);
if (hasAnnotation && !certificateExists) {
logger.warning("No certificates found. Are we at the beginning of a new year (January)? Then this may be okay. Otherwise, please check what's up!");
Assumptions.assumeTrue(false, "Skipping test: no valid ORC certificates found.");
}
}
}
@@ -6,13 +6,12 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/***
/**
* A {@link FailIfNoValidOrcCertificates} is an annotation which is used to identify whether we need to execute the
* {@link FailIfNoValidOrcCertificateRule} for that particular test case. i.e. you can find the usage of
* {@link FailIfNoValidOrcCertificates} in {@link TestORCPublicCertificateDatabase} class.
*
* @author Usman Ali
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.orc;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@@ -15,12 +16,9 @@ import java.text.SimpleDateFormat;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.rules.ErrorCollector;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.orc.impl.RaceLogORCLegDataEventImpl;
@@ -73,25 +71,6 @@ public class ORCPerformanceCurveRankingTest extends OnlineTracTracBasedTest {
private RegattaLog regattaLog;
private LogEventAuthorImpl author;
@Rule
public ErrorCollector collector = new ErrorCollector();
public void assertEquals(double a, double b, double accuracy) {
try {
Assertions.assertEquals(a, b, accuracy);
} catch (AssertionError e) {
collector.addError(e);
}
}
public void assertEquals(String message, double a, double b, double accuracy) {
try {
Assertions.assertEquals(a, b, accuracy, message);
} catch (AssertionError e) {
collector.addError(e);
}
}
public ORCPerformanceCurveRankingTest() throws MalformedURLException, URISyntaxException {
}
@@ -213,8 +192,8 @@ public class ORCPerformanceCurveRankingTest extends OnlineTracTracBasedTest {
private void assertCorrectedTimeAtEnd(Duration scratchBoatDuration, Duration winnerCorrectedTime, String boatName, int hours, int minutes, int seconds) {
final Duration expectedCorrectedTime = winnerCorrectedTime.plus(new SecondsDurationImpl(3600*hours+60*minutes+seconds));
final Duration correctedTimeForNamedBoat = rankingMetric.getCorrectedTime(getCompetitor(boatName), MillisecondsTimePoint.now());
assertEquals("Expected corrected time "+expectedCorrectedTime+" but got "+correctedTimeForNamedBoat+" for "+boatName,
expectedCorrectedTime.asSeconds(), correctedTimeForNamedBoat.asSeconds(), 0.7);
assertEquals(expectedCorrectedTime.asSeconds(), correctedTimeForNamedBoat.asSeconds(), 0.7,
"Expected corrected time "+expectedCorrectedTime+" but got "+correctedTimeForNamedBoat+" for "+boatName);
}
private Competitor getCompetitor(String boatName) {
@@ -26,7 +26,7 @@ public class TestORCCertificateImporterJSON extends AbstractORCCertificateImport
@FailIfNoValidOrcCertificates
@Test
public void testSimpleOnlineFileRead() throws IOException, ParseException, InterruptedException {
Collection<ORCCertificate> certificates = customIgnoreRule.getAvailableCerts();
Collection<ORCCertificate> certificates = FailIfNoValidOrcCertificateRule.getAvailableCerts();
final ORCCertificate referenceCert = certificates.stream().findFirst().get();
assertNotNull(referenceCert);
assertTrue(referenceCert.getWindwardLeewardSpeedPrediction().get(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[0]).getDuration(ORCCertificate.NAUTICAL_MILE).asSeconds() > 10);
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.orc;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -19,11 +21,10 @@ import org.apache.commons.math.ArgumentOutsideDomainException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.json.simple.parser.ParseException;
import org.junit.Rule;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.rules.ErrorCollector;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.function.Executable;
import org.w3c.dom.DOMException;
import org.xml.sax.SAXException;
@@ -51,12 +52,10 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
* @author Daniel Lisunkin {i505543)
*
*/
@ExtendWith(FailIfNoValidOrcCertificateRule.class)
public class TestORCPerformanceCurve {
private static final Logger logger = Logger.getLogger(TestORCPerformanceCurve.class.getName());
// set true to see all the differences i
private final boolean collectErrors = true;
private static ORCPerformanceCurveCourse alturaCourse;
private static ORCCertificatesCollection importerLocal;
private static ORCCertificatesCollection importerWithSpecificBins;
@@ -64,32 +63,6 @@ public class TestORCPerformanceCurve {
private static final String RESOURCES = "resources/orc/";
@Rule
public FailIfNoValidOrcCertificateRule customFailRule = new FailIfNoValidOrcCertificateRule();
@Rule
public ErrorCollector collector = new ErrorCollector();
public void assertEquals(double a, double b, double accuracy) {
try {
Assertions.assertEquals(a, b, accuracy);
} catch (AssertionError e) {
if (collectErrors) {
collector.addError(e);
}
}
}
public void assertEquals(String message, double a, double b, double accuracy) {
try {
Assertions.assertEquals(a, b, accuracy, message);
} catch (AssertionError e) {
if (collectErrors) {
collector.addError(e);
}
}
}
@BeforeAll
public static void initialize() throws IOException, ParseException, DOMException, SAXException,
ParserConfigurationException, java.text.ParseException {
@@ -285,15 +258,17 @@ public class TestORCPerformanceCurve {
final double allowanceAccuracy = 0.1;
final Distance ONE_NAUTICAL_MILE = new NauticalMileDistance(1.0);
final ORCCertificate certificateWithSpecificBins = importerWithSpecificBins.getCertificateById("N/A");
final List<Executable> assertions = new ArrayList<>();
for (final Bearing twa : certificateWithSpecificBins.getTrueWindAngles()) {
final ORCPerformanceCurveCourse singleLegOneMileCourseWithTwa = createSingleLegCourseWithTwa(twa);
final ORCPerformanceCurve performanceCurveSpecificBins = new ORCPerformanceCurveImpl(certificateWithSpecificBins, singleLegOneMileCourseWithTwa);
for (final Speed tws : certificateWithSpecificBins.getTrueWindSpeeds()) {
final Duration duration = certificateWithSpecificBins.getVelocityPredictionPerTrueWindSpeedAndAngle().get(tws).get(twa).getDuration(ONE_NAUTICAL_MILE);
assertEquals("mismatch for twa "+twa+", tws "+tws, duration.asSeconds(), performanceCurveSpecificBins.getAllowancePerCourse(tws).asSeconds(), allowanceAccuracy);
assertEquals("mismatch for twa "+twa+", tws "+tws, tws.getKnots(), performanceCurveSpecificBins.getImpliedWind(duration).getKnots(), highAccuracy);
assertions.add(()->assertEquals(duration.asSeconds(), performanceCurveSpecificBins.getAllowancePerCourse(tws).asSeconds(), allowanceAccuracy, "mismatch for twa "+twa+", tws "+tws));
assertions.add(()->assertEquals(tws.getKnots(), performanceCurveSpecificBins.getImpliedWind(duration).getKnots(), highAccuracy, "mismatch for twa "+twa+", tws "+tws));
}
}
assertAll(assertions);
}
private ORCPerformanceCurveCourse createSingleLegCourseWithTwa(Bearing twa) {
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.orc;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Instant;
@@ -26,10 +27,10 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Logger;
import org.junit.Rule;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.common.orc.ORCCertificate;
@@ -37,6 +38,7 @@ import com.sap.sailing.domain.orc.ORCPublicCertificateDatabase.CertificateHandle
import com.sap.sailing.domain.orc.impl.ORCPublicCertificateDatabaseImpl;
import com.sap.sse.common.Util;
@ExtendWith(FailIfNoValidOrcCertificateRule.class)
public class TestORCPublicCertificateDatabase {
private static final Logger logger = Logger.getLogger(TestORCPublicCertificateDatabase.class.getName());
@@ -45,9 +47,6 @@ public class TestORCPublicCertificateDatabase {
private List<String> dateFailureCases = Arrays.asList("2019-02-21T10:44GMT+2","2019-02-21T10:38+0800","2019-02-21T10:38+08:00",
"2019-02-21T10:38-08","2019-02-21T10:38Z","2019-02-21T10z","2019-02-21T10:38z");
@Rule
public FailIfNoValidOrcCertificateRule customIgnoreRule = new FailIfNoValidOrcCertificateRule();
@BeforeEach
public void setUp() {
db = new ORCPublicCertificateDatabaseImpl();
@@ -153,7 +152,7 @@ public class TestORCPublicCertificateDatabase {
@FailIfNoValidOrcCertificates
@Test
public void testGetCertificate() throws Exception {
Collection<ORCCertificate> certificates = customIgnoreRule.getAvailableCerts();
Collection<ORCCertificate> certificates = FailIfNoValidOrcCertificateRule.getAvailableCerts();
final ORCCertificate cert = certificates.stream().findFirst().get();
Iterable<CertificateHandle> certHandles = db.search(/* country */ null, LocalDate.now().getYear(), /* referenceNumber */ null, cert.getBoatName(),
cert.getSailNumber(), /*
@@ -207,7 +206,7 @@ public class TestORCPublicCertificateDatabase {
int year = LocalDate.now().getYear();
ArrayList<Future<Set<ORCCertificate>>> futures = new ArrayList<Future<Set<ORCCertificate>>>();
boolean isYearFound = false;
for (ORCCertificate orcCertificate : customIgnoreRule.getAvailableCerts()) {
for (ORCCertificate orcCertificate : FailIfNoValidOrcCertificateRule.getAvailableCerts()) {
futures.add(db.search(orcCertificate.getBoatName(), orcCertificate.getSailNumber(),
new BoatClassImpl(orcCertificate.getBoatClassName(), true)));
}
@@ -225,12 +224,14 @@ public class TestORCPublicCertificateDatabase {
}
}
@Test(expected = DateTimeParseException.class)
@Test
public void testShould() throws Exception {
for (String dateString : dateFailureCases) {
db.parseDate(dateString);
Assertions.fail(dateString + " is parsable");
}
assertThrows(DateTimeParseException.class, ()->{
for (String dateString : dateFailureCases) {
db.parseDate(dateString);
Assertions.fail(dateString + " is parsable");
}
});
}
private boolean assertFoundYear(final Set<ORCCertificate> certificates, int year) {
@@ -9,11 +9,11 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import org.junit.Rule;
import org.junit.jupiter.api.Test;
import org.junit.rules.Timeout;
import org.junit.jupiter.api.Timeout;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.RaceDefinition;
@@ -37,10 +37,8 @@ import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sse.replication.FullyInitializedReplicableTracker;
import com.sap.sse.util.ThreadLocalTransporter;
@Timeout(value = 100, unit = TimeUnit.SECONDS) // fail after 1s
public class TestDeadlockInRegattaListener {
@Rule
public Timeout globalTimeout = Timeout.millis(100000); // fail after 1s
@Test
public void testDeadlockInRegattaListener() throws InterruptedException, BrokenBarrierException, MalformedURLException, IOException {
CyclicBarrier latch = new CyclicBarrier(2);
@@ -4,10 +4,10 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.jupiter.api.Test;
import org.junit.rules.Timeout;
import org.junit.jupiter.api.Timeout;
/**
* Tests around the Timer class; e.g., does it kill a timer if a task throws an exception?
@@ -15,10 +15,8 @@ import org.junit.rules.Timeout;
* @author Axel Uhl (d043530)
*
*/
@Timeout(value = 10, unit = TimeUnit.SECONDS)
public class TimerTest {
@Rule
public Timeout AbstractTracTracLiveTestTimeout = Timeout.millis(10 * 1000);
@Test
public void exceptionInTask() throws InterruptedException {
Timer t = new Timer("Test");
@@ -9,11 +9,11 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.rules.Timeout;
import org.junit.jupiter.api.Timeout;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
@@ -29,12 +29,11 @@ import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
import com.sap.sailing.domain.tractracadapter.impl.RaceTrackingConnectivityParametersImpl;
@Timeout(value = 2, unit = TimeUnit.MINUTES)
public class UnicodeCharactersInCompetitorNamesTest {
protected static final boolean tractracTunnel = Boolean.valueOf(System.getProperty("tractrac.tunnel", "false"));
protected static final String tractracTunnelHost = System.getProperty("tractrac.tunnel.host", "localhost");
private DomainFactory domainFactory;
@Rule public Timeout AbstractTracTracLiveTestTimeout = Timeout.millis(2 * 60 * 1000);
@BeforeEach
public void setUp() {
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking.impl;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import java.util.Arrays;
@@ -55,67 +56,68 @@ public class TrackedRegattaTest {
/* registrationLinkSecret */ UUID.randomUUID().toString()));
}
@Test(expected = TimeoutException.class)
@Test
public void testBug4429() throws Exception {
final Phaser addPhaser = new Phaser(2);
final CyclicBarrier removeBarrier = new CyclicBarrier(2);
regatta.addRaceListener(new RaceListener() {
@Override
public void raceRemoved(TrackedRace trackedRace) {
try {
removeBarrier.await(1, TimeUnit.SECONDS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
assertThrows(TimeoutException.class, ()->{
final Phaser addPhaser = new Phaser(2);
final CyclicBarrier removeBarrier = new CyclicBarrier(2);
@Override
public void raceAdded(TrackedRace trackedRace) {
try {
addPhaser.arriveAndAwaitAdvance();
addPhaser.arriveAndAwaitAdvance();
} catch (Exception e) {
throw new RuntimeException(e);
regatta.addRaceListener(new RaceListener() {
@Override
public void raceRemoved(TrackedRace trackedRace) {
try {
removeBarrier.await(1, TimeUnit.SECONDS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}, Optional.empty(), /* synchronous */ false);
DynamicTrackedRace race1 = createRace("R1");
Thread thread1 = new Thread(() -> {
regatta.addTrackedRace(race1, Optional.empty());
});
thread1.start();
// This ensures, that the add event is being processed but is not finished because
// this unblocks the first arriveAndAwaitAdvance() in raceAdded, but not the second.
// This way, the raceRemoved(...) call is expected to not be started because it has
// to wait for the raceAdded(...) call to have finished.
addPhaser.arriveAndAwaitAdvance();
Thread thread2 = new Thread(() -> {
regatta.removeTrackedRace(race1, Optional.empty());
});
thread2.start();
// If the implementation ensures that the events are fired in order,
// the removeBarrier will run into a TimeoutException because the addBarrier
// is not solved and while the first event is processed the second one
// should not be started to be processed.
try {
removeBarrier.await(10, TimeUnit.MILLISECONDS);
// if this line is reached, the order of events is not correctly ensured
Assertions.fail();
} finally {
addPhaser.forceTermination();
@Override
public void raceAdded(TrackedRace trackedRace) {
try {
addPhaser.arriveAndAwaitAdvance();
addPhaser.arriveAndAwaitAdvance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, Optional.empty(), /* synchronous */ false);
DynamicTrackedRace race1 = createRace("R1");
Thread thread1 = new Thread(() -> {
regatta.addTrackedRace(race1, Optional.empty());
});
thread1.start();
// This ensures, that the add event is being processed but is not finished because
// this unblocks the first arriveAndAwaitAdvance() in raceAdded, but not the second.
// This way, the raceRemoved(...) call is expected to not be started because it has
// to wait for the raceAdded(...) call to have finished.
addPhaser.arriveAndAwaitAdvance();
Thread thread2 = new Thread(() -> {
regatta.removeTrackedRace(race1, Optional.empty());
});
thread2.start();
// If the implementation ensures that the events are fired in order,
// the removeBarrier will run into a TimeoutException because the addBarrier
// is not solved and while the first event is processed the second one
// should not be started to be processed.
try {
// solved the barrier if one hangs at this point
// a TimeoutException can occur but we do not care about it
removeBarrier.await(10, TimeUnit.MILLISECONDS);
} catch (Exception e) {
// if this line is reached, the order of events is not correctly ensured
Assertions.fail();
} finally {
addPhaser.forceTermination();
try {
// solved the barrier if one hangs at this point
// a TimeoutException can occur but we do not care about it
removeBarrier.await(10, TimeUnit.MILLISECONDS);
} catch (Exception e) {
}
thread1.join(1000);
thread2.join(1000);
}
thread1.join(1000);
thread2.join(1000);
}
});
}
private DynamicTrackedRace createRace(String name) {