From 5a6e109dc7e55791c1a4c8b0cab03c8b066aea40 Mon Sep 17 00:00:00 2001 From: Abel Salgado Romero Date: Sun, 21 Mar 2021 22:12:20 +0100 Subject: [PATCH] Migrate AsciidoctorHttpMojoTest from Groovy to Java --- .../maven/test/AsciidoctorHttpMojoTest.groovy | 314 ------------------ .../maven/AsciidoctorHttpMojoTest.java | 300 +++++++++++++++++ .../java/org/asciidoctor/maven/TestUtils.java | 5 + .../maven/io/DoubleOutputStream.java | 2 +- .../maven/io/PrefilledInputStream.java | 4 +- 5 files changed, 308 insertions(+), 317 deletions(-) delete mode 100644 src/test/groovy/org/asciidoctor/maven/test/AsciidoctorHttpMojoTest.groovy create mode 100644 src/test/java/org/asciidoctor/maven/AsciidoctorHttpMojoTest.java diff --git a/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorHttpMojoTest.groovy b/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorHttpMojoTest.groovy deleted file mode 100644 index ca3f4a3d..00000000 --- a/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorHttpMojoTest.groovy +++ /dev/null @@ -1,314 +0,0 @@ -package org.asciidoctor.maven.test - -import lombok.SneakyThrows -import org.asciidoctor.maven.AsciidoctorHttpMojo -import org.asciidoctor.maven.io.DoubleOutputStream -import org.asciidoctor.maven.io.PrefilledInputStream -import org.asciidoctor.maven.io.TestFilesHelper -import org.asciidoctor.maven.test.plexus.MockPlexusContainer -import spock.lang.Specification - -import java.nio.file.Files -import java.util.concurrent.CountDownLatch - -class AsciidoctorHttpMojoTest extends Specification { - - def setupSpec() { - MockPlexusContainer.initializeMockContext(AsciidoctorHttpMojo) - } - - def "http front should let access converted files"() { - setup: - def srcDir = new File('target/test-classes/src/asciidoctor-http') - def outputDir = TestFilesHelper.newOutputTestDirectory('http-mojo') - - srcDir.mkdirs() - - def inputLatch = new CountDownLatch(1) - - def originalOut = System.out - def originalIn = System.in - - def newOut = new DoubleOutputStream(originalOut) - def newIn = new PrefilledInputStream('exit\r\n'.bytes, inputLatch) - - System.setOut(new PrintStream(newOut)) - System.setIn(newIn) - - def httpPort = availablePort - - def content = new File(srcDir, "content.asciidoc") - content.withWriter{ it << - '''Document Title - ============== - - This is test, only a test.'''.stripIndent() } - - def mojo = new AsciidoctorHttpMojo() - mojo.backend = 'html5' - mojo.port = httpPort - mojo.sourceDirectory = srcDir - mojo.outputDirectory = outputDir - mojo.headerFooter = true - mojo.home = 'index' - def mojoThread = new Thread(new Runnable() { - @Override - void run() { - mojo.execute() - } - }) - mojoThread.start() - - while (!new String(newOut.toByteArray()).contains('Type ')) { - Thread.sleep(200) - } - - when: - def html = "http://localhost:${httpPort}/content".toURL().text - - then: - assert html.contains('This is test, only a test') - assert html.contains('') - - cleanup: - System.setOut(originalOut) - inputLatch.countDown() - System.setIn(originalIn) - awaitTermination(mojoThread) - } - - def "should return default page"() { - setup: - def srcDir = new File('target/test-classes/src/asciidoctor-http-default') - def outputDir = TestFilesHelper.newOutputTestDirectory('http-mojo') - - srcDir.mkdirs() - - def inputLatch = new CountDownLatch(1) - - def originalOut = System.out - def originalIn = System.in - - def newOut = new DoubleOutputStream(originalOut) - def newIn = new PrefilledInputStream('exit\r\nexit\r\nexit\r\n'.bytes, inputLatch) - - def httpPort = availablePort - - System.setOut(new PrintStream(newOut)) - System.setIn(newIn) - - def content = new File(srcDir, "content.asciidoc") - content.withWriter{ it << - '''Document Title - ============== - - DEFAULT.'''.stripIndent() } - - def mojo = new AsciidoctorHttpMojo() - mojo.backend = 'html5' - mojo.port = httpPort - mojo.sourceDirectory = srcDir - mojo.outputDirectory = outputDir - mojo.headerFooter = true - mojo.home = 'content' - def mojoThread = new Thread(new Runnable() { - @Override - void run() { - mojo.execute() - } - }) - mojoThread.start() - - while (!new String(newOut.toByteArray()).contains('Type ')) { - Thread.sleep(200) - } - - when: - def html = "http://localhost:${httpPort}/".toURL().text - - then: - assert html.contains('DEFAULT') - - cleanup: - System.setOut(originalOut) - inputLatch.countDown() - System.setIn(originalIn) - awaitTermination(mojoThread) - } - - def "should return 404 when file does not exist"() { - setup: - def emptySrcDir = new File('some_path') - def outputDir = TestFilesHelper.newOutputTestDirectory('http-mojo') - - def inputLatch = new CountDownLatch(1) - - def originalOut = System.out - def originalIn = System.in - - def newOut = new DoubleOutputStream(originalOut) - def newIn = new PrefilledInputStream('exit\r\nexit\r\nexit\r\n'.bytes, inputLatch) - - def httpPort = availablePort - - System.setOut(new PrintStream(newOut)) - System.setIn(newIn) - - def mojo = new AsciidoctorHttpMojo() - mojo.backend = 'html5' - mojo.port = httpPort - mojo.sourceDirectory = emptySrcDir - mojo.outputDirectory = outputDir - mojo.headerFooter = true - mojo.home = 'content' - def mojoThread = new Thread(new Runnable() { - @Override - void run() { - mojo.execute() - } - }) - mojoThread.start() - - while (!new String(newOut.toByteArray()).contains('Type ')) { - Thread.sleep(200) - } - - when: - HttpURLConnection connection = new URL("http://localhost:${httpPort}/").openConnection() - def status = connection.getResponseCode() - - then: - status == 404 - - cleanup: - System.setOut(originalOut) - inputLatch.countDown() - System.setIn(originalIn) - awaitTermination(mojoThread) - } - - def "should return 405 when method is not POST"() { - setup: - def emptySrcDir = new File('some_path') - def outputDir = TestFilesHelper.newOutputTestDirectory('http-mojo') - - def inputLatch = new CountDownLatch(1) - - def originalOut = System.out - def originalIn = System.in - - def newOut = new DoubleOutputStream(originalOut) - def newIn = new PrefilledInputStream('exit\r\nexit\r\nexit\r\n'.bytes, inputLatch) - - def httpPort = availablePort - - System.setOut(new PrintStream(newOut)) - System.setIn(newIn) - - def mojo = new AsciidoctorHttpMojo() - mojo.backend = 'html5' - mojo.port = httpPort - mojo.sourceDirectory = emptySrcDir - mojo.outputDirectory = outputDir - mojo.headerFooter = true - mojo.home = 'content' - def mojoThread = new Thread(new Runnable() { - @Override - void run() { - mojo.execute() - } - }) - mojoThread.start() - - while (!new String(newOut.toByteArray()).contains('Type ')) { - Thread.sleep(200) - } - - when: - HttpURLConnection connection = new URL("http://localhost:${httpPort}/").openConnection() - connection.setRequestMethod("POST") - def status = connection.getResponseCode() - - then: - status == 405 - - cleanup: - System.setOut(originalOut) - inputLatch.countDown() - System.setIn(originalIn) - awaitTermination(mojoThread) - } - - def "should return 205 when method is HEAD and resource exists"() { - setup: - def emptySrcDir = new File('some_path') - def outputDir = TestFilesHelper.newOutputTestDirectory('http-mojo') - TestFilesHelper.createFileWithContent(outputDir,'index.html') - - def inputLatch = new CountDownLatch(1) - - def originalOut = System.out - def originalIn = System.in - - def newOut = new DoubleOutputStream(originalOut) - def newIn = new PrefilledInputStream('exit\r\nexit\r\nexit\r\n'.bytes, inputLatch) - - def httpPort = availablePort - - System.setOut(new PrintStream(newOut)) - System.setIn(newIn) - - def mojo = new AsciidoctorHttpMojo() - mojo.backend = 'html5' - mojo.port = httpPort - mojo.sourceDirectory = emptySrcDir - mojo.outputDirectory = outputDir - mojo.headerFooter = true - mojo.home = 'index' - def mojoThread = new Thread(new Runnable() { - @Override - void run() { - mojo.execute() - } - }) - mojoThread.start() - - while (!new String(newOut.toByteArray()).contains('Type ')) { - Thread.sleep(200) - } - - when: - HttpURLConnection connection = new URL("http://localhost:${httpPort}/").openConnection() - connection.setRequestMethod("HEAD") - def status = connection.getResponseCode() - - then: - status == 205 - - cleanup: - System.setOut(originalOut) - inputLatch.countDown() - System.setIn(originalIn) - awaitTermination(mojoThread) - } - - private int getAvailablePort() { - ServerSocket socket = new ServerSocket(0) - int port = socket.getLocalPort() - socket.close() - return port - } - - @SneakyThrows - private void awaitTermination(Thread thread) { - int pollTime = 250; - int ticks = (10 * 1000 / pollTime); - while (thread.isAlive()) { - ticks--; - if (ticks == 0) - throw new InterruptedException("Max wait time reached"); - else - Thread.sleep(pollTime); - } - } -} diff --git a/src/test/java/org/asciidoctor/maven/AsciidoctorHttpMojoTest.java b/src/test/java/org/asciidoctor/maven/AsciidoctorHttpMojoTest.java new file mode 100644 index 00000000..f6e67e52 --- /dev/null +++ b/src/test/java/org/asciidoctor/maven/AsciidoctorHttpMojoTest.java @@ -0,0 +1,300 @@ +package org.asciidoctor.maven; + +import lombok.SneakyThrows; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.asciidoctor.maven.io.DoubleOutputStream; +import org.asciidoctor.maven.io.PrefilledInputStream; +import org.asciidoctor.maven.io.TestFilesHelper; +import org.junit.Test; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.ServerSocket; +import java.net.URL; +import java.util.concurrent.CountDownLatch; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.asciidoctor.maven.TestUtils.mockAsciidoctorHttpMojo; +import static org.assertj.core.api.Assertions.assertThat; + +public class AsciidoctorHttpMojoTest { + + + @Test + public void http_front_should_let_access_converted_files() throws IOException, InterruptedException { + // given + File srcDir = new File("target/test-classes/src/asciidoctor-http"); + File outputDir = TestFilesHelper.newOutputTestDirectory("http-mojo"); + + CountDownLatch inputLatch = new CountDownLatch(1); + PrintStream originalOut = System.out; + + ByteArrayOutputStream newOut = new DoubleOutputStream(originalOut); + InputStream newIn = new PrefilledInputStream("exit\r\n".getBytes(), inputLatch); + + System.setOut(new PrintStream(newOut)); + System.setIn(newIn); + + int httpPort = getAvailablePort(); + + File content = new File(srcDir, "content.asciidoc"); + FileUtils.write(content, "= Document Title\n\nThis is test, only a test.", UTF_8); + + AsciidoctorHttpMojo mojo = mockAsciidoctorHttpMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.port = httpPort; + mojo.home = "index"; + Thread mojoThread = new Thread(() -> { + try { + mojo.execute(); + } catch (MojoExecutionException | MojoFailureException e) { + e.printStackTrace(); + } + }); + mojoThread.start(); + + while (!new String(newOut.toByteArray()).contains("Type ")) { + Thread.sleep(200); + } + + // then + String html = responseContent("http://localhost:" + httpPort + "/content"); + assertThat(html) + .contains("This is test, only a test", ""); + + // cleanup + System.setOut(originalOut); + inputLatch.countDown(); + awaitTermination(mojoThread); + } + + @Test + public void should_return_default_page() throws IOException, InterruptedException { + // given + File srcDir = new File("target/test-classes/src/asciidoctor-http-default"); + File outputDir = TestFilesHelper.newOutputTestDirectory("http-mojo"); + + CountDownLatch inputLatch = new CountDownLatch(1); + PrintStream originalOut = System.out; + + ByteArrayOutputStream newOut = new DoubleOutputStream(originalOut); + InputStream newIn = new PrefilledInputStream("exit\r\nexit\r\nexit\r\n".getBytes(), inputLatch); + + int httpPort = getAvailablePort(); + + System.setOut(new PrintStream(newOut)); + System.setIn(newIn); + + File content = new File(srcDir, "content.asciidoc"); + FileUtils.write(content, "= Document Title\n\nDEFAULT", UTF_8); + + AsciidoctorHttpMojo mojo = mockAsciidoctorHttpMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.port = httpPort; + mojo.home = "content"; + Thread mojoThread = new Thread(() -> { + try { + mojo.execute(); + } catch (MojoExecutionException | MojoFailureException e) { + e.printStackTrace(); + } + }); + mojoThread.start(); + + while (!new String(newOut.toByteArray()).contains("Type ")) { + Thread.sleep(200); + } + + // when + assertThat(responseContent("http://localhost:" + httpPort + "/content")) + .contains("DEFAULT"); + + // cleanup + System.setOut(originalOut); + inputLatch.countDown(); + awaitTermination(mojoThread); + } + + @Test + public void should_return_404_when_file_does_not_exist() throws InterruptedException, IOException { + // given + File emptySrcDir = new File("some_path"); + File outputDir = TestFilesHelper.newOutputTestDirectory("http-mojo"); + + CountDownLatch inputLatch = new CountDownLatch(1); + PrintStream originalOut = System.out; + + ByteArrayOutputStream newOut = new DoubleOutputStream(originalOut); + InputStream newIn = new PrefilledInputStream("exit\r\nexit\r\nexit\r\n".getBytes(), inputLatch); + + int httpPort = getAvailablePort(); + + System.setOut(new PrintStream(newOut)); + System.setIn(newIn); + + AsciidoctorHttpMojo mojo = mockAsciidoctorHttpMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = emptySrcDir; + mojo.outputDirectory = outputDir; + mojo.port = httpPort; + mojo.home = "content"; + Thread mojoThread = new Thread(() -> { + try { + mojo.execute(); + } catch (MojoExecutionException | MojoFailureException e) { + e.printStackTrace(); + } + }); + mojoThread.start(); + + while (!new String(newOut.toByteArray()).contains("Type ")) { + Thread.sleep(200); + } + + // then + assertThat(responseStatus("http://localhost:" + httpPort, "GET")) + .isEqualTo(404); + + // cleanup + System.setOut(originalOut); + inputLatch.countDown(); + awaitTermination(mojoThread); + } + + @Test + public void should_return_405_when_method_is_not_POST() throws IOException, InterruptedException { + // given + File emptySrcDir = new File("some_path"); + File outputDir = TestFilesHelper.newOutputTestDirectory("http-mojo"); + + CountDownLatch inputLatch = new CountDownLatch(1); + PrintStream originalOut = System.out; + + ByteArrayOutputStream newOut = new DoubleOutputStream(originalOut); + InputStream newIn = new PrefilledInputStream("exit\r\nexit\r\nexit\r\n".getBytes(), inputLatch); + + int httpPort = getAvailablePort(); + + System.setOut(new PrintStream(newOut)); + System.setIn(newIn); + + AsciidoctorHttpMojo mojo = mockAsciidoctorHttpMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = emptySrcDir; + mojo.outputDirectory = outputDir; + mojo.port = httpPort; + mojo.home = "content"; + Thread mojoThread = new Thread(() -> { + try { + mojo.execute(); + } catch (MojoExecutionException | MojoFailureException e) { + e.printStackTrace(); + } + }); + mojoThread.start(); + + while (!new String(newOut.toByteArray()).contains("Type ")) { + Thread.sleep(200); + } + + // then + assertThat(responseStatus("http://localhost:" + httpPort, "POST")) + .isEqualTo(405); + + // cleanup + System.setOut(originalOut); + inputLatch.countDown(); + awaitTermination(mojoThread); + } + + @Test + public void should_return_205_when_method_is_HEAD_and_resource_exists() throws IOException, InterruptedException { + // given + File emptySrcDir = new File("some_path"); + File outputDir = TestFilesHelper.newOutputTestDirectory("http-mojo"); + TestFilesHelper.createFileWithContent(outputDir, "index.html"); + + CountDownLatch inputLatch = new CountDownLatch(1); + PrintStream originalOut = System.out; + + ByteArrayOutputStream newOut = new DoubleOutputStream(originalOut); + InputStream newIn = new PrefilledInputStream("exit\r\nexit\r\nexit\r\n".getBytes(), inputLatch); + + int httpPort = getAvailablePort(); + + System.setOut(new PrintStream(newOut)); + System.setIn(newIn); + + AsciidoctorHttpMojo mojo = mockAsciidoctorHttpMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = emptySrcDir; + mojo.outputDirectory = outputDir; + mojo.port = httpPort; + mojo.home = "index"; + Thread mojoThread = new Thread(() -> { + try { + mojo.execute(); + } catch (MojoExecutionException | MojoFailureException e) { + e.printStackTrace(); + } + }); + mojoThread.start(); + + while (!new String(newOut.toByteArray()).contains("Type ")) { + Thread.sleep(200); + } + + // when + assertThat(responseStatus("http://localhost:" + httpPort, "HEAD")) + .isEqualTo(205); + + // cleanup + System.setOut(originalOut); + inputLatch.countDown(); + awaitTermination(mojoThread); + } + + @SneakyThrows + private int responseStatus(String url, String httpMethod) { + final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setRequestMethod(httpMethod); + return connection.getResponseCode(); + } + + @SneakyThrows + private String responseContent(String url) { + try (final BufferedInputStream in = new BufferedInputStream(new URL(url).openStream()); + final ByteArrayOutputStream os = new ByteArrayOutputStream()) { + IOUtils.copy(in, os); + return new String(os.toByteArray()); + } + } + + @SneakyThrows + private int getAvailablePort() { + ServerSocket socket = new ServerSocket(0); + int port = socket.getLocalPort(); + socket.close(); + return port; + } + + @SneakyThrows + private void awaitTermination(Thread thread) { + int pollTime = 250; + int ticks = (10 * 1000 / pollTime); + while (thread.isAlive()) { + ticks--; + if (ticks == 0) + throw new InterruptedException("Max wait time reached"); + else + Thread.sleep(pollTime); + } + } +} diff --git a/src/test/java/org/asciidoctor/maven/TestUtils.java b/src/test/java/org/asciidoctor/maven/TestUtils.java index 8a430c1f..9db8d0dd 100644 --- a/src/test/java/org/asciidoctor/maven/TestUtils.java +++ b/src/test/java/org/asciidoctor/maven/TestUtils.java @@ -35,6 +35,11 @@ public static AsciidoctorMojo mockAsciidoctorMojo() { return mockAsciidoctorMojo(AsciidoctorMojo.class, null, null); } + @SneakyThrows + public static AsciidoctorHttpMojo mockAsciidoctorHttpMojo() { + return mockAsciidoctorMojo(AsciidoctorHttpMojo.class, null, null); + } + @SneakyThrows public static AsciidoctorMojo mockAsciidoctorMojo(Map mavenProperties) { return mockAsciidoctorMojo(AsciidoctorMojo.class, mavenProperties, null); diff --git a/src/test/java/org/asciidoctor/maven/io/DoubleOutputStream.java b/src/test/java/org/asciidoctor/maven/io/DoubleOutputStream.java index 5ccde241..4722e042 100644 --- a/src/test/java/org/asciidoctor/maven/io/DoubleOutputStream.java +++ b/src/test/java/org/asciidoctor/maven/io/DoubleOutputStream.java @@ -5,7 +5,7 @@ import java.io.ByteArrayOutputStream; import java.io.OutputStream; -class DoubleOutputStream extends ByteArrayOutputStream { +public class DoubleOutputStream extends ByteArrayOutputStream { final OutputStream other; diff --git a/src/test/java/org/asciidoctor/maven/io/PrefilledInputStream.java b/src/test/java/org/asciidoctor/maven/io/PrefilledInputStream.java index 71ee570f..21dc858d 100644 --- a/src/test/java/org/asciidoctor/maven/io/PrefilledInputStream.java +++ b/src/test/java/org/asciidoctor/maven/io/PrefilledInputStream.java @@ -5,11 +5,11 @@ import java.io.ByteArrayInputStream; import java.util.concurrent.CountDownLatch; -class PrefilledInputStream extends ByteArrayInputStream { +public class PrefilledInputStream extends ByteArrayInputStream { final CountDownLatch latch; - PrefilledInputStream(final byte[] buf, final CountDownLatch latch) { + public PrefilledInputStream(final byte[] buf, final CountDownLatch latch) { super(buf); this.latch = latch; }