Relocate projects to spring-boot-project

Move projects to better reflect the way that Spring Boot is released.

The following projects are under `spring-boot-project`:

  - `spring-boot`
  - `spring-boot-autoconfigure`
  - `spring-boot-tools`
  - `spring-boot-starters`
  - `spring-boot-actuator`
  - `spring-boot-actuator-autoconfigure`
  - `spring-boot-test`
  - `spring-boot-test-autoconfigure`
  - `spring-boot-devtools`
  - `spring-boot-cli`
  - `spring-boot-docs`

See gh-9316
This commit is contained in:
Phillip Webb
2017-09-19 14:29:46 -07:00
parent 0419d42b7c
commit 0ba4830b4f
4023 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2012-2013 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 cli.command;
import org.springframework.boot.cli.command.AbstractCommand;
import org.springframework.boot.cli.command.status.ExitStatus;
/**
* @author Dave Syer
*/
public class CustomCommand extends AbstractCommand {
public CustomCommand() {
super("custom", "Custom command added in tests");
}
@Override
public ExitStatus run(String... args) throws Exception {
System.err.println("Custom Command Hello");
return ExitStatus.OK;
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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 cli.command;
import java.util.Collection;
import java.util.Collections;
import org.springframework.boot.cli.command.Command;
import org.springframework.boot.cli.command.CommandFactory;
/**
* @author Dave Syer
*/
public class CustomCommandFactory implements CommandFactory {
@Override
public Collection<Command> getCommands() {
return Collections.<Command>singleton(new CustomCommand());
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2012-2016 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 org.junit.Rule;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for CLI Classloader issues.
*
* @author Phillip Webb
*/
public class ClassLoaderIntegrationTests {
@Rule
public CliTester cli = new CliTester("src/test/resources/");
@Test
public void runWithIsolatedClassLoader() throws Exception {
// CLI classes or dependencies should not be exposed to the app
String output = this.cli.run("classloader-test-app.groovy",
SpringCli.class.getName());
assertThat(output).contains("HasClasses-false-true-false");
}
}

View File

@@ -0,0 +1,238 @@
/*
* Copyright 2012-2017 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.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.Assume;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springframework.boot.cli.command.AbstractCommand;
import org.springframework.boot.cli.command.OptionParsingCommand;
import org.springframework.boot.cli.command.archive.JarCommand;
import org.springframework.boot.cli.command.grab.GrabCommand;
import org.springframework.boot.cli.command.run.RunCommand;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.util.FileCopyUtils;
/**
* {@link TestRule} that can be used to invoke CLI commands.
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
*/
public class CliTester implements TestRule {
private final OutputCapture outputCapture = new OutputCapture();
private long timeout = TimeUnit.MINUTES.toMillis(6);
private final List<AbstractCommand> commands = new ArrayList<>();
private final String prefix;
public CliTester(String prefix) {
this.prefix = prefix;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
public String run(String... args) throws Exception {
List<String> updatedArgs = new ArrayList<>();
boolean classpathUpdated = false;
for (String arg : args) {
if (arg.startsWith("--classpath=")) {
arg = arg + ":" + new File("target/test-classes").getAbsolutePath();
classpathUpdated = true;
}
updatedArgs.add(arg);
}
if (!classpathUpdated) {
updatedArgs.add(
"--classpath=.:" + new File("target/test-classes").getAbsolutePath());
}
Future<RunCommand> future = submitCommand(new RunCommand(),
updatedArgs.toArray(new String[updatedArgs.size()]));
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
public String grab(String... args) throws Exception {
Future<GrabCommand> future = submitCommand(new GrabCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
public String jar(String... args) throws Exception {
Future<JarCommand> future = submitCommand(new JarCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
private <T extends OptionParsingCommand> Future<T> submitCommand(final T command,
String... args) {
clearUrlHandler();
final String[] sources = getSources(args);
return Executors.newSingleThreadExecutor().submit(() -> {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.setProperty("server.port", "0");
System.setProperty("spring.application.class.name",
"org.springframework.boot.cli.CliTesterSpringApplication");
System.setProperty("portfile",
new File("target/server.port").getAbsolutePath());
try {
command.run(sources);
return command;
}
finally {
System.clearProperty("server.port");
System.clearProperty("spring.application.class.name");
System.clearProperty("portfile");
Thread.currentThread().setContextClassLoader(loader);
}
});
}
/**
* The TomcatURLStreamHandlerFactory fails if the factory is already set, use
* reflection to reset it.
*/
private void clearUrlHandler() {
try {
Field field = URL.class.getDeclaredField("factory");
field.setAccessible(true);
field.set(null, null);
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
protected String[] getSources(String... args) {
final String[] sources = new String[args.length];
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (!arg.endsWith(".groovy") && !arg.endsWith(".xml")) {
if (new File(this.prefix + arg).isDirectory()) {
sources[i] = this.prefix + arg;
}
else {
sources[i] = arg;
}
}
else {
sources[i] = new File(arg).isAbsolute() ? arg : this.prefix + arg;
}
}
return sources;
}
private String getOutput() {
String output = this.outputCapture.toString();
this.outputCapture.reset();
return output;
}
@Override
public Statement apply(final Statement base, final Description description) {
final Statement statement = CliTester.this.outputCapture
.apply(new RunLauncherStatement(base), description);
return new Statement() {
@Override
public void evaluate() throws Throwable {
Assume.assumeTrue(
"Not running sample integration tests because integration profile not active",
System.getProperty("spring.profiles.active", "integration")
.contains("integration"));
statement.evaluate();
}
};
}
public String getHttpOutput() {
return getHttpOutput("/");
}
public String getHttpOutput(String uri) {
try {
int port = Integer.parseInt(
FileCopyUtils.copyToString(new FileReader("target/server.port")));
InputStream stream = URI.create("http://localhost:" + port + uri).toURL()
.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
StringBuilder result = new StringBuilder();
while ((line = reader.readLine()) != null) {
result.append(line);
}
return result.toString();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private final class RunLauncherStatement extends Statement {
private final Statement base;
private RunLauncherStatement(Statement base) {
this.base = base;
}
@Override
public void evaluate() throws Throwable {
System.setProperty("disableSpringSnapshotRepos", "false");
try {
try {
this.base.evaluate();
}
finally {
for (AbstractCommand command : CliTester.this.commands) {
if (command != null && command instanceof RunCommand) {
((RunCommand) command).stop();
}
}
System.clearProperty("disableSpringSnapshotRepos");
}
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2012-2017 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 org.springframework.boot.SpringApplication;
import org.springframework.boot.system.EmbeddedServerPortFileWriter;
import org.springframework.context.ConfigurableApplicationContext;
/**
* Custom {@link SpringApplication} used by {@link CliTester}.
*
* @author Andy Wilkinson
*/
public class CliTesterSpringApplication extends SpringApplication {
public CliTesterSpringApplication(Class<?>... sources) {
super(sources);
}
@Override
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
context.addApplicationListener(new EmbeddedServerPortFileWriter());
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2012-2017 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 org.junit.Rule;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for code in directories.
*
* @author Dave Syer
*/
public class DirectorySourcesIntegrationTests {
@Rule
public CliTester cli = new CliTester("src/test/resources/dir-sample/");
@Test
public void runDirectory() throws Exception {
assertThat(this.cli.run("code")).contains("Hello World");
}
@Test
public void runDirectoryRecursive() throws Exception {
assertThat(this.cli.run("")).contains("Hello World");
}
@Test
public void runPathPattern() throws Exception {
assertThat(this.cli.run("**/*.groovy")).contains("Hello World");
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2012-2016 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.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.cli.command.grab.GrabCommand;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
/**
* Integration tests for {@link GrabCommand}
*
* @author Andy Wilkinson
* @author Dave Syer
*/
public class GrabCommandIntegrationTests {
@Rule
public CliTester cli = new CliTester("src/test/resources/grab-samples/");
@Before
@After
public void deleteLocalRepository() {
FileSystemUtils.deleteRecursively(new File("target/repository"));
System.clearProperty("grape.root");
System.clearProperty("groovy.grape.report.downloads");
}
@Test
public void grab() throws Exception {
System.setProperty("grape.root", "target");
System.setProperty("groovy.grape.report.downloads", "true");
// Use --autoconfigure=false to limit the amount of downloaded dependencies
String output = this.cli.grab("grab.groovy", "--autoconfigure=false");
assertThat(new File("target/repository/joda-time/joda-time").isDirectory())
.isTrue();
// Should be resolved from local repository cache
assertThat(output.contains("Downloading: file:")).isTrue();
}
@Test
public void duplicateDependencyManagementBomAnnotationsProducesAnError()
throws Exception {
try {
this.cli.grab("duplicateDependencyManagementBom.groovy");
fail();
}
catch (Exception ex) {
assertThat(ex.getMessage())
.contains("Duplicate @DependencyManagementBom annotation");
}
}
@Test
public void customMetadata() throws Exception {
System.setProperty("grape.root", "target");
FileSystemUtils.copyRecursively(
new File("src/test/resources/grab-samples/repository"),
new File("target/repository"));
this.cli.grab("customDependencyManagement.groovy", "--autoconfigure=false");
assertThat(new File("target/repository/javax/ejb/ejb-api/3.0").isDirectory())
.isTrue();
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2012-2017 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 org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests to exercise and reproduce specific issues.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
public class ReproIntegrationTests {
@Rule
public CliTester cli = new CliTester("src/test/resources/repro-samples/");
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void grabAntBuilder() throws Exception {
this.cli.run("grab-ant-builder.groovy");
assertThat(this.cli.getHttpOutput()).contains("{\"message\":\"Hello World\"}");
}
// Security depends on old versions of Spring so if the dependencies aren't pinned
// this will fail
@Test
public void securityDependencies() throws Exception {
assertThat(this.cli.run("secure.groovy")).contains("Hello World");
}
@Test
public void dataJpaDependencies() throws Exception {
assertThat(this.cli.run("data-jpa.groovy")).contains("Hello World");
}
@Test
public void jarFileExtensionNeeded() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("is not a JAR file");
this.cli.jar("secure.groovy", "data-jpa.groovy");
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2012-2017 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.util.Properties;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.cli.command.run.RunCommand;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link RunCommand}.
*
* @author Andy Wilkinson
*/
public class RunCommandIntegrationTests {
@Rule
public CliTester cli = new CliTester("src/it/resources/run-command/");
private Properties systemProperties = new Properties();
@Before
public void captureSystemProperties() {
this.systemProperties.putAll(System.getProperties());
}
@After
public void restoreSystemProperties() {
System.setProperties(this.systemProperties);
}
@Test
public void bannerAndLoggingIsOutputByDefault() throws Exception {
String output = this.cli.run("quiet.groovy");
assertThat(output).contains(" :: Spring Boot ::");
assertThat(output).contains("Starting application");
assertThat(output).contains("Ssshh");
}
@Test
public void quietModeSuppressesAllCliOutput() throws Exception {
this.cli.run("quiet.groovy");
String output = this.cli.run("quiet.groovy", "-q");
assertThat(output).isEqualTo("Ssshh");
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright 2012-2017 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.File;
import java.net.URI;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests to exercise the samples.
*
* @author Dave Syer
* @author Greg Turnquist
* @author Roy Clarkson
* @author Phillip Webb
*/
public class SampleIntegrationTests {
@Rule
public CliTester cli = new CliTester("samples/");
@Test
public void appSample() throws Exception {
String output = this.cli.run("app.groovy");
URI scriptUri = new File("samples/app.groovy").toURI();
assertThat(output).contains("Hello World! From " + scriptUri);
}
@Test
public void retrySample() throws Exception {
String output = this.cli.run("retry.groovy");
URI scriptUri = new File("samples/retry.groovy").toURI();
assertThat(output).contains("Hello World! From " + scriptUri);
}
@Test
public void beansSample() throws Exception {
this.cli.run("beans.groovy");
String output = this.cli.getHttpOutput();
assertThat(output).contains("Hello World!");
}
@Test
public void templateSample() throws Exception {
String output = this.cli.run("template.groovy");
assertThat(output).contains("Hello World!");
}
@Test
public void jobSample() throws Exception {
String output = this.cli.run("job.groovy", "foo=bar");
assertThat(output).contains("completed with the following parameters");
}
@Test
public void jobWebSample() throws Exception {
String output = this.cli.run("job.groovy", "web.groovy", "foo=bar");
assertThat(output).contains("completed with the following parameters");
String result = this.cli.getHttpOutput();
assertThat(result).isEqualTo("World!");
}
@Test
public void webSample() throws Exception {
this.cli.run("web.groovy");
assertThat(this.cli.getHttpOutput()).isEqualTo("World!");
}
@Test
public void uiSample() throws Exception {
this.cli.run("ui.groovy", "--classpath=.:src/test/resources");
String result = this.cli.getHttpOutput();
assertThat(result).contains("Hello World");
result = this.cli.getHttpOutput("/css/bootstrap.min.css");
assertThat(result).contains("container");
}
@Test
public void actuatorSample() throws Exception {
this.cli.run("actuator.groovy");
assertThat(this.cli.getHttpOutput()).isEqualTo("{\"message\":\"Hello World!\"}");
}
@Test
public void httpSample() throws Exception {
String output = this.cli.run("http.groovy");
assertThat(output).contains("Hello World");
}
@Test
public void integrationSample() throws Exception {
String output = this.cli.run("integration.groovy");
assertThat(output).contains("Hello, World");
}
@Test
public void xmlSample() throws Exception {
String output = this.cli.run("runner.xml", "runner.groovy");
assertThat(output).contains("Hello World");
}
@Test
public void txSample() throws Exception {
String output = this.cli.run("tx.groovy");
assertThat(output).contains("Foo count=");
}
@Test
public void jmsSample() throws Exception {
System.setProperty("spring.artemis.embedded.queues", "spring-boot");
try {
String output = this.cli.run("jms.groovy");
assertThat(output)
.contains("Received Greetings from Spring Boot via Artemis");
}
finally {
System.clearProperty("spring.artemis.embedded.queues");
}
}
@Test
@Ignore("Requires RabbitMQ to be run, so disable it be default")
public void rabbitSample() throws Exception {
String output = this.cli.run("rabbit.groovy");
assertThat(output).contains("Received Greetings from Spring Boot via RabbitMQ");
}
@Test
public void deviceSample() throws Exception {
this.cli.run("device.groovy");
assertThat(this.cli.getHttpOutput()).isEqualTo("Hello Normal Device!");
}
@Test
public void caching() throws Exception {
assertThat(this.cli.run("caching.groovy")).contains("Hello World");
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2012-2017 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.app;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link SpringApplicationLauncher}
*
* @author Andy Wilkinson
*/
public class SpringApplicationLauncherTests {
private Map<String, String> env = new HashMap<>();
@After
public void cleanUp() {
System.clearProperty("spring.application.class.name");
}
@Test
public void defaultLaunch() throws Exception {
assertThat(launch()).contains("org.springframework.boot.SpringApplication");
}
@Test
public void launchWithClassConfiguredBySystemProperty() {
System.setProperty("spring.application.class.name",
"system.property.SpringApplication");
assertThat(launch()).contains("system.property.SpringApplication");
}
@Test
public void launchWithClassConfiguredByEnvironmentVariable() {
this.env.put("SPRING_APPLICATION_CLASS_NAME",
"environment.variable.SpringApplication");
assertThat(launch()).contains("environment.variable.SpringApplication");
}
@Test
public void systemPropertyOverridesEnvironmentVariable() {
System.setProperty("spring.application.class.name",
"system.property.SpringApplication");
this.env.put("SPRING_APPLICATION_CLASS_NAME",
"environment.variable.SpringApplication");
assertThat(launch()).contains("system.property.SpringApplication");
}
@Test
public void sourcesDefaultPropertiesAndArgsAreUsedToLaunch() throws Exception {
System.setProperty("spring.application.class.name",
TestSpringApplication.class.getName());
Class<?>[] sources = new Class<?>[0];
String[] args = new String[0];
new SpringApplicationLauncher(getClass().getClassLoader()).launch(sources, args);
assertThat(sources == TestSpringApplication.sources).isTrue();
assertThat(args == TestSpringApplication.args).isTrue();
Map<String, String> defaultProperties = TestSpringApplication.defaultProperties;
assertThat(defaultProperties).hasSize(1)
.containsEntry("spring.groovy.template.check-template-location", "false");
}
private Set<String> launch() {
TestClassLoader classLoader = new TestClassLoader(getClass().getClassLoader());
try {
new TestSpringApplicationLauncher(classLoader).launch(new Class<?>[0],
new String[0]);
}
catch (Exception ex) {
// Launch will fail, but we can still check that the launcher tried to use
// the right class
}
return classLoader.classes;
}
private static class TestClassLoader extends ClassLoader {
private Set<String> classes = new HashSet<>();
TestClassLoader(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
this.classes.add(name);
return super.loadClass(name, resolve);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
this.classes.add(name);
return super.findClass(name);
}
}
public static class TestSpringApplication {
private static Object[] sources;
private static Map<String, String> defaultProperties;
private static String[] args;
public TestSpringApplication(Class<?>[] sources) {
TestSpringApplication.sources = sources;
}
public void setDefaultProperties(Map<String, String> defaultProperties) {
TestSpringApplication.defaultProperties = defaultProperties;
}
public void run(String[] args) {
TestSpringApplication.args = args;
}
}
private class TestSpringApplicationLauncher extends SpringApplicationLauncher {
TestSpringApplicationLauncher(ClassLoader classLoader) {
super(classLoader);
}
@Override
protected String getEnvironmentVariable(String name) {
String variable = SpringApplicationLauncherTests.this.env.get(name);
if (variable == null) {
variable = super.getEnvironmentVariable(name);
}
return variable;
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2012-2016 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.command;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.cli.command.run.RunCommand;
import org.springframework.boot.test.rule.OutputCapture;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
*/
public class CommandRunnerIntegrationTests {
@Rule
public OutputCapture output = new OutputCapture();
@Test
public void debugAddsAutoconfigReport() {
CommandRunner runner = new CommandRunner("spring");
runner.addCommand(new RunCommand());
// -d counts as "debug" for the spring command, but not for the
// LoggingApplicationListener
runner.runAndHandleErrors("run", "samples/app.groovy", "-d");
assertThat(this.output.toString()).contains("Negative matches:");
}
@Test
public void debugSwitchedOffForAppArgs() {
CommandRunner runner = new CommandRunner("spring");
runner.addCommand(new RunCommand());
runner.runAndHandleErrors("run", "samples/app.groovy", "--", "-d");
assertThat(this.output.toString()).doesNotContain("Negative matches:");
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright 2012-2017 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.command;
import java.util.EnumSet;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.cli.command.core.HelpCommand;
import org.springframework.boot.cli.command.core.HintCommand;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link CommandRunner}.
*
* @author Phillip Webb
* @author Dave Syer
*/
public class CommandRunnerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private CommandRunner commandRunner;
@Mock
private Command regularCommand;
@Mock
private Command shellCommand;
@Mock
private Command anotherCommand;
private final Set<Call> calls = EnumSet.noneOf(Call.class);
private ClassLoader loader;
@After
public void close() {
Thread.currentThread().setContextClassLoader(this.loader);
System.clearProperty("debug");
}
@Before
public void setup() {
this.loader = Thread.currentThread().getContextClassLoader();
MockitoAnnotations.initMocks(this);
this.commandRunner = new CommandRunner("spring") {
@Override
protected void showUsage() {
CommandRunnerTests.this.calls.add(Call.SHOW_USAGE);
super.showUsage();
}
@Override
protected boolean errorMessage(String message) {
CommandRunnerTests.this.calls.add(Call.ERROR_MESSAGE);
return super.errorMessage(message);
}
@Override
protected void printStackTrace(Exception ex) {
CommandRunnerTests.this.calls.add(Call.PRINT_STACK_TRACE);
super.printStackTrace(ex);
}
};
given(this.anotherCommand.getName()).willReturn("another");
given(this.regularCommand.getName()).willReturn("command");
given(this.regularCommand.getDescription()).willReturn("A regular command");
this.commandRunner.addCommand(this.regularCommand);
this.commandRunner.addCommand(new HelpCommand(this.commandRunner));
this.commandRunner.addCommand(new HintCommand(this.commandRunner));
}
@Test
public void runWithoutArguments() throws Exception {
this.thrown.expect(NoArgumentsException.class);
this.commandRunner.run();
}
@Test
public void runCommand() throws Exception {
this.commandRunner.run("command", "--arg1", "arg2");
verify(this.regularCommand).run("--arg1", "arg2");
}
@Test
public void missingCommand() throws Exception {
this.thrown.expect(NoSuchCommandException.class);
this.commandRunner.run("missing");
}
@Test
public void appArguments() throws Exception {
this.commandRunner.runAndHandleErrors("command", "--", "--debug", "bar");
verify(this.regularCommand).run("--", "--debug", "bar");
// When handled by the command itself it shouldn't cause the system property to be
// set
assertThat(System.getProperty("debug")).isNull();
}
@Test
public void handlesSuccess() throws Exception {
int status = this.commandRunner.runAndHandleErrors("command");
assertThat(status).isEqualTo(0);
assertThat(this.calls).isEmpty();
}
@Test
public void handlesNoSuchCommand() throws Exception {
int status = this.commandRunner.runAndHandleErrors("missing");
assertThat(status).isEqualTo(1);
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE);
}
@Test
public void handlesRegularExceptionWithMessage() throws Exception {
willThrow(new RuntimeException("With Message")).given(this.regularCommand).run();
int status = this.commandRunner.runAndHandleErrors("command");
assertThat(status).isEqualTo(1);
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE);
}
@Test
public void handlesRegularExceptionWithoutMessage() throws Exception {
willThrow(new NullPointerException()).given(this.regularCommand).run();
int status = this.commandRunner.runAndHandleErrors("command");
assertThat(status).isEqualTo(1);
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE, Call.PRINT_STACK_TRACE);
}
@Test
public void handlesExceptionWithDashD() throws Exception {
willThrow(new RuntimeException()).given(this.regularCommand).run();
int status = this.commandRunner.runAndHandleErrors("command", "-d");
assertThat(System.getProperty("debug")).isEqualTo("true");
assertThat(status).isEqualTo(1);
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE, Call.PRINT_STACK_TRACE);
}
@Test
public void handlesExceptionWithDashDashDebug() throws Exception {
willThrow(new RuntimeException()).given(this.regularCommand).run();
int status = this.commandRunner.runAndHandleErrors("command", "--debug");
assertThat(System.getProperty("debug")).isEqualTo("true");
assertThat(status).isEqualTo(1);
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE, Call.PRINT_STACK_TRACE);
}
@Test
public void exceptionMessages() throws Exception {
assertThat(new NoSuchCommandException("name").getMessage())
.isEqualTo("'name' is not a valid command. See 'help'.");
}
@Test
public void help() throws Exception {
this.commandRunner.run("help", "command");
verify(this.regularCommand).getHelp();
}
@Test
public void helpNoCommand() throws Exception {
this.thrown.expect(NoHelpCommandArgumentsException.class);
this.commandRunner.run("help");
}
@Test
public void helpUnknownCommand() throws Exception {
this.thrown.expect(NoSuchCommandException.class);
this.commandRunner.run("help", "missing");
}
private enum Call {
SHOW_USAGE, ERROR_MESSAGE, PRINT_STACK_TRACE
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2012-2016 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.command;
import org.junit.Test;
import org.springframework.boot.cli.command.options.OptionHandler;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OptionParsingCommand}.
*
* @author Dave Syer
*/
public class OptionParsingCommandTests {
@Test
public void optionHelp() {
OptionHandler handler = new OptionHandler();
handler.option("bar", "Bar");
OptionParsingCommand command = new TestOptionParsingCommand("foo", "Foo",
handler);
assertThat(command.getHelp()).contains("--bar");
}
private static class TestOptionParsingCommand extends OptionParsingCommand {
TestOptionParsingCommand(String name, String description, OptionHandler handler) {
super(name, description, handler);
}
}
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright 2012-2017 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.command.archive;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.assertj.core.api.Condition;
import org.junit.Test;
import org.springframework.boot.cli.command.archive.ResourceMatcher.MatchedResource;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ResourceMatcher}.
*
* @author Andy Wilkinson
*/
public class ResourceMatcherTests {
@Test
public void nonExistentRoot() throws IOException {
ResourceMatcher resourceMatcher = new ResourceMatcher(
Arrays.asList("alpha/**", "bravo/*", "*"),
Arrays.asList(".*", "alpha/**/excluded"));
List<MatchedResource> matchedResources = resourceMatcher
.find(Arrays.asList(new File("does-not-exist")));
assertThat(matchedResources).isEmpty();
}
@SuppressWarnings("unchecked")
@Test
public void defaults() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList(""),
Arrays.asList(""));
Collection<String> includes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "includes");
Collection<String> excludes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "excludes");
assertThat(includes).contains("static/**");
assertThat(excludes).contains("**/*.jar");
}
@Test
public void excludedWins() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("*"),
Arrays.asList("**/*.jar"));
List<MatchedResource> found = resourceMatcher
.find(Arrays.asList(new File("src/test/resources")));
assertThat(found).areNot(new Condition<MatchedResource>() {
@Override
public boolean matches(MatchedResource value) {
return value.getFile().getName().equals("foo.jar");
}
});
}
@SuppressWarnings("unchecked")
@Test
public void includedDeltas() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("-static/**"),
Arrays.asList(""));
Collection<String> includes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "includes");
assertThat(includes).contains("templates/**");
assertThat(includes).doesNotContain("static/**");
}
@SuppressWarnings("unchecked")
@Test
public void includedDeltasAndNewEntries() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(
Arrays.asList("-static/**", "foo.jar"), Arrays.asList("-**/*.jar"));
Collection<String> includes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "includes");
Collection<String> excludes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "excludes");
assertThat(includes).contains("foo.jar");
assertThat(includes).contains("templates/**");
assertThat(includes).doesNotContain("static/**");
assertThat(excludes).doesNotContain("**/*.jar");
}
@SuppressWarnings("unchecked")
@Test
public void excludedDeltas() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList(""),
Arrays.asList("-**/*.jar"));
Collection<String> excludes = (Collection<String>) ReflectionTestUtils
.getField(resourceMatcher, "excludes");
assertThat(excludes).doesNotContain("**/*.jar");
}
@Test
public void jarFileAlwaysMatches() throws Exception {
ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("*"),
Arrays.asList("**/*.jar"));
List<MatchedResource> found = resourceMatcher
.find(Arrays.asList(new File("src/test/resources/templates"),
new File("src/test/resources/foo.jar")));
assertThat(found).areAtLeastOne(new Condition<MatchedResource>() {
@Override
public boolean matches(MatchedResource value) {
return value.getFile().getName().equals("foo.jar") && value.isRoot();
}
});
}
@Test
public void resourceMatching() throws IOException {
ResourceMatcher resourceMatcher = new ResourceMatcher(
Arrays.asList("alpha/**", "bravo/*", "*"),
Arrays.asList(".*", "alpha/**/excluded"));
List<MatchedResource> matchedResources = resourceMatcher
.find(Arrays.asList(new File("src/test/resources/resource-matcher/one"),
new File("src/test/resources/resource-matcher/two"),
new File("src/test/resources/resource-matcher/three")));
List<String> paths = new ArrayList<>();
for (MatchedResource resource : matchedResources) {
paths.add(resource.getName());
}
assertThat(paths).containsOnly("alpha/nested/fileA", "bravo/fileC", "fileD",
"bravo/fileE", "fileF", "three");
}
}

View File

@@ -0,0 +1,215 @@
/*
* Copyright 2012-2017 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.command.init;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.json.JSONException;
import org.json.JSONObject;
import org.mockito.ArgumentMatcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Abstract base class for tests that use a mock {@link CloseableHttpClient}.
*
* @author Stephane Nicoll
*/
public abstract class AbstractHttpClientMockTests {
protected final CloseableHttpClient http = mock(CloseableHttpClient.class);
protected void mockSuccessfulMetadataTextGet() throws IOException {
mockSuccessfulMetadataGet("metadata/service-metadata-2.1.0.txt", "text/plain",
true);
}
protected void mockSuccessfulMetadataGet(boolean serviceCapabilities)
throws IOException {
mockSuccessfulMetadataGet("metadata/service-metadata-2.1.0.json",
"application/vnd.initializr.v2.1+json", serviceCapabilities);
}
protected void mockSuccessfulMetadataGetV2(boolean serviceCapabilities)
throws IOException {
mockSuccessfulMetadataGet("metadata/service-metadata-2.0.0.json",
"application/vnd.initializr.v2+json", serviceCapabilities);
}
protected void mockSuccessfulMetadataGet(String contentPath, String contentType,
boolean serviceCapabilities) throws IOException {
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
byte[] content = readClasspathResource(contentPath);
mockHttpEntity(response, content, contentType);
mockStatus(response, 200);
given(this.http.execute(argThat(getForMetadata(serviceCapabilities))))
.willReturn(response);
}
protected byte[] readClasspathResource(String contentPath) throws IOException {
Resource resource = new ClassPathResource(contentPath);
return StreamUtils.copyToByteArray(resource.getInputStream());
}
protected void mockSuccessfulProjectGeneration(
MockHttpProjectGenerationRequest request) throws IOException {
// Required for project generation as the metadata is read first
mockSuccessfulMetadataGet(false);
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockHttpEntity(response, request.content, request.contentType);
mockStatus(response, 200);
String header = (request.fileName != null
? contentDispositionValue(request.fileName) : null);
mockHttpHeader(response, "Content-Disposition", header);
given(this.http.execute(argThat(getForNonMetadata()))).willReturn(response);
}
protected void mockProjectGenerationError(int status, String message)
throws IOException, JSONException {
// Required for project generation as the metadata is read first
mockSuccessfulMetadataGet(false);
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockHttpEntity(response, createJsonError(status, message).getBytes(),
"application/json");
mockStatus(response, status);
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
}
protected void mockMetadataGetError(int status, String message)
throws IOException, JSONException {
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockHttpEntity(response, createJsonError(status, message).getBytes(),
"application/json");
mockStatus(response, status);
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
}
protected HttpEntity mockHttpEntity(CloseableHttpResponse response, byte[] content,
String contentType) {
try {
HttpEntity entity = mock(HttpEntity.class);
given(entity.getContent()).willReturn(new ByteArrayInputStream(content));
Header contentTypeHeader = contentType != null
? new BasicHeader("Content-Type", contentType) : null;
given(entity.getContentType()).willReturn(contentTypeHeader);
given(response.getEntity()).willReturn(entity);
return entity;
}
catch (IOException ex) {
throw new IllegalStateException("Should not happen", ex);
}
}
protected void mockStatus(CloseableHttpResponse response, int status) {
StatusLine statusLine = mock(StatusLine.class);
given(statusLine.getStatusCode()).willReturn(status);
given(response.getStatusLine()).willReturn(statusLine);
}
protected void mockHttpHeader(CloseableHttpResponse response, String headerName,
String value) {
Header header = value != null ? new BasicHeader(headerName, value) : null;
given(response.getFirstHeader(headerName)).willReturn(header);
}
private ArgumentMatcher<HttpGet> getForMetadata(boolean serviceCapabilities) {
if (!serviceCapabilities) {
return new HasAcceptHeader(InitializrService.ACCEPT_META_DATA, true);
}
return new HasAcceptHeader(InitializrService.ACCEPT_SERVICE_CAPABILITIES, true);
}
private ArgumentMatcher<HttpGet> getForNonMetadata() {
return new HasAcceptHeader(InitializrService.ACCEPT_META_DATA, false);
}
private String contentDispositionValue(String fileName) {
return "attachment; filename=\"" + fileName + "\"";
}
private String createJsonError(int status, String message) throws JSONException {
JSONObject json = new JSONObject();
json.put("status", status);
if (message != null) {
json.put("message", message);
}
return json.toString();
}
protected static class MockHttpProjectGenerationRequest {
String contentType;
String fileName;
byte[] content = new byte[] { 0, 0, 0, 0 };
public MockHttpProjectGenerationRequest(String contentType, String fileName) {
this(contentType, fileName, new byte[] { 0, 0, 0, 0 });
}
public MockHttpProjectGenerationRequest(String contentType, String fileName,
byte[] content) {
this.contentType = contentType;
this.fileName = fileName;
this.content = content;
}
}
private static class HasAcceptHeader implements ArgumentMatcher<HttpGet> {
private final String value;
private final boolean shouldMatch;
HasAcceptHeader(String value, boolean shouldMatch) {
this.value = value;
this.shouldMatch = shouldMatch;
}
@Override
public boolean matches(HttpGet get) {
if (get == null) {
return false;
}
Header acceptHeader = get.getFirstHeader(HttpHeaders.ACCEPT);
if (this.shouldMatch) {
return acceptHeader != null && this.value.equals(acceptHeader.getValue());
}
return acceptHeader == null || !this.value.equals(acceptHeader.getValue());
}
}
}

View File

@@ -0,0 +1,403 @@
/*
* Copyright 2012-2017 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.command.init;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import joptsimple.OptionSet;
import org.apache.http.Header;
import org.apache.http.client.methods.HttpUriRequest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.cli.command.status.ExitStatus;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link InitCommand}
*
* @author Stephane Nicoll
* @author Eddú Meléndez
*/
public class InitCommandTests extends AbstractHttpClientMockTests {
@Rule
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
private final TestableInitCommandOptionHandler handler;
private final InitCommand command;
@Captor
private ArgumentCaptor<HttpUriRequest> requestCaptor;
@Before
public void setupMocks() {
MockitoAnnotations.initMocks(this);
}
public InitCommandTests() {
InitializrService initializrService = new InitializrService(this.http);
this.handler = new TestableInitCommandOptionHandler(initializrService);
this.command = new InitCommand(this.handler);
}
@Test
public void listServiceCapabilitiesText() throws Exception {
mockSuccessfulMetadataTextGet();
this.command.run("--list", "--target=http://fake-service");
}
@Test
public void listServiceCapabilities() throws Exception {
mockSuccessfulMetadataGet(true);
this.command.run("--list", "--target=http://fake-service");
}
@Test
public void listServiceCapabilitiesV2() throws Exception {
mockSuccessfulMetadataGetV2(true);
this.command.run("--list", "--target=http://fake-service");
}
@Test
public void generateProject() throws Exception {
String fileName = UUID.randomUUID().toString() + ".zip";
File file = new File(fileName);
assertThat(file.exists()).as("file should not exist").isFalse();
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", fileName);
mockSuccessfulProjectGeneration(request);
try {
assertThat(this.command.run()).isEqualTo(ExitStatus.OK);
assertThat(file.exists()).as("file should have been created").isTrue();
}
finally {
assertThat(file.delete()).as("failed to delete test file").isTrue();
}
}
@Test
public void generateProjectNoFileNameAvailable() throws Exception {
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", null);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run()).isEqualTo(ExitStatus.ERROR);
}
@Test
public void generateProjectAndExtract() throws Exception {
File folder = this.temporaryFolder.newFolder();
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.OK);
File archiveFile = new File(folder, "test.txt");
assertThat(archiveFile).exists();
}
@Test
public void generateProjectAndExtractWithConvention() throws Exception {
File folder = this.temporaryFolder.newFolder();
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run(folder.getAbsolutePath() + "/"))
.isEqualTo(ExitStatus.OK);
File archiveFile = new File(folder, "test.txt");
assertThat(archiveFile).exists();
}
@Test
public void generateProjectArchiveExtractedByDefault() throws Exception {
String fileName = UUID.randomUUID().toString();
assertThat(fileName.contains(".")).as("No dot in filename").isFalse();
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
File file = new File(fileName);
File archiveFile = new File(file, "test.txt");
try {
assertThat(this.command.run(fileName)).isEqualTo(ExitStatus.OK);
assertThat(archiveFile).exists();
}
finally {
archiveFile.delete();
file.delete();
}
}
@Test
public void generateProjectFileSavedAsFileByDefault() throws Exception {
String fileName = UUID.randomUUID().toString();
String content = "Fake Content";
byte[] archive = content.getBytes();
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/octet-stream", "pom.xml", archive);
mockSuccessfulProjectGeneration(request);
File file = new File(fileName);
try {
assertThat(this.command.run(fileName)).isEqualTo(ExitStatus.OK);
assertThat(file.exists()).as("File not saved properly").isTrue();
assertThat(file.isFile()).as("Should not be a directory").isTrue();
}
finally {
file.delete();
}
}
@Test
public void generateProjectAndExtractUnsupportedArchive() throws Exception {
File folder = this.temporaryFolder.newFolder();
String fileName = UUID.randomUUID().toString() + ".zip";
File file = new File(fileName);
assertThat(file.exists()).as("file should not exist").isFalse();
try {
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/foobar", fileName, archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.OK);
assertThat(file.exists()).as("file should have been saved instead").isTrue();
}
finally {
assertThat(file.delete()).as("failed to delete test file").isTrue();
}
}
@Test
public void generateProjectAndExtractUnknownContentType() throws Exception {
File folder = this.temporaryFolder.newFolder();
String fileName = UUID.randomUUID().toString() + ".zip";
File file = new File(fileName);
assertThat(file.exists()).as("file should not exist").isFalse();
try {
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
null, fileName, archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.OK);
assertThat(file.exists()).as("file should have been saved instead").isTrue();
}
finally {
assertThat(file.delete()).as("failed to delete test file").isTrue();
}
}
@Test
public void fileNotOverwrittenByDefault() throws Exception {
File file = this.temporaryFolder.newFile();
long fileLength = file.length();
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", file.getAbsolutePath());
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run()).as("Should have failed")
.isEqualTo(ExitStatus.ERROR);
assertThat(file.length()).as("File should not have changed")
.isEqualTo(fileLength);
}
@Test
public void overwriteFile() throws Exception {
File file = this.temporaryFolder.newFile();
long fileLength = file.length();
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", file.getAbsolutePath());
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--force")).isEqualTo(ExitStatus.OK);
assertThat(fileLength != file.length()).as("File should have changed").isTrue();
}
@Test
public void fileInArchiveNotOverwrittenByDefault() throws Exception {
File folder = this.temporaryFolder.newFolder();
File conflict = new File(folder, "test.txt");
assertThat(conflict.createNewFile()).as("Should have been able to create file")
.isTrue();
long fileLength = conflict.length();
// also contains test.txt
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.ERROR);
assertThat(conflict.length()).as("File should not have changed")
.isEqualTo(fileLength);
}
@Test
public void parseProjectOptions() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("-g=org.demo", "-a=acme", "-v=1.2.3-SNAPSHOT", "-n=acme-sample",
"--description=Acme sample project", "--package-name=demo.foo",
"-t=ant-project", "--build=grunt", "--format=web", "-p=war", "-j=1.9",
"-l=groovy", "-b=1.2.0.RELEASE", "-d=web,data-jpa");
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
assertThat(this.handler.lastRequest.getDescription())
.isEqualTo("Acme sample project");
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
List<String> dependencies = this.handler.lastRequest.getDependencies();
assertThat(dependencies).hasSize(2);
assertThat(dependencies.contains("web")).isTrue();
assertThat(dependencies.contains("data-jpa")).isTrue();
}
@Test
public void overwriteFileInArchive() throws Exception {
File folder = this.temporaryFolder.newFolder();
File conflict = new File(folder, "test.txt");
assertThat(conflict.createNewFile()).as("Should have been able to create file")
.isTrue();
long fileLength = conflict.length();
// also contains test.txt
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(
"application/zip", "demo.zip", archive);
mockSuccessfulProjectGeneration(request);
assertThat(this.command.run("--force", "--extract", folder.getAbsolutePath()))
.isEqualTo(ExitStatus.OK);
assertThat(fileLength != conflict.length()).as("File should have changed")
.isTrue();
}
@Test
public void parseTypeOnly() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("-t=ant-project");
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("maven");
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("project");
assertThat(this.handler.lastRequest.isDetectType()).isFalse();
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
}
@Test
public void parseBuildOnly() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("--build=ant");
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("ant");
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("project");
assertThat(this.handler.lastRequest.isDetectType()).isTrue();
assertThat(this.handler.lastRequest.getType()).isNull();
}
@Test
public void parseFormatOnly() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("--format=web");
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("maven");
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
assertThat(this.handler.lastRequest.isDetectType()).isTrue();
assertThat(this.handler.lastRequest.getType()).isNull();
}
@Test
public void parseLocation() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("foobar.zip");
assertThat(this.handler.lastRequest.getOutput()).isEqualTo("foobar.zip");
}
@Test
public void parseLocationWithSlash() throws Exception {
this.handler.disableProjectGeneration();
this.command.run("foobar/");
assertThat(this.handler.lastRequest.getOutput()).isEqualTo("foobar");
assertThat(this.handler.lastRequest.isExtract()).isTrue();
}
@Test
public void parseMoreThanOneArg() throws Exception {
this.handler.disableProjectGeneration();
assertThat(this.command.run("foobar", "barfoo")).isEqualTo(ExitStatus.ERROR);
}
@Test
public void userAgent() throws Exception {
this.command.run("--list", "--target=http://fake-service");
verify(this.http).execute(this.requestCaptor.capture());
Header agent = this.requestCaptor.getValue().getHeaders("User-Agent")[0];
assertThat(agent.getValue()).startsWith("SpringBootCli/");
}
private byte[] createFakeZipArchive(String fileName, String content)
throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(bos)) {
ZipEntry entry = new ZipEntry(fileName);
zos.putNextEntry(entry);
zos.write(content.getBytes());
zos.closeEntry();
return bos.toByteArray();
}
}
private static class TestableInitCommandOptionHandler
extends InitCommand.InitOptionHandler {
private boolean disableProjectGeneration;
private ProjectGenerationRequest lastRequest;
TestableInitCommandOptionHandler(InitializrService initializrService) {
super(initializrService);
}
void disableProjectGeneration() {
this.disableProjectGeneration = true;
}
@Override
protected void generateProject(OptionSet options) throws IOException {
this.lastRequest = createProjectGenerationRequest(options);
if (!this.disableProjectGeneration) {
super.generateProject(options);
}
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2012-2017 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.command.init;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link InitializrServiceMetadata}
*
* @author Stephane Nicoll
*/
public class InitializrServiceMetadataTests {
@Test
public void parseDefaults() throws Exception {
InitializrServiceMetadata metadata = createInstance("2.0.0");
assertThat(metadata.getDefaults().get("bootVersion")).isEqualTo("1.1.8.RELEASE");
assertThat(metadata.getDefaults().get("javaVersion")).isEqualTo("1.7");
assertThat(metadata.getDefaults().get("groupId")).isEqualTo("org.test");
assertThat(metadata.getDefaults().get("name")).isEqualTo("demo");
assertThat(metadata.getDefaults().get("description"))
.isEqualTo("Demo project for Spring Boot");
assertThat(metadata.getDefaults().get("packaging")).isEqualTo("jar");
assertThat(metadata.getDefaults().get("language")).isEqualTo("java");
assertThat(metadata.getDefaults().get("artifactId")).isEqualTo("demo");
assertThat(metadata.getDefaults().get("packageName")).isEqualTo("demo");
assertThat(metadata.getDefaults().get("type")).isEqualTo("maven-project");
assertThat(metadata.getDefaults().get("version")).isEqualTo("0.0.1-SNAPSHOT");
assertThat(metadata.getDefaults()).as("Wrong number of defaults").hasSize(11);
}
@Test
public void parseDependencies() throws Exception {
InitializrServiceMetadata metadata = createInstance("2.0.0");
assertThat(metadata.getDependencies()).hasSize(5);
// Security description
assertThat(metadata.getDependency("aop").getName()).isEqualTo("AOP");
assertThat(metadata.getDependency("security").getName()).isEqualTo("Security");
assertThat(metadata.getDependency("security").getDescription())
.isEqualTo("Security description");
assertThat(metadata.getDependency("jdbc").getName()).isEqualTo("JDBC");
assertThat(metadata.getDependency("data-jpa").getName()).isEqualTo("JPA");
assertThat(metadata.getDependency("data-mongodb").getName()).isEqualTo("MongoDB");
}
@Test
public void parseTypes() throws Exception {
InitializrServiceMetadata metadata = createInstance("2.0.0");
ProjectType projectType = metadata.getProjectTypes().get("maven-project");
assertThat(projectType).isNotNull();
assertThat(projectType.getTags().get("build")).isEqualTo("maven");
assertThat(projectType.getTags().get("format")).isEqualTo("project");
}
private static InitializrServiceMetadata createInstance(String version)
throws JSONException {
try {
return new InitializrServiceMetadata(readJson(version));
}
catch (IOException ex) {
throw new IllegalStateException("Failed to read json", ex);
}
}
private static JSONObject readJson(String version) throws IOException, JSONException {
Resource resource = new ClassPathResource(
"metadata/service-metadata-" + version + ".json");
try (InputStream stream = resource.getInputStream()) {
return new JSONObject(
StreamUtils.copyToString(stream, Charset.forName("UTF-8")));
}
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2012-2017 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.command.init;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link InitializrService}
*
* @author Stephane Nicoll
*/
public class InitializrServiceTests extends AbstractHttpClientMockTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private final InitializrService invoker = new InitializrService(this.http);
@Test
public void loadMetadata() throws Exception {
mockSuccessfulMetadataGet(false);
InitializrServiceMetadata metadata = this.invoker.loadMetadata("http://foo/bar");
assertThat(metadata).isNotNull();
}
@Test
public void generateSimpleProject() throws Exception {
ProjectGenerationRequest request = new ProjectGenerationRequest();
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest(
"application/xml", "foo.zip");
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
assertProjectEntity(entity, mockHttpRequest.contentType,
mockHttpRequest.fileName);
}
@Test
public void generateProjectCustomTargetFilename() throws Exception {
ProjectGenerationRequest request = new ProjectGenerationRequest();
request.setOutput("bar.zip");
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest(
"application/xml", null);
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
assertProjectEntity(entity, mockHttpRequest.contentType, null);
}
@Test
public void generateProjectNoDefaultFileName() throws Exception {
ProjectGenerationRequest request = new ProjectGenerationRequest();
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest(
"application/xml", null);
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
assertProjectEntity(entity, mockHttpRequest.contentType, null);
}
@Test
public void generateProjectBadRequest() throws Exception {
String jsonMessage = "Unknown dependency foo:bar";
mockProjectGenerationError(400, jsonMessage);
ProjectGenerationRequest request = new ProjectGenerationRequest();
request.getDependencies().add("foo:bar");
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage(jsonMessage);
this.invoker.generate(request);
}
@Test
public void generateProjectBadRequestNoExtraMessage() throws Exception {
mockProjectGenerationError(400, null);
ProjectGenerationRequest request = new ProjectGenerationRequest();
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("unexpected 400 error");
this.invoker.generate(request);
}
@Test
public void generateProjectNoContent() throws Exception {
mockSuccessfulMetadataGet(false);
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockStatus(response, 500);
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
ProjectGenerationRequest request = new ProjectGenerationRequest();
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("No content received from server");
this.invoker.generate(request);
}
@Test
public void loadMetadataBadRequest() throws Exception {
String jsonMessage = "whatever error on the server";
mockMetadataGetError(500, jsonMessage);
ProjectGenerationRequest request = new ProjectGenerationRequest();
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage(jsonMessage);
this.invoker.generate(request);
}
@Test
public void loadMetadataInvalidJson() throws Exception {
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockHttpEntity(response, "Foo-Bar-Not-JSON".getBytes(), "application/json");
mockStatus(response, 200);
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
ProjectGenerationRequest request = new ProjectGenerationRequest();
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("Invalid content received from server");
this.invoker.generate(request);
}
@Test
public void loadMetadataNoContent() throws Exception {
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
mockStatus(response, 500);
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
ProjectGenerationRequest request = new ProjectGenerationRequest();
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("No content received from server");
this.invoker.generate(request);
}
private ProjectGenerationResponse generateProject(ProjectGenerationRequest request,
MockHttpProjectGenerationRequest mockRequest) throws Exception {
mockSuccessfulProjectGeneration(mockRequest);
ProjectGenerationResponse entity = this.invoker.generate(request);
assertThat(entity.getContent()).as("wrong body content")
.isEqualTo(mockRequest.content);
return entity;
}
private static void assertProjectEntity(ProjectGenerationResponse entity,
String mimeType, String fileName) {
if (mimeType == null) {
assertThat(entity.getContentType()).isNull();
}
else {
assertThat(entity.getContentType().getMimeType()).isEqualTo(mimeType);
}
assertThat(entity.getFileName()).isEqualTo(fileName);
}
}

View File

@@ -0,0 +1,266 @@
/*
* Copyright 2012-2017 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.command.init;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ProjectGenerationRequest}
*
* @author Stephane Nicoll
* @author Eddú Meléndez
*/
public class ProjectGenerationRequestTests {
public static final Map<String, String> EMPTY_TAGS = Collections
.<String, String>emptyMap();
@Rule
public final ExpectedException thrown = ExpectedException.none();
private final ProjectGenerationRequest request = new ProjectGenerationRequest();
@Test
public void defaultSettings() {
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?type=test-type"));
}
@Test
public void customServer() throws URISyntaxException {
String customServerUrl = "http://foo:8080/initializr";
this.request.setServiceUrl(customServerUrl);
this.request.getDependencies().add("security");
assertThat(this.request.generateUrl(createDefaultMetadata())).isEqualTo(new URI(
customServerUrl + "/starter.zip?dependencies=security&type=test-type"));
}
@Test
public void customBootVersion() {
this.request.setBootVersion("1.2.0.RELEASE");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?type=test-type&bootVersion=1.2.0.RELEASE"));
}
@Test
public void singleDependency() {
this.request.getDependencies().add("web");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?dependencies=web&type=test-type"));
}
@Test
public void multipleDependencies() {
this.request.getDependencies().add("web");
this.request.getDependencies().add("data-jpa");
assertThat(this.request.generateUrl(createDefaultMetadata())).isEqualTo(
createDefaultUrl("?dependencies=web%2Cdata-jpa&type=test-type"));
}
@Test
public void customJavaVersion() {
this.request.setJavaVersion("1.8");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?type=test-type&javaVersion=1.8"));
}
@Test
public void customPackageName() {
this.request.setPackageName("demo.foo");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?packageName=demo.foo&type=test-type"));
}
@Test
public void customType() throws URISyntaxException {
ProjectType projectType = new ProjectType("custom", "Custom Type", "/foo", true,
EMPTY_TAGS);
InitializrServiceMetadata metadata = new InitializrServiceMetadata(projectType);
this.request.setType("custom");
this.request.getDependencies().add("data-rest");
assertThat(this.request.generateUrl(metadata))
.isEqualTo(new URI(ProjectGenerationRequest.DEFAULT_SERVICE_URL
+ "/foo?dependencies=data-rest&type=custom"));
}
@Test
public void customPackaging() {
this.request.setPackaging("war");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?type=test-type&packaging=war"));
}
@Test
public void customLanguage() {
this.request.setLanguage("groovy");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?type=test-type&language=groovy"));
}
@Test
public void customProjectInfo() {
this.request.setGroupId("org.acme");
this.request.setArtifactId("sample");
this.request.setVersion("1.0.1-SNAPSHOT");
this.request.setDescription("Spring Boot Test");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl(
"?groupId=org.acme&artifactId=sample&version=1.0.1-SNAPSHOT"
+ "&description=Spring+Boot+Test&type=test-type"));
}
@Test
public void outputCustomizeArtifactId() {
this.request.setOutput("my-project");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?artifactId=my-project&type=test-type"));
}
@Test
public void outputArchiveCustomizeArtifactId() {
this.request.setOutput("my-project.zip");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?artifactId=my-project&type=test-type"));
}
@Test
public void outputArchiveWithDotsCustomizeArtifactId() {
this.request.setOutput("my.nice.project.zip");
assertThat(this.request.generateUrl(createDefaultMetadata())).isEqualTo(
createDefaultUrl("?artifactId=my.nice.project&type=test-type"));
}
@Test
public void outputDoesNotOverrideCustomArtifactId() {
this.request.setOutput("my-project");
this.request.setArtifactId("my-id");
assertThat(this.request.generateUrl(createDefaultMetadata()))
.isEqualTo(createDefaultUrl("?artifactId=my-id&type=test-type"));
}
@Test
public void buildNoMatch() throws Exception {
InitializrServiceMetadata metadata = readMetadata();
setBuildAndFormat("does-not-exist", null);
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("does-not-exist");
this.request.generateUrl(metadata);
}
@Test
public void buildMultipleMatch() throws Exception {
InitializrServiceMetadata metadata = readMetadata("types-conflict");
setBuildAndFormat("gradle", null);
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("gradle-project");
this.thrown.expectMessage("gradle-project-2");
this.request.generateUrl(metadata);
}
@Test
public void buildOneMatch() throws Exception {
InitializrServiceMetadata metadata = readMetadata();
setBuildAndFormat("gradle", null);
assertThat(this.request.generateUrl(metadata))
.isEqualTo(createDefaultUrl("?type=gradle-project"));
}
@Test
public void typeAndBuildAndFormat() throws Exception {
InitializrServiceMetadata metadata = readMetadata();
setBuildAndFormat("gradle", "project");
this.request.setType("maven-build");
assertThat(this.request.generateUrl(metadata))
.isEqualTo(createUrl("/pom.xml?type=maven-build"));
}
@Test
public void invalidType() throws Exception {
this.request.setType("does-not-exist");
this.thrown.expect(ReportableException.class);
this.request.generateUrl(createDefaultMetadata());
}
@Test
public void noTypeAndNoDefault() throws Exception {
this.thrown.expect(ReportableException.class);
this.thrown.expectMessage("no default is defined");
this.request.generateUrl(readMetadata("types-conflict"));
}
private static URI createUrl(String actionAndParam) {
try {
return new URI(ProjectGenerationRequest.DEFAULT_SERVICE_URL + actionAndParam);
}
catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
private static URI createDefaultUrl(String param) {
return createUrl("/starter.zip" + param);
}
public void setBuildAndFormat(String build, String format) {
this.request.setBuild(build != null ? build : "maven");
this.request.setFormat(format != null ? format : "project");
this.request.setDetectType(true);
}
private static InitializrServiceMetadata createDefaultMetadata() {
ProjectType projectType = new ProjectType("test-type", "The test type",
"/starter.zip", true, EMPTY_TAGS);
return new InitializrServiceMetadata(projectType);
}
private static InitializrServiceMetadata readMetadata() throws JSONException {
return readMetadata("2.0.0");
}
private static InitializrServiceMetadata readMetadata(String version)
throws JSONException {
try {
Resource resource = new ClassPathResource(
"metadata/service-metadata-" + version + ".json");
String content = StreamUtils.copyToString(resource.getInputStream(),
Charset.forName("UTF-8"));
JSONObject json = new JSONObject(content);
return new InitializrServiceMetadata(json);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to read metadata", ex);
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2012-2016 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.command.init;
import java.io.IOException;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ServiceCapabilitiesReportGenerator}
*
* @author Stephane Nicoll
*/
public class ServiceCapabilitiesReportGeneratorTests extends AbstractHttpClientMockTests {
private final ServiceCapabilitiesReportGenerator command = new ServiceCapabilitiesReportGenerator(
new InitializrService(this.http));
@Test
public void listMetadataFromServer() throws IOException {
mockSuccessfulMetadataTextGet();
String expected = new String(
readClasspathResource("metadata/service-metadata-2.1.0.txt"));
String content = this.command.generate("http://localhost");
assertThat(content).isEqualTo(expected);
}
@Test
public void listMetadata() throws IOException {
mockSuccessfulMetadataGet(true);
doTestGenerateCapabilitiesFromJson();
}
@Test
public void listMetadataV2() throws IOException {
mockSuccessfulMetadataGetV2(true);
doTestGenerateCapabilitiesFromJson();
}
private void doTestGenerateCapabilitiesFromJson() throws IOException {
String content = this.command.generate("http://localhost");
assertThat(content).contains("aop - AOP");
assertThat(content).contains("security - Security: Security description");
assertThat(content).contains("type: maven-project");
assertThat(content).contains("packaging: jar");
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright 2012-2017 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.command.install;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.assertj.core.api.Condition;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration;
import org.springframework.boot.cli.compiler.GroovyCompilerScope;
import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory;
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
import org.springframework.boot.testsupport.assertj.Matched;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.startsWith;
/**
* Tests for {@link GroovyGrabDependencyResolver}.
*
* @author Andy Wilkinson
*/
public class GroovyGrabDependencyResolverTests {
private DependencyResolver resolver;
@Before
public void setupResolver() {
GroovyCompilerConfiguration configuration = new GroovyCompilerConfiguration() {
@Override
public boolean isGuessImports() {
return true;
}
@Override
public boolean isGuessDependencies() {
return true;
}
@Override
public boolean isAutoconfigure() {
return false;
}
@Override
public GroovyCompilerScope getScope() {
return GroovyCompilerScope.DEFAULT;
}
@Override
public List<RepositoryConfiguration> getRepositoryConfiguration() {
return RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
}
@Override
public String[] getClasspath() {
return new String[] { "." };
}
@Override
public boolean isQuiet() {
return false;
}
};
this.resolver = new GroovyGrabDependencyResolver(configuration);
}
@Test
public void resolveArtifactWithNoDependencies() throws Exception {
List<File> resolved = this.resolver
.resolve(Arrays.asList("commons-logging:commons-logging:1.1.3"));
assertThat(resolved).hasSize(1);
assertThat(getNames(resolved)).containsOnly("commons-logging-1.1.3.jar");
}
@Test
public void resolveArtifactWithDependencies() throws Exception {
List<File> resolved = this.resolver
.resolve(Arrays.asList("org.springframework:spring-core:4.1.1.RELEASE"));
assertThat(resolved).hasSize(2);
assertThat(getNames(resolved)).containsOnly("commons-logging-1.1.3.jar",
"spring-core-4.1.1.RELEASE.jar");
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void resolveShorthandArtifactWithDependencies() throws Exception {
List<File> resolved = this.resolver.resolve(Arrays.asList("spring-beans"));
assertThat(resolved).hasSize(3);
assertThat(getNames(resolved))
.has((Condition) Matched.by(hasItems(startsWith("spring-core-"),
startsWith("spring-beans-"), startsWith("spring-jcl-"))));
}
@Test
public void resolveMultipleArtifacts() throws Exception {
List<File> resolved = this.resolver.resolve(Arrays.asList("junit:junit:4.11",
"commons-logging:commons-logging:1.1.3"));
assertThat(resolved).hasSize(3);
assertThat(getNames(resolved)).containsOnly("junit-4.11.jar",
"commons-logging-1.1.3.jar", "hamcrest-core-1.3.jar");
}
public Set<String> getNames(Collection<File> files) {
Set<String> names = new HashSet<>(files.size());
for (File file : files) {
names.add(file.getName());
}
return names;
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2012-2017 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.command.install;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link Installer}
*
* @author Andy Wilkinson
*/
public class InstallerTests {
public DependencyResolver resolver = mock(DependencyResolver.class);
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
private Installer installer;
@Before
public void setUp() throws IOException {
System.setProperty("spring.home", "target");
FileSystemUtils.deleteRecursively(new File("target/lib"));
this.installer = new Installer(this.resolver);
}
@After
public void cleanUp() {
System.clearProperty("spring.home");
}
@Test
public void installNewDependency() throws Exception {
File foo = createTemporaryFile("foo.jar");
given(this.resolver.resolve(Arrays.asList("foo"))).willReturn(Arrays.asList(foo));
this.installer.install(Arrays.asList("foo"));
assertThat(getNamesOfFilesInLibExt()).containsOnly("foo.jar", ".installed");
}
@Test
public void installAndUninstall() throws Exception {
File foo = createTemporaryFile("foo.jar");
given(this.resolver.resolve(Arrays.asList("foo"))).willReturn(Arrays.asList(foo));
this.installer.install(Arrays.asList("foo"));
this.installer.uninstall(Arrays.asList("foo"));
assertThat(getNamesOfFilesInLibExt()).contains(".installed");
}
@Test
public void installAndUninstallWithCommonDependencies() throws Exception {
File alpha = createTemporaryFile("alpha.jar");
File bravo = createTemporaryFile("bravo.jar");
File charlie = createTemporaryFile("charlie.jar");
given(this.resolver.resolve(Arrays.asList("bravo")))
.willReturn(Arrays.asList(bravo, alpha));
given(this.resolver.resolve(Arrays.asList("charlie")))
.willReturn(Arrays.asList(charlie, alpha));
this.installer.install(Arrays.asList("bravo"));
assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar",
".installed");
this.installer.install(Arrays.asList("charlie"));
assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar",
"charlie.jar", ".installed");
this.installer.uninstall(Arrays.asList("bravo"));
assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "charlie.jar",
".installed");
this.installer.uninstall(Arrays.asList("charlie"));
assertThat(getNamesOfFilesInLibExt()).containsOnly(".installed");
}
@Test
public void uninstallAll() throws Exception {
File alpha = createTemporaryFile("alpha.jar");
File bravo = createTemporaryFile("bravo.jar");
File charlie = createTemporaryFile("charlie.jar");
given(this.resolver.resolve(Arrays.asList("bravo")))
.willReturn(Arrays.asList(bravo, alpha));
given(this.resolver.resolve(Arrays.asList("charlie")))
.willReturn(Arrays.asList(charlie, alpha));
this.installer.install(Arrays.asList("bravo"));
this.installer.install(Arrays.asList("charlie"));
assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar",
"charlie.jar", ".installed");
this.installer.uninstallAll();
assertThat(getNamesOfFilesInLibExt()).containsOnly(".installed");
}
private Set<String> getNamesOfFilesInLibExt() {
Set<String> names = new HashSet<>();
for (File file : new File("target/lib/ext").listFiles()) {
names.add(file.getName());
}
return names;
}
private File createTemporaryFile(String name) throws IOException {
File temporaryFile = this.tempFolder.newFile(name);
temporaryFile.deleteOnExit();
return temporaryFile;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2012-2015 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.command.run;
import java.util.logging.Level;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link SpringApplicationRunner}.
*
* @author Andy Wilkinson
*/
public class SpringApplicationRunnerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void exceptionMessageWhenSourcesContainsNoClasses() throws Exception {
SpringApplicationRunnerConfiguration configuration = mock(
SpringApplicationRunnerConfiguration.class);
given(configuration.getClasspath()).willReturn(new String[] { "foo", "bar" });
given(configuration.getLogLevel()).willReturn(Level.INFO);
this.thrown.expect(RuntimeException.class);
this.thrown.expectMessage(equalTo("No classes found in '[foo, bar]'"));
new SpringApplicationRunner(configuration, new String[] { "foo", "bar" })
.compileAndRun();
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright 2012-2016 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.command.shell;
import jline.console.completer.ArgumentCompleter.ArgumentList;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link EscapeAwareWhiteSpaceArgumentDelimiter}.
*
* @author Phillip Webb
*/
public class EscapeAwareWhiteSpaceArgumentDelimiterTests {
private final EscapeAwareWhiteSpaceArgumentDelimiter delimiter = new EscapeAwareWhiteSpaceArgumentDelimiter();
@Test
public void simple() throws Exception {
String s = "one two";
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("one",
"two");
assertThat(this.delimiter.parseArguments(s)).containsExactly("one", "two");
assertThat(this.delimiter.isDelimiter(s, 2)).isFalse();
assertThat(this.delimiter.isDelimiter(s, 3)).isTrue();
assertThat(this.delimiter.isDelimiter(s, 4)).isFalse();
}
@Test
public void escaped() throws Exception {
String s = "o\\ ne two";
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("o\\ ne",
"two");
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "two");
assertThat(this.delimiter.isDelimiter(s, 2)).isFalse();
assertThat(this.delimiter.isDelimiter(s, 3)).isFalse();
assertThat(this.delimiter.isDelimiter(s, 4)).isFalse();
assertThat(this.delimiter.isDelimiter(s, 5)).isTrue();
}
@Test
public void quoted() throws Exception {
String s = "'o ne' 't w o'";
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("'o ne'",
"'t w o'");
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "t w o");
}
@Test
public void doubleQuoted() throws Exception {
String s = "\"o ne\" \"t w o\"";
assertThat(this.delimiter.delimit(s, 0).getArguments())
.containsExactly("\"o ne\"", "\"t w o\"");
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "t w o");
}
@Test
public void nestedQuotes() throws Exception {
String s = "\"o 'n''e\" 't \"w o'";
assertThat(this.delimiter.delimit(s, 0).getArguments())
.containsExactly("\"o 'n''e\"", "'t \"w o'");
assertThat(this.delimiter.parseArguments(s)).containsExactly("o 'n''e",
"t \"w o");
}
@Test
public void escapedQuotes() throws Exception {
String s = "\\'a b";
ArgumentList argumentList = this.delimiter.delimit(s, 0);
assertThat(argumentList.getArguments()).isEqualTo(new String[] { "\\'a", "b" });
assertThat(this.delimiter.parseArguments(s)).containsExactly("'a", "b");
}
@Test
public void escapes() throws Exception {
String s = "\\ \\\\.\\\\\\t";
assertThat(this.delimiter.parseArguments(s)).containsExactly(" \\.\\\t");
}
}

View File

@@ -0,0 +1,180 @@
/*
* Copyright 2012-2016 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.compiler;
import java.util.List;
import groovy.lang.Grab;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.control.SourceUnit;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver;
import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Tests for {@link DependencyCustomizer}
*
* @author Andy Wilkinson
*/
public class DependencyCustomizerTests {
private final ModuleNode moduleNode = new ModuleNode((SourceUnit) null);
private final ClassNode classNode = new ClassNode(DependencyCustomizerTests.class);
@Mock
private ArtifactCoordinatesResolver resolver;
private DependencyCustomizer dependencyCustomizer;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
given(this.resolver.getGroupId("spring-boot-starter-logging"))
.willReturn("org.springframework.boot");
given(this.resolver.getArtifactId("spring-boot-starter-logging"))
.willReturn("spring-boot-starter-logging");
this.moduleNode.addClass(this.classNode);
this.dependencyCustomizer = new DependencyCustomizer(
new GroovyClassLoader(getClass().getClassLoader()), this.moduleNode,
new DependencyResolutionContext() {
@Override
public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() {
return DependencyCustomizerTests.this.resolver;
}
});
}
@Test
public void basicAdd() {
this.dependencyCustomizer.add("spring-boot-starter-logging");
List<AnnotationNode> grabAnnotations = this.classNode
.getAnnotations(new ClassNode(Grab.class));
assertThat(grabAnnotations).hasSize(1);
AnnotationNode annotationNode = grabAnnotations.get(0);
assertGrabAnnotation(annotationNode, "org.springframework.boot",
"spring-boot-starter-logging", "1.2.3", null, null, true);
}
@Test
public void nonTransitiveAdd() {
this.dependencyCustomizer.add("spring-boot-starter-logging", false);
List<AnnotationNode> grabAnnotations = this.classNode
.getAnnotations(new ClassNode(Grab.class));
assertThat(grabAnnotations).hasSize(1);
AnnotationNode annotationNode = grabAnnotations.get(0);
assertGrabAnnotation(annotationNode, "org.springframework.boot",
"spring-boot-starter-logging", "1.2.3", null, null, false);
}
@Test
public void fullyCustomized() {
this.dependencyCustomizer.add("spring-boot-starter-logging", "my-classifier",
"my-type", false);
List<AnnotationNode> grabAnnotations = this.classNode
.getAnnotations(new ClassNode(Grab.class));
assertThat(grabAnnotations).hasSize(1);
AnnotationNode annotationNode = grabAnnotations.get(0);
assertGrabAnnotation(annotationNode, "org.springframework.boot",
"spring-boot-starter-logging", "1.2.3", "my-classifier", "my-type",
false);
}
@Test
public void anyMissingClassesWithMissingClassesPerformsAdd() {
this.dependencyCustomizer.ifAnyMissingClasses("does.not.Exist")
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1);
}
@Test
public void anyMissingClassesWithMixtureOfClassesPerformsAdd() {
this.dependencyCustomizer
.ifAnyMissingClasses(getClass().getName(), "does.not.Exist")
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1);
}
@Test
public void anyMissingClassesWithNoMissingClassesDoesNotPerformAdd() {
this.dependencyCustomizer.ifAnyMissingClasses(getClass().getName())
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty();
}
@Test
public void allMissingClassesWithNoMissingClassesDoesNotPerformAdd() {
this.dependencyCustomizer.ifAllMissingClasses(getClass().getName())
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty();
}
@Test
public void allMissingClassesWithMixtureOfClassesDoesNotPerformAdd() {
this.dependencyCustomizer
.ifAllMissingClasses(getClass().getName(), "does.not.Exist")
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty();
}
@Test
public void allMissingClassesWithAllClassesMissingPerformsAdd() {
this.dependencyCustomizer
.ifAllMissingClasses("does.not.Exist", "does.not.exist.Either")
.add("spring-boot-starter-logging");
assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1);
}
private void assertGrabAnnotation(AnnotationNode annotationNode, String group,
String module, String version, String classifier, String type,
boolean transitive) {
assertThat(getMemberValue(annotationNode, "group")).isEqualTo(group);
assertThat(getMemberValue(annotationNode, "module")).isEqualTo(module);
if (type == null) {
assertThat(annotationNode.getMember("type")).isNull();
}
else {
assertThat(getMemberValue(annotationNode, "type")).isEqualTo(type);
}
if (classifier == null) {
assertThat(annotationNode.getMember("classifier")).isNull();
}
else {
assertThat(getMemberValue(annotationNode, "classifier"))
.isEqualTo(classifier);
}
assertThat(getMemberValue(annotationNode, "transitive")).isEqualTo(transitive);
}
private Object getMemberValue(AnnotationNode annotationNode, String member) {
return ((ConstantExpression) annotationNode.getMember(member)).getValue();
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2012-2017 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.compiler;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ExtendedGroovyClassLoader}.
*
* @author Phillip Webb
*/
public class ExtendedGroovyClassLoaderTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private ClassLoader contextClassLoader;
private ExtendedGroovyClassLoader defaultScopeGroovyClassLoader;
@Before
public void setup() {
this.contextClassLoader = Thread.currentThread().getContextClassLoader();
this.defaultScopeGroovyClassLoader = new ExtendedGroovyClassLoader(
GroovyCompilerScope.DEFAULT);
}
@Test
public void loadsGroovyFromSameClassLoader() throws Exception {
Class<?> c1 = this.contextClassLoader.loadClass("groovy.lang.Script");
Class<?> c2 = this.defaultScopeGroovyClassLoader.loadClass("groovy.lang.Script");
assertThat(c1.getClassLoader()).isSameAs(c2.getClassLoader());
}
@Test
public void filtersNonGroovy() throws Exception {
this.contextClassLoader.loadClass("org.springframework.util.StringUtils");
this.thrown.expect(ClassNotFoundException.class);
this.defaultScopeGroovyClassLoader
.loadClass("org.springframework.util.StringUtils");
}
@Test
public void loadsJavaTypes() throws Exception {
this.defaultScopeGroovyClassLoader.loadClass("java.lang.Boolean");
}
@Test
public void loadsSqlTypes() throws Exception {
this.contextClassLoader.loadClass("java.sql.SQLException");
this.defaultScopeGroovyClassLoader.loadClass("java.sql.SQLException");
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2012-2017 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.compiler;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.PackageNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.ListExpression;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
import org.codehaus.groovy.transform.ASTTransformation;
import org.junit.Test;
import org.springframework.boot.groovy.DependencyManagementBom;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ResolveDependencyCoordinatesTransformation}
*
* @author Andy Wilkinson
* @author Dave Syer
*/
public final class GenericBomAstTransformationTests {
private final SourceUnit sourceUnit = new SourceUnit((String) null,
(ReaderSource) null, null, null, null);
private final ModuleNode moduleNode = new ModuleNode(this.sourceUnit);
private final ASTTransformation transformation = new GenericBomAstTransformation() {
@Override
public int getOrder() {
return DependencyManagementBomTransformation.ORDER - 10;
}
@Override
protected String getBomModule() {
return "test:child:1.0.0";
}
};
@Test
public void transformationOfEmptyPackage() {
this.moduleNode.setPackage(new PackageNode("foo"));
this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit);
assertThat(getValue().toString()).isEqualTo("[test:child:1.0.0]");
}
@Test
public void transformationOfClass() {
this.moduleNode.addClass(ClassHelper.make("MyClass"));
this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit);
assertThat(getValue().toString()).isEqualTo("[test:child:1.0.0]");
}
@Test
public void transformationOfClassWithExistingManagedDependencies() {
this.moduleNode.setPackage(new PackageNode("foo"));
ClassNode cls = ClassHelper.make("MyClass");
this.moduleNode.addClass(cls);
AnnotationNode annotation = new AnnotationNode(
ClassHelper.make(DependencyManagementBom.class));
annotation.addMember("value", new ConstantExpression("test:parent:1.0.0"));
cls.addAnnotation(annotation);
this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit);
assertThat(getValue().toString())
.isEqualTo("[test:parent:1.0.0, test:child:1.0.0]");
}
private List<String> getValue() {
Expression expression = findAnnotation().getMember("value");
if (expression instanceof ListExpression) {
List<String> list = new ArrayList<>();
for (Expression ex : ((ListExpression) expression).getExpressions()) {
list.add((String) ((ConstantExpression) ex).getValue());
}
return list;
}
else if (expression == null) {
return null;
}
else {
throw new IllegalStateException("Member 'value' is not a ListExpression");
}
}
private AnnotationNode findAnnotation() {
PackageNode packageNode = this.moduleNode.getPackage();
ClassNode bom = ClassHelper.make(DependencyManagementBom.class);
if (packageNode != null) {
if (!packageNode.getAnnotations(bom).isEmpty()) {
return packageNode.getAnnotations(bom).get(0);
}
}
if (!this.moduleNode.getClasses().isEmpty()) {
return this.moduleNode.getClasses().get(0).getAnnotations(bom).get(0);
}
throw new IllegalStateException("No package or class node found");
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2012-2017 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.compiler;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
import org.springframework.boot.cli.testutil.SystemProperties;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RepositoryConfigurationFactory}
*
* @author Andy Wilkinson
*/
public class RepositoryConfigurationFactoryTests {
@Test
public void defaultRepositories() {
SystemProperties.doWithSystemProperties(() -> {
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
assertRepositoryConfiguration(repositoryConfiguration, "central", "local",
"spring-snapshot", "spring-milestone");
}, "user.home:src/test/resources/maven-settings/basic");
}
@Test
public void snapshotRepositoriesDisabled() {
SystemProperties.doWithSystemProperties(() -> {
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
assertRepositoryConfiguration(repositoryConfiguration, "central", "local");
}, "user.home:src/test/resources/maven-settings/basic",
"disableSpringSnapshotRepos:true");
}
@Test
public void activeByDefaultProfileRepositories() {
SystemProperties.doWithSystemProperties(() -> {
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
assertRepositoryConfiguration(repositoryConfiguration, "central", "local",
"spring-snapshot", "spring-milestone", "active-by-default");
}, "user.home:src/test/resources/maven-settings/active-profile-repositories");
}
@Test
public void activeByPropertyProfileRepositories() {
SystemProperties.doWithSystemProperties(() -> {
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
assertRepositoryConfiguration(repositoryConfiguration, "central", "local",
"spring-snapshot", "spring-milestone", "active-by-property");
}, "user.home:src/test/resources/maven-settings/active-profile-repositories",
"foo:bar");
}
@Test
public void interpolationProfileRepositories() {
SystemProperties.doWithSystemProperties(() -> {
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
.createDefaultRepositoryConfiguration();
assertRepositoryConfiguration(repositoryConfiguration, "central", "local",
"spring-snapshot", "spring-milestone", "interpolate-releases",
"interpolate-snapshots");
}, "user.home:src/test/resources/maven-settings/active-profile-repositories",
"interpolate:true");
}
private void assertRepositoryConfiguration(
List<RepositoryConfiguration> configurations, String... expectedNames) {
assertThat(configurations).hasSize(expectedNames.length);
Set<String> actualNames = new HashSet<>();
for (RepositoryConfiguration configuration : configurations) {
actualNames.add(configuration.getName());
}
assertThat(actualNames).containsOnly(expectedNames);
}
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright 2012-2016 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.compiler;
import java.util.Arrays;
import groovy.lang.Grab;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.PackageNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.VariableScope;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
import org.codehaus.groovy.transform.ASTTransformation;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver;
import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement;
import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ResolveDependencyCoordinatesTransformation}
*
* @author Andy Wilkinson
*/
public final class ResolveDependencyCoordinatesTransformationTests {
private final SourceUnit sourceUnit = new SourceUnit((String) null,
(ReaderSource) null, null, null, null);
private final ModuleNode moduleNode = new ModuleNode(this.sourceUnit);
private final AnnotationNode grabAnnotation = createGrabAnnotation();
private final ArtifactCoordinatesResolver coordinatesResolver = mock(
ArtifactCoordinatesResolver.class);
private final DependencyResolutionContext resolutionContext = new DependencyResolutionContext() {
{
addDependencyManagement(new SpringBootDependenciesDependencyManagement());
}
@Override
public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() {
return ResolveDependencyCoordinatesTransformationTests.this.coordinatesResolver;
}
};
private final ASTTransformation transformation = new ResolveDependencyCoordinatesTransformation(
this.resolutionContext);
@Before
public void setupExpectations() {
given(this.coordinatesResolver.getGroupId("spring-core"))
.willReturn("org.springframework");
}
@Test
public void transformationOfAnnotationOnImport() {
this.moduleNode.addImport(null, null, Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnStarImport() {
this.moduleNode.addStarImport("org.springframework.util",
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnStaticImport() {
this.moduleNode.addStaticImport(null, null, null,
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnStaticStarImport() {
this.moduleNode.addStaticStarImport(null, null,
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnPackage() {
PackageNode packageNode = new PackageNode("test");
packageNode.addAnnotation(this.grabAnnotation);
this.moduleNode.setPackage(packageNode);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnClass() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
classNode.addAnnotation(this.grabAnnotation);
this.moduleNode.addClass(classNode);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnAnnotation() {
}
@Test
public void transformationOfAnnotationOnField() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
FieldNode fieldNode = new FieldNode("test", 0, new ClassNode(Object.class),
classNode, null);
classNode.addField(fieldNode);
fieldNode.addAnnotation(this.grabAnnotation);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnConstructor() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
ConstructorNode constructorNode = new ConstructorNode(0, null);
constructorNode.addAnnotation(this.grabAnnotation);
classNode.addMethod(constructorNode);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnMethod() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class),
new Parameter[0], new ClassNode[0], null);
methodNode.addAnnotation(this.grabAnnotation);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnMethodParameter() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
Parameter parameter = new Parameter(new ClassNode(Object.class), "test");
parameter.addAnnotation(this.grabAnnotation);
MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class),
new Parameter[] { parameter }, new ClassNode[0], null);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformed();
}
@Test
public void transformationOfAnnotationOnLocalVariable() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
DeclarationExpression declarationExpression = new DeclarationExpression(
new VariableExpression("test"), null, new ConstantExpression("test"));
declarationExpression.addAnnotation(this.grabAnnotation);
BlockStatement code = new BlockStatement(
Arrays.asList((Statement) new ExpressionStatement(declarationExpression)),
new VariableScope());
MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class),
new Parameter[0], new ClassNode[0], code);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformed();
}
private AnnotationNode createGrabAnnotation() {
ClassNode classNode = new ClassNode(Grab.class);
AnnotationNode annotationNode = new AnnotationNode(classNode);
annotationNode.addMember("value", new ConstantExpression("spring-core"));
return annotationNode;
}
private void assertGrabAnnotationHasBeenTransformed() {
this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit);
assertThat(getGrabAnnotationMemberAsString("group"))
.isEqualTo("org.springframework");
assertThat(getGrabAnnotationMemberAsString("module")).isEqualTo("spring-core");
}
private Object getGrabAnnotationMemberAsString(String memberName) {
Expression expression = this.grabAnnotation.getMember(memberName);
if (expression instanceof ConstantExpression) {
return ((ConstantExpression) expression).getValue();
}
else if (expression == null) {
return null;
}
else {
throw new IllegalStateException(
"Member '" + memberName + "' is not a ConstantExpression");
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2012-2016 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.compiler.dependencies;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Tests for {@link CompositeDependencyManagement}
*
* @author Andy Wilkinson
*/
public class CompositeDependencyManagementTests {
@Mock
private DependencyManagement dependencyManagement1;
@Mock
private DependencyManagement dependencyManagement2;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void unknownSpringBootVersion() {
given(this.dependencyManagement1.getSpringBootVersion()).willReturn(null);
given(this.dependencyManagement2.getSpringBootVersion()).willReturn(null);
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getSpringBootVersion()).isNull();
}
@Test
public void knownSpringBootVersion() {
given(this.dependencyManagement1.getSpringBootVersion()).willReturn("1.2.3");
given(this.dependencyManagement2.getSpringBootVersion()).willReturn("1.2.4");
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getSpringBootVersion()).isEqualTo("1.2.3");
}
@Test
public void unknownDependency() {
given(this.dependencyManagement1.find("artifact")).willReturn(null);
given(this.dependencyManagement2.find("artifact")).willReturn(null);
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).find("artifact")).isNull();
}
@Test
public void knownDependency() {
given(this.dependencyManagement1.find("artifact"))
.willReturn(new Dependency("test", "artifact", "1.2.3"));
given(this.dependencyManagement2.find("artifact"))
.willReturn(new Dependency("test", "artifact", "1.2.4"));
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).find("artifact"))
.isEqualTo(new Dependency("test", "artifact", "1.2.3"));
}
@Test
public void getDependencies() {
given(this.dependencyManagement1.getDependencies())
.willReturn(Arrays.asList(new Dependency("test", "artifact", "1.2.3")));
given(this.dependencyManagement2.getDependencies())
.willReturn(Arrays.asList(new Dependency("test", "artifact", "1.2.4")));
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getDependencies()).containsOnly(
new Dependency("test", "artifact", "1.2.3"),
new Dependency("test", "artifact", "1.2.4"));
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2012-2017 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.compiler.dependencies;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link DependencyManagementArtifactCoordinatesResolver}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class DependencyManagementArtifactCoordinatesResolverTests {
private DependencyManagement dependencyManagement;
private DependencyManagementArtifactCoordinatesResolver resolver;
@Before
public void setup() {
this.dependencyManagement = mock(DependencyManagement.class);
given(this.dependencyManagement.find("a1"))
.willReturn(new Dependency("g1", "a1", "0"));
given(this.dependencyManagement.getSpringBootVersion()).willReturn("1");
this.resolver = new DependencyManagementArtifactCoordinatesResolver(
this.dependencyManagement);
}
@Test
public void getGroupIdForBootArtifact() throws Exception {
assertThat(this.resolver.getGroupId("spring-boot-something"))
.isEqualTo("org.springframework.boot");
verify(this.dependencyManagement, never()).find(anyString());
}
@Test
public void getGroupIdFound() throws Exception {
assertThat(this.resolver.getGroupId("a1")).isEqualTo("g1");
}
@Test
public void getGroupIdNotFound() throws Exception {
assertThat(this.resolver.getGroupId("a2")).isNull();
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2012-2016 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.compiler.dependencies;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.empty;
/**
* Tests for {@link SpringBootDependenciesDependencyManagement}
*
* @author Andy Wilkinson
*/
public class SpringBootDependenciesDependencyManagementTests {
private final DependencyManagement dependencyManagement = new SpringBootDependenciesDependencyManagement();
@Test
public void springBootVersion() {
assertThat(this.dependencyManagement.getSpringBootVersion()).isNotNull();
}
@Test
public void find() {
Dependency dependency = this.dependencyManagement.find("spring-boot");
assertThat(dependency).isNotNull();
assertThat(dependency.getGroupId()).isEqualTo("org.springframework.boot");
assertThat(dependency.getArtifactId()).isEqualTo("spring-boot");
}
@Test
public void getDependencies() {
assertThat(this.dependencyManagement.getDependencies()).isNotEqualTo(empty());
}
}

View File

@@ -0,0 +1,256 @@
/*
* Copyright 2012-2017 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.compiler.grape;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import groovy.lang.GroovyClassLoader;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.RemoteRepository;
import org.junit.Test;
import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link AetherGrapeEngine}.
*
* @author Andy Wilkinson
*/
public class AetherGrapeEngineTests {
private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
private final RepositoryConfiguration springMilestones = new RepositoryConfiguration(
"spring-milestones", URI.create("https://repo.spring.io/milestone"), false);
private AetherGrapeEngine createGrapeEngine(
RepositoryConfiguration... additionalRepositories) {
List<RepositoryConfiguration> repositoryConfigurations = new ArrayList<>();
repositoryConfigurations.add(new RepositoryConfiguration("central",
URI.create("http://repo1.maven.org/maven2"), false));
repositoryConfigurations.addAll(Arrays.asList(additionalRepositories));
DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext();
dependencyResolutionContext.addDependencyManagement(
new SpringBootDependenciesDependencyManagement());
return AetherGrapeEngineFactory.create(this.groovyClassLoader,
repositoryConfigurations, dependencyResolutionContext, false);
}
@Test
public void dependencyResolution() {
Map<String, Object> args = new HashMap<>();
createGrapeEngine(this.springMilestones).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs()).hasSize(5);
}
@Test
public void proxySelector() {
doWithCustomUserHome(() -> {
AetherGrapeEngine grapeEngine = createGrapeEngine();
DefaultRepositorySystemSession session = (DefaultRepositorySystemSession) ReflectionTestUtils
.getField(grapeEngine, "session");
assertThat(session.getProxySelector() instanceof CompositeProxySelector)
.isTrue();
});
}
@Test
public void repositoryMirrors() {
doWithCustomUserHome(() -> {
List<RemoteRepository> repositories = getRepositories();
assertThat(repositories).hasSize(1);
assertThat(repositories.get(0).getId()).isEqualTo("central-mirror");
});
}
@Test
public void repositoryAuthentication() {
doWithCustomUserHome(() -> {
List<RemoteRepository> repositories = getRepositories();
assertThat(repositories).hasSize(1);
Authentication authentication = repositories.get(0).getAuthentication();
assertThat(authentication).isNotNull();
});
}
@Test
public void dependencyResolutionWithExclusions() {
Map<String, Object> args = new HashMap<>();
args.put("excludes",
Arrays.asList(createExclusion("org.springframework", "spring-core")));
createGrapeEngine(this.springMilestones).grab(args,
createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE"),
createDependency("org.springframework", "spring-beans", "3.2.4.RELEASE"));
assertThat(this.groovyClassLoader.getURLs().length).isEqualTo(3);
}
@Test
public void nonTransitiveDependencyResolution() {
Map<String, Object> args = new HashMap<>();
createGrapeEngine().grab(args, createDependency("org.springframework",
"spring-jdbc", "3.2.4.RELEASE", false));
assertThat(this.groovyClassLoader.getURLs().length).isEqualTo(1);
}
@Test
public void dependencyResolutionWithCustomClassLoader() {
Map<String, Object> args = new HashMap<>();
GroovyClassLoader customClassLoader = new GroovyClassLoader();
args.put("classLoader", customClassLoader);
createGrapeEngine(this.springMilestones).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs().length).isEqualTo(0);
assertThat(customClassLoader.getURLs().length).isEqualTo(5);
}
@Test
public void resolutionWithCustomResolver() {
Map<String, Object> args = new HashMap<>();
AetherGrapeEngine grapeEngine = this.createGrapeEngine();
grapeEngine
.addResolver(createResolver("restlet.org", "http://maven.restlet.org"));
grapeEngine.grab(args, createDependency("org.restlet", "org.restlet", "1.1.6"));
assertThat(this.groovyClassLoader.getURLs().length).isEqualTo(1);
}
@Test(expected = IllegalArgumentException.class)
public void differingTypeAndExt() {
Map<String, Object> dependency = createDependency("org.grails",
"grails-dependencies", "2.4.0");
dependency.put("type", "foo");
dependency.put("ext", "bar");
createGrapeEngine().grab(Collections.emptyMap(), dependency);
}
@Test
public void pomDependencyResolutionViaType() {
Map<String, Object> args = new HashMap<>();
Map<String, Object> dependency = createDependency("org.springframework",
"spring-framework-bom", "4.0.5.RELEASE");
dependency.put("type", "pom");
createGrapeEngine().grab(args, dependency);
URL[] urls = this.groovyClassLoader.getURLs();
assertThat(urls.length).isEqualTo(1);
assertThat(urls[0].toExternalForm().endsWith(".pom")).isTrue();
}
@Test
public void pomDependencyResolutionViaExt() {
Map<String, Object> args = new HashMap<>();
Map<String, Object> dependency = createDependency("org.springframework",
"spring-framework-bom", "4.0.5.RELEASE");
dependency.put("ext", "pom");
createGrapeEngine().grab(args, dependency);
URL[] urls = this.groovyClassLoader.getURLs();
assertThat(urls.length).isEqualTo(1);
assertThat(urls[0].toExternalForm().endsWith(".pom")).isTrue();
}
@Test
public void resolutionWithClassifier() {
Map<String, Object> args = new HashMap<>();
Map<String, Object> dependency = createDependency("org.springframework",
"spring-jdbc", "3.2.4.RELEASE", false);
dependency.put("classifier", "sources");
createGrapeEngine().grab(args, dependency);
URL[] urls = this.groovyClassLoader.getURLs();
assertThat(urls.length).isEqualTo(1);
assertThat(urls[0].toExternalForm().endsWith("-sources.jar")).isTrue();
}
@SuppressWarnings("unchecked")
private List<RemoteRepository> getRepositories() {
AetherGrapeEngine grapeEngine = createGrapeEngine();
return (List<RemoteRepository>) ReflectionTestUtils.getField(grapeEngine,
"repositories");
}
private Map<String, Object> createDependency(String group, String module,
String version) {
Map<String, Object> dependency = new HashMap<>();
dependency.put("group", group);
dependency.put("module", module);
dependency.put("version", version);
return dependency;
}
private Map<String, Object> createDependency(String group, String module,
String version, boolean transitive) {
Map<String, Object> dependency = createDependency(group, module, version);
dependency.put("transitive", transitive);
return dependency;
}
private Map<String, Object> createResolver(String name, String url) {
Map<String, Object> resolver = new HashMap<>();
resolver.put("name", name);
resolver.put("root", url);
return resolver;
}
private Map<String, Object> createExclusion(String group, String module) {
Map<String, Object> exclusion = new HashMap<>();
exclusion.put("group", group);
exclusion.put("module", module);
return exclusion;
}
private void doWithCustomUserHome(Runnable action) {
doWithSystemProperty("user.home",
new File("src/test/resources").getAbsolutePath(), action);
}
private void doWithSystemProperty(String key, String value, Runnable action) {
String previousValue = setOrClearSystemProperty(key, value);
try {
action.run();
}
finally {
setOrClearSystemProperty(key, previousValue);
}
}
private String setOrClearSystemProperty(String key, String value) {
if (value != null) {
return System.setProperty(key, value);
}
return System.clearProperty(key);
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2012-2016 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.compiler.grape;
import org.junit.Test;
import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
*
*/
public class DependencyResolutionContextTests {
@Test
public void defaultDependenciesEmpty() {
assertThat(new DependencyResolutionContext().getManagedDependencies()).isEmpty();
}
@Test
public void canAddSpringBootDependencies() {
DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext();
dependencyResolutionContext.addDependencyManagement(
new SpringBootDependenciesDependencyManagement());
assertThat(dependencyResolutionContext.getManagedDependencies()).isNotEmpty();
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2012-2016 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.compiler.grape;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferResource;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DetailedProgressReporter}.
*
* @author Andy Wilkinson
*/
public final class DetailedProgressReporterTests {
private static final String REPOSITORY = "http://my.repository.com/";
private static final String ARTIFACT = "org/alpha/bravo/charlie/1.2.3/charlie-1.2.3.jar";
private final TransferResource resource = new TransferResource(REPOSITORY, ARTIFACT,
null, null);
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
private final PrintStream out = new PrintStream(this.baos);
private final DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
@Before
public void initialize() {
new DetailedProgressReporter(this.session, this.out);
}
@Test
public void downloading() throws TransferCancelledException {
TransferEvent startedEvent = new TransferEvent.Builder(this.session,
this.resource).build();
this.session.getTransferListener().transferStarted(startedEvent);
assertThat(new String(this.baos.toByteArray()))
.isEqualTo(String.format("Downloading: %s%s%n", REPOSITORY, ARTIFACT));
}
@Test
public void downloaded() throws InterruptedException {
// Ensure some transfer time
Thread.sleep(100);
TransferEvent completedEvent = new TransferEvent.Builder(this.session,
this.resource).addTransferredBytes(4096).build();
this.session.getTransferListener().transferSucceeded(completedEvent);
String message = new String(this.baos.toByteArray()).replace("\\", "/");
assertThat(message).startsWith("Downloaded: " + REPOSITORY + ARTIFACT);
assertThat(message).contains("4KB at");
assertThat(message).contains("KB/sec");
assertThat(message).endsWith("\n");
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2012-2017 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.compiler.grape;
import java.io.File;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link GrapeRootRepositorySystemSessionAutoConfiguration}
*
* @author Andy Wilkinson
*/
public class GrapeRootRepositorySystemSessionAutoConfigurationTests {
private DefaultRepositorySystemSession session = MavenRepositorySystemUtils
.newSession();
@Mock
private RepositorySystem repositorySystem;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void noLocalRepositoryWhenNoGrapeRoot() {
given(this.repositorySystem.newLocalRepositoryManager(eq(this.session),
any(LocalRepository.class))).willAnswer((invocation) -> {
LocalRepository localRepository = invocation.getArgument(1);
return new SimpleLocalRepositoryManagerFactory().newInstance(
GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session,
localRepository);
});
new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session,
this.repositorySystem);
verify(this.repositorySystem, times(0))
.newLocalRepositoryManager(eq(this.session), any(LocalRepository.class));
assertThat(this.session.getLocalRepository()).isNull();
}
@Test
public void grapeRootConfiguresLocalRepositoryLocation() {
given(this.repositorySystem.newLocalRepositoryManager(eq(this.session),
any(LocalRepository.class)))
.willAnswer(new LocalRepositoryManagerAnswer());
System.setProperty("grape.root", "foo");
try {
new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session,
this.repositorySystem);
}
finally {
System.clearProperty("grape.root");
}
verify(this.repositorySystem, times(1))
.newLocalRepositoryManager(eq(this.session), any(LocalRepository.class));
assertThat(this.session.getLocalRepository()).isNotNull();
assertThat(this.session.getLocalRepository().getBasedir().getAbsolutePath())
.endsWith(File.separatorChar + "foo" + File.separatorChar + "repository");
}
private class LocalRepositoryManagerAnswer implements Answer<LocalRepositoryManager> {
@Override
public LocalRepositoryManager answer(InvocationOnMock invocation)
throws Throwable {
LocalRepository localRepository = invocation.getArgument(1);
return new SimpleLocalRepositoryManagerFactory().newInstance(
GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session,
localRepository);
}
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2012-2017 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.compiler.grape;
import java.io.File;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.AuthenticationContext;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.RemoteRepository;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.cli.testutil.SystemProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
/**
* Tests for {@link SettingsXmlRepositorySystemSessionAutoConfiguration}.
*
* @author Andy Wilkinson
*/
public class SettingsXmlRepositorySystemSessionAutoConfigurationTests {
@Mock
private RepositorySystem repositorySystem;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void basicSessionCustomization() throws SettingsBuildingException {
assertSessionCustomization("src/test/resources/maven-settings/basic");
}
@Test
public void encryptedSettingsSessionCustomization() throws SettingsBuildingException {
assertSessionCustomization("src/test/resources/maven-settings/encrypted");
}
@Test
public void propertyInterpolation() throws SettingsBuildingException {
final DefaultRepositorySystemSession session = MavenRepositorySystemUtils
.newSession();
given(this.repositorySystem.newLocalRepositoryManager(eq(session),
any(LocalRepository.class))).willAnswer((invocation) -> {
LocalRepository localRepository = invocation.getArgument(1);
return new SimpleLocalRepositoryManagerFactory().newInstance(session,
localRepository);
});
SystemProperties.doWithSystemProperties(
() -> new SettingsXmlRepositorySystemSessionAutoConfiguration().apply(
session,
SettingsXmlRepositorySystemSessionAutoConfigurationTests.this.repositorySystem),
"user.home:src/test/resources/maven-settings/property-interpolation",
"foo:bar");
assertThat(session.getLocalRepository().getBasedir().getAbsolutePath())
.endsWith(File.separatorChar + "bar" + File.separatorChar + "repository");
}
private void assertSessionCustomization(String userHome) {
final DefaultRepositorySystemSession session = MavenRepositorySystemUtils
.newSession();
SystemProperties.doWithSystemProperties(
() -> new SettingsXmlRepositorySystemSessionAutoConfiguration().apply(
session,
SettingsXmlRepositorySystemSessionAutoConfigurationTests.this.repositorySystem),
"user.home:" + userHome);
RemoteRepository repository = new RemoteRepository.Builder("my-server", "default",
"http://maven.example.com").build();
assertMirrorSelectorConfiguration(session, repository);
assertProxySelectorConfiguration(session, repository);
assertAuthenticationSelectorConfiguration(session, repository);
}
private void assertProxySelectorConfiguration(DefaultRepositorySystemSession session,
RemoteRepository repository) {
Proxy proxy = session.getProxySelector().getProxy(repository);
repository = new RemoteRepository.Builder(repository).setProxy(proxy).build();
AuthenticationContext authenticationContext = AuthenticationContext
.forProxy(session, repository);
assertThat(proxy.getHost()).isEqualTo("proxy.example.com");
assertThat(authenticationContext.get(AuthenticationContext.USERNAME))
.isEqualTo("proxyuser");
assertThat(authenticationContext.get(AuthenticationContext.PASSWORD))
.isEqualTo("somepassword");
}
private void assertMirrorSelectorConfiguration(DefaultRepositorySystemSession session,
RemoteRepository repository) {
RemoteRepository mirror = session.getMirrorSelector().getMirror(repository);
assertThat(mirror).as("Mirror configured for repository " + repository.getId())
.isNotNull();
assertThat(mirror.getHost()).isEqualTo("maven.example.com");
}
private void assertAuthenticationSelectorConfiguration(
DefaultRepositorySystemSession session, RemoteRepository repository) {
Authentication authentication = session.getAuthenticationSelector()
.getAuthentication(repository);
repository = new RemoteRepository.Builder(repository)
.setAuthentication(authentication).build();
AuthenticationContext authenticationContext = AuthenticationContext
.forRepository(session, repository);
assertThat(authenticationContext.get(AuthenticationContext.USERNAME))
.isEqualTo("tester");
assertThat(authenticationContext.get(AuthenticationContext.PASSWORD))
.isEqualTo("secret");
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2012-2017 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.testutil;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* Utilities for working with System properties in unit tests
*
* @author Andy Wilkinson
*/
public final class SystemProperties {
private SystemProperties() {
}
/**
* Performs the given {@code action} with the given system properties set. System
* properties are restored to their previous values once the action has run.
* @param action The action to perform
* @param systemPropertyPairs The system properties, each in the form
* {@code key:value}
*/
public static void doWithSystemProperties(Runnable action,
String... systemPropertyPairs) {
Map<String, String> originalValues = new HashMap<>();
for (String pair : systemPropertyPairs) {
String[] components = pair.split(":");
String key = components[0];
String value = components[1];
originalValues.put(key, System.setProperty(key, value));
}
try {
action.run();
}
finally {
for (Entry<String, String> entry : originalValues.entrySet()) {
if (entry.getValue() == null) {
System.clearProperty(entry.getKey());
}
else {
System.setProperty(entry.getKey(), entry.getValue());
}
}
}
}
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright 2012-2016 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.util;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import org.junit.Test;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ResourceUtils}.
*
* @author Dave Syer
*/
public class ResourceUtilsTests {
@Test
public void explicitClasspathResource() {
List<String> urls = ResourceUtils.getUrls("classpath:init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void duplicateResource() throws Exception {
URLClassLoader loader = new URLClassLoader(new URL[] {
new URL("file:./src/test/resources/"),
new File("src/test/resources/").getAbsoluteFile().toURI().toURL() });
List<String> urls = ResourceUtils.getUrls("classpath:init.groovy", loader);
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void explicitClasspathResourceWithSlash() {
List<String> urls = ResourceUtils.getUrls("classpath:/init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void implicitClasspathResource() {
List<String> urls = ResourceUtils.getUrls("init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void implicitClasspathResourceWithSlash() {
List<String> urls = ResourceUtils.getUrls("/init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void nonexistentClasspathResource() {
List<String> urls = ResourceUtils.getUrls("classpath:nonexistent.groovy", null);
assertThat(urls).isEmpty();
}
@Test
public void explicitFile() {
List<String> urls = ResourceUtils.getUrls("file:src/test/resources/init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void implicitFile() {
List<String> urls = ResourceUtils.getUrls("src/test/resources/init.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void nonexistentFile() {
List<String> urls = ResourceUtils.getUrls("file:nonexistent.groovy", null);
assertThat(urls).isEmpty();
}
@Test
public void recursiveFiles() {
List<String> urls = ResourceUtils.getUrls("src/test/resources/dir-sample",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void recursiveFilesByPatternWithPrefix() {
List<String> urls = ResourceUtils.getUrls(
"file:src/test/resources/dir-sample/**/*.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void recursiveFilesByPattern() {
List<String> urls = ResourceUtils.getUrls(
"src/test/resources/dir-sample/**/*.groovy",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void directoryOfFilesWithPrefix() {
List<String> urls = ResourceUtils.getUrls(
"file:src/test/resources/dir-sample/code/*",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
@Test
public void directoryOfFiles() {
List<String> urls = ResourceUtils.getUrls("src/test/resources/dir-sample/code/*",
ClassUtils.getDefaultClassLoader());
assertThat(urls).hasSize(1);
assertThat(urls.get(0).startsWith("file:")).isTrue();
}
}