#642 Simplify handling of toolchains file by autodetecting which JDKs are configured there.

This commit is contained in:
Andreas Gudian 2015-10-22 20:18:27 +02:00
parent feb5e2f13b
commit 82ab85d3bc
4 changed files with 215 additions and 36 deletions

View File

@ -52,12 +52,12 @@ public @interface ProcessorSuite {
/**
* Use an Oracle JDK 1.6 (or 1.6.x) via toolchain support to perform the processing
*/
ORACLE_JAVA_6( "oracle-[1.6,1.7)", "javac", "1.6" ),
ORACLE_JAVA_6( new Toolchain( "oracle", "1.6", "1.7" ), "javac", "1.6" ),
/**
* Use an Oracle JDK 1.7 (or 1.7.x) via toolchain support to perform the processing
*/
ORACLE_JAVA_7( "oracle-[1.7,1.8)", "javac", "1.7" ),
ORACLE_JAVA_7( new Toolchain( "oracle", "1.7", "1.8" ), "javac", "1.7" ),
/**
* Use the same JDK that runs the mvn build to perform the processing
@ -67,7 +67,7 @@ public @interface ProcessorSuite {
/**
* Use an Oracle JDK 1.9 (or 1.9.x) via toolchain support to perform the processing
*/
ORACLE_JAVA_9( "oracle-[1.9,1.10)", "javac", "1.9" ),
ORACLE_JAVA_9( new Toolchain( "oracle", "9", "10" ), "javac", "1.9" ),
/**
* Use the eclipse compiler with 1.7 source/target level from tycho-compiler-jdt to perform the build and
@ -100,11 +100,11 @@ public @interface ProcessorSuite {
private ProcessorType[] included = { };
private String toolchain;
private Toolchain toolchain;
private String compilerId;
private String sourceTargetVersion;
private ProcessorType(String toolchain, String compilerId, String sourceTargetVersion) {
private ProcessorType(Toolchain toolchain, String compilerId, String sourceTargetVersion) {
this.toolchain = toolchain;
this.compilerId = compilerId;
this.sourceTargetVersion = sourceTargetVersion;
@ -124,7 +124,7 @@ public @interface ProcessorSuite {
/**
* @return the toolchain
*/
public String getToolchain() {
public Toolchain getToolchain() {
return toolchain;
}

View File

@ -18,13 +18,23 @@
*/
package org.mapstruct.itest.testutil.runner;
import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination;
import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile;
import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.maven.it.Verifier;
import org.junit.internal.AssumptionViolatedException;
import org.junit.internal.runners.model.EachTestNotifier;
@ -35,10 +45,8 @@ import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType;
import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner.ProcessorTestCase;
import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination;
import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile;
import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory;
import org.mapstruct.itest.testutil.runner.xml.Toolchains;
import org.mapstruct.itest.testutil.runner.xml.Toolchains.ProviderDescription;
/**
* Runner for processor integration tests. Requires the annotation {@link ProcessorSuite} on the test class.
@ -57,7 +65,9 @@ public class ProcessorSuiteRunner extends ParentRunner<ProcessorTestCase> {
*/
public static final String SYS_PROP_DEBUG = "processorIntegrationTest.debug";
public static final String SYS_PROP_CAN_USE_JDK_9 = "processorIntegrationTest.canUseJdk9";
private static final File TOOLCHAINS_FILE = getToolchainsFile();
private static final Collection<ProcessorType> ENABLED_PROCESSOR_TYPES = detectSupportedTypes( TOOLCHAINS_FILE );
public static final class ProcessorTestCase {
private final String baseDir;
@ -67,16 +77,10 @@ public class ProcessorSuiteRunner extends ParentRunner<ProcessorTestCase> {
public ProcessorTestCase(String baseDir, ProcessorType processor) {
this.baseDir = baseDir;
this.processor = processor;
this.ignored =
( !TOOLCHAINS_ENABLED && processor.getToolchain() != null )
|| ( processor == ProcessorType.ORACLE_JAVA_9 && !CAN_USE_JDK_9 );
this.ignored = !ENABLED_PROCESSOR_TYPES.contains( processor );
}
}
private static final File SPECIFIED_TOOLCHAINS_FILE = getSpecifiedToolchainsFile();
private static final boolean TOOLCHAINS_ENABLED = toolchainsFileExists();
private static final boolean CAN_USE_JDK_9 = canUseJdk9();
private final List<ProcessorTestCase> methods;
/**
@ -227,15 +231,13 @@ public class ProcessorSuiteRunner extends ParentRunner<ProcessorTestCase> {
private void configureToolchains(ProcessorTestCase child, Verifier verifier, List<String> goals,
PrintStream originalOut) {
if ( child.processor.getToolchain() != null ) {
if ( null != SPECIFIED_TOOLCHAINS_FILE ) {
verifier.addCliOption( "--toolchains" );
verifier.addCliOption( SPECIFIED_TOOLCHAINS_FILE.getPath().replace( '\\', '/' ) );
}
verifier.addCliOption( "--toolchains" );
verifier.addCliOption( TOOLCHAINS_FILE.getPath().replace( '\\', '/' ) );
String[] parts = child.processor.getToolchain().split( "-" );
Toolchain toolchain = child.processor.getToolchain();
verifier.addCliOption( "-Dtoolchain-jdk-vendor=" + parts[0] );
verifier.addCliOption( "-Dtoolchain-jdk-version=" + parts[1] );
verifier.addCliOption( "-Dtoolchain-jdk-vendor=" + toolchain.getVendor() );
verifier.addCliOption( "-Dtoolchain-jdk-version=" + toolchain.getVersionRangeString() );
goals.add( "toolchains:toolchain" );
}
@ -257,7 +259,7 @@ public class ProcessorSuiteRunner extends ParentRunner<ProcessorTestCase> {
return extractResourceToDestination( getClass(), "/" + child.baseDir, tempDir, true );
}
private static File getSpecifiedToolchainsFile() {
private static File getToolchainsFile() {
String specifiedToolchainsFile = System.getProperty( SYS_PROP_TOOLCHAINS_FILE );
if ( null != specifiedToolchainsFile ) {
try {
@ -278,20 +280,59 @@ public class ProcessorSuiteRunner extends ParentRunner<ProcessorTestCase> {
}
}
return null;
// use default location
String defaultPath = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".m2";
return new File( defaultPath, "toolchains.xml" );
}
private static boolean canUseJdk9() {
return Boolean.parseBoolean( System.getProperty( SYS_PROP_CAN_USE_JDK_9, "true" ) );
}
private static boolean toolchainsFileExists() {
if ( null != SPECIFIED_TOOLCHAINS_FILE ) {
return SPECIFIED_TOOLCHAINS_FILE.exists();
private static Collection<ProcessorType> detectSupportedTypes(File toolchainsFile) {
Toolchains toolchains;
try {
if ( toolchainsFile.exists() ) {
Unmarshaller unmarshaller = JAXBContext.newInstance( Toolchains.class ).createUnmarshaller();
toolchains = (Toolchains) unmarshaller.unmarshal( toolchainsFile );
}
else {
toolchains = null;
}
}
catch ( JAXBException e ) {
toolchains = null;
}
String defaultPath = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".m2";
return new File( defaultPath, "toolchains.xml" ).exists();
Collection<ProcessorType> supported = new HashSet<>();
for ( ProcessorType type : ProcessorType.values() ) {
if ( isSupported( type, toolchains ) ) {
supported.add( type );
}
}
return supported;
}
private static boolean isSupported(ProcessorType type, Toolchains toolchains) {
if ( type.getToolchain() == null ) {
return true;
}
if ( toolchains == null ) {
return false;
}
Toolchain required = type.getToolchain();
for ( Toolchains.Toolchain tc : toolchains.getToolchains() ) {
if ( "jdk".equals( tc.getType() ) ) {
ProviderDescription desc = tc.getProviderDescription();
if ( desc != null
&& required.getVendor().equals( desc.getVendor() )
&& desc.getVersion() != null
&& desc.getVersion().startsWith( required.getVersionMinInclusive() ) ) {
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,51 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed 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.
*/
package org.mapstruct.itest.testutil.runner;
/**
* Describes a required entry in the Maven toolchains.xml file.
*
* @author Andreas Gudian
*/
class Toolchain {
private final String vendor;
private final String versionMinInclusive;
private final String versionMaxExclusive;
Toolchain(String vendor, String versionMinInclusive, String versionMaxExclusive) {
this.vendor = vendor;
this.versionMinInclusive = versionMinInclusive;
this.versionMaxExclusive = versionMaxExclusive;
}
String getVendor() {
return vendor;
}
String getVersionMinInclusive() {
return versionMinInclusive;
}
/**
* @return the version range string to be used in the Maven execution to select the toolchain
*/
String getVersionRangeString() {
return "[" + versionMinInclusive + "," + versionMaxExclusive + ")";
}
}

View File

@ -0,0 +1,87 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed 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.
*/
package org.mapstruct.itest.testutil.runner.xml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* JAXB representation of some of the parts in the Maven toolchains.xml file.
*
* @author Andreas Gudian
*/
@XmlRootElement
public class Toolchains {
@XmlElement(name = "toolchain")
private List<Toolchain> toolchains = new ArrayList<>();
public List<Toolchain> getToolchains() {
return toolchains;
}
@Override
public String toString() {
return "Toolchains [toolchains=" + toolchains + "]";
}
public static class Toolchain {
@XmlElement
private String type;
@XmlElement(name = "provides")
private ProviderDescription providerDescription;
public String getType() {
return type;
}
public ProviderDescription getProviderDescription() {
return providerDescription;
}
@Override
public String toString() {
return "Toolchain [type=" + type + ", providerDescription=" + providerDescription + "]";
}
}
public static class ProviderDescription {
@XmlElement
private String version;
@XmlElement
private String vendor;
public String getVersion() {
return version;
}
public String getVendor() {
return vendor;
}
@Override
public String toString() {
return "ProviderDescription [version=" + version + ", vendor=" + vendor + "]";
}
}
}