13c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski/* 23c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * Copyright (C) 2010 The Android Open Source Project 33c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * 43c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * Licensed under the Apache License, Version 2.0 (the "License"); 53c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * you may not use this file except in compliance with the License. 63c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * You may obtain a copy of the License at 73c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * 83c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * http://www.apache.org/licenses/LICENSE-2.0 93c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * 103c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * Unless required by applicable law or agreed to in writing, software 113c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * distributed under the License is distributed on an "AS IS" BASIS, 123c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * See the License for the specific language governing permissions and 143c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * limitations under the License. 153c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski */ 163c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 173c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowskipackage com.android.dumprendertree2; 183c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 19394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowskiimport android.content.Context; 202e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport android.content.res.AssetManager; 212e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport android.content.res.Configuration; 222e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport android.content.res.Resources; 23394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowskiimport android.database.Cursor; 242e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport android.os.Build; 259893d96d1231235f3d984e9dc751f08409a5f873Maksymilian Osowskiimport android.os.Message; 262e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport android.util.DisplayMetrics; 27603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowskiimport android.util.Log; 28603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski 29603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowskiimport com.android.dumprendertree2.forwarder.ForwarderManager; 302e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski 313c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowskiimport java.io.File; 32603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowskiimport java.net.MalformedURLException; 331b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowskiimport java.net.URI; 34603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowskiimport java.net.URL; 356d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowskiimport java.text.SimpleDateFormat; 366d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowskiimport java.util.ArrayList; 376d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowskiimport java.util.Date; 386d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowskiimport java.util.List; 392e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport java.util.regex.Matcher; 402e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowskiimport java.util.regex.Pattern; 413c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 423c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski/** 433c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * A class that collects information about tests that ran and can create HTML 443c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski * files with summaries and easy navigation. 453c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski */ 463c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowskipublic class Summarizer { 473c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 483c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski private static final String LOG_TAG = "Summarizer"; 493c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 503c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski private static final String CSS = 516d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "<style type=\"text/css\">" + 524ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "* {" + 534ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " font-family: Verdana;" + 544ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border: 0;" + 554ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " margin: 0;" + 564ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " padding: 0;}" + 574ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "body {" + 584ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " margin: 10px;}" + 594ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "h1 {" + 606d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-size: 24px;" + 614ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " margin: 4px 0 4px 0;}" + 624ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "h2 {" + 636d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-size:18px;" + 646d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " text-transform: uppercase;" + 654ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " margin: 20px 0 3px 0;}" + 666d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "h3, h3 a {" + 676d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-size: 14px;" + 686d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: black;" + 696d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " text-decoration: none;" + 7001c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " margin-top: 4px;" + 7101c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " margin-bottom: 2px;}" + 726d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "h3 a span.path {" + 736d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " text-decoration: underline;}" + 746d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "h3 span.tri {" + 754a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " text-decoration: none;" + 764a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " float: left;" + 774a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " width: 20px;}" + 784a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski "h3 span.sqr {" + 794a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " text-decoration: none;" + 804a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " float: left;" + 814a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " width: 20px;}" + 828a6def02473ee4fbffcd1b34173daf751d316202Steve Block "h3 span.sqr_pass {" + 838a6def02473ee4fbffcd1b34173daf751d316202Steve Block " color: #8ee100;}" + 848a6def02473ee4fbffcd1b34173daf751d316202Steve Block "h3 span.sqr_fail {" + 858a6def02473ee4fbffcd1b34173daf751d316202Steve Block " color: #c30000;}" + 8601c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski "span.source {" + 8701c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " display: block;" + 8801c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " font-size: 10px;" + 8901c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " color: #888;" + 9001c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " margin-left: 20px;" + 9101c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " margin-bottom: 1px;}" + 9201c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski "span.source a {" + 9301c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " font-size: 10px;" + 9401c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski " color: #888;}" + 956d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "h3 img {" + 966d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " width: 8px;" + 976d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " margin-right: 4px;}" + 986d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "div.diff {" + 996d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " margin-bottom: 25px;}" + 1006d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "div.diff a {" + 1016d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-size: 12px;" + 1026d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: #888;}" + 1034ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff {" + 1044ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-bottom: 0px solid;" + 1054ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-collapse: collapse;" + 1064ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " width: 100%;" + 1076d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " margin-bottom: 2px;}" + 1084ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr.headers td {" + 1094ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-bottom: 1px solid;" + 1104ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-top: 0;" + 1114ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " padding-bottom: 3px;}" + 1124ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr.results td {" + 1134ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-top: 1px dashed;" + 1144ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-right: 1px solid;" + 1154ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " font-size: 15px;" + 1164ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " vertical-align: top;}" + 1174ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr.results td.line_count {" + 1184ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " background-color:#aaa;" + 1194ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " min-width:20px;" + 1204ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " text-align: right;" + 1214ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-right: 1px solid;" + 1224ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-left: 1px solid;" + 1234ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " padding: 2px 1px 2px 0px;}" + 1244ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr.results td.line {" + 1254ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " padding: 2px 0px 2px 4px;" + 1264ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-right: 1px solid;" + 1274ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " width: 49.8%;}" + 1284ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr.footers td {" + 1294ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-top: 1px solid;" + 1304ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border-bottom: 0;}" + 1314ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "table.visual_diff tr td.space {" + 1324ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " border: 0;" + 1334ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " width: 0.4%}" + 1344ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "div.space {" + 1356d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " margin-top:4px;}" + 1364ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "span.eql {" + 1374ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " background-color: #f3f3f3;}" + 1384ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "span.del {" + 1394ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " background-color: #ff8888; }" + 1404ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski "span.ins {" + 1414ee7f4b19489f4dc9b87e90d1e5c7742cfa7ebe0Maksymilian Osowski " background-color: #88ff88; }" + 1426d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "table.summary {" + 1436d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " border: 1px solid black;" + 1446d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " margin-top: 20px;}" + 1456d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "table.summary td {" + 1466d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " padding: 3px;}" + 1476d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "span.listItem {" + 1486d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-size: 11px;" + 1496d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " font-weight: normal;" + 1506d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " text-transform: uppercase;" + 1516d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " padding: 3px;" + 1526d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " -webkit-border-radius: 4px;}" + 1538a6def02473ee4fbffcd1b34173daf751d316202Steve Block "span." + AbstractResult.ResultCode.RESULTS_DIFFER.name() + "{" + 1546d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " background-color: #ccc;" + 1556d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: black;}" + 1568a6def02473ee4fbffcd1b34173daf751d316202Steve Block "span." + AbstractResult.ResultCode.NO_EXPECTED_RESULT.name() + "{" + 1576d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " background-color: #a700e4;" + 1586d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: #fff;}" + 1598a6def02473ee4fbffcd1b34173daf751d316202Steve Block "span.timed_out {" + 1606d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " background-color: #f3cb00;" + 1616d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: black;}" + 1628a6def02473ee4fbffcd1b34173daf751d316202Steve Block "span.crashed {" + 1636d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " background-color: #c30000;" + 1646d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " color: #fff;}" + 1654a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski "span.noLtc {" + 1664a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski " background-color: #944000;" + 1677e2a39b5985a1449588a397195c178bfef9421dbMaksymilian Osowski " color: #fff;}" + 1687e2a39b5985a1449588a397195c178bfef9421dbMaksymilian Osowski "span.noEventSender {" + 1697e2a39b5985a1449588a397195c178bfef9421dbMaksymilian Osowski " background-color: #815600;" + 1707e2a39b5985a1449588a397195c178bfef9421dbMaksymilian Osowski " color: #fff;}" + 1716d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "</style>"; 1723c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 1736d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski private static final String SCRIPT = 1746d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "<script type=\"text/javascript\">" + 1756d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " function toggleDisplay(id) {" + 1766d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " element = document.getElementById(id);" + 1776d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " triangle = document.getElementById('tri.' + id);" + 1786d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " if (element.style.display == 'none') {" + 1796d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " element.style.display = 'inline';" + 1806d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " triangle.innerHTML = '▼ ';" + 1816d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " } else {" + 1826d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " element.style.display = 'none';" + 1836d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " triangle.innerHTML = '▶ ';" + 1846d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " }" + 1856d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski " }" + 1866d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski "</script>"; 1873c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 1886d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski /** TODO: Make it a setting */ 1895fb9ff420d378c5c83e116efadefb669791098d5Maksymilian Osowski private static final String HTML_DETAILS_RELATIVE_PATH = "details.html"; 1903df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski private static final String TXT_SUMMARY_RELATIVE_PATH = "summary.txt"; 1913c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 192fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski private static final int RESULTS_PER_DUMP = 500; 193394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private static final int RESULTS_PER_DB_ACCESS = 50; 194fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski 1956d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski private int mCrashedTestsCount = 0; 1966ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski private List<AbstractResult> mUnexpectedFailures = new ArrayList<AbstractResult>(); 1976ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski private List<AbstractResult> mExpectedFailures = new ArrayList<AbstractResult>(); 19801c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski private List<AbstractResult> mExpectedPasses = new ArrayList<AbstractResult>(); 19901c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski private List<AbstractResult> mUnexpectedPasses = new ArrayList<AbstractResult>(); 2003c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 201394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private Cursor mUnexpectedFailuresCursor; 202394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private Cursor mExpectedFailuresCursor; 203394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private Cursor mUnexpectedPassesCursor; 204394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private Cursor mExpectedPassesCursor; 205394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 2063c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski private FileFilter mFileFilter; 2073c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski private String mResultsRootDirPath; 2082e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski private String mTestsRelativePath; 2092e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski private Date mDate; 2103df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 211fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski private int mResultsSinceLastHtmlDump = 0; 212394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private int mResultsSinceLastDbAccess = 0; 213394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 214394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private SummarizerDBHelper mDbHelper; 215fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski 216cda9448206494b67c0812b9591cc066ca070a7a6Steve Block public Summarizer(String resultsRootDirPath, Context context) { 217cda9448206494b67c0812b9591cc066ca070a7a6Steve Block mFileFilter = new FileFilter(); 2183c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski mResultsRootDirPath = resultsRootDirPath; 219394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 220394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski /** 221394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski * We don't run the database I/O in a separate thread to avoid consumer/producer problem 222394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski * and to simplify code. 223394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski */ 224394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper = new SummarizerDBHelper(context); 225394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.open(); 2263c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 2273c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 2281b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowski public static URI getDetailsUri() { 2291b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowski return new File(ManagerService.RESULTS_ROOT_DIR_PATH + File.separator + 2301b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowski HTML_DETAILS_RELATIVE_PATH).toURI(); 2311b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowski } 2321b034781f4c45608e4d57e46cd46dfab9fc64746Maksymilian Osowski 2336d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski public void appendTest(AbstractResult result) { 2346d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski String relativePath = result.getRelativePath(); 2356d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 2368a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (result.didCrash()) { 2376d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski mCrashedTestsCount++; 2386d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski } 2396d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 2408a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (result.didPass()) { 241394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski result.clearResults(); 2426ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski if (mFileFilter.isFail(relativePath)) { 24301c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski mUnexpectedPasses.add(result); 2446ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski } else { 24501c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski mExpectedPasses.add(result); 2466ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski } 2476d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski } else { 2486ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski if (mFileFilter.isFail(relativePath)) { 2496ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski mExpectedFailures.add(result); 2506ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski } else { 2516ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski mUnexpectedFailures.add(result); 2526ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski } 2536d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski } 254394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 255394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski if (++mResultsSinceLastDbAccess == RESULTS_PER_DB_ACCESS) { 256394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistLists(); 257394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski clearLists(); 258394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 259394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 260394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 261394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private void clearLists() { 262394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedFailures.clear(); 263394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedFailures.clear(); 264394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedPasses.clear(); 265394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedPasses.clear(); 266394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 267394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 268394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private void persistLists() { 269394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistListToTable(mUnexpectedFailures, SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE); 270394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistListToTable(mExpectedFailures, SummarizerDBHelper.EXPECTED_FAILURES_TABLE); 271394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistListToTable(mUnexpectedPasses, SummarizerDBHelper.UNEXPECTED_PASSES_TABLE); 272394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistListToTable(mExpectedPasses, SummarizerDBHelper.EXPECTED_PASSES_TABLE); 273394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mResultsSinceLastDbAccess = 0; 274394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 275394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 276394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski private void persistListToTable(List<AbstractResult> results, String table) { 277394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski for (AbstractResult abstractResult : results) { 278394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.insertAbstractResult(abstractResult, table); 279394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 2803c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 2813c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 2822e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski public void setTestsRelativePath(String testsRelativePath) { 2832e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski mTestsRelativePath = testsRelativePath; 2842e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski } 2852e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski 2869893d96d1231235f3d984e9dc751f08409a5f873Maksymilian Osowski public void summarize(Message onFinishMessage) { 287394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski persistLists(); 288394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski clearLists(); 289394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 290394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedFailuresCursor = 291394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE); 292394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedPassesCursor = 293394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_PASSES_TABLE); 294394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedFailuresCursor = 295394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_FAILURES_TABLE); 296394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedPassesCursor = 297394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_PASSES_TABLE); 298394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 299ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block String webKitRevision = getWebKitRevision(); 300ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block createHtmlDetails(webKitRevision); 301ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block createTxtSummary(webKitRevision); 302394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 303394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski clearLists(); 304394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedFailuresCursor.close(); 305394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedPassesCursor.close(); 306394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedFailuresCursor.close(); 307394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedPassesCursor.close(); 308394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 3099893d96d1231235f3d984e9dc751f08409a5f873Maksymilian Osowski onFinishMessage.sendToTarget(); 3103df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski } 3113df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 312ea46f2595a8718d4478e016fd40b2d57658289cfMaksymilian Osowski public void reset() { 313ea46f2595a8718d4478e016fd40b2d57658289cfMaksymilian Osowski mCrashedTestsCount = 0; 314394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski clearLists(); 315394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mDbHelper.reset(); 3162e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski mDate = new Date(); 317ea46f2595a8718d4478e016fd40b2d57658289cfMaksymilian Osowski } 318ea46f2595a8718d4478e016fd40b2d57658289cfMaksymilian Osowski 319fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski private void dumpHtmlToFile(StringBuilder html, boolean append) { 320fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DETAILS_RELATIVE_PATH), 321fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski html.toString().getBytes(), append); 322fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski html.setLength(0); 323fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski mResultsSinceLastHtmlDump = 0; 324fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski } 325fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski 326ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block private void createTxtSummary(String webKitRevision) { 3273df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski StringBuilder txt = new StringBuilder(); 3283df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 3292e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 33075aa0d382844dbee2d7931f21245112c27dd3d64Maksymilian Osowski txt.append("Path: " + mTestsRelativePath + "\n"); 3312e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski txt.append("Date: " + dateFormat.format(mDate) + "\n"); 3322e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski txt.append("Build fingerprint: " + Build.FINGERPRINT + "\n"); 3332e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski txt.append("WebKit version: " + getWebKitVersionFromUserAgentString() + "\n"); 334ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block txt.append("WebKit revision: " + webKitRevision + "\n"); 3352e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski 3367438b53487cb21f261eac4396aba0dbaa16ee015Steve Block txt.append("TOTAL: " + getTotalTestCount() + "\n"); 3377438b53487cb21f261eac4396aba0dbaa16ee015Steve Block txt.append("CRASHED (among all tests): " + mCrashedTestsCount + "\n"); 338394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski txt.append("UNEXPECTED FAILURES: " + mUnexpectedFailuresCursor.getCount() + "\n"); 339394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski txt.append("UNEXPECTED PASSES: " + mUnexpectedPassesCursor.getCount() + "\n"); 340394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski txt.append("EXPECTED FAILURES: " + mExpectedFailuresCursor.getCount() + "\n"); 341394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski txt.append("EXPECTED PASSES: " + mExpectedPassesCursor.getCount() + "\n"); 3423df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 3433df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski FsUtils.writeDataToStorage(new File(mResultsRootDirPath, TXT_SUMMARY_RELATIVE_PATH), 3443df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski txt.toString().getBytes(), false); 3453df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski } 3463df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 347ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block private void createHtmlDetails(String webKitRevision) { 3483c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski StringBuilder html = new StringBuilder(); 3493c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 3506d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("<html><head>"); 3516d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append(CSS); 3526d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append(SCRIPT); 3536d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("</head><body>"); 3546d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 355ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block createTopSummaryTable(webKitRevision, html); 356fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski dumpHtmlToFile(html, false); 3576d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 358394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createResultsList(html, "Unexpected failures", mUnexpectedFailuresCursor); 359394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createResultsList(html, "Unexpected passes", mUnexpectedPassesCursor); 360394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createResultsList(html, "Expected failures", mExpectedFailuresCursor); 361394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createResultsList(html, "Expected passes", mExpectedPassesCursor); 3626d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 3636d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("</body></html>"); 364fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski dumpHtmlToFile(html, true); 3653c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 3663c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 3672e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski private int getTotalTestCount() { 368394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski return mUnexpectedFailuresCursor.getCount() + 369394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mUnexpectedPassesCursor.getCount() + 370394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedPassesCursor.getCount() + 371394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski mExpectedFailuresCursor.getCount(); 3722e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski } 3733df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 3742e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski private String getWebKitVersionFromUserAgentString() { 3752e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski Resources resources = new Resources(new AssetManager(), new DisplayMetrics(), 3762e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski new Configuration()); 3772e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski String userAgent = 3782e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski resources.getString(com.android.internal.R.string.web_user_agent); 3792e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski 3802e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski Matcher matcher = Pattern.compile("AppleWebKit/([0-9]+?\\.[0-9])").matcher(userAgent); 3812e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski if (matcher.find()) { 3822e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski return matcher.group(1); 3832e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski } 3842e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski return "unknown"; 3853df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski } 3863df4eab3de243d3e9a68d2554eeaed3b1bb4d69dMaksymilian Osowski 3872ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski private String getWebKitRevision() { 3882ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski URL url = null; 3892ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski try { 3900e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block url = new URL(ForwarderManager.getHostSchemePort(false) + "ThirdPartyProject.prop"); 3912ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski } catch (MalformedURLException e) { 3922ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski assert false; 3932ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski } 3942ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski 3950e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block String thirdPartyProjectContents = new String(FsUtils.readDataFromUrl(url)); 3960e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block Matcher matcher = Pattern.compile("^version=([0-9]+)", Pattern.MULTILINE).matcher( 3970e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block thirdPartyProjectContents); 3982ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski if (matcher.find()) { 3992ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski return matcher.group(1); 4002ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski } 4012ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski return "unknown"; 4022ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski } 4032ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski 404ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block private void createTopSummaryTable(String webKitRevision, StringBuilder html) { 4052e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 40675aa0d382844dbee2d7931f21245112c27dd3d64Maksymilian Osowski html.append("<h1>" + "Layout tests' results for: " + 40775aa0d382844dbee2d7931f21245112c27dd3d64Maksymilian Osowski (mTestsRelativePath.equals("") ? "all tests" : mTestsRelativePath) + "</h1>"); 4082e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski html.append("<h3>" + "Date: " + dateFormat.format(new Date()) + "</h3>"); 4092e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski html.append("<h3>" + "Build fingerprint: " + Build.FINGERPRINT + "</h3>"); 4102e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski html.append("<h3>" + "WebKit version: " + getWebKitVersionFromUserAgentString() + "</h3>"); 4113c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4122ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski html.append("<h3>" + "WebKit revision: "); 413ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block html.append("<a href=\"http://trac.webkit.org/browser/trunk?rev=" + webKitRevision + 414ab87db4ad8e16e36f99303933db5267946e7bb34Steve Block "\" target=\"_blank\"><span class=\"path\">" + webKitRevision + "</span></a>"); 4152ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski html.append("</h3>"); 4162ca8acdb5622b03a4ef56159477087adcf87db62Maksymilian Osowski 4176d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("<table class=\"summary\">"); 4182e64bb7afdd97c954491877306ccb8318f8ec3ceMaksymilian Osowski createSummaryTableRow(html, "TOTAL", getTotalTestCount()); 4197438b53487cb21f261eac4396aba0dbaa16ee015Steve Block createSummaryTableRow(html, "CRASHED (among all tests)", mCrashedTestsCount); 420394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createSummaryTableRow(html, "UNEXPECTED FAILURES", mUnexpectedFailuresCursor.getCount()); 421394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createSummaryTableRow(html, "UNEXPECTED PASSES", mUnexpectedPassesCursor.getCount()); 422394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createSummaryTableRow(html, "EXPECTED FAILURES", mExpectedFailuresCursor.getCount()); 423394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski createSummaryTableRow(html, "EXPECTED PASSES", mExpectedPassesCursor.getCount()); 4246d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("</table>"); 4253c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 4263c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4276d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski private void createSummaryTableRow(StringBuilder html, String caption, int size) { 4286d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("<tr>"); 4296d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append(" <td>" + caption + "</td>"); 4306d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append(" <td>" + size + "</td>"); 4316d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("</tr>"); 4326d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski } 4333c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4348a6def02473ee4fbffcd1b34173daf751d316202Steve Block private void createResultsList( 435394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski StringBuilder html, String title, Cursor cursor) { 4366d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski String relativePath; 4376d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski String id = ""; 4386d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski AbstractResult.ResultCode resultCode; 4393c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 440394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski html.append("<h2>" + title + " [" + cursor.getCount() + "]</h2>"); 441394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 442394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski if (!cursor.moveToFirst()) { 443394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski return; 444394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } 445394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 446394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski AbstractResult result; 447394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski do { 448394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski result = SummarizerDBHelper.getAbstractResult(cursor); 449394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 4506d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski relativePath = result.getRelativePath(); 4516d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski resultCode = result.getResultCode(); 4523c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4536d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("<h3>"); 4546d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski 4556ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski /** 4566ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski * Technically, two different paths could end up being the same, because 4576ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski * ':' is a valid character in a path. However, it is probably not going 4586ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski * to cause any problems in this case 4596ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski */ 4606ae5ce4b409759d36f2350e96ff2242e1385b147Maksymilian Osowski id = relativePath.replace(File.separator, ":"); 4618a6def02473ee4fbffcd1b34173daf751d316202Steve Block 4628a6def02473ee4fbffcd1b34173daf751d316202Steve Block /** Write the test name */ 4638a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (resultCode == AbstractResult.ResultCode.RESULTS_DIFFER) { 4648a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');"); 4658a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("return false;\">"); 4668a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<span class=\"tri\" id=\"tri." + id + "\">▶ </span>"); 4678a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<span class=\"path\">" + relativePath + "</span>"); 4688a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("</a>"); 4698a6def02473ee4fbffcd1b34173daf751d316202Steve Block } else { 4708a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<a href=\"" + getViewSourceUrl(result.getRelativePath()).toString() + "\""); 4718a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" target=\"_blank\">"); 4728a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<span class=\"sqr sqr_" + (result.didPass() ? "pass" : "fail")); 4738a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("\">■ </span>"); 4748a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<span class=\"path\">" + result.getRelativePath() + "</span>"); 4758a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("</a>"); 4768a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 4778a6def02473ee4fbffcd1b34173daf751d316202Steve Block 4788a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (!result.didPass()) { 4798a6def02473ee4fbffcd1b34173daf751d316202Steve Block appendTags(html, result); 4807e2a39b5985a1449588a397195c178bfef9421dbMaksymilian Osowski } 4814a9e3a6dc3bfbc885730cfec7b2f1c147d179cc1Maksymilian Osowski 4826d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("</h3>"); 48301c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski appendExpectedResultsSources(result, html); 4843c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4858a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (resultCode == AbstractResult.ResultCode.RESULTS_DIFFER) { 4868a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<div class=\"diff\" style=\"display: none;\" id=\"" + id + "\">"); 4878a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(result.getDiffAsHtml()); 4888a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');"); 4898a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("return false;\">Hide</a>"); 4908a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" | "); 4918a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("<a href=\"" + getViewSourceUrl(relativePath).toString() + "\""); 4928a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" target=\"_blank\">Show source</a>"); 4938a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("</div>"); 4948a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 4953c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 4966d0dae6a6534a01ee4c58d4f4ee1bf115c82319cMaksymilian Osowski html.append("<div class=\"space\"></div>"); 497fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski 498fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski if (++mResultsSinceLastHtmlDump == RESULTS_PER_DUMP) { 499fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski dumpHtmlToFile(html, true); 500fadb0de33d3d4b0da765e2d3f60b895016b89c4fMaksymilian Osowski } 501394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski 502394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski cursor.moveToNext(); 503394e0fb84996f5f5ee9e33c9e2f0e11066e6f943Maksymilian Osowski } while (!cursor.isAfterLast()); 5043c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 5053c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski 5068a6def02473ee4fbffcd1b34173daf751d316202Steve Block private void appendTags(StringBuilder html, AbstractResult result) { 5078a6def02473ee4fbffcd1b34173daf751d316202Steve Block /** Tag tests which crash, time out or where results don't match */ 5088a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (result.didCrash()) { 5098a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" <span class=\"listItem crashed\">Crashed</span>"); 5108a6def02473ee4fbffcd1b34173daf751d316202Steve Block } else { 5118a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (result.didTimeOut()) { 5128a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" <span class=\"listItem timed_out\">Timed out</span>"); 5138a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 5148a6def02473ee4fbffcd1b34173daf751d316202Steve Block AbstractResult.ResultCode resultCode = result.getResultCode(); 5158a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (resultCode != AbstractResult.ResultCode.RESULTS_MATCH) { 5168a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" <span class=\"listItem " + resultCode.name() + "\">"); 5178a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(resultCode.toString()); 5188a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("</span>"); 5198a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 5208a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 5218a6def02473ee4fbffcd1b34173daf751d316202Steve Block 5228a6def02473ee4fbffcd1b34173daf751d316202Steve Block /** Detect missing LTC function */ 5238a6def02473ee4fbffcd1b34173daf751d316202Steve Block String additionalTextOutputString = result.getAdditionalTextOutputString(); 5248a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (additionalTextOutputString != null && 5258a6def02473ee4fbffcd1b34173daf751d316202Steve Block additionalTextOutputString.contains("com.android.dumprendertree") && 5268a6def02473ee4fbffcd1b34173daf751d316202Steve Block additionalTextOutputString.contains("has no method")) { 5278a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (additionalTextOutputString.contains("LayoutTestController")) { 5288a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" <span class=\"listItem noLtc\">LTC function missing</span>"); 5298a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 5308a6def02473ee4fbffcd1b34173daf751d316202Steve Block if (additionalTextOutputString.contains("EventSender")) { 5318a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append(" <span class=\"listItem noEventSender\">"); 5328a6def02473ee4fbffcd1b34173daf751d316202Steve Block html.append("ES function missing</span>"); 5338a6def02473ee4fbffcd1b34173daf751d316202Steve Block } 5343c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 5353c8ccb384513dd9bae0f98ac516ea36fbaa3173bMaksymilian Osowski } 536603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski 53701c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski private static final void appendExpectedResultsSources(AbstractResult result, 53801c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski StringBuilder html) { 53901c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski String textSource = result.getExpectedTextResultPath(); 54001c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski String imageSource = result.getExpectedImageResultPath(); 54101c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski 54224652bc958997dc32d5c8275f2f2ce38daf6e106Steve Block if (result.didCrash()) { 54324652bc958997dc32d5c8275f2f2ce38daf6e106Steve Block html.append("<span class=\"source\">Did not look for expected results</span>"); 54424652bc958997dc32d5c8275f2f2ce38daf6e106Steve Block return; 54524652bc958997dc32d5c8275f2f2ce38daf6e106Steve Block } 54624652bc958997dc32d5c8275f2f2ce38daf6e106Steve Block 547f460dd42190ada4a2c147db5127a9d7870fe0101Steve Block if (textSource == null) { 548f460dd42190ada4a2c147db5127a9d7870fe0101Steve Block // Show if a text result is missing. We may want to revisit this decision when we add 549f460dd42190ada4a2c147db5127a9d7870fe0101Steve Block // support for image results. 550f460dd42190ada4a2c147db5127a9d7870fe0101Steve Block html.append("<span class=\"source\">Expected textual result missing</span>"); 551f460dd42190ada4a2c147db5127a9d7870fe0101Steve Block } else { 55201c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append("<span class=\"source\">Expected textual result from: "); 55301c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" + 55401c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski textSource + "\""); 55501c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append(" target=\"_blank\">"); 55601c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append(textSource + "</a></span>"); 55701c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski } 55801c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski if (imageSource != null) { 55901c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append("<span class=\"source\">Expected image result from: "); 56001c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" + 56101c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski imageSource + "\""); 56201c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append(" target=\"_blank\">"); 56301c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski html.append(imageSource + "</a></span>"); 56401c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski } 56501c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski } 56601c1f9d9e9e7ab3a40a9bf27195a434eb0c9bb9bMaksymilian Osowski 567603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski private static final URL getViewSourceUrl(String relativePath) { 568603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski URL url = null; 569603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski try { 570603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski url = new URL("http", "localhost", ForwarderManager.HTTP_PORT, 571183c3c9ca20f55703f31e3610bca72682f6355dbSteve Block "/Tools/DumpRenderTree/android/view_source.php?src=" + 572603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski relativePath); 573603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski } catch (MalformedURLException e) { 574603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski assert false : "relativePath=" + relativePath; 575603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski } 576603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski return url; 577603b70dd8b1ef8acabf71c52089c6cd5396fe931Maksymilian Osowski } 5780e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block} 579