/*
* 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;
import static com.redhat.rcm.version.testutil.TestProjectFixture.loadModel;
import static org.apache.commons.io.FileUtils.copyDirectory;
import static org.apache.commons.io.FileUtils.copyFile;
import static org.apache.commons.io.FileUtils.writeLines;
import static org.apache.commons.io.IOUtils.closeQuietly;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
import com.redhat.rcm.version.fixture.LoggingFixture;
import com.redhat.rcm.version.mgr.VersionManager;
import com.redhat.rcm.version.testutil.HttpTestService;
public class CliTest
{
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Rule
public TestName name = new TestName();
public void help()
throws Exception
{
Cli.main( new String[] { "-h" } );
}
/*
* Validate the exit value. Use reflection to retrieve the value to avoid
* having to create unnecessary accessors.
*/
private void assertExitValue()
{
try
{
final Field f = Cli.class.getDeclaredField( "exitValue" );
f.setAccessible( true );
assertThat( f.getInt( null ), equalTo( 0 ) );
}
catch ( final SecurityException e )
{
fail( "Exception retrieving field information " + e );
}
catch ( final NoSuchFieldException e )
{
fail( "Exception retrieving field information " + e );
}
catch ( final IllegalArgumentException e )
{
fail( "Exception retrieving field information " + e );
}
catch ( final IllegalAccessException e )
{
fail( "Exception retrieving field information " + e );
}
}
@Test
public void modify_BOMofBOMs()
throws Exception
{
System.out.println( "BOM-of-BOMS test (normalize to BOM usage)..." );
final File srcRepo = getResourceFile( "bom-of-boms" );
copyDirectory( 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 Properties props = new Properties();
props.setProperty( Cli.REMOTE_REPOSITORIES_PROPERTY, remoteRepo.toURI()
.normalize()
.toURL()
.toExternalForm() );
props.setProperty( Cli.BOMS_LIST_PROPERTY, bom.getAbsolutePath() );
final File config = new File( repo, "vman.properties" );
FileOutputStream out = null;
try
{
out = new FileOutputStream( config );
props.store( out, "bom-of-boms test" );
}
finally
{
closeQuietly( out );
}
final String[] args = { "-Z", "-C", config.getPath(), pom.getPath() };
Cli.main( args );
assertExitValue();
// FIXME
// assertPOMsNormalizedToBOMs( Collections.singleton( pom ), Collections.singleton( bom ), session, fixture );
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 File bom = getResourceFile( "bom.xml" );
final File bomListing = writeBomList( bom );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final File config = writeConfig( new Properties() );
final String[] args = { "-Z", "-C", config.getPath(), "-b", bomListing.getPath(), pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
@Test
public void modify_CaptureMissing()
throws Exception
{
System.out.println( "Single POM test with capture..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.missing.pom" );
final File bom = getResourceFile( "bom.xml" );
final File toolchain = getResourceFile( "empty-toolchain.pom" );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final File capturePom = folder.newFile( "capture.pom" );
final Properties props = new Properties();
props.setProperty( Cli.TOOLCHAIN_PROPERTY, toolchain.getAbsolutePath() );
props.setProperty( Cli.BOMS_LIST_PROPERTY, bom.getAbsolutePath() );
props.setProperty( Cli.CAPTURE_POM_PROPERTY, capturePom.getAbsolutePath() );
final File config = writeConfig( props );
final String[] args = { "-Z", "-C", config.getPath(), pom.getPath() };
Cli.main( args );
System.out.println( "\n\n" );
assertThat( capturePom.exists(), equalTo( true ) );
final Model model = loadModel( capturePom );
new MavenXpp3Writer().write( System.out, model );
}
@Test
public void modify_ConfigProperties()
throws Exception
{
System.out.println( "Single POM test (with config properties)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
final Properties props = new Properties();
props.setProperty( "boms", bom.getAbsolutePath() );
final File config = writeConfig( props );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", "-C", config.getPath(), pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
@Test
public void modify_HTTPConfigProperties()
throws Exception
{
System.out.println( "Single POM test (with http config properties)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", "-C", "http://localhost/vman.properties", pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
@Test
public void modify_ConfigProperties_FromBootstrapPath()
throws Exception
{
System.out.println( "Single POM test (with config properties from file path in bootstrap)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
Properties props = new Properties();
props.setProperty( "boms", bom.getAbsolutePath() );
final File config = writeConfig( props );
final File bootstrap = getResourceFile( Cli.BOOTSTRAP_PROPERTIES );
props = new Properties();
props.setProperty( Cli.BOOT_CONFIG_PROPERTY, config.getAbsolutePath() );
writeConfigTo( props, bootstrap );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
@Test
public void modify_ConfigProperties_FromBootstrapURL()
throws Exception
{
System.out.println( "Single POM test (with config properties from file path in bootstrap)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
Properties props = new Properties();
props.setProperty( "boms", bom.getAbsolutePath() );
final File config = writeConfig( props );
final HttpTestService http =
new HttpTestService( Collections.singletonMap( "/bootstrap.properties", config.toURI()
.toURL() ) );
try
{
String baseUrl = null;
try
{
baseUrl = http.start();
}
catch ( final Exception e )
{
fail( "Failed to start HTTP service..." );
}
final File bootstrap = getResourceFile( Cli.BOOTSTRAP_PROPERTIES );
props = new Properties();
props.setProperty( Cli.BOOT_CONFIG_PROPERTY, baseUrl + "/bootstrap.properties" );
writeConfigTo( props, bootstrap );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", pom.getPath() };
Cli.main( args );
assertExitValue();
}
finally
{
if ( http != null )
{
http.stop();
}
}
System.out.println( "\n\n" );
}
@Test
public void modify_ConfigProperties_FromBootstrapPath_UsingBootstrapOption()
throws Exception
{
System.out.println( "Single POM test (with config properties from file path in bootstrap)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
Properties props = new Properties();
props.setProperty( "boms", bom.getAbsolutePath() );
final File config = writeConfig( props );
props = new Properties();
props.setProperty( Cli.BOOT_CONFIG_PROPERTY, config.getAbsolutePath() );
final File bootstrap = writeConfig( props, "bootstrap.properties" );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", "-B", bootstrap.getAbsolutePath(), pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
@Test
public void modify_ConfigProperties_FromBootstrapURL_UsingBootstrapOption()
throws Exception
{
System.out.println( "Single POM test (with config properties from file path in bootstrap)..." );
final File srcPom = getResourceFile( "rwx-parent-0.2.1.pom" );
final File bom = getResourceFile( "bom.xml" );
Properties props = new Properties();
props.setProperty( "boms", bom.getAbsolutePath() );
final File config = writeConfig( props );
final HttpTestService http =
new HttpTestService( Collections.singletonMap( "/bootstrap.properties", config.toURI()
.toURL() ) );
try
{
String baseUrl = null;
try
{
baseUrl = http.start();
}
catch ( final Exception e )
{
fail( "Failed to start HTTP service..." );
}
props = new Properties();
props.setProperty( Cli.BOOT_CONFIG_PROPERTY, baseUrl + "/bootstrap.properties" );
final File bootstrap = writeConfig( props, "bootstrap.properties" );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final String[] args = { "-Z", "-B", bootstrap.getAbsolutePath(), pom.getPath() };
Cli.main( args );
assertExitValue();
}
finally
{
if ( http != null )
{
http.stop();
}
}
System.out.println( "\n\n" );
}
private File writeConfig( final Properties props )
throws IOException
{
return writeConfig( props, "config.properties" );
}
private File writeConfig( final Properties props, final String name )
throws IOException
{
final File config = folder.newFile( name );
config.deleteOnExit();
writeConfigTo( props, config );
return config;
}
private void writeConfigTo( final Properties props, final File config )
throws IOException
{
FileOutputStream out = null;
try
{
out = new FileOutputStream( config );
props.store( out, "Generated for test: " + getClass().getName() + "#" + name.getMethodName() );
}
finally
{
closeQuietly( out );
}
}
@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 File bom = getResourceFile( "bom.interp.xml" );
final File bomListing = writeBomList( bom );
final File pom = new File( repo, srcPom.getName() );
copyFile( srcPom, pom );
final File config = writeConfig( new Properties() );
final String[] args = { "-Z", "-C", config.getPath(), "-b", bomListing.getPath(), pom.getPath() };
Cli.main( args );
assertExitValue();
System.out.println( "\n\n" );
}
private File repo;
@BeforeClass
public static void enableClasspathScanning()
{
System.out.println( "Enabling classpath scanning..." );
VersionManager.setClasspathScanning( true );
}
@BeforeClass
public static void setupLogging()
{
LoggingFixture.setupLogging();
}
@Before
public void setupDirs()
throws IOException
{
repo = folder.newFolder( "repository" );
}
private File writeBomList( final File... boms )
throws IOException
{
final List<String> bomList = new ArrayList<String>( boms.length );
for ( final File bom : boms )
{
bomList.add( bom.getAbsolutePath() );
}
final File bomListing = folder.newFile( "boms.lst" );
bomListing.deleteOnExit();
writeLines( bomListing, bomList );
return bomListing;
}
private File getResourceFile( final String path )
{
final URL resource = Thread.currentThread()
.getContextClassLoader()
.getResource( path );
if ( resource == null )
{
fail( "Resource not found: " + path );
}
return new File( resource.getPath() );
}
}