// Copyright © 2011-2013, Esko Luontola <www.orfjackal.net> // This software is released under the Apache License 2.0. // The license text is at http://www.apache.org/licenses/LICENSE-2.0 package fi.jumi.core.util.timeout; import org.junit.*; import org.junit.rules.ExpectedException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; public class CommandExecutingTimeoutTest { @Rule public final org.junit.rules.Timeout testTimeout = new org.junit.rules.Timeout(1000); @Rule public ExpectedException thrown = ExpectedException.none(); private CommandExecutingTimeout timeout; private final AtomicInteger numberOfTimeouts = new AtomicInteger(0); @Test public void runs_the_command_after_the_timeout() throws InterruptedException { timeout = new CommandExecutingTimeout(new SpyCommand(), 1, TimeUnit.MILLISECONDS); timeout.start(); assertNumberOfTimeouts(1); } @Test public void does_not_run_the_command_if_cancelled_before_the_timeout() throws InterruptedException { timeout = new CommandExecutingTimeout(new SpyCommand(), 100, TimeUnit.MILLISECONDS); timeout.start(); timeout.cancel(); assertNumberOfTimeouts(0); } @Test public void the_timeout_can_be_restarted() throws InterruptedException { timeout = new CommandExecutingTimeout(new SpyCommand(), 10, TimeUnit.MILLISECONDS); timeout.start(); timeout.cancel(); timeout.start(); assertNumberOfTimeouts(1); } @Test public void cancelling_is_idempotent() throws InterruptedException { timeout = new CommandExecutingTimeout(new SpyCommand(), 100, TimeUnit.MILLISECONDS); timeout.cancel(); timeout.cancel(); timeout.start(); timeout.cancel(); timeout.cancel(); assertNumberOfTimeouts(0); } @Test public void cannot_start_many_times_without_cancelling_first() throws InterruptedException { timeout = new CommandExecutingTimeout(new SpyCommand(), 10, TimeUnit.MILLISECONDS); timeout.start(); thrown.expect(IllegalStateException.class); thrown.expectMessage("already started"); timeout.start(); } private void assertNumberOfTimeouts(int expected) throws InterruptedException { waitForPossibleTimeout(); assertThat(numberOfTimeouts.get(), is(expected)); } private void waitForPossibleTimeout() throws InterruptedException { Thread thread = timeout.scheduler; if (thread != null) { thread.join(); } } private class SpyCommand implements Runnable { @Override public void run() { numberOfTimeouts.incrementAndGet(); } } }