TimeoutBudget { public Duration timeLeft() { Instant now = clock.instant(); Duration duration = Duration.between(now, endTime); return duration.isNegative() ? Duration.ZERO : duration; } TimeoutBudget(Clock clock, Duration duration); Duration timeout(); Duration timeLeft(); boolean hasTimeLeft(); boolean hasTimeLeft(String step); String timesUsed(); void assertNotTimedOut(Supplier<String> exceptionMessage);  }
@Test public void testTimeLeft() { ManualClock clock = new ManualClock(); TimeoutBudget budget = new TimeoutBudget(clock, Duration.ofMillis(7)); assertThat(budget.timeLeft().toMillis(), is(7L)); clock.advance(Duration.ofMillis(1)); assertThat(budget.timeLeft().toMillis(), is(6L)); clock.advance(Duration.ofMillis(5)); assertThat(budget.timeLeft().toMillis(), is(1L)); assertThat(budget.timeLeft().toMillis(), is(1L)); clock.advance(Duration.ofMillis(1)); assertThat(budget.timeLeft().toMillis(), is(0L)); clock.advance(Duration.ofMillis(5)); assertThat(budget.timeLeft().toMillis(), is(0L)); clock.advance(Duration.ofMillis(1)); assertThat(budget.timesUsed(), is("[total: 13 ms]")); }