diff --git a/pom.xml b/pom.xml index d6a1f89c32..26c4003d3c 100644 --- a/pom.xml +++ b/pom.xml @@ -100,10 +100,11 @@ The MIT License (MIT) maven-compiler-plugin - 3.7.0 + 3.8.0 1.8 1.8 + false diff --git a/src/test/java/org/cactoos/experimental/ThreadsTest.java b/src/test/java/org/cactoos/experimental/ThreadsTest.java index 342607dc66..c24d93bee4 100644 --- a/src/test/java/org/cactoos/experimental/ThreadsTest.java +++ b/src/test/java/org/cactoos/experimental/ThreadsTest.java @@ -24,25 +24,17 @@ package org.cactoos.experimental; -import java.time.Duration; -import java.util.Collection; -import java.util.concurrent.Callable; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.cactoos.Proc; import org.cactoos.func.Repeated; -import org.cactoos.func.Timed; import org.cactoos.func.UncheckedFunc; -import org.cactoos.list.ListOf; -import org.cactoos.list.Mapped; -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; -import org.hamcrest.core.IsEqual; import org.junit.Test; +import org.llorllale.cactoos.matchers.Assertion; import org.llorllale.cactoos.matchers.HasValues; +import org.llorllale.cactoos.matchers.Throws; /** * Test case for {@link Threads}. @@ -50,88 +42,44 @@ * @since 1.0.0 * @checkstyle MagicNumberCheck (500 lines) * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) + * @todo #1112:30min Continue speeding up the `mvn test` goal until it + * executes in less than 10 seconds, or as fast as reasonably possible. */ @SuppressWarnings("PMD.AvoidDuplicateLiterals") public final class ThreadsTest { - /** - * Example of JDK8 way for handling of concurrent tasks. - * This code base should be simplified. - */ - @Test(timeout = 10000) - public void oldSchoolWay() { - final ExecutorService extor = Executors.newFixedThreadPool(5); - try { - final Collection> futures = extor.invokeAll( - new ListOf>( - () -> { - TimeUnit.SECONDS.sleep(2); - return "1st"; - }, - () -> { - TimeUnit.SECONDS.sleep(6); - return "3rd"; - }, - () -> { - TimeUnit.SECONDS.sleep(4); - return "2nd"; - } - ) - ); - MatcherAssert.assertThat( - new Mapped<>(Future::get, futures), - Matchers.hasItems("1st", "3rd", "2nd") - ); - } catch (final InterruptedException exp) { - Thread.currentThread().interrupt(); - throw new IllegalStateException(exp); - } finally { - try { - extor.shutdown(); - if (!extor.awaitTermination(2, TimeUnit.SECONDS)) { - extor.shutdownNow(); - } - } catch (final InterruptedException exp) { - extor.shutdownNow(); - } - } - } - /** * Execute the tasks concurrently using {@link Threads} when * {@link ExecutorService} was initiated by someone else. */ @Test - public void cactoosWay() { - this.repeatWithTimeout( + public void containsResults() { + this.repeat( arg -> { final ExecutorService extor = Executors.newFixedThreadPool(3); try { - MatcherAssert.assertThat( - new Threads( + new Assertion<>( + "contains results from callables", + () -> new Threads( extor, () -> { - TimeUnit.SECONDS.sleep(3); + this.sleep(); return "txt 1"; }, () -> { - TimeUnit.SECONDS.sleep(3); + this.sleep(); return "txt 2"; }, () -> { - TimeUnit.SECONDS.sleep(3); + this.sleep(); return "txt 3"; } ), new HasValues<>("txt 1", "txt 2", "txt 3") - ); + ).affirm(); } finally { - try { - extor.shutdown(); - if (!extor.awaitTermination(1, TimeUnit.SECONDS)) { - extor.shutdownNow(); - } - } catch (final InterruptedException exp) { + extor.shutdown(); + if (!extor.awaitTermination(1L, TimeUnit.SECONDS)) { extor.shutdownNow(); } } @@ -143,14 +91,21 @@ public void cactoosWay() { * Execute 1 task within executor service and ensure that we'll get the * expected exception type. */ - @Test(expected = CompletionException.class) - public void executionIsFailedDueToException() { - new Threads( - Executors.newSingleThreadExecutor(), - () -> { - throw new IllegalStateException("Something went wrong"); - } - ).iterator().next(); + @Test + public void failsDueToException() { + new Assertion<>( + "wraps error into CompletionException", + () -> new Threads( + Executors.newSingleThreadExecutor(), + () -> { + throw new IllegalStateException("Something went wrong"); + } + ).iterator().next(), + new Throws<>( + "java.lang.IllegalStateException: Something went wrong", + CompletionException.class + ) + ).affirm(); } /** @@ -158,58 +113,55 @@ public void executionIsFailedDueToException() { * {@link ExecutorService} was initiated by {@link Threads} itself. */ @Test - public void cactoosWayWithInlineExecutorService() { - this.repeatWithTimeout( - arg -> { - MatcherAssert.assertThat( - new Threads( - 5, - () -> { - TimeUnit.SECONDS.sleep(3); - return "txt 1"; - }, - () -> { - TimeUnit.SECONDS.sleep(3); - return "txt 2"; - }, - () -> { - TimeUnit.SECONDS.sleep(3); - return "txt 3"; - }, - () -> { - TimeUnit.SECONDS.sleep(3); - return "txt 4"; - }, - () -> { - TimeUnit.SECONDS.sleep(3); - return "txt 5"; - } - ), - new HasValues<>("txt 1", "txt 2", "txt 3", "txt 4", "txt 5") - ); - } + public void containsValuesWithInlineExecutorService() { + this.repeat( + arg -> new Assertion<>( + // @checkstyle LineLength (1 line) + "contains results from the callables when using the inline executor service", + () -> new Threads( + 3, + () -> { + this.sleep(); + return "txt 1"; + }, + () -> { + this.sleep(); + return "txt 2"; + }, + () -> { + this.sleep(); + return "txt 3"; + } + ), + new HasValues<>("txt 1", "txt 2", "txt 3") + ).affirm() ); } /** - * Execute the test at least 10 times with timeout in 5 seconds each. + * Repeat the test several times. * @param test The test to execute. */ - private void repeatWithTimeout(final Proc test) { - MatcherAssert.assertThat( - new UncheckedFunc<>( - new Repeated<>( - new Timed( - input -> { - test.exec(null); - return true; - }, - Duration.ofSeconds(5).toMillis() - ), - 10 - ) - ).apply(true), - new IsEqual<>(true) - ); + private void repeat(final Proc test) { + new UncheckedFunc<>( + new Repeated<>( + arg -> { + test.exec(null); + return null; + }, + 5 + ) + ).apply(Boolean.TRUE); + } + + /** + * Sleep. + */ + private void sleep() { + try { + TimeUnit.MILLISECONDS.sleep(100L); + } catch (final InterruptedException iex) { + throw new IllegalStateException(iex); + } } }