Java tutorial
/******************************************************************************* * Copyright (c) 2009, 2016 Xored Software Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Xored Software Inc - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.rcptt.maven; import static java.lang.String.format; import static java.util.Arrays.asList; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.apache.maven.artifact.versioning.ComparableVersion; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.StreamConsumer; import org.eclipse.rcptt.maven.util.Injection; import org.eclipse.rcptt.maven.util.JavaExec; import org.eclipse.rcptt.maven.util.NetUtils; import org.eclipse.rcptt.maven.util.TestOptions; /** * Executes q7 tests * * @author ivaninozemtsev * * @goal execute * @phase compile */ public class ExecuteMojo extends AbstractRCPTTMojo { private static final String REUSE_EXISTING_WORKSPACE = "-reuseExistingWorkspace"; private static final String IMPORT_SEP = ";"; private static final String IMPORT = "-import"; private static final String MEMORY_USAGE = "-memoryUsage"; private static final String Q7_REPORT = "-q7report"; private static final String HTML_REPORT = "-htmlReport"; private static final String JUNIT_REPORT = "-junitReport"; private static final String REPORT = "-report"; private static final String AUT_ARGS = "-autArgs"; private static final String AUT_CONSOLE_PREFIX = "-autConsolePrefix"; private static final String AUT_VM = "-autVM"; private static final String AUT_VM_ARGS = "-autVMArgs"; private static final String AUT_WS_PREFIX = "-autWsPrefix"; private static final String AUT_LOC = "-aut"; private static final String AUT_COUNT = "-autCount"; private static final String WORKSPACE = "-data"; private static final String INJECTION = "-injection:site"; private static final String INJECTION_FEATURE_SEP = ";"; private static final String TEST_OPTIONS = "-testOptions"; private static final String IGNORE_OTHER_INJECTIONS = "-injectSpecified"; private static final String SHUTDOWN_LISTENER_PORT = "-shutdownListenerPort"; private static final String SKIP_TAGS = "-skipTags"; private static final String SUITES = "-suites"; private static final String TESTS = "-tests"; private static final String LIMIT = "-limit"; private static final String SPLIT_HTML_REPORT = "-splitHtmlReport"; private static final String NO_SECURITY_OVERRIDE = "-noSecurityOverride"; private static final String EXECUTION_TIMEOUT = "-timeout"; private static int shutdownListenerPort; private static final String[] DEFAULT_Q7_VM_ARGS = new String[] { "-Xms128m", "-Xmx256m", "-Dorg.eclipse.rcptt.runner.returnTestFailure=true" }; // TODO: Replace this random number with carefully thought one private static final int TEST_FAIL_EXIT_CODE = 56; @Override public void execute() throws MojoExecutionException, MojoFailureException { if (skipTests()) { getLog().info("Tests are skipped"); return; } if (!projectHasTests()) { getLog().info("No RCPTT tests found in project, skipping execution"); return; } validatePreparation(); JavaExec java = JavaExec.getDefault(); Commandline cmd = new Commandline(); cmd.setExecutable(java.getFile().getAbsolutePath()); cmd.setWorkingDirectory(getResolvedQ7Dir()); // Q7 VM Args List<String> q7VmArgs = new ArrayList<String>(); String[] userArgs = getQ7Coords().getVmArgs(); if (userArgs == null || userArgs.length == 0) { q7VmArgs.addAll(asList(DEFAULT_Q7_VM_ARGS)); if (java.hasPermGen()) { q7VmArgs.add("-XX:MaxPermSize=256m"); } } else { q7VmArgs.addAll(asList(userArgs)); } for (String arg : q7VmArgs) { cmd.createArg().setValue(arg); } // Equinox launcher cmd.createArg().setValue(JAR); cmd.createArg().setFile(getEquinoxJar()); // Workspace cmd.createArg().setValue("-application"); ComparableVersion version = RunnerVersionDispatcher.parseVersion(getQ7Coords().getVersion()); String applicationId = RunnerVersionDispatcher.getApplicationId(version); cmd.createArg().setValue(applicationId); cmd.createArg().setValue(WORKSPACE); cmd.createArg().setFile(getQ7WsDir()); // AUT location cmd.createArg().setValue(AUT_LOC); cmd.createArg().setFile(getResolvedAutDir()); // AUT count if (autCount != null) { cmd.createArg().setValue(AUT_COUNT); cmd.createArg().setValue(autCount); } // AUT Workspace prefix cmd.createArg().setValue(AUT_WS_PREFIX); cmd.createArg().setFile(getAutWorkspacePrefix()); if (aut.reuseExistingWorkspace()) cmd.createArg().setValue(REUSE_EXISTING_WORKSPACE); // AUT console prefix cmd.createArg().setValue(AUT_CONSOLE_PREFIX); cmd.createArg().setFile(getAutConsolePrefix()); // AUT VM Args if (aut.getVmArgs() != null && aut.getVmArgs().length > 0) { cmd.createArg().setValue(AUT_VM_ARGS); cmd.createArg().setValue(StringUtils.join(aut.getVmArgs(), ";")); } // AUT args if (aut.getArgs() != null && aut.getArgs().length > 0) { cmd.createArg().setValue(AUT_ARGS); cmd.createArg().setValue(StringUtils.join(aut.getArgs(), ";")); } // AUT VM if (aut.getVm() != null) { cmd.createArg().setValue(AUT_VM); cmd.createArg().setValue(aut.getVm()); } // Memory usage if (memoryUsage) { cmd.createArg().setValue(MEMORY_USAGE); } // Q7 Report cmd.createArg().setValue(Q7_REPORT); cmd.createArg().setFile(getQ7ReportFile()); // HTML Report cmd.createArg().setValue(HTML_REPORT); cmd.createArg().setFile(getHtmlReportFile()); // Split HTML report if (splitHtmlReport) { cmd.createArg().setValue(SPLIT_HTML_REPORT); } // JUnit Report cmd.createArg().setValue(JUNIT_REPORT); cmd.createArg().setFile(getJUnitReportFile()); if (report != null) { cmd.createArg().setValue(REPORT); cmd.createArg() .setValue(report.getId() + ";" + getResultsDir().getAbsolutePath() + "/" + report.getName()); } if (limit != -1) { cmd.createArg().setValue(LIMIT); cmd.createArg().setValue(Integer.toString(limit)); } // Imports list cmd.createArg().setValue(IMPORT); cmd.createArg().setValue(getImports()); // injection setInjectionParams(cmd, aut.getInjections()); // eclipse.keyring if (useDefaultEclipseKeyring) { cmd.createArg().setValue(NO_SECURITY_OVERRIDE); } // test options cmd.createArg().setValue(TEST_OPTIONS); cmd.createArg().setValue(TestOptions.toString(getTestOptions())); cmd.createArg().setValue(EXECUTION_TIMEOUT); cmd.createArg().setValue(TestOptions.get(getTestOptions(), TestOptions.EXEC_TIMEOUT)); int shift = (int) (new Random().nextLong() % 1000); shutdownListenerPort = NetUtils.findFreePort(9000 + shift, 9999 + shift); if (shutdownListenerPort != -1) { cmd.createArg().setValue(SHUTDOWN_LISTENER_PORT); cmd.createArg().setValue(((Integer) shutdownListenerPort).toString()); } if (skipTags != null) { cmd.createArg().setValue(SKIP_TAGS); cmd.createArg().setValue(StringUtils.join(skipTags, ";")); } if (suites != null && suites.length > 0) { cmd.createArg().setValue(SUITES); cmd.createArg().setValue(StringUtils.join(suites, ";")); } if (tests != null && tests.length > 0) { cmd.createArg().setValue(TESTS); cmd.createArg().setValue(StringUtils.join(tests, ";")); } // whoo, almost ready to launch getLog().info(format("Runner command line is %s", cmd.toString())); FileStreamConsumer outConsumer; FileStreamConsumer errConsumer; try { outConsumer = new FileStreamConsumer(getQ7Out(), getLog(), false); errConsumer = new FileStreamConsumer(getQ7Err(), getLog(), true); } catch (FileNotFoundException e) { throw new MojoExecutionException("Can't write out and err files", e); } try { int duration = TestOptions.getInt(getTestOptions(), TestOptions.EXEC_TIMEOUT); getLog().info(format("The execution timeout is set to %d seconds", duration)); Runtime.getRuntime().addShutdownHook(ShutdownHook); CommandLineUtils.removeShutdownHook(false); int exitCode = CommandLineUtils.executeCommandLine(cmd, outConsumer, errConsumer, duration); getLog().info(format("Runner exit code is: %d", exitCode)); if (exitCode != 0) { if (exitCode == TEST_FAIL_EXIT_CODE) { if (testFailureIgnore) { getLog().error("There are test failures"); } else { throw new MojoFailureException("There are test failures"); } } else { throw new MojoExecutionException( format("Failed to launch RCPTT runner. Runner exit code is: %d", exitCode)); } } Runtime.getRuntime().removeShutdownHook(ShutdownHook); outConsumer.done(); errConsumer.done(); } catch (MojoExecutionException e) { throw e; } catch (MojoFailureException e) { throw e; } catch (/* CommandLine */Exception e) { throw new MojoExecutionException("Failed to launch RCPTT runner", e); } } static final ComparableVersion v154 = new ComparableVersion("1.5.4"); static final ComparableVersion v155 = new ComparableVersion("1.5.5"); Thread ShutdownHook = new Thread() { @Override public void run() { try { new Socket("127.0.0.1", shutdownListenerPort); } catch (IOException e) { System.out.println(e); } getLog().info("Process terminated. Send shutdown request to RCPTT runner."); } }; private String getImports() throws MojoFailureException { StringBuilder sb = new StringBuilder(); for (File file : getProjectsDir().listFiles()) { sb.append(file.getAbsolutePath()).append(IMPORT_SEP); } if (projects != null) for (String projectPath : projects) sb.append(projectPath).append(IMPORT_SEP); sb.setLength(sb.length() - 1); return sb.toString(); } /** * Validate that all necessary information is present and no one has * corrupted the results of {@link PrepareMojo} by customizing lifecycle * * @throws MojoFailureException */ private void validatePreparation() throws MojoFailureException { boolean ok = true; ok &= getProjectsDir().exists(); ok &= getThisProjectDir().exists(); ok &= getAutDir().exists(); ok &= getQ7Dir().exists(); if (!ok) { throw new MojoFailureException( "Cannot execute RCPTT tests. Something is corrupted during prepare goal. Is lifecycle have been modified?"); } } private static final class FileStreamConsumer implements StreamConsumer { private Log fLog; private boolean fIsError; public FileStreamConsumer(File dest, Log log, boolean isError) throws FileNotFoundException { this.writer = new PrintWriter(new FileOutputStream(dest), true); fLog = log; fIsError = isError; } public void done() { writer.flush(); writer.close(); } private PrintWriter writer; @Override public void consumeLine(String line) { writer.println(line); if (fLog != null) { if (fIsError) { fLog.error(line); } else { fLog.info(line); } } } } private void setInjectionParams(Commandline cmd, Injection[] injections) { if (injections == null) { return; } final Log log = getLog(); for (Injection injection : injections) { final String site = injection.getSite(); if (site == null || site.length() == 0) { // <site> parameter is // missed or empty log.warn("Ingored injection with invalid site paramater."); continue; } final StringBuilder argValue = new StringBuilder(site); if (injection.getFeatures() != null) { // list of features is // specified for (String feature : injection.getFeatures()) { if (feature.length() == 0) { log.warn("Ingored empty name feature in the injection with site " + site); } argValue.append(INJECTION_FEATURE_SEP).append(feature); } } cmd.createArg().setValue(INJECTION); cmd.createArg().setValue(argValue.toString()); } if (aut.isIgnoreOtherInjections()) { cmd.createArg().setValue(IGNORE_OTHER_INJECTIONS); cmd.createArg().setValue(Boolean.toString(aut.isIgnoreOtherInjections())); } } }