Summarizer.java revision 3c8ccb384513dd9bae0f98ac516ea36fbaa3173b
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dumprendertree2;
18
19import android.util.Log;
20
21import java.io.File;
22import java.util.EnumMap;
23import java.util.HashSet;
24import java.util.LinkedList;
25import java.util.Map;
26import java.util.Set;
27
28/**
29 * A class that collects information about tests that ran and can create HTML
30 * files with summaries and easy navigation.
31 */
32public class Summarizer {
33
34    private static final String LOG_TAG = "Summarizer";
35
36    private static final String CSS =
37            "body {font-family: Verdana;} a {font-size: 12px; color: black; } h3" +
38            "{ font-size: 20px; padding: 0; margin: 0; margin-bottom: 10px; } " +
39            ".space { margin-top:30px; } table.diff_both, table.diff_both tr, " +
40            "table.diff_both td { border: 0; padding: 0; margin: 0; } " +
41            "table.diff_both { width: 600px; } table.diff_both td.dleft, " +
42            "table.diff_both td.dright { border: 0; width: 50%; } " +
43            "table.diff " + "table.diff_both caption { text-align: left; margin-bottom: 3px;}" +
44            "{ border:1px solid black; border-collapse: collapse; width: 100%; } " +
45            "table.diff tr {   vertical-align: top; border-bottom: 1px dashed black; " +
46            "border-top: 1px dashed black; font-size: 15px; } table.diff td.linecount " +
47            "{ border-right: 1px solid; background-color: #aaa; width: 20px; text-align: " +
48            "right; padding-right: 1px; padding-top: 2px; padding-bottom: 2px; } " +
49            "table.diff td.line { padding-left: 3px; padding-top: 2px; " +
50            "padding-bottom: 2px; } span.eql { background-color: #f3f3f3;} " +
51            "span.del { background-color: #ff8888; } span.ins { background-color: #88ff88; }";
52    private static final String HTML_DIFF_BEGINNING = "<html><head><style type=\"text/css\">" +
53            CSS + "</style></head><body>";
54    private static final String HTML_DIFF_ENDING = "</body></html>";
55
56    /** TODO: Make it a setting */
57    private static final String HTML_DIFF_RELATIVE_PATH = "_diff.html";
58    private static final String HTML_DIFF_INDEX_RELATIVE_PATH = "_diff-index.html";
59
60    /** A list containing relatives paths of tests that were skipped */
61    private LinkedList<String> mSkippedTestsList = new LinkedList<String>();
62
63    /** Collection of tests grouped according to result. Sets are initialized lazily. */
64    private Map<AbstractResult.ResultCode, Set<String>> mResults =
65            new EnumMap<AbstractResult.ResultCode, Set<String>>(AbstractResult.ResultCode.class);
66
67    /**
68     * Collection of tests for which results are ignored grouped according to result. Sets are
69     * initialized lazily.
70     */
71    private Map<AbstractResult.ResultCode, Set<String>> mResultsIgnored =
72            new EnumMap<AbstractResult.ResultCode, Set<String>>(AbstractResult.ResultCode.class);
73
74    private FileFilter mFileFilter;
75    private String mResultsRootDirPath;
76
77    public Summarizer(FileFilter fileFilter, String resultsRootDirPath) {
78        mFileFilter = fileFilter;
79        mResultsRootDirPath = resultsRootDirPath;
80        createHtmlDiff();
81    }
82
83    private void createHtmlDiff() {
84        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
85                HTML_DIFF_BEGINNING.getBytes(), false);
86    }
87
88    private void appendHtmlDiff(String relativePath, String diff) {
89        StringBuilder html = new StringBuilder();
90        html.append("<label id=\"" + relativePath + "\" />");
91        html.append(diff);
92        html.append("<a href=\"" + HTML_DIFF_INDEX_RELATIVE_PATH + "\">Back to index</a>");
93        html.append("<div class=\"space\"></div>");
94        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
95                html.toString().getBytes(), true);
96    }
97
98    private void finalizeHtmlDiff() {
99        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_RELATIVE_PATH),
100                HTML_DIFF_ENDING.getBytes(), true);
101    }
102
103    /** TODO: Add settings method, like setIndexSkippedTests(), setIndexTimedOutTests(), etc */
104
105    public void addSkippedTest(String relativePath) {
106        mSkippedTestsList.addLast(relativePath);
107    }
108
109    public void appendTest(LayoutTest test) {
110        String testPath = test.getRelativePath();
111
112        /** Obtain the result */
113        AbstractResult result = test.getResult();
114        if (result == null) {
115            Log.e(LOG_TAG + "::appendTest", testPath + ": result NULL!!");
116            return;
117        }
118
119        AbstractResult.ResultCode resultCode = result.getCode();
120
121        /** Add the test to correct collection according to its result code */
122        if (mFileFilter.isIgnoreRes(testPath)) {
123            /** Lazy initialization */
124            if (mResultsIgnored.get(resultCode) == null) {
125                mResultsIgnored.put(resultCode, new HashSet<String>());
126            }
127
128            mResultsIgnored.get(resultCode).add(testPath);
129        } else {
130            /** Lazy initialization */
131            if (mResults.get(resultCode) == null) {
132                mResults.put(resultCode, new HashSet<String>());
133            }
134
135            mResults.get(resultCode).add(testPath);
136        }
137
138        if (resultCode != AbstractResult.ResultCode.PASS) {
139            appendHtmlDiff(testPath, result.getDiffAsHtml());
140        }
141    }
142
143    public void summarize() {
144        finalizeHtmlDiff();
145        createHtmlDiffIndex();
146    }
147
148    private void createHtmlDiffIndex() {
149        StringBuilder html = new StringBuilder();
150        html.append(HTML_DIFF_BEGINNING);
151        Set<String> results;
152        html.append("<h1>Tests that were _not_ ignored</h1>");
153        appendResultsMap(mResults, html);
154        html.append("<h1>Tests that _were_ ignored</h1>");
155        appendResultsMap(mResultsIgnored, html);
156        html.append(HTML_DIFF_ENDING);
157        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DIFF_INDEX_RELATIVE_PATH),
158                html.toString().getBytes(), false);
159    }
160
161    private void appendResultsMap(Map<AbstractResult.ResultCode, Set<String>> resultsMap,
162            StringBuilder html) {
163        Set<String> results;
164        for (AbstractResult.ResultCode resultCode : AbstractResult.ResultCode.values()) {
165            results = resultsMap.get(resultCode);
166            if (results != null) {
167                html.append("<h2>");
168                html.append(resultCode.toString());
169                html.append("</h2");
170                for (String relativePath : results) {
171                    html.append("<a href=\"");
172                    html.append(HTML_DIFF_RELATIVE_PATH);
173                    html.append("#");
174                    html.append(relativePath);
175                    html.append("\">");
176                    html.append(relativePath);
177                    html.append("</a><br />");
178                }
179            }
180        }
181    }
182}
183