[MINVOKER-245] Using an alternate toolchain file
authorrfscholte <rfscholte@apache.org>
Fri, 11 Jan 2019 08:27:40 +0000 (09:27 +0100)
committerrfscholte <rfscholte@apache.org>
Fri, 11 Jan 2019 08:27:40 +0000 (09:27 +0100)
Add toolchain selector

13 files changed:
pom.xml
src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties [new file with mode: 0644]
src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml [new file with mode: 0644]
src/it/selector-conditions/src/it/toolchain-mismatch/postbuild.bsh [moved from src/it/selector-conditions/setup.groovy with 61% similarity]
src/it/selector-conditions/verify.bsh [deleted file]
src/it/selector-conditions/verify.groovy [new file with mode: 0644]
src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
src/main/java/org/apache/maven/plugins/invoker/InvokerProperties.java
src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java [new file with mode: 0644]
src/main/java/org/apache/maven/plugins/invoker/Selector.java
src/main/java/org/apache/maven/plugins/invoker/SelectorUtils.java
src/test/java/org/apache/maven/plugins/invoker/SelectorTest.java
src/test/java/org/apache/maven/plugins/invoker/SelectorUtilsTest.java

diff --git a/pom.xml b/pom.xml
index da83e0c..91b9956 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -226,6 +226,12 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>2.23.4</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
       <artifactId>maven-plugin-testing-harness</artifactId>
       <version>2.1</version>
diff --git a/src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties b/src/it/selector-conditions/src/it/toolchain-mismatch/invoker.properties
new file mode 100644 (file)
index 0000000..b22a425
--- /dev/null
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.toolchain.jdk.vendor = mycomp
diff --git a/src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml b/src/it/selector-conditions/src/it/toolchain-mismatch/pom.xml
new file mode 100644 (file)
index 0000000..ea5c00f
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>test</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+</project>
  * under the License.
  */
 
-import java.io.File
-import org.apache.commons.io.FileUtils
+import java.io.*;
 
-// Previous potential target 'content' has impact on IT execution
-// (Some new file should be created by verify.sh) 
-FileUtils.deleteQuietly( new File( basedir, "target/invoker-reports" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/jre-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/maven-version-match/target" ) );
-FileUtils.deleteQuietly( new File( basedir, "src/it/os-family-match/target" ) );
-return true;
+// create touch file so that the parent build can verify whether this build was executed
+File touchFile = new File( basedir, "target/touch.txt" );
+System.out.println( "Creating touch file: " + touchFile );
+touchFile.getParentFile().mkdirs();
+touchFile.createNewFile();
diff --git a/src/it/selector-conditions/verify.bsh b/src/it/selector-conditions/verify.bsh
deleted file mode 100644 (file)
index 2618914..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.*;
-import java.util.*;
-import java.util.regex.*;
-
-try
-{
-    String[] expected = {
-            "target/its/jre-version-match/target/touch.txt",
-            "target/its/os-family-match/target/touch.txt",
-      };
-    for ( String file : expected )
-    {
-        File touchFile = new File( basedir, file );
-        System.out.println( "Checking for existence of: " + touchFile );
-        if ( !touchFile.isFile() )
-        {
-            System.out.println( "FAILED!" );
-            return false;
-        }
-    }
-
-    String[] unexpected = {
-            "target/its/jre-version-mismatch/target/touch.txt",
-            "target/its/os-family-mismatch/target/touch.txt",
-      };
-    for ( String file : unexpected )
-    {
-        File touchFile = new File( basedir, file );
-        System.out.println( "Checking for absence of: " + touchFile );
-        if ( touchFile.exists() )
-        {
-            System.out.println( "FAILED!" );
-            return false;
-        }
-    }
-}
-catch( Throwable t )
-{
-    t.printStackTrace();
-    return false;
-}
-
-return true;
diff --git a/src/it/selector-conditions/verify.groovy b/src/it/selector-conditions/verify.groovy
new file mode 100644 (file)
index 0000000..68eb51e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+def FS = System.getProperty('file.separator')
+
+assert new File(basedir, 'target/its/jre-version-match/build.log').exists()
+assert !(new File(basedir, 'target/its/jre-version-mismatch/build.log').exists())
+assert new File(basedir, 'target/its/maven-version-match/build.log').exists()
+assert !(new File(basedir, 'target/its/maven-version-mismatch/build.log').exists())
+assert new File(basedir, 'target/its/os-family-match/build.log').exists()
+assert !(new File(basedir, 'target/its/os-family-mismatch/build.log').exists())
+assert !(new File(basedir, 'target/its/toolchain-mismatch/build.log').exists())
+
+def log = new File( basedir, 'build.log').text
+
+assert log.contains("jre-version-match${FS}pom.xml ........................ SUCCESS")
+assert log.contains("jre-version-mismatch${FS}pom.xml ..................... SKIPPED due to JRE version")
+assert log.contains("maven-version-match${FS}pom.xml ...................... SUCCESS")
+assert log.contains("maven-version-mismatch${FS}pom.xml ................... SKIPPED due to Maven version")
+assert log.contains("os-family-match${FS}pom.xml .......................... SUCCESS")
+assert log.contains("os-family-mismatch${FS}pom.xml ....................... SKIPPED due to OS")
+assert log.contains("toolchain-mismatch${FS}pom.xml ....................... SKIPPED due to Toolchain")
\ No newline at end of file
index e75c2c4..13ab1a8 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.maven.plugins.invoker;
  */\r
 \r
 import org.apache.maven.artifact.Artifact;\r
+import org.apache.maven.execution.MavenSession;\r
 import org.apache.maven.model.Model;\r
 import org.apache.maven.model.Profile;\r
 import org.apache.maven.plugin.AbstractMojo;\r
@@ -50,6 +51,9 @@ import org.apache.maven.shared.scriptinterpreter.RunErrorException;
 import org.apache.maven.shared.scriptinterpreter.RunFailureException;\r
 import org.apache.maven.shared.scriptinterpreter.ScriptRunner;\r
 import org.apache.maven.shared.utils.logging.MessageBuilder;\r
+import org.apache.maven.toolchain.MisconfiguredToolchainException;\r
+import org.apache.maven.toolchain.ToolchainManagerPrivate;\r
+import org.apache.maven.toolchain.ToolchainPrivate;\r
 import org.codehaus.plexus.interpolation.InterpolationException;\r
 import org.codehaus.plexus.interpolation.Interpolator;\r
 import org.codehaus.plexus.interpolation.MapBasedValueSource;\r
@@ -255,6 +259,9 @@ public abstract class AbstractInvokerMojo
 \r
     @Component\r
     private SettingsBuilder settingsBuilder;\r
+    \r
+    @Component\r
+    private ToolchainManagerPrivate toolchainManagerPrivate;\r
 \r
     /**\r
      * Relative path of a selector script to run prior in order to decide if the build should be executed. This script\r
@@ -348,6 +355,9 @@ public abstract class AbstractInvokerMojo
     @Parameter( defaultValue = "${project}", readonly = true, required = true )\r
     private MavenProject project;\r
 \r
+    @Parameter( defaultValue = "${session}", readonly = true, required = true )\r
+    private MavenSession session;\r
+\r
     @Parameter( defaultValue = "${mojoExecution}", readonly = true, required = true )\r
     private MojoExecution mojoExecution;\r
 \r
@@ -514,7 +524,12 @@ public abstract class AbstractInvokerMojo
      * # Since plugin version 1.5\r
      * invoker.maven.version = 2.0.10+, !2.1.0, !2.2.0\r
      * \r
-     * # For java.version, maven.version and os.family it is possible to define multiple selectors.\r
+     * # A mapping for toolchain to ensure it exists\r
+     * # Since plugin version 3.2.0\r
+     * invoker.toolchain.&lt;type&gt;.&lt;provides&gt; = value\r
+     * invoker.toolchain.jdk.version = 11\r
+     * \r
+     * # For java.version, maven.version, os.family and toolchain it is possible to define multiple selectors.\r
      * # If one of the indexed selectors matches, the test is executed.\r
      * # With the invoker.x.y equivalents you can specify global matchers.  \r
      * selector.1.java.version = 1.8+\r
@@ -1584,6 +1599,14 @@ public abstract class AbstractInvokerMojo
                         }\r
                         message.append( "OS" );\r
                     }\r
+                    if ( ( selection & Selector.SELECTOR_TOOLCHAIN ) != 0 )\r
+                    {\r
+                        if ( message.length() > 0 )\r
+                        {\r
+                            message.append( ", " );\r
+                        }\r
+                        message.append( "Toolchain" );\r
+                    }\r
                 }\r
 \r
                 if ( !suppressSummaries )\r
@@ -1673,7 +1696,13 @@ public abstract class AbstractInvokerMojo
      */\r
     private int getSelection( InvokerProperties invokerProperties, CharSequence actualJreVersion )\r
     {\r
-        return new Selector( actualMavenVersion, actualJreVersion.toString() ).getSelection( invokerProperties );\r
+        return new Selector( actualMavenVersion, actualJreVersion.toString(),\r
+                             getToolchainPrivateManager() ).getSelection( invokerProperties );\r
+    }\r
+\r
+    private ToolchainPrivateManager getToolchainPrivateManager()\r
+    {\r
+        return new ToolchainPrivateManager( toolchainManagerPrivate, session );\r
     }\r
 \r
     /**\r
@@ -2561,4 +2590,21 @@ public abstract class AbstractInvokerMojo
         return parallelThreads > 1;\r
     }\r
 \r
+    static class ToolchainPrivateManager\r
+    {\r
+        private ToolchainManagerPrivate manager;\r
+        \r
+        private MavenSession session;\r
+\r
+        ToolchainPrivateManager( ToolchainManagerPrivate manager, MavenSession session )\r
+        {\r
+            this.manager = manager;\r
+            this.session = session;\r
+        }\r
+\r
+        ToolchainPrivate[] getToolchainPrivates( String type ) throws MisconfiguredToolchainException\r
+        {\r
+            return manager.getToolchainsForType( type, session );\r
+        }\r
+    }\r
 }\r
index 0e0124f..e8ba20e 100644 (file)
@@ -22,7 +22,12 @@ package org.apache.maven.plugins.invoker;
 import java.io.File;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
 import java.util.Properties;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
 \r
 import org.apache.maven.shared.invoker.InvocationRequest;\r
 import org.apache.maven.shared.invoker.InvocationRequest.ReactorFailureBehavior;\r
@@ -196,8 +201,41 @@ class InvokerProperties
     {\r
         return this.properties.getProperty( SELECTOR_PREFIX + index + SelectorProperty.OS_FAMLY.suffix,\r
                                             getOsFamily() );\r
-    }   \r
+    }\r
     \r
+    public Collection<InvokerToolchain> getToolchains()\r
+    {\r
+        return getToolchains( Pattern.compile( "invoker\\.toolchain\\.([^\\.]+)\\.(.+)" ) );\r
+    }\r
+\r
+    public Collection<InvokerToolchain> getToolchains( int index )\r
+    {\r
+        return getToolchains( Pattern.compile( "selector\\." + index + "\\.invoker\\.toolchain\\.([^\\.]+)\\.(.+)" ) );\r
+    }\r
+\r
+    private Collection<InvokerToolchain> getToolchains( Pattern p )\r
+    {\r
+        Map<String, InvokerToolchain> toolchains = new HashMap<>();\r
+        for ( Map.Entry<Object, Object> entry : this.properties.entrySet() )\r
+        {\r
+            Matcher m = p.matcher( entry.getKey().toString() );\r
+            if ( m.matches() )\r
+            {\r
+                String type = m.group( 1 );\r
+                String providesKey = m.group( 2 );\r
+                String providesValue = entry.getValue().toString();\r
+\r
+                InvokerToolchain tc = toolchains.get( type );\r
+                if ( tc == null )\r
+                {\r
+                    tc = new InvokerToolchain( type );\r
+                    toolchains.put( type, tc );\r
+                }\r
+                tc.addProvides( providesKey, providesValue );\r
+            }\r
+        }\r
+        return toolchains.values();\r
+    }\r
 \r
     /**\r
      * Determines whether these invoker properties contain a build definition for the specified invocation index.\r
diff --git a/src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java b/src/main/java/org/apache/maven/plugins/invoker/InvokerToolchain.java
new file mode 100644 (file)
index 0000000..c2381fe
--- /dev/null
@@ -0,0 +1,55 @@
+package org.apache.maven.plugins.invoker;
+
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+/**
+ * 
+ * @author Robert Scholte
+ * @since 3.2.0
+ */
+public class InvokerToolchain
+{
+    private final String type;
+    
+    private Map<String, String> provides = new HashMap<>();
+    
+    public InvokerToolchain( String type )
+    {
+        this.type = type;
+    }
+    
+    public String getType()
+    {
+        return type;
+    }
+    
+    public void addProvides( String key, String value )
+    {
+        provides.put( key, value );
+    }
+    
+    public Map<String, String> getProvides()
+    {
+        return provides;
+    }
+}
index f1386d4..0391dd3 100644 (file)
@@ -19,6 +19,8 @@ package org.apache.maven.plugins.invoker;
  * under the License.\r
  */\r
 \r
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;\r
+\r
 /**\r
  * \r
  * @author Robert Scholte\r
@@ -32,16 +34,21 @@ class Selector
 \r
     static final int SELECTOR_OSFAMILY = 4;\r
     \r
-    static final int SELECTOR_MULTI = 8;\r
+    static final int SELECTOR_TOOLCHAIN = 8;\r
+\r
+    static final int SELECTOR_MULTI = 16;\r
     \r
     private final String actualMavenVersion;\r
     \r
     private final String actualJavaVersion;\r
     \r
-    Selector( String actualMavenVersion, String actualJavaVersion )\r
+    private final ToolchainPrivateManager toolchainPrivateManager; \r
+    \r
+    Selector( String actualMavenVersion, String actualJavaVersion, ToolchainPrivateManager toolchainPrivateManager )\r
     {\r
         this.actualMavenVersion = actualMavenVersion;\r
         this.actualJavaVersion = actualJavaVersion;\r
+        this.toolchainPrivateManager = toolchainPrivateManager;\r
     }\r
     \r
     public int getSelection( InvokerProperties invokerProperties ) \r
@@ -75,6 +82,12 @@ class Selector
                 selection |= SELECTOR_OSFAMILY;\r
             }\r
 \r
+            if ( !SelectorUtils.isToolchain( toolchainPrivateManager,\r
+                                             invokerProperties.getToolchains( selectorIndex ) ) )\r
+            {\r
+                selection |= SELECTOR_TOOLCHAIN;\r
+            }\r
+\r
             if ( selection == 0 )\r
             {\r
                 return 0;\r
@@ -108,6 +121,11 @@ class Selector
             selection |= SELECTOR_OSFAMILY;\r
         }\r
 \r
+        if ( !SelectorUtils.isToolchain( toolchainPrivateManager, invokerProperties.getToolchains() ) )\r
+        {\r
+            selection |= SELECTOR_TOOLCHAIN;\r
+        }\r
+\r
         return selection;\r
     }\r
 }\r
index 5f18259..fe89761 100644 (file)
@@ -30,7 +30,10 @@ import java.util.Iterator;
 import java.util.List;\r
 import java.util.Properties;\r
 \r
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;\r
 import org.apache.maven.project.MavenProject;\r
+import org.apache.maven.toolchain.MisconfiguredToolchainException;\r
+import org.apache.maven.toolchain.ToolchainPrivate;\r
 import org.codehaus.plexus.util.Os;\r
 import org.codehaus.plexus.util.StringUtils;\r
 \r
@@ -279,5 +282,46 @@ class SelectorUtils
             }\r
         }\r
     }\r
+    \r
+    /**\r
+     * @param toolchainPrivateManager\r
+     * @param invokerToolchains\r
+     * @return {@code true} if all invokerToolchains are available, otherwise {@code false}\r
+     */\r
+    static boolean isToolchain( ToolchainPrivateManager toolchainPrivateManager,\r
+                                Collection<InvokerToolchain> invokerToolchains )\r
+    {\r
+        for ( InvokerToolchain invokerToolchain : invokerToolchains )\r
+        {\r
+            boolean found = false;\r
+            try\r
+            {\r
+                for ( ToolchainPrivate tc : toolchainPrivateManager.getToolchainPrivates( invokerToolchain.getType() ) )\r
+                {\r
+                    if ( !invokerToolchain.getType().equals( tc.getType() ) )\r
+                    {\r
+                        // useful because of MNG-5716\r
+                        continue;\r
+                    }\r
+\r
+                    if ( tc.matchesRequirements( invokerToolchain.getProvides() ) )\r
+                    {\r
+                        found = true;\r
+                        continue;\r
+                    }\r
+                }\r
+            }\r
+            catch ( MisconfiguredToolchainException e )\r
+            {\r
+                return false;\r
+            }\r
+            \r
+            if ( !found )\r
+            { \r
+                return false;\r
+            }\r
+        }\r
 \r
+        return true;\r
+    }\r
 }\r
index 70886fc..bd79a5a 100644 (file)
@@ -31,7 +31,7 @@ public class SelectorTest
     @Test\r
     public void testGlobalMatch()\r
     {\r
-        Selector selector = new Selector( "3.2.5", "1.7" );\r
+        Selector selector = new Selector( "3.2.5", "1.7", null );\r
 \r
         Properties props = new Properties();\r
         props.setProperty( "invoker.maven.version", "3.0+" );\r
@@ -42,7 +42,7 @@ public class SelectorTest
     @Test\r
     public void testSelectorMatch()\r
     {\r
-        Selector selector = new Selector( "3.2.5", "1.7" );\r
+        Selector selector = new Selector( "3.2.5", "1.7", null );\r
 \r
         Properties props = new Properties();\r
         props.setProperty( "selector.1.maven.version", "3.0+" );\r
@@ -56,7 +56,7 @@ public class SelectorTest
     @Test\r
     public void testSelectorWithGlobalMatch()\r
     {\r
-        Selector selector = new Selector( "3.2.5", "1.7" );\r
+        Selector selector = new Selector( "3.2.5", "1.7", null );\r
 \r
         Properties props = new Properties();\r
         // invoker.maven.version is used by all selectors\r
index 02760da..785f974 100644 (file)
@@ -19,13 +19,22 @@ package org.apache.maven.plugins.invoker;
  * under the License.\r
  */\r
 \r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.when;\r
+import static org.mockito.Mockito.isA;\r
+\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.Collections;\r
 import java.util.List;\r
+import java.util.Map;\r
 \r
-import org.apache.maven.plugins.invoker.SelectorUtils;\r
-\r
-import junit.framework.TestCase;\r
+import org.apache.maven.plugins.invoker.AbstractInvokerMojo.ToolchainPrivateManager;\r
+import org.apache.maven.toolchain.ToolchainPrivate;\r
+import org.junit.Test;\r
 \r
 /**\r
  * Tests {@link SelectorUtils}.\r
@@ -33,9 +42,9 @@ import junit.framework.TestCase;
  * @author Benjamin Bentmann\r
  */\r
 public class SelectorUtilsTest\r
-    extends TestCase\r
 {\r
 \r
+    @Test\r
     public void testParseList()\r
     {\r
         List<String> includes = new ArrayList<String>();\r
@@ -48,6 +57,7 @@ public class SelectorUtilsTest
         assertEquals( Arrays.asList( "1.4" ), excludes );\r
     }\r
 \r
+    @Test\r
     public void testParseVersion()\r
     {\r
         assertEquals( Arrays.asList( 1, 6, 0, 12 ), SelectorUtils.parseVersion( "1.6.0_12" ) );\r
@@ -56,6 +66,7 @@ public class SelectorUtilsTest
         assertEquals( Arrays.asList( 1, 6, 0, 12 ), SelectorUtils.parseVersion( "1.6.0_12-" ) );\r
     }\r
 \r
+    @Test\r
     public void testCompareVersions()\r
     {\r
         assertTrue( SelectorUtils.compareVersions( Arrays.asList( 1, 6 ), Arrays.asList( 1, 6 ) ) == 0 );\r
@@ -67,6 +78,7 @@ public class SelectorUtilsTest
         assertTrue( SelectorUtils.compareVersions( Arrays.asList( 1, 6 ), Arrays.asList( 1 ) ) > 0 );\r
     }\r
 \r
+    @Test\r
     public void testIsMatchingJre()\r
     {\r
 \r
@@ -88,5 +100,40 @@ public class SelectorUtilsTest
         assertTrue( SelectorUtils.isJreVersion( (String) null, "1.5" ) );\r
         assertTrue( SelectorUtils.isJreVersion( "", "1.5" ) );\r
     }\r
+    \r
+    @Test\r
+    public void testIsMatchingToolchain() throws Exception\r
+    {\r
+        InvokerToolchain openJdk9 = new InvokerToolchain( "jdk" );\r
+        openJdk9.addProvides( "version", "9" );\r
+        openJdk9.addProvides( "vendor", "openJDK" );\r
+\r
+        InvokerToolchain maven360 = new InvokerToolchain( "maven" );\r
+        openJdk9.addProvides( "version", "3.6.0" );\r
+\r
+        ToolchainPrivateManager toolchainPrivateManager = mock( ToolchainPrivateManager.class );\r
+        ToolchainPrivate jdkMatching = mock( ToolchainPrivate.class );\r
+        when( jdkMatching.matchesRequirements( isA( Map.class ) ) ).thenReturn( true );\r
+        when( jdkMatching.getType() ).thenReturn( "jdk");\r
+\r
+        ToolchainPrivate jdkMismatch = mock( ToolchainPrivate.class );\r
+        when( jdkMismatch.getType() ).thenReturn( "jdk");\r
+\r
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching } );\r
+        assertTrue( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );\r
+\r
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMismatch } );\r
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );\r
+\r
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching, jdkMismatch, jdkMatching } );\r
+        assertTrue( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );\r
+\r
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[0] );\r
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Collections.singleton( openJdk9 ) ) );\r
+        \r
+        when( toolchainPrivateManager.getToolchainPrivates( "jdk" ) ).thenReturn( new ToolchainPrivate[] { jdkMatching } );\r
+        when( toolchainPrivateManager.getToolchainPrivates( "maven" ) ).thenReturn( new ToolchainPrivate[0] );\r
+        assertFalse( SelectorUtils.isToolchain( toolchainPrivateManager, Arrays.asList( openJdk9, maven360 ) ) );\r
+    }\r
 \r
 }\r