hudson.plugins.robot.RobotBuildAction.java Source code

Java tutorial

Introduction

Here is the source code for hudson.plugins.robot.RobotBuildAction.java

Source

/*
* Copyright 2008-2014 Nokia Solutions and Networks Oy
*
* 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 hudson.plugins.robot;

import hudson.FilePath;
import hudson.XmlFile;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.DirectoryBrowserSupport;
import hudson.plugins.robot.graph.RobotGraphHelper;
import hudson.plugins.robot.model.RobotTestObject;
import hudson.plugins.robot.model.RobotCaseResult;
import hudson.plugins.robot.model.RobotResult;
import hudson.plugins.robot.model.RobotSuiteResult;
import hudson.tasks.test.AbstractTestResultAction;
import hudson.util.ChartUtil;
import hudson.util.Graph;
import hudson.util.HeapSpaceStringConverter;
import hudson.util.XStream2;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.StaplerProxy;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import com.thoughtworks.xstream.XStream;

public class RobotBuildAction extends AbstractTestResultAction<RobotBuildAction> implements StaplerProxy {

    private static final Logger logger = Logger.getLogger(RobotBuildAction.class.getName());
    private static final XStream XSTREAM = new XStream2();

    private transient WeakReference<RobotResult> resultReference;
    private transient String reportFileName;
    private String outputPath;
    private String logFileLink;
    private String logHtmlLink;
    private AbstractBuild<?, ?> build;
    private RobotResult result;

    static {
        XSTREAM.alias("result", RobotResult.class);
        XSTREAM.alias("suite", RobotSuiteResult.class);
        XSTREAM.alias("case", RobotCaseResult.class);
        XSTREAM.registerConverter(new HeapSpaceStringConverter(), 100);
    }

    /**
     * Create new Robot build action
     * @param build Build which this action is associated to
     * @param result Robot result
     * @param outputPath Path where the Robot report is stored relative to build root
     * @param logFileLink
     * @param reportFileLink
     */
    public RobotBuildAction(AbstractBuild<?, ?> build, RobotResult result, String outputPath,
            BuildListener listener, String logFileLink, String logHtmlLink) {
        super(build);
        this.build = build;
        this.outputPath = outputPath;
        this.logFileLink = logFileLink;
        this.logHtmlLink = logHtmlLink;
        setResult(result, listener);
    }

    /**
     * Get build associated to action
     * @return build object
     */
    public AbstractBuild<?, ?> getOwner() {
        return build;
    }

    /**
     * Get filename to link to
     * @return null if no filename specified
     */
    public String getLogFileLink() {
        return logFileLink;
    }

    public String getLogHtmlLink() {
        return logHtmlLink;
    }

    /**
     * Loads new data to {@link RobotResult}.
     */
    public synchronized void setResult(RobotResult result, BuildListener listener) {
        result.tally(this);
        try {
            getDataFile().write(result);
        } catch (IOException e) {
            e.printStackTrace(listener.fatalError("Failed to save the Robot test result"));
        }

        this.resultReference = new WeakReference<RobotResult>(result);
    }

    private XmlFile getDataFile() {
        return new XmlFile(XSTREAM, new File(getOwner().getRootDir(), "robot_results.xml"));
    }

    /**
     * Returns Robotresult. If not in memory loads it from disk.
     */
    public synchronized RobotResult getResult() {
        RobotResult returnable;
        if (result != null)
            return result;
        if (resultReference == null) {
            returnable = load();
            resultReference = new WeakReference<RobotResult>(returnable);
        } else {
            returnable = resultReference.get();
        }

        if (returnable == null) {
            returnable = load();
            resultReference = new WeakReference<RobotResult>(returnable);
        }
        return returnable;
    }

    /**
     * Loads a {@link RobotResult} from disk.
     */
    private RobotResult load() {
        RobotResult loadedResult = null;
        try {
            loadedResult = (RobotResult) getDataFile().read();
        } catch (IOException e) {
            logger.log(Level.WARNING, "Couldn't load " + getDataFile(), e);
            return null;
        }
        loadedResult.tally(this);
        return loadedResult;
    }

    /**
     * Get file name for Robot html report.
     * @return file name as string
     */
    public String getReportFileName() {
        return reportFileName;
    }

    /**
     * Get ratio of passed tests per total tests. Accounts for all tests run.
     * @return percent number
     */
    public double getOverallPassPercentage() {
        return getResult().getPassPercentage(false);
    }

    /**
     * Get ratio of passed tests per total tests. Accounts for only critical tests run.
     * @return percent number
     */
    public double getCriticalPassPercentage() {
        return getResult().getPassPercentage(true);
    }

    /**
     * Find test object from the results object tree
     * @param id path e.g. "suite/nestedsuite/testcase"
     * @return test object
     */
    public RobotTestObject findObjectById(String id) {
        return getResult().findObjectById(id);
    }

    /**
     * Get the result object which is responsible for UI. If an old project doesn't have it provides buildaction as this.
     */
    public Object getTarget() {
        if (reportFileName != null)
            return this;
        return getResult();
    }

    /**
     * Serves Robot html report via robot url. Shows not found page if file is missing.
     * @param req
     * @param rsp
     * @throws IOException
     * @throws ServletException
     * @throws InterruptedException
     */
    public void doIndex(StaplerRequest req, StaplerResponse rsp)
            throws IOException, ServletException, InterruptedException {
        String indexFile = getReportFileName();
        FilePath robotDir = getRobotDir();

        if (!new FilePath(robotDir, indexFile).exists()) {
            rsp.sendRedirect("notfound");
            return;
        }

        DirectoryBrowserSupport dbs = new DirectoryBrowserSupport(this, getRobotDir(), getDisplayName(),
                "folder.gif", false);

        dbs.setIndexFileName(indexFile);
        dbs.generateResponse(req, rsp, this);
    }

    /**
     * Return robot trend graph in the request.
     * @param req
     * @param rsp
     * @throws IOException
     */
    public void doGraph(StaplerRequest req, StaplerResponse rsp) throws IOException {
        // TODO: When is this executed?
        if (ChartUtil.awtProblemCause != null) {
            rsp.sendRedirect2(req.getContextPath() + "/images/headless.png");
            return;
        }

        Calendar t = build.getTimestamp();

        if (req.checkIfModified(t, rsp))
            return;

        Graph g = RobotGraphHelper.createTestResultsGraphForTestObject(getResult(),
                Boolean.valueOf(req.getParameter("zoomSignificant")), false,
                Boolean.valueOf(req.getParameter("hd")), Boolean.valueOf(req.getParameter("failedOnly")),
                Boolean.valueOf(req.getParameter("criticalOnly")),
                Integer.valueOf(req.getParameter("maxBuildsToShow")));
        g.doPng(req, rsp);
    }

    /**
     * Return path of robot files in build
     * @return
     */
    public FilePath getRobotDir() {
        FilePath rootDir = new FilePath(build.getRootDir());
        if (StringUtils.isNotBlank(outputPath))
            return new FilePath(rootDir, outputPath);
        return rootDir;
    }

    @Override
    public int getFailCount() {
        return (int) getResult().getOverallFailed();
    }

    @Override
    public int getTotalCount() {
        return (int) getResult().getOverallTotal();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getIconFileName() {
        return "/plugin/robot/robot.png";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDisplayName() {
        return Messages.robot_sidebar_link();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getUrlName() {
        return "robot";
    }
}