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