/*
* 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(new Runnable() {
@Override
public void run() {
AetherGrapeEngine grapeEngine = createGrapeEngine();
DefaultRepositorySystemSession session = (DefaultRepositorySystemSession) ReflectionTestUtils
.getField(grapeEngine, "session");
assertThat(session.getProxySelector() instanceof CompositeProxySelector)
.isTrue();
}
});
}
@Test
public void repositoryMirrors() {
doWithCustomUserHome(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
AetherGrapeEngine grapeEngine = createGrapeEngine();
List<RemoteRepository> repositories = (List<RemoteRepository>) ReflectionTestUtils
.getField(grapeEngine, "repositories");
assertThat(repositories).hasSize(1);
assertThat(repositories.get(0).getId()).isEqualTo("central-mirror");
}
});
}
@Test
public void repositoryAuthentication() {
doWithCustomUserHome(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
AetherGrapeEngine grapeEngine = createGrapeEngine();
List<RemoteRepository> repositories = (List<RemoteRepository>) ReflectionTestUtils
.getField(grapeEngine, "repositories");
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();
}
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);
}
}