All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.gwt.shell.TestMojo Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
package org.codehaus.mojo.gwt.shell;

/*
 * 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 org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.surefire.report.ReporterManager;
import org.codehaus.mojo.gwt.test.MavenTestRunner;
import org.codehaus.mojo.gwt.test.TestTemplate;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.net.URL;
import java.util.Collection;

/**
 * Mimic surefire to run GWTTestCases during integration-test phase, until SUREFIRE-508 is fixed
 *
 * @author Nicolas De Loof
 * @version $Id: TestMojo.java 9466 2009-04-16 12:03:15Z ndeloof $
 */
@Mojo(name = "test", defaultPhase = LifecyclePhase.INTEGRATION_TEST, requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
public class TestMojo
    extends AbstractGwtShellMojo
{

    /**
     * Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED,
     * but quite convenient on occasion.
     */
    @Parameter(property = "skipTests")
    private boolean skipTests;

    /**
     * DEPRECATED This old parameter is just like skipTests, but bound to the old property
     * maven.test.skip.exec. Use -DskipTests instead; it's shorter.
     */
    @Deprecated
    @Parameter(property = "maven.test.skip.exec")
    private boolean skipExec;

    /**
     * Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if
     * you enable it using the "maven.test.skip" property, because maven.test.skip disables both
     * running the tests and compiling the tests. Consider using the skipTests parameter instead.
     */
    @Parameter(property = "maven.test.skip")
    private boolean skip;

    /**
     * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite
     * convenient on occasion.
     */
    @Parameter(property = "maven.test.failure.ignore")
    private boolean testFailureIgnore;

    /**
     * output directory for code generated by GWT for tests
     */
    @Parameter(defaultValue = "${project.build.directory}/www-test")
    private String out;

    /**
     * run tests using web mode rather than developer (a.k.a. hosted) mode
     * 
     * @deprecated Use productionMode instead.
     */
    @Deprecated
    @Parameter(defaultValue = "false", property = "gwt.test.web")
    private boolean webMode;

    /**
     * run tests using production mode rather than development (a.k.a. hosted) mode.
     * 
     * @see http://code.google.com/intl/fr-FR/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html#DevGuideProdMode
     */
    @Parameter(defaultValue = "false", property = "gwt.test.prod")
    private boolean productionMode;

    /**
     * Configure test mode. Can be set to "manual", "htmlunit" or "selenium". If set
     * to any other value, that value will be passed as the -runStyle argument,
     * allowing you to use an arbitrary RunStyle when running tests.
     */
    @Parameter(defaultValue = "htmlunit", property = "gwt.test.mode")
    private String mode;

    /**
     * Configure options to run tests with HTMLUnit. The value must describe the browser emulation
     * to be used, FF31, FF38, IE8, IE11, Chrome or Edge (possible multiple values separated by comas).
     * 
     * @see http://code.google.com/intl/fr/webtoolkit/doc/latest/DevGuideTestingHtmlUnit.html
     */
    @Parameter(defaultValue = "FF38", property = "gwt.test.htmlunit")
    private String htmlunit;

    /**
     * Configure options to run tests with Selenium. The value must describe the Selenium Remote
     * Control target
     * 
     * @see http://code.google.com/intl/fr/webtoolkit/doc/latest/DevGuideTestingRemoteTesting.html#Selenium
     */
    @Parameter(property = "gwt.test.selenium")
    private String selenium;

    /**
     * Time out (in seconds) for test execution in dedicated JVM
     */
    @Parameter(defaultValue = "60")
    @SuppressWarnings("unused")
    private int testTimeOut;

    /**
     * Comma separated list of ant-style inclusion patterns for GWT integration tests. For example,
     * can be set to **\/*GwtTest.java to match all test class following this naming
     * convention. Surefire plugin may then ne configured to exclude such tests.
     * 

* It is recommended to use a TestSuite to run GwtTests, as they require some huge setup and are * very slow. Running inside a suite allow to execute the setup only once. The default value is * defined with this best practice in mind. */ @Parameter(defaultValue = "**/GwtTest*.java,**/Gwt*Suite.java") protected String includes; /** * Comma separated list of ant-style exclusion patterns for GWT integration tests */ @Parameter protected String excludes; /** * Directory for test reports, defaults to surefire one to match the surefire-report plugin */ @Parameter(defaultValue = "${project.build.directory}/surefire-reports") private File reportsDirectory; /** * Specify the user agents to reduce the number of permutations in '-prod' mode; * e.g. ie8,safari,gecko1_8 * * @since 2.5.0-rc1 */ @Parameter(property = "gwt.test.userAgents") private String userAgents; /** * Configure batch execution of tests. *

* Value must be one of 'none', 'class' or 'module'. *

* * @since 2.5.0-rc1 */ @Parameter(property = "gwt.test.batch") private String batch; /** * Causes the log window and browser windows to be displayed; useful for debugging. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "false", property = "gwt.test.showUi") private boolean showUi; /** * The compiler's working directory for internal use (must be writeable; defaults to a system temp dir) * * @since 2.6.0-rc1 */ @Parameter private File workDir; /** * Logs to a file in the given directory * * @since 2.6.0-rc1 */ @Parameter private File logDir; /** * Specifies Java source level. *

* The default value depends on the JVM used to launch Maven. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "auto", property = "maven.compiler.source") private String sourceLevel; /** * Whether or not to enable assertions in generated scripts (-checkAssertions). * * @since 2.6.0-rc1 */ @Parameter(alias = "enableAssertions", defaultValue = "false") private boolean checkAssertions; /** * EXPERIMENTAL: Disables some java.lang.Class methods (e.g. getName()). *

* Can be set from command line using '-Dgwt.disableClassMetadata=true'. *

* * @since 2.6.0-rc1 */ @Parameter(defaultValue = "false", property = "gwt.disableClassMetadata") private boolean disableClassMetadata; /** * EXPERIMENTAL: Disables run-time checking of cast operations. *

* Can be set from command line using '-Dgwt.disableCastChecking=true'. *

* * @since 2.6.0-rc1 */ @Parameter(defaultValue = "false", property = "gwt.disableCastChecking") private boolean disableCastChecking; /** * EXPERIMENTAL: Disables code-splitting. *

* Can be set from command line using '-Dgwt.disableRunAsync=true'. *

* * @since 2.6.0-rc1 */ @Parameter(defaultValue = "false", property = "gwt.disableRunAsync") private boolean disableRunAsync; /** * Enable faster, but less-optimized, compilations. *

* Can be set from command line using '-Dgwt.draftCompile=true'. *

* * @since 2.6.0-rc1 */ @Parameter(defaultValue = "false", property = "gwt.draftCompiler") private boolean draftCompile; /** * EXPERIMENTAL: Cluster similar functions in the output to improve compression. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "true", property = "gwt.compiler.clusterFunctions") private boolean clusterFunctions; /** * EXPERIMENTAL: Inline literal parameters to shrink function declarations and * provide more deadcode elimination possibilities. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "true", property = "gwt.compiler.inlineLiteralParameters") private boolean inlineLiteralParameters; /** * EXPERIMENTAL: Analyze and optimize dataflow. * * since 2.6.0-rc1 */ @Parameter(defaultValue = "true", property = "gwt.compiler.optimizeDataflow") private boolean optimizeDataflow; /** * EXPERIMENTAL: Ordinalize enums to reduce some large strings. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "true", property = "gwt.compiler.ordinalizeEnums") private boolean ordinalizeEnums; /** * EXPERIMENTAL: Removing duplicate functions. *

* Will interfere with stacktrace deobfuscation and so is only honored when compiler.stackMode is set to strip. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "true", property = "gwt.compiler.removeDuplicateFunctions") private boolean removeDuplicateFunctions; /** * Sets the optimization level used by the compiler. 0=none 9=maximum. *

* -1 uses the default level of the compiler. *

*

* Can be set from command line using '-Dgwt.compiler.optimizationLevel=n'. *

* * @since 2.6.0-rc1 */ @Parameter(defaultValue = "-1", property = "gwt.compiler.optimizationLevel") private int optimizationLevel; /** * Set the test method timeout, in minutes * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "5", property = "gwt.testMethodTimeout") private int testMethodTimeout; /** * Set the test begin timeout (time for clients to contact server), in minutes * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "1", property = "gwt.testBeginTimeout") private int testBeginTimeout; /** * Precompile modules as tests are running (speeds up remote tests but requires more memory) *

* The value is one of simple, all, or parallel. * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "simple", property = "gwt.test.precompile") private String precompile; /** * EXPERIMENTAL: Sets the maximum number of attempts for running each test method * * @since 2.6.0-rc1 */ @Parameter(defaultValue = "1", property = "gwt.test.tries") private int tries; /** * Puts most JavaScript globals into namespaces. *

* Value is one of PACKAGE or NONE. *

* Default: PACKAGE for -draftCompile, otherwise NONE * * @since 2.7.0-rc1 */ @Parameter private String namespace; /** * Compiles faster by reusing data from the previous compile. * * @since 2.7.0-rc1 */ @Parameter(alias = "compilePerFile", defaultValue = "false", property = "gwt.compiler.incremental") private boolean incremental; /** * Generate exports for JsInterop purposes. * * @since 2.8.0-rc1 */ @Parameter(alias = "generateJsInteropExports", defaultValue = "false", property = "gwt.compiler.generateJsInteropExports") private boolean generateJsInteropExports; /** failures counter */ private int failures; @Override public void doExecute() throws MojoExecutionException, MojoFailureException { if ( skip || skipTests || skipExec ) { return; } new TestTemplate( getProject(), includes, excludes, new TestTemplate.CallBack() { public void doWithTest( File sourceDir, String test ) throws MojoExecutionException { forkToRunTest( test ); } } ); if ( failures > 0 ) { if ( testFailureIgnore ) { getLog().error( "There are test failures.\n\nPlease refer to " + reportsDirectory + " for the individual test results." ); } else { throw new MojoExecutionException( "There were test failures." ); } } } /** * @param classpath the test execution classpath * @param jvm the JVM process command * @param test the test to run * @throws MojoExecutionException some error occured */ private void forkToRunTest( String test ) throws MojoExecutionException { test = test.substring( 0, test.length() - 5 ); test = StringUtils.replace( test, File.separator, "." ); try { File outFile = new File(out); if (outFile.isAbsolute()) { outFile.mkdirs(); } else { new File( getProject().getBasedir(), out ).mkdirs(); } try { JavaCommand cmd = createJavaCommand() .setMainClass( MavenTestRunner.class.getName() ); if ( gwtSdkFirstInClasspath ) { cmd.addToClasspath( getGwtUserJar() ) .addToClasspath( getGwtDevJar() ); } cmd.addToClasspath( getClasspath( Artifact.SCOPE_TEST ) ); if ( !gwtSdkFirstInClasspath ) { cmd.addToClasspath( getGwtUserJar() ) .addToClasspath( getGwtDevJar() ); } addCompileSourceArtifacts( cmd ); cmd.arg( test ); cmd.systemProperty( "surefire.reports", reportsDirectory.getAbsolutePath() ); cmd.systemProperty( "gwt.args", StringUtils.escape(getGwtArgs()) ); cmd.execute(); } catch ( JavaCommandException e ) { getLog().warn("GWT test failure", e); failures++; } } catch ( Exception e ) { throw new MojoExecutionException( "Failed to run GWT tests", e ); } } protected String getGwtArgs() { StringBuilder sb = new StringBuilder(); sb.append( "-war " ).append( quote( out ) ); sb.append( " -logLevel " ).append( quote( getLogLevel() ) ); sb.append( ( webMode || productionMode ) ? " -nodevMode" : " -devMode" ); sb.append( checkAssertions ? " -checkAssertions" : " -nocheckAssertions" ); sb.append( clusterFunctions ? " -XclusterFunctions" : " -XnoclusterFunctions" ); sb.append( disableCastChecking ? " -XnocheckCasts" : " -XcheckCasts" ); sb.append( disableClassMetadata ? " -XnoclassMetadata" : " -XclassMetadata" ); sb.append( disableRunAsync ? " -XnocodeSplitting" : " -XcodeSplitting" ); sb.append( draftCompile ? " -draftCompile" : " -nodraftCompile" ); sb.append( inlineLiteralParameters ? " -XinlineLiteralParameters" : " -XnoinlineLiteralParameters" ); sb.append( optimizeDataflow ? " -XoptimizeDataflow" : " -XnooptimizeDataflow" ); sb.append( ordinalizeEnums ? " -XordinalizeEnums" : " -XnoordinalizeEnums" ); sb.append( removeDuplicateFunctions ? " -XremoveDuplicateFunctions" : " -XnoremoveDuplicateFunctions" ); sb.append( showUi ? " -showUi" : " -noshowUi" ); sb.append( " -sourceLevel " ).append( quote( sourceLevel ) ); sb.append( " -testBeginTimeout " ).append( testBeginTimeout ); sb.append( " -testMethodTimeout ").append( testMethodTimeout ); sb.append( " -Xtries " ).append( tries ); sb.append( incremental ? " -incremental" : " -noincremental" ); if ( optimizationLevel >= 0 ) { sb.append( " -optimize " ).append( optimizationLevel ); } if ( precompile != null && !precompile.trim().isEmpty() ) { sb.append( " -precompile " ).append( quote( precompile ) ); } if ( logDir != null ) { sb.append( " -logdir " ).append( quote( logDir.getAbsolutePath() ) ); } if ( workDir != null ) { sb.append( " -workDir " ).append( quote( workDir.getAbsolutePath() ) ); } if ( namespace != null && !namespace.trim().isEmpty() ) { sb.append( " -Xnamespace " ).append( quote( namespace ) ); } if ( generateJsInteropExports ) { sb.append( " -generateJsInteropExports" ); } if ( mode.equalsIgnoreCase( "manual" ) ) { sb.append( " -runStyle Manual:1" ); } else if ( mode.equalsIgnoreCase( "htmlunit" ) ) { sb.append( " -runStyle ").append( quote( "HtmlUnit:" + htmlunit ) ); } else if ( mode.equalsIgnoreCase( "selenium" ) ) { sb.append( " -runStyle ").append( quote( "Selenium:" + selenium ) ); } else if ( !mode.trim().isEmpty() ) { sb.append( " -runStyle ").append( quote( mode ) ); } if ( userAgents != null && !userAgents.trim().isEmpty() ) { sb.append( " -userAgents " ).append( quote( userAgents ) ); } if ( batch != null && !batch.trim().isEmpty() ) { sb.append( " -batch " ).append( quote( batch ) ); } // TODO Is addArgumentDeploy(cmd) also needed to get readable test stacktraces with an alternative deploy dir? return sb.toString(); } private String quote(String arg) { return StringUtils.quoteAndEscape( arg, '"', new char[] { '"', ' ', '\t', '\r', '\n' } ); } @Override protected void postProcessClassPath( Collection classpath ) { classpath.add( getClassPathElementFor( TestMojo.class ) ); classpath.add( getClassPathElementFor( ReporterManager.class ) ); } /** * @param clazz class to check for classpath resolution * @return The classpath element this class was loaded from */ private File getClassPathElementFor( Class clazz ) { String classFile = clazz.getName().replace( '.', '/' ) + ".class"; ClassLoader cl = Thread.currentThread().getContextClassLoader(); if ( cl == null ) { cl = getClass().getClassLoader(); } URL url = cl.getResource( classFile ); getLog().debug( "getClassPathElementFor " + clazz.getName() + " file " + url.toString() ); String path = url.toString(); if ( path.startsWith( "jar:" ) ) { path = path.substring( 4, path.indexOf( "!" ) ); } else { path = path.substring( 0, path.length() - classFile.length() ); } if ( path.startsWith( "file:" ) ) { path = path.substring( 5 ); // windauze hack with maven 3 we get those ! path = path.replace( "%20", " " ); } File file = new File( path ); getLog().debug( "getClassPathElementFor " + clazz.getName() + " file " + file.getPath() ); return file; } /** * @param testTimeOut the testTimeOut to set */ public void setTestTimeOut( int testTimeOut ) { setTimeOut( testTimeOut ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy