From 43d225464e7187b8b6f3d0646302e11cb40be199 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 4 Sep 2024 12:37:08 -0400 Subject: [PATCH] Faster StopWatchTest.testSuspend() - Replace Matcher calls with sane assertTrue() - Use variable names in assertion messages to match the source --- .../commons/lang3/time/StopWatchTest.java | 89 +++++++++++-------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java b/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java index 1365f76e0..7e3f07838 100644 --- a/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java +++ b/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java @@ -17,10 +17,7 @@ package org.apache.commons.lang3.time; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -47,7 +44,6 @@ public class StopWatchTest extends AbstractLangTest { private static final int SPLIT_CLOCK_STR_LEN = 12; private static final Duration MIN_DURATION = Duration.ofMillis(20); - private static final Duration MILLIS_550 = Duration.ofMillis(550); private static final String MESSAGE = "Baking cookies"; private static final String ZERO_HOURS_PREFIX = "00:"; private static final String ZERO_TIME_ELAPSED = "00:00:00.000"; @@ -88,8 +84,14 @@ public class StopWatchTest extends AbstractLangTest { return watch; } - private void sleep(final Duration duration) throws InterruptedException { - ThreadUtils.sleep(duration); + /** + * Sleeps the requested duration plus one millisecond. On Java 8, sleeping for 2 or 20 millis can sleep for a tiny bit less. + * + * @param duration How long to sleep. + * @throws InterruptedException if any thread has interrupted the current thread. + */ + private void sleepPlus1(final Duration duration) throws InterruptedException { + ThreadUtils.sleep(duration.plusMillis(1)); } /** @@ -201,7 +203,7 @@ public class StopWatchTest extends AbstractLangTest { assertEquals(Duration.ZERO, watch.getDuration()); assertEquals(ZERO_TIME_ELAPSED, watch.toString()); watch.start(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); final long nanos = watch.getNanoTime(); assertTrue(nanos > 0, () -> "getNanoTime(): " + nanos); assertTrue(DurationUtils.isPositive(watch.getDuration())); @@ -251,7 +253,7 @@ public class StopWatchTest extends AbstractLangTest { assertEquals(0, watch.getTime()); assertEquals(ZERO_TIME_ELAPSED, watch.toString()); watch.start(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); final long time = watch.getTime(); assertTrue(time > 0, () -> "getTime() millis: " + time); assertTrue(time < 2000, () -> "getTime() millis: " + time); @@ -276,11 +278,11 @@ public class StopWatchTest extends AbstractLangTest { @Test public void testLang315() throws InterruptedException { final StopWatch watch = StopWatch.createStarted(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.suspend(); final long suspendTime = watch.getTime(); final Duration suspendDuration = watch.getDuration(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.stop(); final long totalTime = watch.getTime(); final Duration totalDuration = watch.getDuration(); @@ -303,7 +305,7 @@ public class StopWatchTest extends AbstractLangTest { public void testSimple() throws InterruptedException { final StopWatch watch = StopWatch.createStarted(); final Duration sleepDuration = MIN_DURATION; - sleep(sleepDuration); + sleepPlus1(sleepDuration); watch.stop(); final long time = watch.getTime(); final Duration duration = watch.getDuration(); @@ -321,15 +323,15 @@ public class StopWatchTest extends AbstractLangTest { final Duration sleepDuration = MIN_DURATION; final long sleepMillis = sleepDuration.toMillis(); assertTrue(sleepMillis > 0); - sleep(sleepDuration); + sleepPlus1(sleepDuration); watch.split(); final long splitTime = watch.getSplitTime(); final Duration splitDuration = watch.getSplitDuration(); assertEquals(splitTime, watch.getSplitDuration().toMillis()); assertEquals(SPLIT_CLOCK_STR_LEN, watch.toSplitString().length(), "Formatted split string not the correct length"); - sleep(sleepDuration); + sleepPlus1(sleepDuration); watch.unsplit(); - sleep(sleepDuration); + sleepPlus1(sleepDuration); watch.stop(); final long totalTime = watch.getTime(); final Duration totalDuration = watch.getDuration(); @@ -350,7 +352,7 @@ public class StopWatchTest extends AbstractLangTest { public void testStopInstantSimple() throws InterruptedException { final StopWatch watch = StopWatch.createStarted(); final long testStartMillis = System.currentTimeMillis(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.stop(); final long testEndMillis = System.currentTimeMillis(); final Instant stopTime = watch.getStopInstant(); @@ -364,7 +366,7 @@ public class StopWatchTest extends AbstractLangTest { public void testStopTimeSimple() throws InterruptedException { final StopWatch watch = StopWatch.createStarted(); final long testStartMillis = System.currentTimeMillis(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.stop(); final long testEndMillis = System.currentTimeMillis(); final long stopTime = watch.getStopTime(); @@ -380,44 +382,59 @@ public class StopWatchTest extends AbstractLangTest { final long testStartMillis = System.currentTimeMillis(); final long testStartNanos = System.nanoTime(); final Instant testStartInstant = Instant.ofEpochMilli(testStartMillis); - sleep(MILLIS_550); + final Duration sleepDuration = MIN_DURATION; + final long sleepMillis = sleepDuration.toMillis(); + sleepPlus1(sleepDuration); watch.suspend(); final long testSuspendMillis = System.currentTimeMillis(); final long testSuspendNanos = System.nanoTime(); final long testSuspendTimeNanos = testSuspendNanos - testStartNanos; - final Duration testSuspendDuration = Duration.ofNanos(testSuspendTimeNanos); + // See sleepPlus1 + final Duration testSuspendDuration = Duration.ofNanos(testSuspendTimeNanos).plusMillis(1); final long suspendTimeFromNanos = watch.getTime(); final Duration suspendDuration = watch.getDuration(); final long stopTimeMillis = watch.getStopTime(); final Instant stopInstant = watch.getStopInstant(); - assertThat("testStartMillis <= stopTimeMillis", testStartMillis, lessThanOrEqualTo(stopTimeMillis)); - assertThat("testStartInstant <= stopInstant", testStartInstant, lessThanOrEqualTo(stopInstant)); - assertThat("testSuspendMillis <= stopTimeMillis", testSuspendMillis, lessThanOrEqualTo(stopTimeMillis)); - assertThat("testSuspendMillis <= stopInstant", testSuspendMillis, lessThanOrEqualTo(stopInstant.toEpochMilli())); + assertTrue(testStartMillis <= stopTimeMillis, () -> String.format("testStartMillis %s <= stopTimeMillis %s", testStartMillis, stopTimeMillis)); + assertTrue(testStartInstant.isBefore(stopInstant), () -> String.format("testStartInstant %s < stopInstant %s", testStartInstant, stopInstant)); + assertTrue(testSuspendMillis <= stopTimeMillis, () -> String.format("testSuspendMillis %s <= stopTimeMillis %s", testSuspendMillis, stopTimeMillis)); + assertTrue(testSuspendMillis <= stopInstant.toEpochMilli(), + () -> String.format("testSuspendMillis %s <= stopInstant %s", testSuspendMillis, stopInstant)); - sleep(MILLIS_550); + sleepPlus1(sleepDuration); watch.resume(); - sleep(MILLIS_550); + sleepPlus1(sleepDuration); watch.stop(); final long totalTimeFromNanos = watch.getTime(); final Duration totalDuration = watch.getDuration(); - assertThat("suspendTimeFromNanos", suspendTimeFromNanos, greaterThanOrEqualTo(500L)); - assertThat("suspendDuration", suspendDuration, greaterThanOrEqualTo(Duration.ofMillis(500L))); - assertThat("suspendTimeFromNanos <= testSuspendTimeNanos", suspendTimeFromNanos, lessThanOrEqualTo(testSuspendTimeNanos)); - assertThat("suspendDuration <= testSuspendDuration", suspendDuration, lessThanOrEqualTo(testSuspendDuration)); - assertThat("totalTimeFromNanos", totalTimeFromNanos, greaterThanOrEqualTo(1000L)); - assertThat("totalDuration", totalDuration, greaterThanOrEqualTo(Duration.ofMillis(1000L))); + assertTrue(suspendTimeFromNanos >= sleepMillis, () -> String.format("suspendTimeFromNanos %s >= sleepMillis %s", suspendTimeFromNanos, sleepMillis)); + assertTrue(suspendDuration.compareTo(Duration.ofMillis(sleepMillis)) >= 0, + () -> String.format("suspendDuration %s >= sleepMillis %s", suspendDuration, sleepMillis)); + assertTrue(suspendTimeFromNanos <= testSuspendTimeNanos, + () -> String.format("suspendTimeFromNanos %s <= testSuspendTimeNanos %s", suspendTimeFromNanos, testSuspendTimeNanos)); + assertTrue(suspendDuration.compareTo(testSuspendDuration) <= 0, + () -> String.format("suspendDuration %s <= testSuspendDuration %s", suspendDuration, testSuspendDuration)); + + final long sleepMillisX2 = sleepMillis + sleepMillis; + assertTrue(totalTimeFromNanos >= sleepMillisX2, () -> String.format("totalTimeFromNanos %s >= sleepMillisX2 %s", totalTimeFromNanos, sleepMillisX2)); + assertTrue(totalDuration.compareTo(Duration.ofMillis(sleepMillisX2)) >= 0, + () -> String.format("totalDuration >= sleepMillisX2", totalDuration, sleepMillisX2)); + ; // Be lenient for slow running builds - assertThat("totalTimeFromNanos", totalTimeFromNanos, lessThan(2500L)); - assertThat("totalDuration", totalDuration, lessThan(Duration.ofMillis(2500L))); + final long testTooLongMillis = sleepMillis * 5; + assertTrue(totalTimeFromNanos < testTooLongMillis, + () -> String.format("totalTimeFromNanos %s < testTooLongMillis %s", totalTimeFromNanos, testTooLongMillis)); + assertTrue(totalDuration.compareTo(Duration.ofMillis(testTooLongMillis)) < 0, + () -> String.format("totalDuration %s < testTooLongMillis %s", totalDuration, testTooLongMillis)); + ; } @Test public void testToSplitString() throws InterruptedException { final StopWatch watch = StopWatch.createStarted(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.split(); final String splitStr = watch.toSplitString(); assertEquals(SPLIT_CLOCK_STR_LEN, splitStr.length(), "Formatted split string not the correct length"); @@ -427,7 +444,7 @@ public class StopWatchTest extends AbstractLangTest { public void testToSplitStringWithMessage() throws InterruptedException { final StopWatch watch = new StopWatch(MESSAGE); watch.start(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.split(); final String splitStr = watch.toSplitString(); assertEquals(SPLIT_CLOCK_STR_LEN + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length"); @@ -437,7 +454,7 @@ public class StopWatchTest extends AbstractLangTest { public void testToString() throws InterruptedException { // final StopWatch watch = StopWatch.createStarted(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.split(); final String splitStr = watch.toString(); assertEquals(SPLIT_CLOCK_STR_LEN, splitStr.length(), "Formatted split string not the correct length"); @@ -449,7 +466,7 @@ public class StopWatchTest extends AbstractLangTest { // final StopWatch watch = new StopWatch(MESSAGE); watch.start(); - sleep(MIN_DURATION); + sleepPlus1(MIN_DURATION); watch.split(); final String splitStr = watch.toString(); assertEquals(SPLIT_CLOCK_STR_LEN + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length");