Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b969722c authored by Maksymilian Osowski's avatar Maksymilian Osowski Committed by Android (Google) Code Review
Browse files

Merge "Upgraded DRT2 to generate nice HTML summaries of the tests."

parents 81cf7714 6d0dae6a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@ LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_STATIC_JAVA_LIBRARIES := diff_match_patch

LOCAL_PACKAGE_NAME := DumpRenderTree2

include $(BUILD_PACKAGE)
 No newline at end of file
+9 −5
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import android.webkit.WebView;
 * A class that represent a result of the test. It is responsible for returning the result's
 * raw data and generating its own diff in HTML format.
 */
public abstract class AbstractResult {
public abstract class AbstractResult implements Comparable<AbstractResult> {

    public enum TestType {
        TEXT {
@@ -46,10 +46,10 @@ public abstract class AbstractResult {

    public enum ResultCode {
        PASS("Passed"),
        FAIL_RESULT_DIFFERS("Failed: different results"),
        FAIL_NO_EXPECTED_RESULT("Failed: no expected result"),
        FAIL_TIMED_OUT("Failed: timed out"),
        FAIL_CRASHED("Failed: crashed");
        FAIL_RESULT_DIFFERS("Result differs"),
        FAIL_NO_EXPECTED_RESULT("No expected result"),
        FAIL_TIMED_OUT("Timed out"),
        FAIL_CRASHED("Crashed");

        private String mTitle;

@@ -63,6 +63,10 @@ public abstract class AbstractResult {
        }
    }

    public int compareTo(AbstractResult another) {
        return getRelativePath().compareTo(another.getRelativePath());
    }

    /**
     * Makes the result object obtain the results of the test from the webview
     * and store them in the format that suits itself bests. This method is asynchronous.
+173 −106
Original line number Diff line number Diff line
@@ -17,11 +17,11 @@
package com.android.dumprendertree2;

import java.io.File;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * A class that collects information about tests that ran and can create HTML
@@ -32,6 +32,7 @@ public class Summarizer {
    private static final String LOG_TAG = "Summarizer";

    private static final String CSS =
            "<style type=\"text/css\">" +
            "* {" +
            "       font-family: Verdana;" +
            "       border: 0;" +
@@ -39,23 +40,35 @@ public class Summarizer {
            "       padding: 0;}" +
            "body {" +
            "       margin: 10px;}" +
            "a {" +
            "       font-size: 12px;" +
            "       color: black;}" +
            "h1 {" +
            "       font-size: 33px;" +
            "       font-size: 24px;" +
            "       margin: 4px 0 4px 0;}" +
            "h2 {" +
            "       font-size:22px;" +
            "       font-size:18px;" +
            "       text-transform: uppercase;" +
            "       margin: 20px 0 3px 0;}" +
            "h3 {" +
            "       font-size: 20px;" +
            "       margin-bottom: 6px;}" +
            "h3, h3 a {" +
            "       font-size: 14px;" +
            "       color: black;" +
            "       text-decoration: none;" +
            "       margin-bottom: 4px;}" +
            "h3 a span.path {" +
            "       text-decoration: underline;}" +
            "h3 span.tri {" +
            "       text-decoration: none;}" +
            "h3 img {" +
            "       width: 8px;" +
            "       margin-right: 4px;}" +
            "div.diff {" +
            "       margin-bottom: 25px;}" +
            "div.diff a {" +
            "       font-size: 12px;" +
            "       color: #888;}" +
            "table.visual_diff {" +
            "       border-bottom: 0px solid;" +
            "       border-collapse: collapse;" +
            "       width: 100%;" +
            "       margin-bottom: 3px;}" +
            "       margin-bottom: 2px;}" +
            "table.visual_diff tr.headers td {" +
            "       border-bottom: 1px solid;" +
            "       border-top: 0;" +
@@ -83,7 +96,7 @@ public class Summarizer {
            "       border: 0;" +
            "       width: 0.4%}" +
            "div.space {" +
            "       margin-top:30px;}" +
            "       margin-top:4px;}" +
            "span.eql {" +
            "       background-color: #f3f3f3;}" +
            "span.del {" +
@@ -95,28 +108,57 @@ public class Summarizer {
            "span.pass {" +
            "       color: green;}" +
            "span.time_out {" +
            "       color: orange;}";
    private static final String HTML_DIFF_BEGINNING = "<html><head><style type=\"text/css\">" +
            CSS + "</style></head><body>";
    private static final String HTML_DIFF_ENDING = "</body></html>";

    /** TODO: Make it a setting */
    private static final String HTML_DIFF_RELATIVE_PATH = "_diff.html";
    private static final String HTML_DIFF_INDEX_RELATIVE_PATH = "_diff-index.html";
            "       color: orange;}" +
            "table.summary {" +
            "       border: 1px solid black;" +
            "       margin-top: 20px;}" +
            "table.summary td {" +
            "       padding: 3px;}" +
            "span.listItem {" +
            "       font-size: 11px;" +
            "       font-weight: normal;" +
            "       text-transform: uppercase;" +
            "       padding: 3px;" +
            "       -webkit-border-radius: 4px;}" +
            "span." + AbstractResult.ResultCode.PASS.name() + "{" +
            "       background-color: #8ee100;" +
            "       color: black;}" +
            "span." + AbstractResult.ResultCode.FAIL_RESULT_DIFFERS.name() + "{" +
            "       background-color: #ccc;" +
            "       color: black;}" +
            "span." + AbstractResult.ResultCode.FAIL_NO_EXPECTED_RESULT.name() + "{" +
            "       background-color: #a700e4;" +
            "       color: #fff;}" +
            "span." + AbstractResult.ResultCode.FAIL_TIMED_OUT.name() + "{" +
            "       background-color: #f3cb00;" +
            "       color: black;}" +
            "span." + AbstractResult.ResultCode.FAIL_CRASHED.name() + "{" +
            "       background-color: #c30000;" +
            "       color: #fff;}" +
            "</style>";

    /** A list containing relatives paths of tests that were skipped */
    private LinkedList<String> mSkippedTestsList = new LinkedList<String>();
    private static final String SCRIPT =
            "<script type=\"text/javascript\">" +
            "    function toggleDisplay(id) {" +
            "        element = document.getElementById(id);" +
            "        triangle = document.getElementById('tri.' + id);" +
            "        if (element.style.display == 'none') {" +
            "            element.style.display = 'inline';" +
            "            triangle.innerHTML = '&#x25bc; ';" +
            "        } else {" +
            "            element.style.display = 'none';" +
            "            triangle.innerHTML = '&#x25b6; ';" +
            "        }" +
            "    }" +
            "</script>";

    /** Collection of tests grouped according to result. Sets are initialized lazily. */
    private Map<AbstractResult.ResultCode, Set<String>> mResults =
            new EnumMap<AbstractResult.ResultCode, Set<String>>(AbstractResult.ResultCode.class);
    /** TODO: Make it a setting */
    private static final String HTML_SUMMARY_RELATIVE_PATH = "summary.html";

    /**
     * Collection of tests for which results are ignored grouped according to result. Sets are
     * initialized lazily.
     */
    private Map<AbstractResult.ResultCode, Set<String>> mResultsIgnored =
            new EnumMap<AbstractResult.ResultCode, Set<String>>(AbstractResult.ResultCode.class);
    private int mCrashedTestsCount = 0;
    private List<AbstractResult> mFailedNotIgnoredTests = new ArrayList<AbstractResult>();
    private List<AbstractResult> mIgnoredTests = new ArrayList<AbstractResult>();
    private List<String> mPassedNotIgnoredTests = new ArrayList<String>();

    private FileFilter mFileFilter;
    private String mResultsRootDirPath;
@@ -124,99 +166,124 @@ public class Summarizer {
    public Summarizer(FileFilter fileFilter, String resultsRootDirPath) {
        mFileFilter = fileFilter;
        mResultsRootDirPath = resultsRootDirPath;
        createHtmlDiff();
    }

    private void createHtmlDiff() {
        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
                HTML_DIFF_BEGINNING.getBytes(), false);
    }
    public void appendTest(AbstractResult result) {
        String relativePath = result.getRelativePath();

    private void appendHtmlDiff(String relativePath, String diff) {
        StringBuilder html = new StringBuilder();
        html.append("<label id=\"" + relativePath + "\" />");
        html.append(diff);
        html.append("<a href=\"" + HTML_DIFF_INDEX_RELATIVE_PATH + "\">Back to index</a>");
        html.append("<div class=\"space\"></div>");
        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
                html.toString().getBytes(), true);
        if (result.getResultCode() == AbstractResult.ResultCode.FAIL_CRASHED) {
            mCrashedTestsCount++;
        }

    private void finalizeHtmlDiff() {
        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
                HTML_DIFF_ENDING.getBytes(), true);
        if (mFileFilter.isIgnoreRes(relativePath)) {
            mIgnoredTests.add(result);
        } else if (result.getResultCode() == AbstractResult.ResultCode.PASS) {
            mPassedNotIgnoredTests.add(relativePath);
        } else {
            mFailedNotIgnoredTests.add(result);
        }
    }

    /** TODO: Add settings method, like setIndexSkippedTests(), setIndexTimedOutTests(), etc */
    public void summarize() {
        StringBuilder html = new StringBuilder();

    public void addSkippedTest(String relativePath) {
        mSkippedTestsList.addLast(relativePath);
    }
        html.append("<html><head>");
        html.append(CSS);
        html.append(SCRIPT);
        html.append("</head><body>");

    public void appendTest(AbstractResult result) {
        String testPath = result.getRelativePath();
        createTopSummaryTable(html);

        AbstractResult.ResultCode resultCode = result.getResultCode();
        createResultsListWithDiff(html, "Failed", mFailedNotIgnoredTests);

        /** Add the test to correct collection according to its result code */
        if (mFileFilter.isIgnoreRes(testPath)) {
            /** Lazy initialization */
            if (mResultsIgnored.get(resultCode) == null) {
                mResultsIgnored.put(resultCode, new HashSet<String>());
            }
        createResultsListWithDiff(html, "Ignored", mIgnoredTests);

            mResultsIgnored.get(resultCode).add(testPath);
        } else {
            /** Lazy initialization */
            if (mResults.get(resultCode) == null) {
                mResults.put(resultCode, new HashSet<String>());
            }
        createResultsListNoDiff(html, "Passed", mPassedNotIgnoredTests);

            mResults.get(resultCode).add(testPath);
        }
        html.append("</body></html>");

        if (resultCode != AbstractResult.ResultCode.PASS) {
            appendHtmlDiff(testPath, result.getDiffAsHtml());
        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_SUMMARY_RELATIVE_PATH),
                html.toString().getBytes(), false);
    }

    private void createTopSummaryTable(StringBuilder html) {
        int total = mFailedNotIgnoredTests.size() +
                mPassedNotIgnoredTests.size() +
                mIgnoredTests.size();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        html.append("<h1> - total of " + total + " tests - ");
        html.append(dateFormat.format(new Date()) + "</h1>");

        html.append("<table class=\"summary\">");
        createSummaryTableRow(html, "CRASHED", mCrashedTestsCount);
        createSummaryTableRow(html, "FAILED", mFailedNotIgnoredTests.size());
        createSummaryTableRow(html, "IGNORED", mIgnoredTests.size());
        createSummaryTableRow(html, "PASSED", mPassedNotIgnoredTests.size());
        html.append("</table>");
    }

    public void summarize() {
        finalizeHtmlDiff();
        createHtmlDiffIndex();
    private void createSummaryTableRow(StringBuilder html, String caption, int size) {
        html.append("<tr>");
        html.append("    <td>" + caption + "</td>");
        html.append("    <td>" + size + "</td>");
        html.append("</tr>");
    }

    private void createHtmlDiffIndex() {
        StringBuilder html = new StringBuilder();
        html.append(HTML_DIFF_BEGINNING);
        Set<String> results;
        html.append("<h1>NOT ignored</h1>");
        appendResultsMap(mResults, html);
        html.append("<h1>Ignored</h1>");
        appendResultsMap(mResultsIgnored, html);
        html.append(HTML_DIFF_ENDING);
        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_INDEX_RELATIVE_PATH),
                html.toString().getBytes(), false);
    private void createResultsListWithDiff(StringBuilder html, String title,
            List<AbstractResult> resultsList) {
        String relativePath;
        String id = "";
        AbstractResult.ResultCode resultCode;

        Collections.sort(resultsList);
        html.append("<h2>" + title + " [" + resultsList.size() + "]</h2>");
        for (AbstractResult result : resultsList) {
            relativePath = result.getRelativePath();
            resultCode = result.getResultCode();

            html.append("<h3>");

            if (resultCode == AbstractResult.ResultCode.PASS) {
                html.append(relativePath);
            } else {
                /**
                 * Technically, two different paths could end up being the same, because
                 * ':' is a valid  character in a path. However, it is probably not going
                 * to cause any problems in this case
                 */
                id = relativePath.replace(File.separator, ":");
                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
                html.append("return false;\">");
                html.append("<span class=\"tri\" id=\"tri." + id + "\">&#x25b6; </span>");
                html.append("<span class=\"path\">" + relativePath + "</span>");
                html.append("</a>");
            }

    private void appendResultsMap(Map<AbstractResult.ResultCode, Set<String>> resultsMap,
            StringBuilder html) {
        Set<String> results;
        for (AbstractResult.ResultCode resultCode : AbstractResult.ResultCode.values()) {
            results = resultsMap.get(resultCode);
            if (results != null) {
                html.append("<h2>");
            html.append(" <span class=\"listItem " + resultCode.name() + "\">");
            html.append(resultCode.toString());
                html.append("</h2");
                for (String relativePath : results) {
                    html.append("<a href=\"");
                    html.append(HTML_DIFF_RELATIVE_PATH);
                    html.append("#");
                    html.append(relativePath);
                    html.append("\">");
                    html.append(relativePath);
                    html.append("</a><br />");
            html.append("</span>");

            html.append("</h3>");

            if (resultCode != AbstractResult.ResultCode.PASS) {
                html.append("<div class=\"diff\" style=\"display: none;\" id=\"" + id + "\">");
                html.append(result.getDiffAsHtml());
                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
                html.append("return false;\">Hide</a>");
                html.append("</div>");
            }

            html.append("<div class=\"space\"></div>");
        }
    }

    private void createResultsListNoDiff(StringBuilder html, String title,
            List<String> resultsList) {
        Collections.sort(resultsList);
        html.append("<h2>Passed [" + resultsList.size() + "]</h2>");
        for (String result : resultsList) {
            html.append("<h3>" + result + "</h3>");
            html.append("<div class=\"space\"></div>");
        }
    }
}
 No newline at end of file
+57 −32
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ import android.os.Handler;
import android.os.Message;
import android.webkit.WebView;

import name.fraser.neil.plaintext.diff_match_patch;

import java.util.LinkedList;

/**
 * A result object for which the expected output is text. It does not have an image
 * expected result.
@@ -106,50 +110,71 @@ public class TextResult extends AbstractResult {

    @Override
    public String getDiffAsHtml() {
        /** TODO: just a stub
         * Probably needs rethinking anyway - just one table would be much better
         * This will require some changes in Summarizer in CSS as well */
        StringBuilder html = new StringBuilder();
        html.append("<h3>");
        html.append(mRelativePath);
        html.append("</h3>");
        html.append("<table class=\"visual_diff\">");

        html.append("    <tr class=\"headers\">");
        html.append("        <td colspan=\"2\">Expected result:</td>");
        html.append("        <td class=\"space\"></td>");
        html.append("        <td colspan=\"2\">Actual result:</td>");
        html.append("    </tr>");

        if (mExpectedResult == null || mActualResult == null) {
            appendNullsHtml(html);
        } else {
            appendDiffHtml(html);
        }

        html.append("    <tr class=\"footers\">");
        html.append("        <td colspan=\"2\"></td>");
        html.append("        <td class=\"space\"></td>");
        html.append("        <td colspan=\"2\"></td>");
        html.append("    </tr>");
        html.append("</table>");

        return html.toString();
    }

    private void appendDiffHtml(StringBuilder html) {
        LinkedList<diff_match_patch.Diff> diffs =
                new diff_match_patch().diff_main(mExpectedResult, mActualResult);

        diffs = VisualDiffUtils.splitDiffsOnNewline(diffs);

        LinkedList<String> expectedLines = new LinkedList<String>();
        LinkedList<Integer> expectedLineNums = new LinkedList<Integer>();
        LinkedList<String> actualLines = new LinkedList<String>();
        LinkedList<Integer> actualLineNums = new LinkedList<Integer>();

        VisualDiffUtils.generateExpectedResultLines(diffs, expectedLineNums, expectedLines);
        VisualDiffUtils.generateActualResultLines(diffs, actualLineNums, actualLines);

        html.append(VisualDiffUtils.getHtml(expectedLineNums, expectedLines,
                actualLineNums, actualLines));
    }

    private void appendNullsHtml(StringBuilder html) {
        /** TODO: Create a separate row for each line of not null result */
        html.append("    <tr class=\"results\">");
        html.append("<td class=\"line_count\">1:</td>");
        html.append("    <td class=\"line_count\">");
        html.append("    </td>");
        html.append("    <td class=\"line\">");
        if (mExpectedResult == null) {
            html.append("NULL");
            html.append("Expected result was NULL");
        } else {
            html.append(mExpectedResult.replace("\n", "<br />"));
        }
        html.append("        </td>");
        html.append("        <td class=\"space\"></td>");
        html.append("<td class=\"line_count\">1:</td>");
        html.append("    <td class=\"line_count\">");
        html.append("    </td>");
        html.append("    <td class=\"line\">");
        if (mActualResult == null) {
            html.append("NULL");
            html.append("Actual result was NULL");
        } else {
            html.append(mActualResult.replace("\n", "<br />"));
        }
        html.append("        </td>");
        html.append("    </tr>");

        html.append("<tr class=\"footers\">");
        html.append("<td colspan=\"2\"></td>");
        html.append("<td class=\"space\"></td>");
        html.append("<td colspan=\"2\"></td>");
        html.append("</tr>");

        html.append("</table>");

        return html.toString();
    }

    @Override
+207 −0

File added.

Preview size limit exceeded, changes collapsed.