Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-31999] massive improvements and refactoring
- replaced boolean return values with equivalent ETPluginException when
performing SimpleBuildStep operations to catch build errors
- improved DataBoundSetter by adding null checks
- muted process launcher output
- properly catch tool timeout exceptions
- workaround missing workspace directory in pipeline node allocation
- fixed NPE when using Computer.currentComputer inside pipelines
- fixed minor typos
  • Loading branch information
cpoenisch committed May 27, 2016
1 parent 7229b19 commit a0f5632
Show file tree
Hide file tree
Showing 28 changed files with 545 additions and 456 deletions.
@@ -0,0 +1,79 @@
/**
* Copyright (c) 2015-2016 TraceTronic GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of TraceTronic GmbH nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package de.tracetronic.jenkins.plugins.ecutest;

/**
* Exception thrown if an error occurs while performing plugin-specific operations.
*
* @author Christian Pönisch <christian.poenisch@tracetronic.de>
*/
public class ETPluginException extends Exception {

private static final long serialVersionUID = 1L;

/**
* Instantiates a new {@link ETPluginException}.
*
* @param cause
* the cause of the {@link Exception}
*/
public ETPluginException(final Throwable cause) {
super(cause);
}

/**
* Instantiates a new {@link ETPluginException}.
*
* @param message
* the message to attach to the {@link Exception}
* @param cause
* the cause of the {@link Exception}
*/
public ETPluginException(final String message, final Throwable cause) {
super(message, cause);
}

/**
* Instantiates a new {@link ETPluginException}.
*
* @param message
* the message to attach to the {@link Exception}
*/
public ETPluginException(final String message) {
super(message);
}

/**
* Instantiates a new {@link ETPluginException}.
*/
public ETPluginException() {
super();
}
}
Expand Up @@ -305,7 +305,7 @@ public void failedOnError(final boolean value) {
}

/**
* Option defining whether to parse the test specific log files.
* Option defining whether to parse the test-specific log files.
*
* @param value
* the value
Expand Down
Expand Up @@ -29,14 +29,15 @@
*/
package de.tracetronic.jenkins.plugins.ecutest.report;

import hudson.AbortException;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.Result;
import hudson.model.TaskListener;
import hudson.model.AbstractItem;
import hudson.model.Computer;
import hudson.model.Node;
import hudson.model.Run;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Recorder;
Expand All @@ -54,14 +55,16 @@
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundSetter;

import de.tracetronic.jenkins.plugins.ecutest.ETPluginException;
import de.tracetronic.jenkins.plugins.ecutest.env.TestEnvInvisibleAction;
import de.tracetronic.jenkins.plugins.ecutest.env.ToolEnvInvisibleAction;
import de.tracetronic.jenkins.plugins.ecutest.log.TTConsoleLogger;
import de.tracetronic.jenkins.plugins.ecutest.report.atx.ATXPublisher;
import de.tracetronic.jenkins.plugins.ecutest.report.junit.JUnitPublisher;
import de.tracetronic.jenkins.plugins.ecutest.report.log.ETLogPublisher;
import de.tracetronic.jenkins.plugins.ecutest.report.trf.TRFPublisher;
import de.tracetronic.jenkins.plugins.ecutest.tool.installation.AbstractToolInstallation;
import de.tracetronic.jenkins.plugins.ecutest.tool.installation.ETInstallation;
import de.tracetronic.jenkins.plugins.ecutest.util.ProcessUtil;

/**
* Common base class for {@link ATXPublisher}, {@link ETLogPublisher}, {@link JUnitPublisher} and {@link TRFPublisher}.
Expand Down Expand Up @@ -208,25 +211,47 @@ public void setKeepAll(final boolean keepAll) {
this.keepAll = keepAll;
}

// @Override
// public abstract Action getProjectAction(final AbstractProject<?, ?> project);
//
// @Override
// public Collection<? extends Action> getProjectActions(final AbstractProject<?, ?> project) {
// final ArrayList<Action> actions = new ArrayList<Action>();
// actions.add(getProjectAction(project));
// if (project instanceof MatrixProject && ((MatrixProject) project).getActiveConfigurations() != null) {
// for (final MatrixConfiguration mc : ((MatrixProject) project).getActiveConfigurations()) {
// try {
// mc.onLoad(mc.getParent(), mc.getName());
// } catch (final IOException e) {
// LOGGER.log(Level.SEVERE, "Could not reload the matrix configuration");
// }
// }
// }
//
// return actions;
// }
@Override
public void perform(final Run<?, ?> run, final FilePath workspace, final Launcher launcher,
final TaskListener listener) throws InterruptedException, IOException {
// FIXME: workaround because pipeline node allocation does not create the actual workspace directory
if (!workspace.exists()) {
workspace.mkdirs();
}

try {
ProcessUtil.checkOS(launcher);
performReport(run, workspace, launcher, listener);
} catch (final IOException e) {
Util.displayIOException(e, listener);
throw e;
} catch (final ETPluginException e) {
final TTConsoleLogger logger = new TTConsoleLogger(listener);
logger.logError(e.getMessage());
throw new AbortException(e.getMessage());
}
}

/**
* Performs the report-specific post-build operations.
*
* @param run
* the run
* @param workspace
* the workspace
* @param launcher
* the launcher
* @param listener
* the listener
* @throws InterruptedException
* the interrupted exception
* @throws IOException
* signals that an I/O exception has occurred
* @throws ETPluginException
* in case of report operation errors
*/
protected abstract void performReport(final Run<?, ?> run, final FilePath workspace, final Launcher launcher,
final TaskListener listener) throws InterruptedException, IOException, ETPluginException;

@Override
public BuildStepMonitor getRequiredMonitorService() {
Expand Down Expand Up @@ -254,6 +279,8 @@ protected boolean canContinue(final Result result) {
*
* @param toolName
* the tool name identifying the specific tool
* @param computer
* the computer
* @param listener
* the listener
* @param envVars
Expand All @@ -263,17 +290,18 @@ protected boolean canContinue(final Result result) {
* signals that an I/O exception has occurred
* @throws InterruptedException
* if the build gets interrupted
* @throws ETPluginException
* if the selected tool installation is not configured
*/
protected AbstractToolInstallation configureToolInstallation(final String toolName,
final TaskListener listener, final EnvVars envVars) throws IOException, InterruptedException {
AbstractToolInstallation installation = getToolInstallation(toolName, envVars);

if (installation != null) {
final Node node = Computer.currentComputer().getNode();
if (node != null) {
installation = installation.forNode(node, listener);
}
protected ETInstallation configureToolInstallation(final String toolName, final Computer computer,
final TaskListener listener, final EnvVars envVars) throws IOException, InterruptedException,
ETPluginException {
ETInstallation installation = getToolInstallation(toolName, envVars);
if (installation != null && computer != null && computer.getNode() != null) {
installation = installation.forNode(computer.getNode(), listener);
installation = installation.forEnvironment(envVars);
} else {
throw new ETPluginException("The selected ECU-TEST installation is not configured for this node!");
}
return installation;
}
Expand Down
Expand Up @@ -68,6 +68,7 @@
import org.kohsuke.stapler.StaplerRequest;

import de.tracetronic.jenkins.plugins.ecutest.ETPlugin;
import de.tracetronic.jenkins.plugins.ecutest.ETPluginException;
import de.tracetronic.jenkins.plugins.ecutest.log.TTConsoleLogger;
import de.tracetronic.jenkins.plugins.ecutest.report.AbstractReportPublisher;
import de.tracetronic.jenkins.plugins.ecutest.report.atx.installation.ATXConfig;
Expand All @@ -76,10 +77,8 @@
import de.tracetronic.jenkins.plugins.ecutest.report.atx.installation.ATXSetting;
import de.tracetronic.jenkins.plugins.ecutest.tool.StartETBuilder;
import de.tracetronic.jenkins.plugins.ecutest.tool.client.ETClient;
import de.tracetronic.jenkins.plugins.ecutest.tool.installation.AbstractToolInstallation;
import de.tracetronic.jenkins.plugins.ecutest.tool.installation.ETInstallation;
import de.tracetronic.jenkins.plugins.ecutest.util.ATXUtil;
import de.tracetronic.jenkins.plugins.ecutest.util.ProcessUtil;
import de.tracetronic.jenkins.plugins.ecutest.util.validation.ATXValidator;

/**
Expand All @@ -104,7 +103,7 @@ public class ATXPublisher extends AbstractReportPublisher {
* the tool name identifying the {@link ATXInstallation} to be used
*/
@DataBoundConstructor
public ATXPublisher(final String atxName) {
public ATXPublisher(@Nonnull final String atxName) {
super();
this.atxName = StringUtils.trimToEmpty(atxName);
}
Expand All @@ -129,7 +128,7 @@ public ATXPublisher(final String atxName) {
public ATXPublisher(final String atxName, final boolean allowMissing, final boolean runOnFailed,
final boolean archiving, final boolean keepAll) {
super(allowMissing, runOnFailed, archiving, keepAll);
this.atxName = atxName;
this.atxName = StringUtils.trimToEmpty(atxName);
}

/**
Expand Down Expand Up @@ -167,14 +166,8 @@ public String getAtxName() {
}

@Override
public void perform(final Run<?, ?> run, final FilePath workspace, final Launcher launcher,
final TaskListener listener) throws InterruptedException, IOException {
// Check OS running this build
if (!ProcessUtil.checkOS(launcher, listener)) {
return;
}

// Initialize logger
public void performReport(final Run<?, ?> run, final FilePath workspace, final Launcher launcher,
final TaskListener listener) throws InterruptedException, IOException, ETPluginException {
final TTConsoleLogger logger = new TTConsoleLogger(listener);
logger.logInfo("Publishing ATX reports...");

Expand All @@ -187,15 +180,9 @@ public void perform(final Run<?, ?> run, final FilePath workspace, final Launche
// Get selected TEST-GUIDE installation
final ATXInstallation installation = getInstallation(run.getEnvironment(listener));
if (installation == null) {
logger.logError("Selected TEST-GUIDE installation is not configured!");
return;
throw new ETPluginException("Selected TEST-GUIDE installation is not configured!");
}

// Get selected ECU-TEST installation
String toolName = installation.getToolName();
final AbstractToolInstallation etInstallation = configureToolInstallation(toolName, listener,
run.getEnvironment(listener));

boolean isPublished = false;
final List<String> foundProcesses = ETClient.checkProcesses(launcher, false);
final boolean isETRunning = !foundProcesses.isEmpty();
Expand All @@ -204,29 +191,22 @@ public void perform(final Run<?, ?> run, final FilePath workspace, final Launche
if (isETRunning) {
isPublished = publishReports(installation, run, launcher, listener);
} else {
if (etInstallation instanceof ETInstallation) {
final String installPath = etInstallation.getExecutable(launcher);
final String workspaceDir = getWorkspaceDir(run);
final String settingsDir = getSettingsDir(run);
toolName = run.getEnvironment(listener).expand(etInstallation.getName());
final ETClient etClient = new ETClient(toolName, installPath, workspaceDir, settingsDir,
StartETBuilder.DEFAULT_TIMEOUT, false);
logger.logInfo(String.format("Starting %s...", toolName));
if (etClient.start(false, launcher, listener)) {
logger.logInfo(String.format("%s started successfully.", toolName));
isPublished = publishReports(installation, run, launcher, listener);
} else {
logger.logError(String.format("Starting %s failed.", toolName));
}
logger.logInfo(String.format("Stopping %s...", toolName));
if (etClient.stop(true, launcher, listener)) {
logger.logInfo(String.format("%s stopped successfully.", toolName));
} else {
logger.logError(String.format("Stopping %s failed.", toolName));
}
String toolName = installation.getToolName();
final ETInstallation etInstallation = configureToolInstallation(toolName, workspace.toComputer(), listener,
run.getEnvironment(listener));
final String installPath = etInstallation.getExecutable(launcher);
final String workspaceDir = getWorkspaceDir(run);
final String settingsDir = getSettingsDir(run);
toolName = run.getEnvironment(listener).expand(etInstallation.getName());
final ETClient etClient = new ETClient(toolName, installPath, workspaceDir, settingsDir,
StartETBuilder.DEFAULT_TIMEOUT, false);
if (etClient.start(false, workspace, launcher, listener)) {
isPublished = publishReports(installation, run, launcher, listener);
} else {
logger.logError("Selected ECU-TEST installation is not configured for this node!");
return;
logger.logError(String.format("Starting %s failed.", toolName));
}
if (!etClient.stop(true, workspace, launcher, listener)) {
logger.logError(String.format("Stopping %s failed.", toolName));
}
}

Expand All @@ -235,7 +215,6 @@ public void perform(final Run<?, ?> run, final FilePath workspace, final Launche
} else {
run.setResult(Result.FAILURE);
}
return;
}

/**
Expand Down

0 comments on commit a0f5632

Please sign in to comment.