/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.test.runner.api;
import static com.google.common.collect.Lists.newArrayList;
import static org.eclipse.aether.util.artifact.ArtifactIdUtils.toId;
import static org.eclipse.aether.util.artifact.JavaScopes.COMPILE;
import static org.eclipse.aether.util.artifact.JavaScopes.PROVIDED;
import static org.eclipse.aether.util.artifact.JavaScopes.TEST;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.rules.ExpectedException.none;
import static org.mockito.AdditionalMatchers.and;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mule.test.runner.api.ArtifactClassificationType.APPLICATION;
import static org.mule.test.runner.api.ArtifactClassificationType.MODULE;
import static org.mule.test.runner.api.ArtifactClassificationType.PLUGIN;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import org.mule.tck.junit4.AbstractMuleTestCase;
import org.mule.tck.size.SmallTest;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.resolution.ArtifactDescriptorException;
import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.eclipse.aether.resolution.ArtifactResult;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ArtifactDescriptorResult.class, ArtifactResult.class})
@PowerMockIgnore("javax.management.*")
@SmallTest
public class AetherClassPathClassifierTestCase extends AbstractMuleTestCase {
private static final String SERVICE_PROPERTIES = "service.properties";
private static final String SERVICE_PROVIDER_CLASS_NAME = "service.className";
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public ExpectedException expectedException = none();
private DependencyResolver dependencyResolver;
private ArtifactClassificationTypeResolver artifactClassificationTypeResolver;
private ClassPathClassifierContext context;
private AetherClassPathClassifier classifier;
private Artifact rootArtifact;
private Artifact serviceArtifact;
private Dependency fooCoreDep;
private Dependency fooToolsArtifactDep;
private Dependency fooTestsSupportDep;
private Dependency guavaDep;
private Dependency derbyDriverDep;
private Dependency fooServiceDep;
private List<Dependency> directDependencies;
@Before
public void before() throws Exception {
this.rootArtifact = new DefaultArtifact("org.foo:foo-root:1.0-SNAPSHOT");
this.fooCoreDep = new Dependency(new DefaultArtifact("org.foo:foo-core:1.0-SNAPSHOT"), PROVIDED);
this.fooToolsArtifactDep = new Dependency(new DefaultArtifact("org.foo.tools:foo-artifact:1.0-SNAPSHOT"), PROVIDED);
this.fooTestsSupportDep = new Dependency(new DefaultArtifact("org.foo.tests:foo-tests-support:1.0-SNAPSHOT"), TEST);
this.derbyDriverDep = new Dependency(new DefaultArtifact("org.apache.derby:derby:10.11.1.1"), TEST);
this.guavaDep = new Dependency(new DefaultArtifact("org.google:guava:18.0"), COMPILE);
serviceArtifact = new DefaultArtifact("org.foo:foo-service:jar:mule-service:1.0-SNAPSHOT");
this.fooServiceDep = new Dependency(serviceArtifact, PROVIDED);
this.dependencyResolver = mock(DependencyResolver.class);
this.context = mock(ClassPathClassifierContext.class);
this.artifactClassificationTypeResolver = mock(ArtifactClassificationTypeResolver.class);
this.classifier = new AetherClassPathClassifier(dependencyResolver, artifactClassificationTypeResolver);
when(context.getRootArtifact()).thenReturn(rootArtifact);
this.directDependencies = newArrayList(fooCoreDep, fooToolsArtifactDep, fooTestsSupportDep, derbyDriverDep, guavaDep);
when(dependencyResolver.getDirectDependencies(rootArtifact)).thenReturn(directDependencies);
}
@After
public void after() throws Exception {
verify(context, atLeastOnce()).getRootArtifact();
verify(dependencyResolver, atLeastOnce()).getDirectDependencies(rootArtifact);
}
@Test
public void onlyProvidedDependenciesNoTransitiveNoManageDependenciesNoFilters() throws Exception {
Dependency compileMuleCoreDep = fooCoreDep.setScope(COMPILE);
Dependency compileMuleArtifactDep = fooToolsArtifactDep.setScope(COMPILE);
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(MODULE);
ArtifactDescriptorResult artifactDescriptorResult = mock(ArtifactDescriptorResult.class);
List<Dependency> managedDependencies = newArrayList(guavaDep);
when(artifactDescriptorResult.getManagedDependencies()).thenReturn(managedDependencies);
when(dependencyResolver.readArtifactDescriptor(any(Artifact.class))).thenReturn(artifactDescriptorResult);
File rootArtifactFile = temporaryFolder.newFile();
File fooCoreArtifactFile = temporaryFolder.newFile();
File fooToolsArtifactFile = temporaryFolder.newFile();
Artifact jarRootArtifact = rootArtifact.setFile(rootArtifactFile);
ArtifactResult rootArtifactResult = mock(ArtifactResult.class);
when(rootArtifactResult.getArtifact()).thenReturn(jarRootArtifact);
when(dependencyResolver
.resolveArtifact(argThat(new ArtifactMatcher(rootArtifact.getGroupId(), rootArtifact.getArtifactId()))))
.thenReturn(rootArtifactResult);
when(dependencyResolver.resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) argThat(hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep))),
(List<Dependency>) argThat(hasItems(equalTo(guavaDep))),
argThat(instanceOf(DependencyFilter.class))))
.thenReturn(newArrayList(fooCoreArtifactFile, fooToolsArtifactFile));
ArtifactsUrlClassification classification = classifier.classify(context);
assertThat(classification.getApplicationUrls(), is(empty()));
assertThat(classification.getPluginUrlClassifications(), is(empty()));
assertThat(classification.getPluginSharedLibUrls(), is(empty()));
assertThat(classification.getContainerUrls(), hasSize(3));
assertThat(classification.getContainerUrls(),
hasItems(fooCoreArtifactFile.toURI().toURL(), fooToolsArtifactFile.toURI().toURL(),
rootArtifactFile.toURI().toURL()));
verify(artifactDescriptorResult, atLeastOnce()).getManagedDependencies();
verify(dependencyResolver, atLeastOnce()).readArtifactDescriptor(any(Artifact.class));
verify(dependencyResolver).resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) argThat(
hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep))),
(List<Dependency>) argThat(hasItems(equalTo(guavaDep))),
argThat(instanceOf(DependencyFilter.class)));
verify(artifactClassificationTypeResolver).resolveArtifactClassificationType(rootArtifact);
verify(rootArtifactResult).getArtifact();
}
@Test
public void appendApplicationUrls() throws Exception {
Dependency compileMuleCoreDep = fooCoreDep.setScope(COMPILE);
Dependency compileMuleArtifactDep = fooToolsArtifactDep.setScope(COMPILE);
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(APPLICATION);
ArtifactDescriptorResult artifactDescriptorResult = mock(ArtifactDescriptorResult.class);
List<Dependency> managedDependencies = newArrayList(guavaDep);
when(artifactDescriptorResult.getManagedDependencies()).thenReturn(managedDependencies);
when(dependencyResolver.readArtifactDescriptor(any(Artifact.class))).thenReturn(artifactDescriptorResult);
File rootArtifactFile = temporaryFolder.newFile();
File fooCoreArtifactFile = temporaryFolder.newFile();
File fooToolsArtifactFile = temporaryFolder.newFile();
Artifact jarRootArtifact = rootArtifact.setFile(rootArtifactFile);
ArtifactResult rootArtifactResult = mock(ArtifactResult.class);
when(rootArtifactResult.getArtifact()).thenReturn(jarRootArtifact);
when(dependencyResolver
.resolveArtifact(argThat(new ArtifactMatcher(rootArtifact.getGroupId(), rootArtifact.getArtifactId()))))
.thenReturn(rootArtifactResult);
when(dependencyResolver.resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) argThat(hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep))),
(List<Dependency>) argThat(hasItems(equalTo(guavaDep))),
argThat(instanceOf(DependencyFilter.class))))
.thenReturn(newArrayList(fooCoreArtifactFile, fooToolsArtifactFile));
URL url = mock(URL.class);
List<URL> appUrls = newArrayList(url);
when(context.getApplicationUrls()).thenReturn(appUrls);
ArtifactsUrlClassification classification = classifier.classify(context);
assertThat(classification.getApplicationUrls(), hasSize(2));
assertThat(classification.getApplicationUrls(), contains(rootArtifactFile.toURI().toURL(), url));
assertThat(classification.getPluginUrlClassifications(), is(empty()));
assertThat(classification.getPluginSharedLibUrls(), is(empty()));
assertThat(classification.getContainerUrls(), hasSize(2));
assertThat(classification.getContainerUrls(),
hasItems(fooCoreArtifactFile.toURI().toURL(), fooToolsArtifactFile.toURI().toURL()));
verify(artifactDescriptorResult, atLeastOnce()).getManagedDependencies();
verify(dependencyResolver, atLeastOnce()).readArtifactDescriptor(any(Artifact.class));
verify(dependencyResolver).resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) argThat(
hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep))),
(List<Dependency>) argThat(hasItems(equalTo(guavaDep))),
argThat(instanceOf(DependencyFilter.class)));
verify(artifactClassificationTypeResolver).resolveArtifactClassificationType(rootArtifact);
verify(context, atLeastOnce()).getApplicationUrls();
verify(rootArtifactResult).getArtifact();
}
@Test
public void pluginSharedLibUrlsNotDeclaredLibraryAsDirectDependency() throws Exception {
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(PLUGIN);
when(context.getSharedPluginLibCoordinates()).thenReturn(newArrayList("org.foo.tools:foo-repository"));
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage(containsString("has to be declared"));
expectedException.expectMessage(containsString(TEST));
classifier.classify(context);
}
@Test
public void pluginSharedLibUrlsInvalidCoordiantes() throws Exception {
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(PLUGIN);
when(context.getSharedPluginLibCoordinates()).thenReturn(newArrayList("foo-repository"));
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(containsString("not a valid format"));
classifier.classify(context);
}
@Test
public void pluginSharedLibUrlsNoTransitiveNoManageDependenciesNoFilters() throws Exception {
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(APPLICATION);
when(context.getSharedPluginLibCoordinates())
.thenReturn(newArrayList(derbyDriverDep.getArtifact().getGroupId() + ":" + derbyDriverDep.getArtifact().getArtifactId()));
File rootArtifactFile = temporaryFolder.newFile();
Artifact jarRootArtifact = rootArtifact.setFile(rootArtifactFile);
ArtifactResult rootArtifactResult = mock(ArtifactResult.class);
when(rootArtifactResult.getArtifact()).thenReturn(jarRootArtifact);
when(dependencyResolver
.resolveArtifact(argThat(new ArtifactMatcher(rootArtifact.getGroupId(), rootArtifact.getArtifactId()))))
.thenReturn(rootArtifactResult);
File derbyDriverFile = temporaryFolder.newFile();
ArtifactResult artifactResult = mock(ArtifactResult.class);
Artifact derbyDriverFatArtifact = derbyDriverDep.getArtifact().setFile(derbyDriverFile);
when(artifactResult.getArtifact()).thenReturn(derbyDriverFatArtifact);
when(dependencyResolver.resolveArtifact(argThat(equalTo(derbyDriverDep.getArtifact()))))
.thenReturn(artifactResult);
ArtifactDescriptorResult defaultArtifactDescriptorResult = noManagedDependencies();
ArtifactsUrlClassification classification = classifier.classify(context);
assertThat(classification.getApplicationUrls(), hasSize(1));
assertThat(classification.getApplicationUrls(), hasItem(rootArtifactFile.toURI().toURL()));
assertThat(classification.getPluginUrlClassifications(), is(empty()));
assertThat(classification.getPluginSharedLibUrls(), hasSize(1));
assertThat(classification.getPluginSharedLibUrls(), hasItem(derbyDriverFile.toURI().toURL()));
assertThat(classification.getContainerUrls(), is(empty()));
verify(defaultArtifactDescriptorResult, atLeastOnce()).getManagedDependencies();
verify(dependencyResolver, atLeastOnce()).readArtifactDescriptor(any(Artifact.class));
verify(dependencyResolver).resolveArtifact(argThat(equalTo(derbyDriverDep.getArtifact())));
verify(artifactClassificationTypeResolver).resolveArtifactClassificationType(rootArtifact);
}
@Test
public void serviceClassification() throws Exception {
this.directDependencies =
newArrayList(fooCoreDep, fooToolsArtifactDep, fooTestsSupportDep, derbyDriverDep, guavaDep, fooServiceDep);
when(dependencyResolver.getDirectDependencies(rootArtifact)).thenReturn(directDependencies);
when(artifactClassificationTypeResolver.resolveArtifactClassificationType(rootArtifact))
.thenReturn(APPLICATION);
File fooServiceArtifactFile = temporaryFolder.newFile();
File metaInfFolder = temporaryFolder.newFolder("META-INF");
File fooServicePropertyFile = new File(metaInfFolder, SERVICE_PROPERTIES);
Properties fooServiceProperties = new Properties();
fooServiceProperties.put(SERVICE_PROVIDER_CLASS_NAME, "org.foo.ServiceProvider");
fooServiceProperties.store(new FileWriter(fooServicePropertyFile), "Writing " + SERVICE_PROPERTIES);
List<File> fooServiceUrls = newArrayList(fooServiceArtifactFile, metaInfFolder);
when(dependencyResolver.resolveDependencies(argThat(equalTo(new Dependency(fooServiceDep.getArtifact(), COMPILE))),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(instanceOf(DependencyFilter.class)))).thenReturn(fooServiceUrls);
File rootArtifactFile = temporaryFolder.newFile();
Artifact jarRootArtifact = rootArtifact.setFile(rootArtifactFile);
ArtifactResult rootArtifactResult = mock(ArtifactResult.class);
when(rootArtifactResult.getArtifact()).thenReturn(jarRootArtifact);
when(dependencyResolver
.resolveArtifact(argThat(new ArtifactMatcher(rootArtifact.getGroupId(), rootArtifact.getArtifactId()))))
.thenReturn(rootArtifactResult);
File serviceArtifactFile = temporaryFolder.newFile();
ArtifactResult serviceArtifactResult = mock(ArtifactResult.class);
Artifact jarServiceArtifact = serviceArtifact.setFile(serviceArtifactFile);
when(serviceArtifactResult.getArtifact()).thenReturn(jarServiceArtifact);
when(dependencyResolver
.resolveArtifact(argThat(new ArtifactMatcher(serviceArtifact.getGroupId(), serviceArtifact.getArtifactId()))))
.thenReturn(serviceArtifactResult);
ArtifactDescriptorResult defaultArtifactDescriptorResult = noManagedDependencies();
Dependency compileMuleCoreDep = fooCoreDep.setScope(COMPILE);
Dependency compileMuleArtifactDep = fooToolsArtifactDep.setScope(COMPILE);
File fooCoreArtifactFile = temporaryFolder.newFile();
File fooToolsArtifactFile = temporaryFolder.newFile();
when(dependencyResolver.resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) and((argThat(hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep)))),
argThat(hasSize(2))),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(instanceOf(DependencyFilter.class))))
.thenReturn(newArrayList(fooCoreArtifactFile, fooToolsArtifactFile));
ArtifactsUrlClassification classification = classifier.classify(context);
assertThat(classification.getApplicationUrls(), hasSize(1));
assertThat(classification.getApplicationUrls(), hasItem(rootArtifactFile.toURI().toURL()));
assertThat(classification.getPluginUrlClassifications(), is(empty()));
assertThat(classification.getPluginSharedLibUrls(), is(empty()));
assertThat(classification.getContainerUrls(), hasSize(2));
assertThat(classification.getServiceUrlClassifications(), hasSize(1));
assertThat(classification.getServiceUrlClassifications().get(0).getUrls(), hasItem(fooServiceArtifactFile.toURI().toURL()));
verify(defaultArtifactDescriptorResult, atLeastOnce()).getManagedDependencies();
verify(dependencyResolver, atLeastOnce()).readArtifactDescriptor(any(Artifact.class));
verify(dependencyResolver, atLeastOnce())
.resolveDependencies(argThat(equalTo(new Dependency(fooServiceDep.getArtifact(), COMPILE))),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(instanceOf(DependencyFilter.class)));
verify(artifactClassificationTypeResolver).resolveArtifactClassificationType(rootArtifact);
verify(dependencyResolver, atLeastOnce()).resolveDependencies(argThat(nullValue(Dependency.class)),
(List<Dependency>) and((argThat(hasItems(equalTo(compileMuleCoreDep),
equalTo(compileMuleArtifactDep)))),
argThat(hasSize(2))),
argThat(equalTo(Collections.<Dependency>emptyList())),
argThat(instanceOf(DependencyFilter.class)));
}
private ArtifactDescriptorResult noManagedDependencies() throws ArtifactDescriptorException {
ArtifactDescriptorResult artifactDescriptorResult = mock(ArtifactDescriptorResult.class);
List<Dependency> managedDependencies = Collections.<Dependency>emptyList();
when(artifactDescriptorResult.getManagedDependencies()).thenReturn(managedDependencies);
when(dependencyResolver.readArtifactDescriptor(any(Artifact.class))).thenReturn(artifactDescriptorResult);
return artifactDescriptorResult;
}
class ArtifactMatcher extends TypeSafeMatcher<Artifact> {
private String groupId;
private String artifactId;
public ArtifactMatcher(String groupId, String artifactId) {
this.groupId = groupId;
this.artifactId = artifactId;
}
@Override
protected boolean matchesSafely(Artifact artifact) {
return artifact.getGroupId().equals(groupId) && artifact.getArtifactId().equals(artifactId);
}
@Override
public void describeTo(Description description) {
description.appendText("artifact with groupId:artifactId ").appendValue(groupId + ":" + artifactId);
}
@Override
protected void describeMismatchSafely(Artifact artifact, Description mismatchDescription) {
mismatchDescription.appendText("got artifact with id ").appendValue(toId(artifact));
}
}
}