From 18cecd077d6d3672806788e359a93365530403c4 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 20 Jan 2014 12:12:10 -0800 Subject: [PATCH] Move CLI integration tests into spring-boot-cli Use `maven-failsafe-plugin` to run CLI integration tests as part of the `spring-boot-cli` project, removing the need for `spring-boot-cli-integration-tests`. --- pom.xml | 1 - spring-boot-cli-integration-tests/pom.xml | 51 ------ .../boot/cli/it/UsabilityTests.java | 70 -------- .../boot/cli/it/infrastructure/Cli.java | 48 ------ .../cli/it/infrastructure/CliInvocation.java | 84 ---------- spring-boot-cli/pom.xml | 21 +++ .../boot/cli/CommandLineIT.java | 84 ++++++++++ .../infrastructure/CommandLineInvoker.java | 150 ++++++++++++++++++ spring-boot-parent/pom.xml | 11 ++ 9 files changed, 266 insertions(+), 254 deletions(-) delete mode 100644 spring-boot-cli-integration-tests/pom.xml delete mode 100644 spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/UsabilityTests.java delete mode 100644 spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/Cli.java delete mode 100644 spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/CliInvocation.java create mode 100644 spring-boot-cli/src/it/java/org/springframework/boot/cli/CommandLineIT.java create mode 100644 spring-boot-cli/src/it/java/org/springframework/boot/cli/infrastructure/CommandLineInvoker.java diff --git a/pom.xml b/pom.xml index c4279e4a38c..a5fc6365fc7 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,6 @@ spring-boot-integration-tests - spring-boot-cli-integration-tests diff --git a/spring-boot-cli-integration-tests/pom.xml b/spring-boot-cli-integration-tests/pom.xml deleted file mode 100644 index bc520793ffe..00000000000 --- a/spring-boot-cli-integration-tests/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-parent - 0.5.0.BUILD-SNAPSHOT - ../spring-boot-parent - - spring-boot-cli-integration-tests - - ${basedir}/.. - - - - junit - junit - test - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-resources - - unpack - - - - - ${project.groupId} - spring-boot-cli - ${project.version} - bin - zip - true - - - - - - - - - \ No newline at end of file diff --git a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/UsabilityTests.java b/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/UsabilityTests.java deleted file mode 100644 index 4387707acbe..00000000000 --- a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/UsabilityTests.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.springframework.boot.cli.it; - -import java.io.IOException; - -import org.junit.Test; -import org.springframework.boot.cli.it.infrastructure.Cli; -import org.springframework.boot.cli.it.infrastructure.CliInvocation; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Andy Wilkinson - */ -public class UsabilityTests { - - private final Cli cli = new Cli(); - - @Test - public void hintProducesListOfValidCommands() throws IOException, - InterruptedException { - CliInvocation cli = this.cli.invoke("hint"); - - assertEquals(0, cli.await()); - assertEquals(0, cli.getErrorOutput().length()); - assertEquals(6, cli.getStandardOutputLines().size()); - } - - @Test - public void invokingWithNoArgumentsDisplaysHelp() throws IOException, - InterruptedException { - CliInvocation cli = this.cli.invoke(); - - assertEquals(1, cli.await()); // TODO Should this be 0? Probably not. - assertEquals(0, cli.getErrorOutput().length()); - assertTrue(cli.getStandardOutput().startsWith("usage:")); - } - - @Test - public void unrecognizedCommandsAreHandledGracefully() throws IOException, - InterruptedException { - CliInvocation cli = this.cli.invoke("not-a-real-command"); - - assertEquals(1, cli.await()); - assertTrue( - cli.getErrorOutput(), - cli.getErrorOutput().contains( - "'not-a-real-command' is not a valid command")); - assertEquals(0, cli.getStandardOutput().length()); - } - - @Test - public void version() throws IOException, InterruptedException { - CliInvocation cli = this.cli.invoke("version"); - - assertEquals(0, cli.await()); - assertEquals(0, cli.getErrorOutput().length()); - assertTrue(cli.getStandardOutput(), - cli.getStandardOutput().startsWith("Spring CLI v")); - } - - @Test - public void help() throws IOException, InterruptedException { - CliInvocation cli = this.cli.invoke("help"); - - assertEquals(1, cli.await()); // TODO Should this be 0? Perhaps. - assertEquals(0, cli.getErrorOutput().length()); - assertTrue(cli.getStandardOutput().startsWith("usage:")); - } -} diff --git a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/Cli.java b/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/Cli.java deleted file mode 100644 index b9bc3b9a3ad..00000000000 --- a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/Cli.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.springframework.boot.cli.it.infrastructure; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author Andy Wilkinson - */ -public final class Cli { - - public CliInvocation invoke(String... args) throws IOException { - return new CliInvocation(launchCli(args)); - } - - private Process launchCli(String... args) throws IOException { - List arguments = Arrays.asList(args); - - List command = new ArrayList(); - command.add(findLaunchScript().getAbsolutePath()); - command.addAll(arguments); - - return new ProcessBuilder(command).start(); - } - - private File findLaunchScript() { - File dependencyDirectory = new File("target/dependency"); - if (dependencyDirectory.isDirectory()) { - File[] files = dependencyDirectory.listFiles(); - if (files.length == 1) { - File binDirectory = new File(files[0], "bin"); - if (isWindows()) { - return new File(binDirectory, "spring.bat"); - } - else { - return new File(binDirectory, "spring"); - } - } - } - throw new IllegalStateException("Could not find CLI launch script"); - } - - private boolean isWindows() { - return File.separatorChar == '\\'; - } -} diff --git a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/CliInvocation.java b/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/CliInvocation.java deleted file mode 100644 index c4580e0c6e0..00000000000 --- a/spring-boot-cli-integration-tests/src/test/java/org/springframework/boot/cli/it/infrastructure/CliInvocation.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.springframework.boot.cli.it.infrastructure; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Andy Wilkinson - */ -public final class CliInvocation { - - private final StringBuffer errorOutput = new StringBuffer(); - - private final StringBuffer standardOutput = new StringBuffer(); - - private final Process process; - - CliInvocation(Process process) { - this.process = process; - - new Thread(new StreamReadingRunnable(this.process.getErrorStream(), - this.errorOutput)).start(); - new Thread(new StreamReadingRunnable(this.process.getInputStream(), - this.standardOutput)).start(); - } - - public String getErrorOutput() { - return this.errorOutput.toString(); - } - - public String getStandardOutput() { - return this.standardOutput.toString(); - } - - public List getStandardOutputLines() { - BufferedReader reader = new BufferedReader(new StringReader( - this.standardOutput.toString())); - String line; - List lines = new ArrayList(); - try { - while ((line = reader.readLine()) != null) { - lines.add(line); - } - } - catch (IOException e) { - throw new RuntimeException("Failed to read standard output"); - } - return lines; - } - - public int await() throws InterruptedException { - return this.process.waitFor(); - } - - private final class StreamReadingRunnable implements Runnable { - - private final InputStream stream; - - private final StringBuffer output; - - private final byte[] buffer = new byte[4096]; - - private StreamReadingRunnable(InputStream stream, StringBuffer buffer) { - this.stream = stream; - this.output = buffer; - } - - public void run() { - int read; - try { - while ((read = this.stream.read(this.buffer)) > 0) { - this.output.append(new String(this.buffer, 0, read)); - } - } - catch (IOException e) { - // Allow thread to die - } - } - } - -} diff --git a/spring-boot-cli/pom.xml b/spring-boot-cli/pom.xml index aa5900a5df2..fbd691e6f5e 100644 --- a/spring-boot-cli/pom.xml +++ b/spring-boot-cli/pom.xml @@ -154,6 +154,9 @@ + + maven-failsafe-plugin + maven-surefire-plugin @@ -329,6 +332,24 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + add-test-source + process-resources + + add-test-source + + + + src/it/java + + + + + diff --git a/spring-boot-cli/src/it/java/org/springframework/boot/cli/CommandLineIT.java b/spring-boot-cli/src/it/java/org/springframework/boot/cli/CommandLineIT.java new file mode 100644 index 00000000000..a03985500c0 --- /dev/null +++ b/spring-boot-cli/src/it/java/org/springframework/boot/cli/CommandLineIT.java @@ -0,0 +1,84 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cli; + +import java.io.IOException; + +import org.junit.Test; +import org.springframework.boot.cli.infrastructure.CommandLineInvoker; +import org.springframework.boot.cli.infrastructure.CommandLineInvoker.Invocation; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; + +/** + * Integration Tests for the command line application. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +public class CommandLineIT { + + private final CommandLineInvoker cli = new CommandLineInvoker(); + + @Test + public void hintProducesListOfValidCommands() throws IOException, + InterruptedException { + Invocation cli = this.cli.invoke("hint"); + assertThat(cli.await(), equalTo(0)); + assertThat(cli.getErrorOutput().length(), equalTo(0)); + assertThat(cli.getStandardOutputLines().size(), equalTo(6)); + } + + @Test + public void invokingWithNoArgumentsDisplaysHelp() throws IOException, + InterruptedException { + Invocation cli = this.cli.invoke(); + assertThat(cli.await(), equalTo(1)); + assertThat(cli.getErrorOutput().length(), equalTo(0)); + assertThat(cli.getStandardOutput(), startsWith("usage:")); + } + + @Test + public void unrecognizedCommandsAreHandledGracefully() throws IOException, + InterruptedException { + Invocation cli = this.cli.invoke("not-a-real-command"); + assertThat(cli.await(), equalTo(1)); + assertThat(cli.getErrorOutput(), + containsString("'not-a-real-command' is not a valid command")); + assertThat(cli.getStandardOutput().length(), equalTo(0)); + } + + @Test + public void version() throws IOException, InterruptedException { + Invocation cli = this.cli.invoke("version"); + assertThat(cli.await(), equalTo(0)); + assertThat(cli.getErrorOutput().length(), equalTo(0)); + assertThat(cli.getStandardOutput(), startsWith("Spring CLI v")); + } + + @Test + public void help() throws IOException, InterruptedException { + Invocation cli = this.cli.invoke("help"); + assertThat(cli.await(), equalTo(1)); + assertThat(cli.getErrorOutput().length(), equalTo(0)); + assertThat(cli.getStandardOutput(), startsWith("usage:")); + } + +} diff --git a/spring-boot-cli/src/it/java/org/springframework/boot/cli/infrastructure/CommandLineInvoker.java b/spring-boot-cli/src/it/java/org/springframework/boot/cli/infrastructure/CommandLineInvoker.java new file mode 100644 index 00000000000..2665a4fcb8b --- /dev/null +++ b/spring-boot-cli/src/it/java/org/springframework/boot/cli/infrastructure/CommandLineInvoker.java @@ -0,0 +1,150 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.cli.infrastructure; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.util.Assert; + +/** + * Utility to invoke the command line in the same way as a user would, i.e. via the shell + * script in the package's bin directory. + * + * @author Andy Wilkinson + * @author Phillip Webb + */ +public final class CommandLineInvoker { + + public Invocation invoke(String... args) throws IOException { + return new Invocation(runCliProcess(args)); + } + + private Process runCliProcess(String... args) throws IOException { + List command = new ArrayList(); + command.add(findLaunchScript().getAbsolutePath()); + command.addAll(Arrays.asList(args)); + return new ProcessBuilder(command).start(); + } + + private File findLaunchScript() { + File dir = new File("target"); + dir = dir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isDirectory() && pathname.getName().contains("-bin"); + } + })[0]; + dir = new File(dir, dir.getName().replace("-bin", "") + .replace("spring-boot-cli", "spring")); + dir = new File(dir, "bin"); + File launchScript = new File(dir, isWindows() ? "spring.bat" : "spring"); + Assert.state(launchScript.exists() && launchScript.isFile(), + "Could not find CLI launch script " + launchScript.getAbsolutePath()); + return launchScript; + } + + private boolean isWindows() { + return File.separatorChar == '\\'; + } + + /** + * An ongoing CLI invocation. + */ + public final class Invocation { + + private final StringBuffer err = new StringBuffer(); + + private final StringBuffer out = new StringBuffer(); + + private final Process process; + + Invocation(Process process) { + this.process = process; + new Thread(new StreamReadingRunnable(this.process.getErrorStream(), this.err)) + .start(); + new Thread(new StreamReadingRunnable(this.process.getInputStream(), this.out)) + .start(); + } + + public String getErrorOutput() { + return this.err.toString(); + } + + public String getStandardOutput() { + return this.out.toString(); + } + + public List getStandardOutputLines() { + BufferedReader reader = new BufferedReader(new StringReader( + this.out.toString())); + String line; + List lines = new ArrayList(); + try { + while ((line = reader.readLine()) != null) { + lines.add(line); + } + } + catch (IOException e) { + throw new RuntimeException("Failed to read standard output"); + } + return lines; + } + + public int await() throws InterruptedException { + return this.process.waitFor(); + } + + /** + * {@link Runnable} to copy stream output. + */ + private final class StreamReadingRunnable implements Runnable { + + private final InputStream stream; + + private final StringBuffer output; + + private final byte[] buffer = new byte[4096]; + + private StreamReadingRunnable(InputStream stream, StringBuffer buffer) { + this.stream = stream; + this.output = buffer; + } + + public void run() { + int read; + try { + while ((read = this.stream.read(this.buffer)) > 0) { + this.output.append(new String(this.buffer, 0, read)); + } + } + catch (IOException ex) { + // Allow thread to die + } + } + } + + } + +} diff --git a/spring-boot-parent/pom.xml b/spring-boot-parent/pom.xml index 6959b15e91e..90a49575f45 100644 --- a/spring-boot-parent/pom.xml +++ b/spring-boot-parent/pom.xml @@ -233,6 +233,17 @@ maven-enforcer-plugin 1.3.1 + + maven-failsafe-plugin + + + + integration-test + verify + + + + maven-plugin-plugin 3.2