/*
* Copyright (c) 2011 Red Hat, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
* <http://www.gnu.org/licenses>.
*/
package com.redhat.rcm.version.mgr;
import static com.redhat.rcm.version.testutil.TestProjectFixture.getResourceFile;
import static com.redhat.rcm.version.testutil.TestProjectFixture.loadModel;
import static com.redhat.rcm.version.testutil.TestProjectFixture.newVersionManagerSession;
import static com.redhat.rcm.version.testutil.VManAssertions.assertPOMsNormalizedToBOMs;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.maven.mae.project.ProjectToolsException;
import org.apache.maven.mae.project.key.VersionlessProjectKey;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.ModelBuildingException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import com.redhat.rcm.version.fixture.LoggingFixture;
import com.redhat.rcm.version.mgr.capture.MissingInfoCapture;
import com.redhat.rcm.version.mgr.mod.BomModder;
import com.redhat.rcm.version.mgr.session.SessionBuilder;
import com.redhat.rcm.version.mgr.session.VersionManagerSession;
import com.redhat.rcm.version.model.Project;
import com.redhat.rcm.version.testutil.TestProjectFixture;
public class BOMManagementTest
extends AbstractVersionManagerTest
{
private static final String TEST_DIR = "relocations/";
@Rule
public TestName name = new TestName();
@Rule
public TestProjectFixture fixture = new TestProjectFixture();
@BeforeClass
public static void enableLogging()
{
LoggingFixture.setupLogging();
}
@Before
public void setup()
throws Throwable
{
setupDirs();
setupVersionManager();
System.out.println( "START: " + name.getMethodName() + "\n\n" );
}
@After
public void teardown()
{
LoggingFixture.flushLogging();
System.out.println( "\n\nEND: " + name.getMethodName() );
}
@Test
public void modifyProjectTree_BOMInjected()
throws Exception
{
final File srcRepo = getResourceFile( "bom-injection-multi" );
FileUtils.copyDirectoryStructure( srcRepo, new File( repo, "project" ) );
final File pom = new File( repo, "project/pom.xml" );
final File bom = getResourceFile( "bom.xml" );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
final Set<File> modified =
vman.modifyVersions( pom, Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
// NOTE: Child POM not modified...nothing to do there!
assertThat( modified.size(), equalTo( 1 ) );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePom_BOMInjected()
throws Exception
{
final File srcPom = getResourceFile( "bom-injection-single/pom.xml" );
final File bom = getResourceFile( "bom.xml" );
final File pom = new File( repo, srcPom.getName() );
FileUtils.copyFile( srcPom, pom );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
final Set<File> modified =
vman.modifyVersions( pom, Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
assertThat( modified.size(), equalTo( 1 ) );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePom_BOMWithParentInRepo()
throws Exception
{
final File srcRepo = getResourceFile( "bom-parent-in-repo" );
FileUtils.copyDirectoryStructure( srcRepo, repo );
final File pom = new File( repo, "project/pom.xml" );
final File bom = new File( repo, "bom.xml" );
final File remoteRepo = new File( repo, "repo" );
final Repository resolve = new Repository();
resolve.setId( "vman" );
resolve.setUrl( remoteRepo.toURI()
.normalize()
.toURL()
.toExternalForm() );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
session.setResolveRepositories( resolve );
final Set<File> modified =
vman.modifyVersions( pom, Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePom_BOMofBOMs()
throws Exception
{
System.out.println( "BOM-of-BOMS test (normalize to BOM usage)..." );
final File srcRepo = getResourceFile( "bom-of-boms" );
FileUtils.copyDirectoryStructure( srcRepo, repo );
final File pom = new File( repo, "project/pom.xml" );
final File bom = new File( repo, "bom.xml" );
final File remoteRepo = new File( repo, "repo" );
final Repository resolve = new Repository();
resolve.setId( "vman" );
resolve.setUrl( remoteRepo.toURI()
.normalize()
.toURL()
.toExternalForm() );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
session.setResolveRepositories( resolve );
final Set<File> modified =
vman.modifyVersions( pom, Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePom_NormalizeToBOMUsage()
throws Exception
{
System.out.println( "Single POM test (normalize to BOM usage)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
final File pom = new File( repo, srcPom.getName() );
FileUtils.copyFile( srcPom, pom );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
final Set<File> modified =
vman.modifyVersions( pom, Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifyMultimodule_NormalizeToBOMUsage()
throws Exception
{
System.out.println( "Mult-module project tree test (normalize to BOM usage)..." );
final File srcRepo = getResourceFile( "project-dir" );
final File bom = getResourceFile( "bom.xml" );
FileUtils.copyDirectoryStructure( srcRepo, repo );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
final Set<File> modified =
vman.modifyVersions( repo, "pom.xml", "", Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture );
System.out.println( "\n\n" );
}
@Test
public void modifyMultimodule_IgnoreProjectInterdependency()
throws Exception
{
System.out.println( "Multi-module tree with interdependencies test (normalize to BOM usage)..." );
final File srcRepo = getResourceFile( "project-dir-with-interdep" );
final File bom = getResourceFile( "bom.xml" );
FileUtils.copyDirectoryStructure( srcRepo, repo );
final VersionManagerSession session = newVersionManagerSession( workspace, reports, null );
final Set<File> modified =
vman.modifyVersions( repo, "pom.xml", "", Collections.singletonList( bom.getAbsolutePath() ), null, session );
assertNoErrors( session );
final String g = "org.commonjava.rwx";
final Set<Dependency> skipped =
assertPOMsNormalizedToBOMs( modified, Collections.singleton( bom ), session, fixture,
new VersionlessProjectKey( g, "rwx-parent" ),
new VersionlessProjectKey( g, "rwx-core" ),
new VersionlessProjectKey( g, "rwx-bindings" ),
new VersionlessProjectKey( g, "rwx-http" ) );
for ( final Dependency dep : skipped )
{
assertThat( "Dependency: " + dep + " should NOT be modified!", dep.getVersion(), notNullValue() );
}
System.out.println( "\n\n" );
}
@Test
public void modifySinglePom()
throws Exception
{
System.out.println( "Single POM test..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final String bom = getResourceFile( "bom.xml" ).getAbsolutePath();
final File pom = new File( repo, srcPom.getName() );
FileUtils.copyFile( srcPom, pom );
final VersionManagerSession session = createVersionManagerSession();
/* final File out = */vman.modifyVersions( pom, Collections.singletonList( bom ), getToolchainPath(), session );
vman.generateReports( reports, session );
// final String source = FileUtils.fileRead( srcPom );
//
// System.out.println( "Original source POM:\n\n" + source );
//
// final String result = FileUtils.fileRead( out );
//
// System.out.println( "Rewritten POM:\n\n" + result );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePomUsingInterpolatedBOM()
throws Exception
{
System.out.println( "Single POM test (interpolated BOM)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final String bom = getResourceFile( "bom.interp.xml" ).getAbsolutePath();
final File pom = new File( repo, srcPom.getName() );
FileUtils.copyFile( srcPom, pom );
final VersionManagerSession session = createVersionManagerSession();
vman.modifyVersions( pom, Collections.singletonList( bom ), null, session );
assertNoErrors( session );
vman.generateReports( reports, session );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePomWithRelocations()
throws Exception
{
System.out.println( "Single POM test (with relocations)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final String bom = getResourceFile( "bom-relocations.xml" ).getAbsolutePath();
final File pom = new File( repo, srcPom.getName() );
FileUtils.copyFile( srcPom, pom );
final VersionManagerSession session = createVersionManagerSession();
final Set<File> modified = vman.modifyVersions( pom, Collections.singletonList( bom ), null, session );
assertNoErrors( session );
assertNotNull( modified );
assertThat( modified.size(), equalTo( 1 ) );
final File out = modified.iterator()
.next();
vman.generateReports( reports, session );
final String result = FileUtils.fileRead( out );
assertFalse( result.contains( "<groupId>commons-codec</groupId>" ) );
assertFalse( result.contains( "<groupId>commons-lang</groupId>" ) );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePomWithRelocations_InBom()
throws IOException, ProjectToolsException
{
final Model original = loadModel( TEST_DIR + "relocate-dep.pom" );
final String bomPath = "bom-dep-1.0.pom";
final Model bomModel = loadModel( TEST_DIR + bomPath );
final MavenProject bomProject = new MavenProject( bomModel );
bomProject.setOriginalModel( bomModel );
assertThat( original.getDependencies(), notNullValue() );
assertThat( original.getDependencies()
.size(), equalTo( 1 ) );
Dependency dep = original.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "old-dep" ) );
assertThat( dep.getVersion(), equalTo( "1.0" ) );
final VersionManagerSession session =
new SessionBuilder( workspace, reports ).withCoordinateRelocation( "org.test:old-dep:1.0",
"org.test:new-dep:1.1" )
.withStrict( true )
.build();
session.addBOM( getResourceFile( TEST_DIR + bomPath ), bomProject );
final Project project = new Project( original );
final boolean changed = new BomModder().inject( project, session );
assertThat( changed, equalTo( true ) );
final Model model = project.getModel();
assertThat( model.getDependencies(), notNullValue() );
assertThat( model.getDependencies()
.size(), equalTo( 1 ) );
dep = model.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "new-dep" ) );
assertThat( dep.getVersion(), nullValue() );
}
@Test
public void modifySinglePomWithRelocations_NotInBom_NonStrictMode()
throws IOException, ProjectToolsException
{
final Model original = loadModel( TEST_DIR + "relocate-dep.pom" );
final String bomPath = "bom-empty-1.0.pom";
final Model bomModel = loadModel( TEST_DIR + bomPath );
final MavenProject bomProject = new MavenProject( bomModel );
bomProject.setOriginalModel( bomModel );
assertThat( original.getDependencies(), notNullValue() );
assertThat( original.getDependencies()
.size(), equalTo( 1 ) );
Dependency dep = original.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "old-dep" ) );
assertThat( dep.getVersion(), equalTo( "1.0" ) );
final VersionManagerSession session =
new SessionBuilder( workspace, reports ).withCoordinateRelocation( "org.test:old-dep:1.0",
"org.test:new-dep:1.1" )
.withStrict( false )
.build();
session.addBOM( getResourceFile( TEST_DIR + bomPath ), bomProject );
final Project project = new Project( original );
final boolean changed = new BomModder().inject( project, session );
assertThat( changed, equalTo( true ) );
final Model model = project.getModel();
assertThat( model.getDependencies(), notNullValue() );
assertThat( model.getDependencies()
.size(), equalTo( 1 ) );
dep = model.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "new-dep" ) );
assertThat( dep.getVersion(), nullValue() );
}
@Test
public void modifySinglePomWithRelocations_NotInBom_StrictMode()
throws IOException, ProjectToolsException
{
final Model original = loadModel( TEST_DIR + "relocate-dep.pom" );
final String bomPath = "bom-empty-1.0.pom";
final Model bomModel = loadModel( TEST_DIR + bomPath );
final MavenProject bomProject = new MavenProject( bomModel );
bomProject.setOriginalModel( bomModel );
assertThat( original.getDependencies(), notNullValue() );
assertThat( original.getDependencies()
.size(), equalTo( 1 ) );
Dependency dep = original.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "old-dep" ) );
assertThat( dep.getVersion(), equalTo( "1.0" ) );
final VersionManagerSession session =
new SessionBuilder( workspace, reports ).withCoordinateRelocation( "org.test:old-dep:1.0",
"org.test:new-dep:1.1" )
.withStrict( true )
.build();
session.addBOM( getResourceFile( TEST_DIR + bomPath ), bomProject );
final Project project = new Project( original );
final boolean changed = new BomModder().inject( project, session );
assertThat( changed, equalTo( true ) );
final Model model = project.getModel();
assertThat( model.getDependencies(), notNullValue() );
assertThat( model.getDependencies()
.size(), equalTo( 1 ) );
dep = model.getDependencies()
.get( 0 );
assertThat( dep.getArtifactId(), equalTo( "new-dep" ) );
assertThat( dep.getVersion(), equalTo( "1.1" ) );
}
@Test
public void modifySinglePomWithNonBOMRelocatedCoordinates()
throws IOException, ProjectToolsException
{
System.out.println( "Single POM test (with relocations NOT from BOM)..." );
final File pom = getResourceFile( "pom-with-relocation.xml" );
final String bom = getResourceFile( "bom-min.xml" ).getAbsolutePath();
final Model model = loadModel( pom );
final VersionManagerSession session =
new SessionBuilder( workspace, reports ).withCoordinateRelocation( "old.group.id:some-artifact:1",
"new.group.id:new-artifact:1.0.0" )
.build();
vman.configureSession( Collections.singletonList( bom ), bom, session );
new BomModder().inject( new Project( model ), session );
assertNoErrors( session );
assertThat( model.getDependencies()
.size(), equalTo( 1 ) );
final Dependency dep = model.getDependencies()
.get( 0 );
assertThat( dep.getGroupId(), equalTo( "new.group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "new-artifact" ) );
assertThat( dep.getVersion(), nullValue() );
System.out.println( "\n\n" );
}
@Test
public void modifySinglePomWithNonBOMRelocatedCoordinatesWhenDepNotInBOM()
throws IOException, ProjectToolsException
{
System.out.println( "Single POM test (with relocations NOT from BOM, no dep in BOM)..." );
final File pom = getResourceFile( "pom-with-relocation.xml" );
final String bom = getResourceFile( "bom-empty.xml" ).getAbsolutePath();
final Model model = loadModel( pom );
final VersionManagerSession session =
new SessionBuilder( workspace, reports ).withCoordinateRelocation( "old.group.id:some-artifact:1",
"new.group.id:new-artifact:1.0.0" )
.build();
vman.configureSession( Collections.singletonList( bom ), bom, session );
new BomModder().inject( new Project( model ), session );
assertNoErrors( session );
assertThat( model.getDependencies()
.size(), equalTo( 1 ) );
final Dependency dep = model.getDependencies()
.get( 0 );
assertThat( dep.getGroupId(), equalTo( "new.group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "new-artifact" ) );
assertThat( dep.getVersion(), equalTo( "1.0.0" ) );
System.out.println( "\n\n" );
}
@Test
public void managedDepsMissingFromBOMIncludedInCapturePOM()
throws IOException, ProjectToolsException, ModelBuildingException
{
System.out.println( "capture missing managed deps..." );
final File pom = getResourceFile( "pom-with-managed-dep.xml" );
final File bom = getResourceFile( "bom-min.xml" );
final VersionManagerSession session = new SessionBuilder( workspace, reports ).build();
fixture.getVman()
.configureSession( Collections.singletonList( bom.getAbsolutePath() ), null, session, pom, bom );
final Project project = fixture.loadProject( pom, session );
final Set<Project> projects = new HashSet<Project>();
projects.add( project );
session.setCurrentProjects( projects );
final File capturePom = tempFolder.newFile( "capture.pom" );
session.setCapturePom( capturePom );
new BomModder().inject( project, session );
new MissingInfoCapture().captureMissing( session );
assertNoErrors( session );
final Model capture = loadModel( pom );
assertThat( capture.getDependencyManagement(), notNullValue() );
assertThat( capture.getDependencyManagement()
.getDependencies(), notNullValue() );
assertThat( capture.getDependencyManagement()
.getDependencies()
.size(), equalTo( 1 ) );
final Dependency dep = capture.getDependencyManagement()
.getDependencies()
.get( 0 );
assertThat( dep.getGroupId(), equalTo( "group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "some-artifact" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
System.out.println( "\n\n" );
}
@Test
public void managedDepsMissingFromBOMIncludedInCapturePOM_NonStrictMode()
throws ProjectToolsException, ModelBuildingException, IOException
{
System.out.println( "capture missing managed deps..." );
final File pom = getResourceFile( "pom-with-managed-dep.xml" );
final File bom = getResourceFile( "bom-min.xml" );
final VersionManagerSession session = new SessionBuilder( workspace, reports ).build();
fixture.getVman()
.configureSession( Collections.singletonList( bom.getAbsolutePath() ), null, session, pom, bom );
final Project project = fixture.loadProject( pom, session );
final Set<Project> projects = new HashSet<Project>();
projects.add( project );
session.setCurrentProjects( projects );
final File capturePom = tempFolder.newFile( "capture.pom" );
session.setCapturePom( capturePom );
new BomModder().inject( project, session );
new MissingInfoCapture().captureMissing( session );
assertNoErrors( session );
final Model capture = loadModel( pom );
assertThat( capture.getDependencyManagement(), notNullValue() );
assertThat( capture.getDependencyManagement()
.getDependencies(), notNullValue() );
assertThat( capture.getDependencyManagement()
.getDependencies()
.size(), equalTo( 1 ) );
final Dependency dep = capture.getDependencyManagement()
.getDependencies()
.get( 0 );
assertThat( dep.getGroupId(), equalTo( "group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "some-artifact" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
System.out.println( "\n\n" );
}
@Test
public void injectBOMsAheadOfPreexistingBOMInStrictMode()
throws ProjectToolsException, ModelBuildingException, IOException
{
final File pom = getResourceFile( "pom-with-existing-import.xml" );
final File originalBom = getResourceFile( "some-bom.xml" );
final File bom1 = getResourceFile( "bom-min.xml" );
final File bom2 = getResourceFile( "bom-min2.xml" );
final List<String> boms = new ArrayList<String>();
boms.add( bom1.getAbsolutePath() );
boms.add( bom2.getAbsolutePath() );
final VersionManagerSession session = new SessionBuilder( workspace, reports ).build();
fixture.getVman()
.configureSession( boms, null, session, pom, bom1, bom2, originalBom );
final Project project = fixture.loadProject( pom, session );
final Model model = project.getModel();
final Set<Project> projects = new HashSet<Project>();
projects.add( project );
session.setCurrentProjects( projects );
assertThat( model.getDependencyManagement(), notNullValue() );
assertThat( model.getDependencyManagement()
.getDependencies(), notNullValue() );
assertThat( model.getDependencyManagement()
.getDependencies()
.size(), equalTo( 1 ) );
Dependency dep = model.getDependencyManagement()
.getDependencies()
.get( 0 );
assertThat( dep.getGroupId(), equalTo( "group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "some-bom" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
assertThat( dep.getType(), equalTo( "pom" ) );
assertThat( dep.getScope(), equalTo( "import" ) );
new BomModder().inject( project, session );
assertNoErrors( session );
assertThat( model.getDependencyManagement(), notNullValue() );
assertThat( model.getDependencyManagement()
.getDependencies(), notNullValue() );
assertThat( model.getDependencyManagement()
.getDependencies()
.size(), equalTo( 3 ) );
int idx = 0;
dep = model.getDependencyManagement()
.getDependencies()
.get( idx++ );
assertThat( dep.getGroupId(), equalTo( "group" ) );
assertThat( dep.getArtifactId(), equalTo( "bom-min" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
assertThat( dep.getType(), equalTo( "pom" ) );
assertThat( dep.getScope(), equalTo( "import" ) );
dep = model.getDependencyManagement()
.getDependencies()
.get( idx++ );
assertThat( dep.getGroupId(), equalTo( "group" ) );
assertThat( dep.getArtifactId(), equalTo( "bom-min2" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
assertThat( dep.getType(), equalTo( "pom" ) );
assertThat( dep.getScope(), equalTo( "import" ) );
dep = model.getDependencyManagement()
.getDependencies()
.get( idx++ );
assertThat( dep.getGroupId(), equalTo( "group.id" ) );
assertThat( dep.getArtifactId(), equalTo( "some-bom" ) );
assertThat( dep.getVersion(), equalTo( "1" ) );
assertThat( dep.getType(), equalTo( "pom" ) );
assertThat( dep.getScope(), equalTo( "import" ) );
}
}