MavenEmbedderTest.java
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* 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.appformer.maven.integration.embedder;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.List;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.model.building.ModelSource;
import org.apache.maven.project.DependencyResolutionResult;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.apache.maven.settings.building.SettingsSource;
import org.appformer.maven.integration.MavenRepositoryConfiguration;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.resolution.ArtifactDescriptorException;
import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.junit.Assert;
import org.junit.Test;
import static java.util.Collections.singletonList;
import static org.appformer.maven.integration.embedder.MavenSettings.CUSTOM_SETTINGS_PROPERTY;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MavenEmbedderTest {
private final String EMPTY_SETTINGS = "<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0\n" +
" http://maven.apache.org/xsd/settings-1.0.0.xsd\"/>\n";
final ComponentProvider componentProviderMocked = mock(ComponentProvider.class);
@Test
public void testInvalidLocalDependency() throws MavenEmbedderException, ProjectBuildingException, ComponentLookupException, SettingsBuildingException, InvalidRepositoryException {
final MavenExecutionRequestPopulator mavenExecutionRequestPopulator = mock(MavenExecutionRequestPopulator.class);
final Logger logger = mock(Logger.class);
final RepositorySystem repositorySystem = mock(RepositorySystem.class);
final ArtifactRepository artifactRepository = mock(ArtifactRepository.class);
final SettingsBuilder settingsBuilder = mock(SettingsBuilder.class);
final SettingsBuildingResult settingsBuildingResult = mock(SettingsBuildingResult.class);
final ProjectBuilder projectBuilderMock = mock(ProjectBuilder.class);
final DependencyResolutionResult drr = mock(DependencyResolutionResult.class);
final ProjectBuildingResult projectBuildingResult = mock(ProjectBuildingResult.class);
final ArtifactDescriptorException exception = mock(ArtifactDescriptorException.class);
final ArtifactDescriptorRequest request = new ArtifactDescriptorRequest();
final ArtifactDescriptorResult result = new ArtifactDescriptorResult(request);
final Artifact artifactResult = mock(Artifact .class);
final List<Exception> list = singletonList(exception);
request.setArtifact(artifactResult);
result.setArtifact(artifactResult);
doReturn(settingsBuilder).when(componentProviderMocked).lookup(SettingsBuilder.class);
doReturn(settingsBuildingResult).when(settingsBuilder).build(any(SettingsBuildingRequest.class));
when(settingsBuildingResult.getEffectiveSettings()).thenReturn(mock(Settings.class));
when(componentProviderMocked.getSystemClassLoader()).thenReturn(getClass().getClassLoader());
doReturn(artifactRepository).when(repositorySystem).createLocalRepository(any(File.class));
doReturn(new File("").toPath().toString()).when(artifactRepository).getBasedir();
doReturn(repositorySystem).when(componentProviderMocked).lookup(RepositorySystem.class);
doReturn(projectBuilderMock).when(componentProviderMocked).lookup(ProjectBuilder.class);
doReturn(logger).when(componentProviderMocked).lookup(Logger.class);
doReturn(mavenExecutionRequestPopulator).when(componentProviderMocked).lookup(MavenExecutionRequestPopulator.class);
doReturn(projectBuildingResult).when(projectBuilderMock).build(any(ModelSource.class), any(ProjectBuildingRequest.class));
when(projectBuildingResult.getDependencyResolutionResult()).thenReturn(drr);
when(projectBuildingResult.getDependencyResolutionResult()).thenReturn(drr);
when(drr.getCollectionErrors()).thenReturn(list);
when(exception.getResult()).thenReturn(result);
boolean[] didExecuteTryRemoveLocalArtifact = {false};
final MavenRequest mavenRequest = createMavenRequest(null);
final MavenEmbedder embedder = new MavenEmbedderMock2( mavenRequest, null ) {
void tryRemoveLocalArtifact(Artifact artifact) {
didExecuteTryRemoveLocalArtifact[0] = true;
assertEquals(artifact, artifactResult);
}
};
assertThatThrownBy(() -> embedder.readProject(mock(InputStream.class)))
.isInstanceOf(MavenEmbedderException.class);
assertTrue(didExecuteTryRemoveLocalArtifact[0]);
}
@Test
public void testExternalRepositories() {
String oldSettingsXmlPath = System.getProperty( CUSTOM_SETTINGS_PROPERTY );
try {
if (oldSettingsXmlPath != null) {
System.clearProperty( CUSTOM_SETTINGS_PROPERTY );
}
MavenSettings.reinitSettingsFromString( EMPTY_SETTINGS );
final MavenRequest mavenRequest = createMavenRequest( null );
final MavenEmbedder embedder = new MavenEmbedderWithRepoMock( mavenRequest );
final MavenExecutionRequest request = embedder.getMavenExecutionRequest();
assertNotNull( request );
final List<ArtifactRepository> remoteRepositories = request.getRemoteRepositories();
assertEquals( 2,
remoteRepositories.size() );
for ( ArtifactRepository remoteRepository : remoteRepositories ) {
assertTrue( remoteRepository.getId().equals( "central" )
|| remoteRepository.getId().equals( "kie-wb-m2-repo" ) );
}
} catch ( MavenEmbedderException mee ) {
fail( mee.getMessage() );
} finally {
if (oldSettingsXmlPath != null) {
System.setProperty( CUSTOM_SETTINGS_PROPERTY, oldSettingsXmlPath );
}
MavenSettings.reinitSettings();
}
}
@Test
public void testCustomSettingSource() {
try {
final MavenRequest mavenRequest = createMavenRequest(new SettingsSourceMock( "<settings/>" ) );
final MavenEmbedder embedder = new MavenEmbedderWithRepoMock( mavenRequest );
final MavenExecutionRequest request = embedder.getMavenExecutionRequest();
assertNotNull( request );
Assert.assertEquals( "<settings/>", readFileAsString( request.getUserSettingsFile() ).trim() );
} catch ( MavenEmbedderException mee ) {
fail( mee.getMessage() );
}
}
@Test
public void testProxies() {
String oldSettingsXmlPath = System.getProperty( CUSTOM_SETTINGS_PROPERTY );
try {
if (oldSettingsXmlPath != null) {
System.clearProperty( CUSTOM_SETTINGS_PROPERTY );
}
MavenSettings.reinitSettingsFromString(EMPTY_SETTINGS);
final MavenRequest mavenRequest = createMavenRequest(null);
final MavenEmbedder embedder = new MavenEmbedderWithProxyMock( mavenRequest );
final MavenExecutionRequest request = embedder.getMavenExecutionRequest();
assertNotNull( request );
final List<Proxy> proxies = request.getProxies();
assertEquals( 1, proxies.size() );
assertEquals( "MyProxy", proxies.get(0).getId() );
} catch ( MavenEmbedderException mee ) {
fail( mee.getMessage() );
} finally {
if (oldSettingsXmlPath != null) {
System.setProperty( CUSTOM_SETTINGS_PROPERTY, oldSettingsXmlPath );
}
MavenSettings.reinitSettings();
}
}
class MavenEmbedderMock2 extends MavenEmbedder {
protected MavenEmbedderMock2(MavenRequest mavenRequest, ComponentProvider componentProvider) throws MavenEmbedderException {
super(mavenRequest, componentProviderMocked);
}
public String getLocalRepositoryPath(){
return new File("").toString();
}
void init(){
}
ProjectBuildingRequest getProjectBuildingRequest() throws ComponentLookupException {
return mock(ProjectBuildingRequest.class);
}
}
public static abstract class MavenEmbedderMock extends MavenEmbedder {
public MavenEmbedderMock( MavenRequest mavenRequest ) throws MavenEmbedderException {
super( mavenRequest );
}
@Override
protected MavenRepositoryConfiguration getMavenRepositoryConfiguration() {
return new MavenRepositoryConfiguration(getMavenSettings());
}
private Settings getMavenSettings() {
String path = getClass().getResource( "." ).toString().substring( "file:".length() );
File testSettingsFile = new File( path + getSettingsFile() );
assertTrue( testSettingsFile.exists() );
SettingsBuilder settingsBuilder = new DefaultSettingsBuilderFactory().newInstance();
DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
request.setUserSettingsFile( testSettingsFile );
try {
return settingsBuilder.build( request ).getEffectiveSettings();
} catch ( SettingsBuildingException e ) {
throw new RuntimeException( e );
}
}
protected abstract String getSettingsFile();
}
public static class MavenEmbedderWithRepoMock extends MavenEmbedderMock {
public MavenEmbedderWithRepoMock( MavenRequest mavenRequest ) throws MavenEmbedderException {
super( mavenRequest );
}
@Override
protected String getSettingsFile() {
return "settings_with_repositories.xml";
}
}
public static class MavenEmbedderWithProxyMock extends MavenEmbedderMock {
public MavenEmbedderWithProxyMock( MavenRequest mavenRequest ) throws MavenEmbedderException {
super( mavenRequest );
}
@Override
protected String getSettingsFile() {
return "settings_with_proxies.xml";
}
}
private static MavenRequest createMavenRequest(SettingsSource settingsSource) {
MavenRequest mavenRequest = new MavenRequest();
mavenRequest.setLocalRepositoryPath( MavenSettings.getSettings().getLocalRepository() );
mavenRequest.setUserSettingsSource(settingsSource != null ? settingsSource : MavenSettings.getUserSettingsSource());
mavenRequest.setResolveDependencies( true );
mavenRequest.setOffline( true );
return mavenRequest;
}
public static class SettingsSourceMock implements SettingsSource {
private final String settings;
public SettingsSourceMock( String settings ) {
this.settings = settings;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream( settings.getBytes( "UTF-8" ) );
}
@Override
public String getLocation() {
return "test";
}
}
private static String readFileAsString(File file) {
StringBuffer sb = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader( new FileInputStream( file), Charset.forName( "UTF-8" )));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
sb.append(line).append("\n");
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) { }
}
}
return sb.toString();
}
}