diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/BlockTimerTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/BlockTimerTest.java index fd4b561f80..ab167bb333 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/BlockTimerTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/BlockTimerTest.java @@ -13,8 +13,6 @@ package tech.pegasys.pantheon.consensus.ibft; import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.hamcrest.CoreMatchers.equalTo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -30,7 +28,6 @@ import tech.pegasys.pantheon.ethereum.core.BlockHeader; import tech.pegasys.pantheon.ethereum.core.BlockHeaderTestFixture; import java.time.Clock; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -44,6 +41,7 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.StrictStubs.class) public class BlockTimerTest { + private ScheduledExecutorService mockExecutorService; private IbftEventQueue mockQueue; private Clock mockClock; @@ -95,7 +93,7 @@ public class BlockTimerTest { } @Test - public void aBlockTimerExpiryEventIsAddedToTheQueueOnExpiry() { + public void aBlockTimerExpiryEventIsAddedToTheQueueOnExpiry() throws InterruptedException { final long MINIMAL_TIME_BETWEEN_BLOCKS_SECONDS = 1; final long NOW_MILLIS = 300_500L; final long BLOCK_TIME_STAMP = 300; @@ -108,27 +106,33 @@ public class BlockTimerTest { final ConsensusRoundIdentifier round = new ConsensusRoundIdentifier(0xFEDBCA9876543210L, 0x12345678); + final ScheduledFuture mockedFuture = mock(ScheduledFuture.class); + Mockito.>when( + mockExecutorService.schedule(any(Runnable.class), anyLong(), any())) + .thenReturn(mockedFuture); + + final IbftEventQueue eventQueue = new IbftEventQueue(); final BlockTimer timer = new BlockTimer( - mockQueue, - MINIMAL_TIME_BETWEEN_BLOCKS_SECONDS, - Executors.newSingleThreadScheduledExecutor(), - mockClock); + eventQueue, MINIMAL_TIME_BETWEEN_BLOCKS_SECONDS, mockExecutorService, mockClock); timer.startTimer(round, header); // Verify that the event will not be added to the queue immediately - verify(mockQueue, never()).add(any()); - - await() - .atMost(EXPECTED_DELAY + 200, TimeUnit.MILLISECONDS) - .atLeast(EXPECTED_DELAY - 200, TimeUnit.MILLISECONDS) - .until(timer::isRunning, equalTo(false)); - - final ArgumentCaptor ibftEventCaptor = ArgumentCaptor.forClass(IbftEvent.class); - verify(mockQueue).add(ibftEventCaptor.capture()); - - assertThat(ibftEventCaptor.getValue() instanceof BlockTimerExpiry).isTrue(); - assertThat(((BlockTimerExpiry) ibftEventCaptor.getValue()).getRoundIndentifier()) + assertThat(eventQueue.isEmpty()).isTrue(); + + // Verify that a task is sceheduled for EXPECTED_DELAY milliseconds in the future + ArgumentCaptor expiryTask = ArgumentCaptor.forClass(Runnable.class); + verify(mockExecutorService, times(1)) + .schedule(expiryTask.capture(), eq(EXPECTED_DELAY), eq(TimeUnit.MILLISECONDS)); + + // assert that the task puts a BlockExpired event into the queue + final Runnable scheduledTask = expiryTask.getValue(); + assertThat(eventQueue.isEmpty()).isTrue(); + scheduledTask.run(); + assertThat(eventQueue.size()).isEqualTo(1); + final IbftEvent queuedEvent = eventQueue.poll(0, TimeUnit.SECONDS); + assertThat(queuedEvent).isInstanceOf(BlockTimerExpiry.class); + assertThat(((BlockTimerExpiry) queuedEvent).getRoundIndentifier()) .isEqualToComparingFieldByField(round); }