blob: 032ef2827bcae749763327c020f3d440f2925d18 [file] [log] [blame]
package org.apache.maven.model.interpolation;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Repository;
import org.apache.maven.model.Resource;
import org.apache.maven.model.Scm;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.SimpleProblemCollector;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author jdcasey
*/
public abstract class AbstractModelInterpolatorTest
{
private Properties context;
@BeforeEach
public void setUp()
{
context = new Properties();
context.put( "basedir", "myBasedir" );
context.put( "project.baseUri", "myBaseUri" );
}
protected void assertProblemFree( SimpleProblemCollector collector )
{
assertEquals( 0, collector.getErrors().size(), "Expected no errors" );
assertEquals( 0, collector.getWarnings().size(), "Expected no warnings" );
assertEquals( 0, collector.getFatals().size(), "Expected no fatals" );
}
protected void assertCollectorState( int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector )
{
assertEquals( numErrors, collector.getErrors().size(), "Errors" );
assertEquals( numWarnings, collector.getWarnings().size(), "Warnings" );
assertEquals( numFatals, collector.getFatals().size(), "Fatals" );
}
private ModelBuildingRequest createModelBuildingRequest( Properties p )
{
ModelBuildingRequest config = new DefaultModelBuildingRequest();
if ( p != null )
{
config.setSystemProperties( p );
}
return config;
}
@Test
public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat()
{
Calendar cal = Calendar.getInstance();
cal.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
cal.set( Calendar.HOUR, 12 );
cal.set( Calendar.AM_PM, Calendar.AM );
// just to make sure all the bases are covered...
cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 16 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.YEAR, 1976 );
cal.set( Calendar.MONTH, Calendar.NOVEMBER );
cal.set( Calendar.DATE, 11 );
Date firstTestDate = cal.getTime();
cal.set( Calendar.HOUR, 11 );
cal.set( Calendar.AM_PM, Calendar.PM );
// just to make sure all the bases are covered...
cal.set( Calendar.HOUR_OF_DAY, 23 );
Date secondTestDate = cal.getTime();
SimpleDateFormat format = new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
format.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
assertEquals( "1976-11-11T00:16:00Z", format.format( firstTestDate ) );
assertEquals( "1976-11-11T23:16:00Z", format.format( secondTestDate ) );
}
@Test
public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover()
{
Calendar cal = Calendar.getInstance();
cal.setTimeZone( TimeZone.getTimeZone( "Europe/Berlin" ) );
cal.set( Calendar.HOUR_OF_DAY, 1 );
cal.set( Calendar.MINUTE, 16 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.YEAR, 2014 );
cal.set( Calendar.MONTH, Calendar.JUNE );
cal.set( Calendar.DATE, 16 );
Date firstTestDate = cal.getTime();
cal.set( Calendar.MONTH, Calendar.NOVEMBER );
Date secondTestDate = cal.getTime();
SimpleDateFormat format = new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
format.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
assertEquals( "2014-06-15T23:16:00Z", format.format( firstTestDate ) );
assertEquals( "2014-11-16T00:16:00Z", format.format( secondTestDate ) );
}
@Test
public void testShouldNotThrowExceptionOnReferenceToNonExistentValue() throws Exception
{
Model model = new Model();
Scm scm = new Scm();
scm.setConnection( "${test}/somepath" );
model.setScm( scm );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( "${test}/somepath", out.getScm().getConnection() );
}
@Test
public void testShouldThrowExceptionOnRecursiveScmConnectionReference() throws Exception
{
Model model = new Model();
Scm scm = new Scm();
scm.setConnection( "${project.scm.connection}/somepath" );
model.setScm( scm );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
assertCollectorState( 0, 1, 0, collector );
}
@Test
public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception
{
Model model = new Model();
Scm scm = new Scm();
scm.setConnection( "${test}/somepath" );
model.setScm( scm );
model.addProperty( "test", "test" );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( "test/somepath", out.getScm().getConnection() );
}
@Test
public void shouldInterpolateOrganizationNameCorrectly() throws Exception
{
String orgName = "MyCo";
Model model = new Model();
model.setName( "${pom.organization.name} Tools" );
Organization org = new Organization();
org.setName( orgName );
model.setOrganization( org );
ModelInterpolator interpolator = createInterpolator();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
new SimpleProblemCollector() );
assertEquals( orgName + " Tools", out.getName() );
}
@Test
public void shouldInterpolateDependencyVersionToSetSameAsProjectVersion() throws Exception
{
Model model = new Model();
model.setVersion( "3.8.1" );
Dependency dep = new Dependency();
dep.setVersion( "${version}" );
model.addDependency( dep );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertCollectorState( 0, 0, 1, collector );
assertEquals( "3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
}
@Test
public void testShouldNotInterpolateDependencyVersionWithInvalidReference() throws Exception
{
Model model = new Model();
model.setVersion( "3.8.1" );
Dependency dep = new Dependency();
dep.setVersion( "${something}" );
model.addDependency( dep );
/*
// This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
// timing of executing the interpolation
try
{
new RegexBasedModelInterpolator().interpolate( model, context );
fail( "Should have failed to interpolate with invalid reference" );
}
catch ( ModelInterpolationException expected )
{
assertTrue( true );
}
*/
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( "${something}", ( out.getDependencies().get( 0 ) ).getVersion() );
}
@Test
public void testTwoReferences() throws Exception
{
Model model = new Model();
model.setVersion( "3.8.1" );
model.setArtifactId( "foo" );
Dependency dep = new Dependency();
dep.setVersion( "${artifactId}-${version}" );
model.addDependency( dep );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertCollectorState( 0, 0, 2, collector );
assertEquals( "foo-3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
}
@Test
public void testBasedir() throws Exception
{
Model model = new Model();
model.setVersion( "3.8.1" );
model.setArtifactId( "foo" );
Repository repository = new Repository();
repository.setUrl( "file://localhost/${basedir}/temp-repo" );
model.addRepository( repository );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
assertProblemFree( collector );
assertEquals( "file://localhost/myBasedir/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
}
@Test
public void testBaseUri() throws Exception
{
Model model = new Model();
model.setVersion( "3.8.1" );
model.setArtifactId( "foo" );
Repository repository = new Repository();
repository.setUrl( "${project.baseUri}/temp-repo" );
model.addRepository( repository );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
assertProblemFree( collector );
assertEquals( "myBaseUri/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
}
@Test
public void testEnvars() throws Exception
{
Properties context = new Properties();
context.put( "env.HOME", "/path/to/home" );
Model model = new Model();
Properties modelProperties = new Properties();
modelProperties.setProperty( "outputDirectory", "${env.HOME}" );
model.setProperties( modelProperties );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) );
}
@Test
public void envarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
{
Model model = new Model();
Properties modelProperties = new Properties();
modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" );
model.setProperties( modelProperties );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
}
@Test
public void expressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
{
Model model = new Model();
Properties modelProperties = new Properties();
modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" );
model.setProperties( modelProperties );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" );
}
@Test
public void shouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly() throws Exception
{
Model model = new Model();
Build build = new Build();
build.setSourceDirectory( "correct" );
Resource res = new Resource();
res.setDirectory( "${project.build.sourceDirectory}" );
build.addResource( res );
Resource res2 = new Resource();
res2.setDirectory( "${pom.build.sourceDirectory}" );
build.addResource( res2 );
Resource res3 = new Resource();
res3.setDirectory( "${build.sourceDirectory}" );
build.addResource( res3 );
model.setBuild( build );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
assertCollectorState( 0, 0, 2, collector );
List<Resource> outResources = out.getBuild().getResources();
Iterator<Resource> resIt = outResources.iterator();
assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
}
@Test
public void shouldInterpolateUnprefixedBasedirExpression() throws Exception
{
File basedir = new File( "/test/path" );
Model model = new Model();
Dependency dep = new Dependency();
dep.setSystemPath( "${basedir}/artifact.jar" );
model.addDependency( dep );
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model result = interpolator.interpolateModel( model, basedir, createModelBuildingRequest( context ),
collector );
assertProblemFree( collector );
List<Dependency> rDeps = result.getDependencies();
assertNotNull( rDeps );
assertEquals( 1, rDeps.size() );
assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(),
new File( rDeps.get( 0 ).getSystemPath() ).getAbsolutePath() );
}
@Test
public void testRecursiveExpressionCycleNPE() throws Exception
{
Properties props = new Properties();
props.setProperty( "aa", "${bb}" );
props.setProperty( "bb", "${aa}" );
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = new Model();
model.setProperties( props );
SimpleProblemCollector collector = new SimpleProblemCollector();
ModelInterpolator interpolator = createInterpolator();
interpolator.interpolateModel( model, null, request, collector );
assertCollectorState( 0, 2, 0, collector );
assertTrue( collector.getErrors().get( 0 ).contains( "Detected the following recursive expression cycle" ) );
}
@Test
public void testRecursiveExpressionCycleBaseDir() throws Exception
{
Properties props = new Properties();
props.setProperty( "basedir", "${basedir}" );
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = new Model();
model.setProperties( props );
SimpleProblemCollector collector = new SimpleProblemCollector();
ModelInterpolator interpolator = createInterpolator();
interpolator.interpolateModel( model, null, request, collector );
assertCollectorState( 0, 1, 0, collector );
assertEquals(
"Resolving expression: '${basedir}': Detected the following recursive expression cycle in 'basedir': [basedir]",
collector.getErrors().get( 0 ) );
}
protected abstract ModelInterpolator createInterpolator() throws Exception;
}