You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2022/01/07 16:54:15 UTC

[maven-invoker-plugin] branch MINVOKER-295 created (now a9de3f6)

This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a change to branch MINVOKER-295
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git.


      at a9de3f6  [MINVOKER-295] Refactor for settings InvocationRequest in one place

This branch includes the following new commits:

     new a9de3f6  [MINVOKER-295] Refactor for settings InvocationRequest in one place

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[maven-invoker-plugin] 01/01: [MINVOKER-295] Refactor for settings InvocationRequest in one place

Posted by sj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a commit to branch MINVOKER-295
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git

commit a9de3f6c6d9211f4b5480c7b1af64438086a869b
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Fri Jan 7 17:50:13 2022 +0100

    [MINVOKER-295] Refactor for settings InvocationRequest in one place
---
 .../maven/plugins/invoker/AbstractInvokerMojo.java |  87 ++++----
 .../maven/plugins/invoker/InvokerProperties.java   | 220 ++++++++++++---------
 .../plugins/invoker/InvokerPropertiesTest.java     | 184 ++++++++++-------
 3 files changed, 287 insertions(+), 204 deletions(-)

diff --git a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
index 729659d..7e78147 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
@@ -492,32 +492,41 @@ public abstract class AbstractInvokerMojo
      * invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:run
      *
      * # A comma or space separated list of profiles to activate
+     * # can be indexed
      * invoker.profiles = its,jdk15
      *
      * # The path to an alternative POM or base directory to invoke Maven on, defaults to the
      * # project that was originally specified in the plugin configuration
      * # Since plugin version 1.4
+     * # can be indexed
      * invoker.project = sub-module
      *
      * # The value for the environment variable MAVEN_OPTS
+     * # can be indexed
      * invoker.mavenOpts = -Dfile.encoding=UTF-16 -Xms32m -Xmx256m
      *
      * # Possible values are &quot;fail-fast&quot; (default), &quot;fail-at-end&quot; and &quot;fail-never&quot;
+     * # can be indexed
      * invoker.failureBehavior = fail-never
      *
      * # The expected result of the build, possible values are &quot;success&quot; (default) and &quot;failure&quot;
+     * # can be indexed
      * invoker.buildResult = failure
      *
      * # A boolean value controlling the aggregator mode of Maven, defaults to &quot;false&quot;
+     *
+     * # can be indexed
      * invoker.nonRecursive = true
      *
      * # A boolean value controlling the network behavior of Maven, defaults to &quot;false&quot;
      * # Since plugin version 1.4
+     * # can be indexed
      * invoker.offline = true
      *
      * # The path to the properties file from which to load system properties, defaults to the
      * # filename given by the plugin parameter testPropertiesFile
      * # Since plugin version 1.4
+     * # can be indexed
      * invoker.systemPropertiesFile = test.properties
      *
      * # An optional human friendly name for this build job to be included in the build reports.
@@ -556,10 +565,17 @@ public abstract class AbstractInvokerMojo
      *
      * # A boolean value controlling the debug logging level of Maven, , defaults to &quot;false&quot;
      * # Since plugin version 1.8
+     * # can be indexed
      * invoker.debug = true
      *
+     * The execution timeout in seconds.
+     * # Since plugin version 3.0.2
+     * # can be indexed
+     * invoker.timeoutInSeconds = 5
+     *
      * # Path to an alternate settings.xml to use for Maven invocation with this IT.
      * # Since plugin version 3.0.1
+     * # can be indexed
      * invoker.settingsFile = ../
      *
      * # An integer value to control run order of projects. sorted in the descending order of the ordinal.
@@ -1981,45 +1997,14 @@ public abstract class AbstractInvokerMojo
                 throw new RunFailureException( BuildJob.Result.FAILURE_PRE_HOOK, e );
             }
 
-            final InvocationRequest request = new DefaultInvocationRequest();
-
-            request.setLocalRepositoryDirectory( localRepositoryPath );
-
-            request.setBatchMode( true );
-
-            request.setShowErrors( showErrors );
-
-            request.setDebug( debug );
-
-            request.setShowVersion( showVersion );
-
-            setupLoggerForBuildJob( logger, request );
-
-            if ( mavenHome != null )
-            {
-                invoker.setMavenHome( mavenHome );
-                // FIXME: Should we really take care of M2_HOME?
-                request.addShellEnvironment( "M2_HOME", mavenHome.getAbsolutePath() );
-            }
+            // TODO - move to request
+            invoker.setMavenHome( mavenHome );
 
             if ( mavenExecutable != null )
             {
                 invoker.setMavenExecutable( new File( mavenExecutable ) );
             }
 
-            if ( actualJavaHome != null )
-            {
-                request.setJavaHome( actualJavaHome );
-            }
-
-            if ( environmentVariables != null )
-            {
-                for ( Map.Entry<String, String> variable : environmentVariables.entrySet() )
-                {
-                    request.addShellEnvironment( variable.getKey(), variable.getValue() );
-                }
-            }
-
             for ( int invocationIndex = 1;; invocationIndex++ )
             {
                 if ( invocationIndex > 1 && !invokerProperties.isInvocationDefined( invocationIndex ) )
@@ -2027,21 +2012,20 @@ public abstract class AbstractInvokerMojo
                     break;
                 }
 
-                request.setBaseDirectory( basedir );
-
-                request.setPomFile( pomFile );
-
-                request.setGoals( goals );
+                final InvocationRequest request = new DefaultInvocationRequest();
 
-                request.setProfiles( profiles );
+                request.setBatchMode( true );
 
-                request.setMavenOpts( mavenOpts );
+                // values only from Mojo configurations
+                request.setLocalRepositoryDirectory( localRepositoryPath );
+                request.setShowErrors( showErrors );
+                request.setShowVersion( showVersion );
+                request.setJavaHome( actualJavaHome );
 
-                request.setOffline( false );
+                setupLoggerForBuildJob( logger, request );
 
-                int timeOut = invokerProperties.getTimeoutInSeconds( invocationIndex );
-                // not set so we use the one at the mojo level
-                request.setTimeoutInSeconds( timeOut < 0 ? timeoutInSeconds : timeOut );
+                request.setBaseDirectory( basedir );
+                request.setPomFile( pomFile );
 
                 String customSettingsFile = invokerProperties.getSettingsFile( invocationIndex );
                 if ( customSettingsFile != null )
@@ -2137,7 +2121,6 @@ public abstract class AbstractInvokerMojo
         if ( logger != null )
         {
             request.setErrorHandler( logger );
-
             request.setOutputHandler( logger );
         }
     }
@@ -2639,7 +2622,19 @@ public abstract class AbstractInvokerMojo
             }
             props.setProperty( key, value );
         }
-        return new InvokerProperties( props );
+
+        InvokerProperties invokerProperties = new InvokerProperties( props );
+
+        // set default value for Invoker - it will be used if not present in properties
+        invokerProperties.setDefaultDebug( debug );
+        invokerProperties.setDefaultGoals( goals );
+        invokerProperties.setDefaultProfiles( profiles );
+        invokerProperties.setDefaultMavenOpts( mavenOpts );
+        invokerProperties.setDefaultTimeoutInSeconds( timeoutInSeconds );
+        invokerProperties.setDefaultEnvironmentVariables( environmentVariables );
+
+
+        return invokerProperties;
     }
 
     static class ToolchainPrivateManager
diff --git a/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java b/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
index b60227a..98fab6b 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
@@ -20,17 +20,19 @@ package org.apache.maven.plugins.invoker;
  */
 
 import java.io.File;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.Properties;
+import java.util.function.Consumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.maven.shared.invoker.InvocationRequest;
-import org.apache.maven.shared.invoker.InvocationRequest.ReactorFailureBehavior;
 import org.codehaus.plexus.util.StringUtils;
 
 /**
@@ -45,9 +47,18 @@ class InvokerProperties
     private static final Pattern ENVIRONMENT_VARIABLES_PATTERN =
             Pattern.compile( "invoker\\.environmentVariables\\.([A-Za-z][^.]+)(\\.([0-9]+))?" );
 
+    // default values from Mojo configuration
+    private Boolean defaultDebug;
+    private List<String> defaultGoals;
+    private List<String> defaultProfiles;
+    private String defaultMavenOpts;
+    private Integer defaultTimeoutInSeconds;
+    private Map<String, String> defaultEnvironmentVariables;
+
     private enum InvocationProperty
     {
         PROJECT( "invoker.project" ),
+        BUILD_RESULT( "invoker.buildResult" ),
         GOALS( "invoker.goals" ),
         PROFILES( "invoker.profiles" ),
         MAVEN_OPTS( "invoker.mavenOpts" ),
@@ -57,8 +68,7 @@ class InvokerProperties
         SYSTEM_PROPERTIES_FILE( "invoker.systemPropertiesFile" ),
         DEBUG( "invoker.debug" ),
         SETTINGS_FILE( "invoker.settingsFile" ),
-        TIMEOUT_IN_SECONDS( "invoker.timeoutInSeconds" ),
-        ORDINAL( "invoker.ordinal" );
+        TIMEOUT_IN_SECONDS( "invoker.timeoutInSeconds" );
 
         private final String key;
 
@@ -111,6 +121,60 @@ class InvokerProperties
     }
 
     /**
+     * Default value for debug
+     * @param defaultDebug a default value
+     */
+    public void setDefaultDebug( boolean defaultDebug )
+    {
+        this.defaultDebug = defaultDebug;
+    }
+
+    /**
+     * Default value for goals
+     * @param defaultGoals a default value
+     */
+    public void setDefaultGoals( List<String> defaultGoals )
+    {
+        this.defaultGoals = defaultGoals;
+    }
+
+    /**
+     * Default value for profiles
+     * @param defaultProfiles a default value
+     */
+    public void setDefaultProfiles( List<String> defaultProfiles )
+    {
+        this.defaultProfiles =  defaultProfiles;
+    }
+
+    /**
+     * Default value for mavenOpts
+     * @param defaultMavenOpts a default value
+     */
+    public void setDefaultMavenOpts( String defaultMavenOpts )
+    {
+        this.defaultMavenOpts = defaultMavenOpts;
+    }
+
+    /**
+     * Default value for timeoutInSeconds
+     * @param defaultTimeoutInSeconds a default value
+     */
+    public void setDefaultTimeoutInSeconds( int defaultTimeoutInSeconds )
+    {
+        this.defaultTimeoutInSeconds = defaultTimeoutInSeconds;
+    }
+
+    /**
+     * Default value for environmentVariables
+     * @param defaultEnvironmentVariables a default value
+     */
+    public void setDefaultEnvironmentVariables( Map<String, String> defaultEnvironmentVariables )
+    {
+        this.defaultEnvironmentVariables = defaultEnvironmentVariables;
+    }
+
+    /**
      * Gets the invoker properties being wrapped.
      *
      * @return The invoker properties being wrapped, never <code>null</code>.
@@ -294,14 +358,10 @@ class InvokerProperties
      */
     public boolean isInvocationDefined( int index )
     {
-        for ( InvocationProperty prop : InvocationProperty.values() )
-        {
-            if ( properties.getProperty( prop.toString() + '.' + index ) != null )
-            {
-                return true;
-            }
-        }
-        return false;
+        return Arrays.stream( InvocationProperty.values() )
+            .map( InvocationProperty::toString )
+            .map( v -> properties.getProperty( v + '.' + index ) )
+            .anyMatch( Objects::nonNull );
     }
 
     /**
@@ -313,14 +373,18 @@ class InvokerProperties
      */
     public boolean isSelectorDefined( int index )
     {
-        for ( SelectorProperty prop : SelectorProperty.values() )
+        return Arrays.stream( SelectorProperty.values() )
+            .map( v -> v.suffix )
+            .map( v -> properties.getProperty( SELECTOR_PREFIX + index + v ) )
+            .anyMatch( Objects::nonNull );
+    }
+
+    private <T> void setIfNotNull( Consumer<T> consumer,  T value )
+    {
+        if ( value != null )
         {
-            if ( properties.getProperty( SELECTOR_PREFIX + index + prop.suffix ) != null )
-            {
-                return true;
-            }
+            consumer.accept( value );
         }
-        return false;
     }
 
     /**
@@ -332,8 +396,7 @@ class InvokerProperties
      */
     public void configureInvocation( InvocationRequest request, int index )
     {
-        String project = get( InvocationProperty.PROJECT, index );
-        if ( project != null )
+        get( InvocationProperty.PROJECT, index ).ifPresent( project ->
         {
             File file = new File( request.getBaseDirectory(), project );
             if ( file.isFile() )
@@ -346,59 +409,48 @@ class InvokerProperties
                 request.setBaseDirectory( file );
                 request.setPomFile( null );
             }
-        }
+        } );
 
-        String goals = get( InvocationProperty.GOALS, index );
-        if ( goals != null )
-        {
-            request.setGoals( new ArrayList<>( Arrays.asList( StringUtils.split( goals, ", \t\n\r\f" ) ) ) );
-        }
+        setIfNotNull( request::setGoals,  get( InvocationProperty.GOALS, index )
+            .map( s -> StringUtils.split( s, ", \t\n\r\f" ) )
+            .map( Arrays::asList )
+            .filter( l -> !l.isEmpty() )
+            .orElse( defaultGoals ) );
 
-        String profiles = get( InvocationProperty.PROFILES, index );
-        if ( profiles != null )
-        {
-            // CHECKSTYLE_OFF: LineLength
-            request.setProfiles( new ArrayList<>( Arrays.asList( StringUtils.split( profiles,
-                                                                                          ", \t\n\r\f" ) ) ) );
-            // CHECKSTYLE_ON: LineLength
-        }
+        setIfNotNull( request::setProfiles, get( InvocationProperty.PROFILES, index )
+            .map( s -> StringUtils.split( s, ", \t\n\r\f" ) )
+            .map( Arrays::asList )
+            .filter( l -> !l.isEmpty() )
+            .orElse( defaultProfiles ) );
 
-        String mvnOpts = get( InvocationProperty.MAVEN_OPTS, index );
-        if ( mvnOpts != null )
-        {
-            request.setMavenOpts( mvnOpts );
-        }
+        setIfNotNull( request::setMavenOpts, get( InvocationProperty.MAVEN_OPTS, index ).orElse( defaultMavenOpts ) );
 
-        String failureBehavior = get( InvocationProperty.FAILURE_BEHAVIOR, index );
-        if ( failureBehavior != null )
-        {
-            ReactorFailureBehavior valueOf =
-                InvocationRequest.ReactorFailureBehavior.valueOfByLongOption( failureBehavior );
-            request.setReactorFailureBehavior( valueOf );
-        }
+        get( InvocationProperty.FAILURE_BEHAVIOR, index )
+            .map( InvocationRequest.ReactorFailureBehavior::valueOfByLongOption )
+            .ifPresent( request::setReactorFailureBehavior );
 
-        String nonRecursive = get( InvocationProperty.NON_RECURSIVE, index );
-        if ( nonRecursive != null )
-        {
-            request.setRecursive( !Boolean.parseBoolean( nonRecursive ) );
-        }
+        get( InvocationProperty.NON_RECURSIVE, index )
+            .map( Boolean::parseBoolean )
+            .map( b -> !b )
+            .ifPresent( request::setRecursive );
 
-        String offline = get( InvocationProperty.OFFLINE, index );
-        if ( offline != null )
-        {
-            request.setOffline( Boolean.parseBoolean( offline ) );
-        }
+        get( InvocationProperty.OFFLINE, index )
+            .map( Boolean::parseBoolean )
+            .ifPresent( request::setOffline );
 
-        String debug = get( InvocationProperty.DEBUG, index );
-        if ( debug != null )
-        {
-            request.setDebug( Boolean.parseBoolean( debug ) );
-        }
+        setIfNotNull( request::setDebug, get( InvocationProperty.DEBUG, index )
+            .map( Boolean::parseBoolean )
+            .orElse( defaultDebug ) );
 
-        for ( Map.Entry<String, String> envItem : getEnvironmentVariables( index ).entrySet() )
-        {
-            request.addShellEnvironment( envItem.getKey(), envItem.getValue() );
-        }
+        setIfNotNull( request::setTimeoutInSeconds, get( InvocationProperty.TIMEOUT_IN_SECONDS, index )
+            .map( Integer::parseInt )
+            .orElse( defaultTimeoutInSeconds ) );
+
+        Optional.ofNullable( defaultEnvironmentVariables )
+                .ifPresent( evn -> evn.forEach( request::addShellEnvironment ) );
+
+        getEnvironmentVariables( index )
+            .forEach( request::addShellEnvironment );
     }
 
     /**
@@ -411,7 +463,7 @@ class InvokerProperties
      */
     public boolean isExpectedResult( int exitCode, int index )
     {
-        boolean nonZeroExit = "failure".equalsIgnoreCase( get( "invoker.buildResult", index ) );
+        boolean nonZeroExit = "failure".equalsIgnoreCase( get( InvocationProperty.BUILD_RESULT, index ).orElse( null ) );
         return ( exitCode != 0 ) == nonZeroExit;
     }
 
@@ -423,7 +475,7 @@ class InvokerProperties
      */
     public String getSystemPropertiesFile( int index )
     {
-        return get( InvocationProperty.SYSTEM_PROPERTIES_FILE, index );
+        return get( InvocationProperty.SYSTEM_PROPERTIES_FILE, index ).orElse( null );
     }
 
     /**
@@ -434,25 +486,10 @@ class InvokerProperties
      */
     public String getSettingsFile( int index )
     {
-        return get( InvocationProperty.SETTINGS_FILE, index );
+        return get( InvocationProperty.SETTINGS_FILE, index ).orElse( null );
     }
 
     /**
-     * Get timeout to execute the project
-     * @param index index The index of the invocation, must not be negative.
-     * @return the value for the timeout or -1
-     */
-    public int getTimeoutInSeconds( int index )
-    {
-        String timeoutInSecondsStr = get( InvocationProperty.TIMEOUT_IN_SECONDS, index );
-        if ( StringUtils.isEmpty( timeoutInSecondsStr ) )
-        {
-            return -1;
-        }
-        // catch NumberFormatException? well we assume users knows what they do :-)
-        return Integer.parseInt( timeoutInSecondsStr );
-    }
-    /**
      * Gets a value from the invoker properties. The invoker properties are intended to describe the invocation settings
      * for multiple builds of the same project. For this reason, the properties are indexed. First, a property named
      * <code>key.index</code> will be queried. If this property does not exist, the value of the property named
@@ -462,22 +499,23 @@ class InvokerProperties
      * @param index The index of the invocation for which to retrieve the value, must not be negative.
      * @return The value for the requested invoker property or <code>null</code> if not defined.
      */
-    String get( String key, int index )
+    Optional<String> get( String key, int index )
     {
         if ( index < 0 )
         {
             throw new IllegalArgumentException( "invalid invocation index: " + index );
         }
 
-        String value = properties.getProperty( key + '.' + index );
-        if ( value == null )
-        {
-            value = properties.getProperty( key );
-        }
-        return value;
+        // lookup in properties
+        String value = Optional.ofNullable( properties.getProperty( key + '.' + index ) )
+            .orElseGet( () -> properties.getProperty( key ) );
+
+        return Optional.ofNullable( value )
+            .map( String::trim )
+            .filter( s -> !s.isEmpty() );
     }
 
-    private String get( InvocationProperty prop, int index )
+    private Optional<String> get( InvocationProperty prop, int index )
     {
         return get( prop.toString(), index );
     }
diff --git a/src/test/java/org/apache/maven/plugins/invoker/InvokerPropertiesTest.java b/src/test/java/org/apache/maven/plugins/invoker/InvokerPropertiesTest.java
index afd9990..c380e20 100644
--- a/src/test/java/org/apache/maven/plugins/invoker/InvokerPropertiesTest.java
+++ b/src/test/java/org/apache/maven/plugins/invoker/InvokerPropertiesTest.java
@@ -32,13 +32,12 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -60,7 +59,7 @@ public class InvokerPropertiesTest
     public void testConstructorNullSafe()
     {
         InvokerProperties facade = new InvokerProperties( null );
-        assertNotNull( facade.getProperties() );
+        assertThat( facade.getProperties() ).isNotNull();
     }
 
     @Test
@@ -69,14 +68,14 @@ public class InvokerPropertiesTest
         Properties props = new Properties();
         InvokerProperties facade = new InvokerProperties( props );
 
-        assertNull( facade.get( "undefined-key", 0 ) );
+        assertThat( facade.get( "undefined-key", 0 ) ).isEmpty();
 
         props.setProperty( "key", "value" );
-        assertEquals( "value", facade.get( "key", 1 ) );
+        assertThat( facade.get( "key", 1 ) ).hasValue( "value" );
 
         props.setProperty( "key.1", "another-value" );
-        assertEquals( "another-value", facade.get( "key", 1 ) );
-        assertEquals( "value", facade.get( "key", 2 ) );
+        assertThat( facade.get( "key", 1 ) ).hasValue( "another-value" );
+        assertThat( facade.get( "key", 2 ) ).hasValue( "value" );
     }
 
     @Test
@@ -87,7 +86,7 @@ public class InvokerPropertiesTest
         props.put( "invoker.name", jobName );
         InvokerProperties facade = new InvokerProperties( props );
 
-        assertEquals( jobName, facade.getJobName() );
+        assertThat( facade.getJobName() ).isEqualTo( jobName );
     }
 
     @Test
@@ -96,16 +95,16 @@ public class InvokerPropertiesTest
         Properties props = new Properties();
         InvokerProperties facade = new InvokerProperties( props );
 
-        assertTrue( facade.isExpectedResult( 0, 0 ) );
-        assertFalse( facade.isExpectedResult( 1, 0 ) );
+        assertThat( facade.isExpectedResult( 0, 0 ) ).isTrue();
+        assertThat( facade.isExpectedResult( 1, 0 ) ).isFalse();
 
         props.setProperty( "invoker.buildResult", "success" );
-        assertTrue( facade.isExpectedResult( 0, 0 ) );
-        assertFalse( facade.isExpectedResult( 1, 0 ) );
+        assertThat( facade.isExpectedResult( 0, 0 ) ).isTrue();
+        assertThat( facade.isExpectedResult( 1, 0 ) ).isFalse();
 
         props.setProperty( "invoker.buildResult", "failure" );
-        assertFalse( facade.isExpectedResult( 0, 0 ) );
-        assertTrue( facade.isExpectedResult( 1, 0 ) );
+        assertThat( facade.isExpectedResult( 0, 0 ) ).isFalse();
+        assertThat( facade.isExpectedResult( 1, 0 ) ).isTrue();
     }
 
     @Test
@@ -126,25 +125,33 @@ public class InvokerPropertiesTest
 
         props.setProperty( "invoker.goals", "verify" );
         facade.configureInvocation( request, 0 );
-        verify( request ).setGoals( eq( Collections.singletonList( "verify" ) ) );
+        verify( request ).setGoals( Collections.singletonList( "verify" ) );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.goals", "   " );
         facade.configureInvocation( request, 0 );
-        verify( request ).setGoals( eq( Collections.emptyList() ) );
+        verify( request, never() ).setGoals( anyList() );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.goals", "" );
         facade.configureInvocation( request, 0 );
-        verify( request ).setGoals( eq( Collections.emptyList() ) );
+        verify( request, never() ).setGoals( anyList() );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.goals", "  clean , test   verify " );
         facade.configureInvocation( request, 0 );
-        verify( request ).setGoals( eq( Arrays.asList( "clean", "test", "verify" ) ) );
+        verify( request ).setGoals( Arrays.asList( "clean", "test", "verify" ) );
+        verifyNoMoreInteractions( request );
+        clearInvocations( request );
+
+        props.clear();
+
+        facade.setDefaultGoals( Arrays.asList( "clean", "test" ) );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setGoals( Arrays.asList( "clean", "test" ) );
         verifyNoMoreInteractions( request );
     }
 
@@ -156,26 +163,34 @@ public class InvokerPropertiesTest
 
         props.setProperty( "invoker.profiles", "verify" );
         facade.configureInvocation( request, 0 );
-        verify( request ).setProfiles( eq( Collections.singletonList( "verify" ) ) );
+        verify( request ).setProfiles( Collections.singletonList( "verify" )  );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.profiles", "   " );
         facade.configureInvocation( request, 0 );
-        verify( request ).setProfiles( eq( Collections.emptyList() ) );
+        verify( request, never() ).setProfiles( anyList()  );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.profiles", "" );
         facade.configureInvocation( request, 0 );
-        verify( request ).setProfiles( eq( Collections.emptyList() ) );
+        verify( request, never() ).setProfiles( anyList() );
         verifyNoMoreInteractions( request );
         clearInvocations( request );
 
         props.setProperty( "invoker.profiles", "  clean , test   verify  ," );
         facade.configureInvocation( request, 0 );
-        verify( request ).setProfiles( eq( Arrays.asList( "clean", "test", "verify" ) ) );
+        verify( request ).setProfiles( Arrays.asList( "clean", "test", "verify" ) );
+        verifyNoMoreInteractions( request );
+        clearInvocations( request );
+
+        props.clear();
+        facade.setDefaultProfiles( Arrays.asList( "profile1",  "profile2" ) );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setProfiles( Arrays.asList( "profile1",  "profile2" ) );
         verifyNoMoreInteractions( request );
+
     }
 
     @Test
@@ -193,17 +208,14 @@ public class InvokerPropertiesTest
             props.setProperty( "invoker.project", tempPom.getName() );
             facade.configureInvocation( request, 0 );
             verify( request ).getBaseDirectory();
-            verify( request ).setBaseDirectory( eq( tempDir ) );
-            verify( request ).setPomFile( eq( tempPom ) );
+            verify( request ).setBaseDirectory( tempDir  );
+            verify( request ).setPomFile( tempPom  );
             verifyNoMoreInteractions( request );
             clearInvocations( request );
 
             props.setProperty( "invoker.project", "" );
             facade.configureInvocation( request, 0 );
-            verify( request ).getBaseDirectory();
-            verify( request ).setBaseDirectory( eq( tempDir ) );
-            verify( request ).setPomFile( null );
-            verifyNoMoreInteractions( request );
+            verifyNoInteractions( request );
         }
         finally
         {
@@ -221,6 +233,15 @@ public class InvokerPropertiesTest
         facade.configureInvocation( request, 0 );
         verify( request ).setMavenOpts( "-Xmx512m" );
         verifyNoMoreInteractions( request );
+        clearInvocations( request );
+
+        props.clear();
+
+        facade.setDefaultMavenOpts( "-Xxx" );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setMavenOpts( "-Xxx" );
+        verifyNoMoreInteractions( request );
+
     }
 
     @Test
@@ -232,6 +253,7 @@ public class InvokerPropertiesTest
         props.setProperty( "invoker.failureBehavior", ReactorFailureBehavior.FailNever.getLongOption() );
         facade.configureInvocation( request, 0 );
         verify( request ).setReactorFailureBehavior( eq( ReactorFailureBehavior.FailNever ) );
+
         verifyNoMoreInteractions( request );
     }
 
@@ -242,14 +264,11 @@ public class InvokerPropertiesTest
         InvokerProperties facade = new InvokerProperties( props );
 
         props.setProperty( "invoker.failureBehavior", "xxxUnKnown" );
-        try
-        {
-            facade.configureInvocation( request, 0 );
-        }
-        catch ( IllegalArgumentException e )
-        {
-            assertEquals( "The string 'xxxUnKnown' can not be converted to enumeration.", e.getMessage() );
-        }
+
+        assertThatCode( () -> facade.configureInvocation( request, 0 ) )
+            .isExactlyInstanceOf( IllegalArgumentException.class  )
+            .hasMessage( "The string 'xxxUnKnown' can not be converted to enumeration." );
+
         verifyNoInteractions( request );
     }
 
@@ -306,6 +325,41 @@ public class InvokerPropertiesTest
         facade.configureInvocation( request, 0 );
         verify( request ).setDebug( false );
         verifyNoMoreInteractions( request );
+
+        props.clear();
+
+        facade.setDefaultDebug( true );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setDebug( true );
+        verifyNoMoreInteractions( request );
+        clearInvocations( request );
+
+        facade.setDefaultDebug( false );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setDebug( false );
+        verifyNoMoreInteractions( request );
+        clearInvocations( request );
+    }
+
+    @Test
+    public void testConfigureRequestTimeoutInSeconds()
+    {
+        Properties props = new Properties();
+        InvokerProperties facade = new InvokerProperties( props );
+
+        props.setProperty( "invoker.timeoutInSeconds", "5" );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setTimeoutInSeconds( 5 );
+        verifyNoMoreInteractions( request );
+        clearInvocations( request );
+
+        props.clear();
+
+        facade.setDefaultTimeoutInSeconds( 3 );
+        facade.configureInvocation( request, 0 );
+        verify( request ).setTimeoutInSeconds( 3 );
+        verifyNoMoreInteractions( request );
+
     }
 
     @Test
@@ -352,21 +406,21 @@ public class InvokerPropertiesTest
         Properties props = new Properties();
         InvokerProperties facade = new InvokerProperties( props );
 
-        assertFalse( facade.isInvocationDefined( 1 ) );
+        assertThat( facade.isInvocationDefined( 1 ) ).isFalse();
 
         props.setProperty( "invoker.goals", "install" );
-        assertFalse( facade.isInvocationDefined( 1 ) );
+        assertThat( facade.isInvocationDefined( 1 ) ).isFalse();
 
         props.setProperty( "invoker.goals.2", "install" );
-        assertFalse( facade.isInvocationDefined( 1 ) );
-        assertTrue( facade.isInvocationDefined( 2 ) );
-        assertFalse( facade.isInvocationDefined( 3 ) );
+        assertThat( facade.isInvocationDefined( 1 ) ).isFalse();
+        assertThat( facade.isInvocationDefined( 2 ) ).isTrue();
+        assertThat( facade.isInvocationDefined( 3 ) ).isFalse();
 
         props.setProperty( "invoker.goals.3", "install" );
-        assertFalse( facade.isInvocationDefined( 1 ) );
-        assertTrue( facade.isInvocationDefined( 2 ) );
-        assertTrue( facade.isInvocationDefined( 3 ) );
-        assertFalse( facade.isInvocationDefined( 4 ) );
+        assertThat( facade.isInvocationDefined( 1 ) ).isFalse();
+        assertThat( facade.isInvocationDefined( 2 ) ).isTrue();
+        assertThat( facade.isInvocationDefined( 3 ) ).isTrue();
+        assertThat( facade.isInvocationDefined( 4 ) ).isFalse();
     }
 
     @Test
@@ -375,21 +429,21 @@ public class InvokerPropertiesTest
         Properties props = new Properties();
         InvokerProperties facade = new InvokerProperties( props );
 
-        assertFalse( facade.isSelectorDefined( 1 ) );
+        assertThat( facade.isSelectorDefined( 1 ) ).isFalse();
 
         props.setProperty( "invoker.java.version", "1.6+" );
         props.setProperty( "invoker.maven.version", "3.0+" );
         props.setProperty( "invoker.os.family", "windows" );
-        assertFalse( facade.isSelectorDefined( 1 ) );
+        assertThat( facade.isSelectorDefined( 1 ) ).isFalse();
 
         props.setProperty( "selector.2.java.version", "1.6+" );
         props.setProperty( "selector.3.maven.version", "3.0+" );
         props.setProperty( "selector.4.os.family", "windows" );
-        assertFalse( facade.isSelectorDefined( 1 ) );
-        assertTrue( facade.isSelectorDefined( 2 ) );
-        assertTrue( facade.isSelectorDefined( 3 ) );
-        assertTrue( facade.isSelectorDefined( 4 ) );
-        assertFalse( facade.isSelectorDefined( 5 ) );
+        assertThat( facade.isSelectorDefined( 1 ) ).isFalse();
+        assertThat( facade.isSelectorDefined( 2 ) ).isTrue();
+        assertThat( facade.isSelectorDefined( 3 ) ).isTrue();
+        assertThat( facade.isSelectorDefined( 4 ) ).isTrue();
+        assertThat( facade.isSelectorDefined( 5 ) ).isFalse();
     }
 
     @Test
@@ -400,12 +454,10 @@ public class InvokerPropertiesTest
         InvokerProperties facade = new InvokerProperties( props );
 
         Collection<InvokerToolchain> toolchains = facade.getToolchains();
-        assertNotNull( toolchains );
-        assertEquals( 0, toolchains.size() );
+        assertThat( toolchains ).isEmpty();
 
         toolchains = facade.getToolchains( 1 );
-        assertNotNull( toolchains );
-        assertEquals( 0, toolchains.size() );
+        assertThat(  toolchains ).isEmpty();
     }
 
     @Test
@@ -416,11 +468,10 @@ public class InvokerPropertiesTest
         InvokerProperties facade = new InvokerProperties( props );
 
         Collection<InvokerToolchain> toolchains = facade.getToolchains();
-        assertNotNull( toolchains );
-        assertEquals( 1, toolchains.size() );
+        assertThat( toolchains ).hasSize( 1 );
         InvokerToolchain toolchain = toolchains.iterator().next();
-        assertEquals( "jdk", toolchain.getType() );
-        assertEquals( Collections.singletonMap( "version", "11" ), toolchain.getProvides() );
+        assertThat( toolchain.getType() ).isEqualTo( "jdk" );
+        assertThat( toolchain.getProvides() ).containsExactlyEntriesOf( Collections.singletonMap( "version", "11" ) );
     }
 
     @Test
@@ -431,11 +482,10 @@ public class InvokerPropertiesTest
         InvokerProperties facade = new InvokerProperties( props );
 
         Collection<InvokerToolchain> toolchains = facade.getToolchains( 1 );
-        assertNotNull( toolchains );
-        assertEquals( 1, toolchains.size() );
+        assertThat( toolchains ).hasSize( 1 );
         InvokerToolchain toolchain = toolchains.iterator().next();
-        assertEquals( "jdk", toolchain.getType() );
-        assertEquals( Collections.singletonMap( "version", "11" ), toolchain.getProvides() );
+        assertThat( toolchain.getType() ).isEqualTo( "jdk" );
+        assertThat( toolchain.getProvides() ).containsExactlyEntriesOf( Collections.singletonMap( "version", "11" ) );
     }
 
 }