org.codehaus.mojo.fitnesse.FitnesseRemoteRunnerMojo.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.fitnesse.FitnesseRemoteRunnerMojo.java

Source

package org.codehaus.mojo.fitnesse;

/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.reporting.MavenReportException;

/**
 * This goal uses the <code>fitnesse.runner.TestRunner</code> class for getting result of a remote FitNesse web page
 * execution. It's possible to define several pages and/or servers.
 * 
 * @goal remotecall
 * @aggregator
 */
public class FitnesseRemoteRunnerMojo extends FitnesseAbstractMojo {

    public static final String START_REPORT_TAG_KO = "document.getElementById(\"test-summary\").className = \"fail\"";

    public static final String START_REPORT_TAG_KO2 = "document.getElementById(\"test-summary\").className = \"error\"";

    public static final String START_REPORT_TAG_OK = "document.getElementById(\"test-summary\").className = \"pass\"";

    public void execute() throws MojoExecutionException, MojoFailureException {
        new File(this.workingDir).mkdirs();
        checkConfiguration();

        try {
            FitnesseReportMojo.copyAllResources(new File(this.workingDir), getLog(), getClass().getClassLoader());
        } catch (MavenReportException e) {
            throw new MojoExecutionException("Unable to copy resources", e.getCause());
        }

        getLog().info("Found " + getFitnesseSize() + " Fitnesse configuration.");
        MojoFailureException tLastFailure = null;
        for (int i = 0; i < getFitnesseSize(); i++) {
            try {
                callFitnesse(i);
            } catch (MojoFailureException e) {
                tLastFailure = e;
            }
        }
        if (tLastFailure != null) {
            throw tLastFailure;
        }
    }

    /**
     * Call a Fitnesse server page.
     * 
     * @param pServerConfPosition The number of the Fitnesse configuration.
     * @throws MojoFailureException
     * @throws MojoExecutionException
     */
    void callFitnesse(int pServerConfPosition) throws MojoFailureException, MojoExecutionException {
        Fitnesse tServer = getFitnesse(pServerConfPosition);

        File tResultFile = new File(this.getFinalFileName(tServer));
        if (tResultFile.exists()) {
            tResultFile.delete();
        }
        File tOutput = new File(this.getOutputFileName(tServer));
        if (tOutput.exists()) {
            tOutput.delete();
        }
        try {
            FileOutputStream tOutputStream = new FileOutputStream(tOutput);

            tResultFile.createNewFile();
            ByteArrayOutputStream tOut = new ByteArrayOutputStream();
            String tUrl = "http://" + tServer.getHostName() + ":" + tServer.getPort() + "/" + tServer.getPageName()
                    + "?responder=" + tServer.getType();
            if (tServer.getSuiteFilter() != null && tServer.getSuiteFilter().length() > 0) {
                if (Fitnesse.PAGE_TYPE_SUITE.equals(tServer.getType())) {
                    tUrl = tUrl + "&testFilter=" + tServer.getType();
                } else {
                    getLog().error(
                            "The FitNesse parameter testFilter is only supported with Suite page (not Test page), it has be ignored...");
                }
            }

            getRemoteResource(tUrl, tOut, tServer);

            String tOutAsString = tOut.toString();
            FitnessePage tFitnessePage = new FitnessePage(tOutAsString);
            transformHtml(new ByteArrayInputStream(tOut.toByteArray()), new FileWriter(tResultFile),
                    getOutputUrl(tServer), tFitnessePage.getStatus());

            getRemoteResource("http://" + tServer.getHostName() + ":" + tServer.getPort() + "/ErrorLogs."
                    + tServer.getPageName(), tOutputStream, tServer);
            transformOutputPage(new File(this.getOutputFileName(tServer)));

            checkFailure(tOutAsString, tResultFile.getAbsolutePath());

        } catch (IOException e) {
            throw new MojoExecutionException("Unable to create File [" + tResultFile.getAbsolutePath() + "].", e);
        }

    }

    void transformOutputPage(File pFinalOutputName) throws IOException, MojoExecutionException {
        String tSrcAsString = FileUtil.getString(pFinalOutputName);
        tSrcAsString = tSrcAsString.replaceAll("/files/css/", "");
        tSrcAsString = tSrcAsString.replaceAll("fitnesse.css", "fitnesse_base.css");
        tSrcAsString = tSrcAsString.replaceAll("/files/javascript/", "");
        StringBuffer tFinal = new StringBuffer();

        int tStartIndex = tSrcAsString.indexOf("<div class=\"sidebar\">");
        if (tStartIndex != -1) {
            int tEndIndex = tSrcAsString.indexOf("<div class=\"mainbar\">");
            tFinal.append(tSrcAsString.substring(0, tStartIndex));
            tFinal.append(tSrcAsString.substring(tEndIndex, tSrcAsString.length()));
            tSrcAsString = tFinal.toString();
        }

        tStartIndex = tSrcAsString.indexOf("<div class=\"header\">");
        if (tStartIndex != -1) {
            tFinal = new StringBuffer();
            int tEndIndex = tSrcAsString.indexOf("</div>\r\n") + "</div>\r\n".length();
            tFinal.append(tSrcAsString.substring(0, tStartIndex));
            tFinal.append(tSrcAsString.substring(tEndIndex, tSrcAsString.length()));
            tSrcAsString = tFinal.toString();
        }

        if (!pFinalOutputName.delete()) {
            throw new MojoExecutionException("Unable to delete output file");
        }
        FileWriter tWriter = null;
        try {
            tWriter = new FileWriter(pFinalOutputName);
            tWriter.write(tSrcAsString);
        } finally {
            if (tWriter != null) {
                tWriter.close();
            }
        }
    }

    void checkFailure(String pFileContent, String pFileName) throws MojoFailureException, MojoExecutionException {
        if (isFailOnError()) {
            int tIndexOk = pFileContent.indexOf(START_REPORT_TAG_OK);
            int tIndexKo = pFileContent.indexOf(START_REPORT_TAG_KO);
            int tIndexKo2 = pFileContent.indexOf(START_REPORT_TAG_KO2);
            if (tIndexOk == -1) {
                if ((tIndexKo == -1) && (tIndexKo2 == -1)) {
                    throw new MojoExecutionException(
                            "Unable to find failure result into FitNesse page, resultFile=[" + pFileName + "].");
                } else {
                    throw new MojoFailureException("FitNesse page fail, resultFile=[" + pFileName + "].");
                }
            } else {
                if ((tIndexKo != -1) || (tIndexKo2 != -1)) {
                    throw new MojoExecutionException(
                            "Find both success and fail result into FitNesse page , resultFile=[" + pFileName
                                    + "].");
                }
            }
        }

    }

    void getRemoteResource(String pUrl, OutputStream pOutStream, Fitnesse pServer) throws MojoExecutionException {
        try {
            HttpClient tClient = new HttpClient();
            getLog().info("Request resources from [" + pUrl + "]");
            if (pServer.getServerId() != null) {
                tClient.getParams().setAuthenticationPreemptive(true);
                Credentials defaultcreds = getCredential(pServer.getServerId());
                AuthScope tAuthScope = new AuthScope(pServer.getHostName(), pServer.getPort(), AuthScope.ANY_REALM);
                tClient.getState().setCredentials(tAuthScope, defaultcreds);
                getLog().info("Use credential for remote connection");
            }
            HttpMethod tMethod = new GetMethod(pUrl);
            int tStatusCode = tClient.executeMethod(tMethod);
            if (tStatusCode != 200) {
                throw new MojoExecutionException(
                        "Bad response code from resource [" + pUrl + "], return code=[" + tStatusCode + "]");
            }

            InputStream tResponseStream = tMethod.getResponseBodyAsStream();
            byte[] tbytes = new byte[512];
            int tReadBytes = tResponseStream.read(tbytes);
            while (tReadBytes >= 0) {
                pOutStream.write(tbytes, 0, tReadBytes);
                tReadBytes = tResponseStream.read(tbytes);
            }
            pOutStream.flush();
            tMethod.releaseConnection();
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to read FitNesse server response.", e);
        } finally {
            try {
                pOutStream.close();
            } catch (IOException e) {
                getLog().error("Unable to close Stream.");
            }
        }
    }

    public void setWorkingDir(String pWorkingDir) {
        workingDir = pWorkingDir;
    }

    String getOutputFileName(Fitnesse pServer) {
        return getResultFileName(pServer, FitnesseAbstractMojo.OUTPUT_EXTENSION, "html");
    }

    String getOutputUrl(Fitnesse pServer) {
        return FITNESSE_RESULT_PREFIX + "_" + pServer.getHostName() + "_" + pServer.getPageName() + "_output.html";
    }

}