blob: 91de01ff1aa1fd836304880a0b3848b70b6580c8 [file] [log] [blame]
Richard Barnette4afcd932014-10-06 15:40:39 +00001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Class to wrap building detail table for board/netbook/testcategory."""
6
7import os
8
9import dash_util
10
11from build_info import BuildInfo
12from dash_view import AutotestDashView
13
14# String resources.
15from dash_strings import BVT_TAG
16
17# Constants
18DEFAULT_TEST_NAME_LENGTH = 18
19
20
21class TableBuilder(object):
22 """Class manages building header and body for details tables."""
23
24 def __init__(self, base_dir, netbook, board_type, category):
25 self._netbook = netbook
26 self._board_type = board_type
27 self._category = category
28 self._build_info = BuildInfo()
29 self._dash_view = AutotestDashView()
30 self._test_list = self._dash_view.GetTestNames(
31 netbook, board_type, category)
32 self._test_list.sort()
33 self._build_numbers = self._dash_view.GetBuilds(
34 netbook, board_type, category)
35 self._good_set, self._failed_list = self._SplitTestList()
36
37 def _SplitTestList(self):
38 """Determine and list the tests that passed and failed."""
39 good_set = set()
40 failed_list = [] # Maintains order discovered.
41
42 for build in self._build_numbers:
43 for test_name in self._test_list:
44 test_details = self._GetTestDetails(test_name, build)
45 if test_details:
46 for t in test_details:
47 good_status = (t['status'] == 'GOOD')
48 test_tuple = (test_name, t['experimental'])
49 if test_tuple in failed_list:
50 continue
51 if good_status:
52 good_set.add(test_tuple)
53 else:
54 failed_list.append(test_tuple)
55 good_set.discard(test_tuple)
56 return sorted(good_set), failed_list
57
58 def _BuildTableHeader(self, test_list):
59 """Generate header with test names for columns."""
60 table_header = []
61 for test_name, experimental in test_list:
62 test_path = self._dash_view.GetAutotestInfo(test_name)[1]
63 if len(test_name) > DEFAULT_TEST_NAME_LENGTH:
64 test_alias = test_name[:DEFAULT_TEST_NAME_LENGTH] + '...'
65 else:
66 test_alias = test_name
67 table_header.append((test_path, test_alias.replace('_', ' '),
68 test_name, experimental))
69 return table_header
70
71 def _GetBuildMetadata(self, build):
72 """Retrieve info used to populate build header popups."""
73 started, finished, elapsed = self._dash_view.GetFormattedJobTimes(
74 self._netbook, self._board_type, self._category, build)
75 fstarted, ffinished, felapsed, ffinished_short = (
76 self._build_info.GetFormattedBuildTimes(self._board_type, build))
77 return (fstarted, ffinished, felapsed,
78 started, finished, elapsed,
79 self._dash_view.GetFormattedLastUpdated())
80
81 def _GetTestDetails(self, test_name, build):
82 return self._dash_view.GetTestDetails(
83 self._netbook, self._board_type, self._category, test_name, build)
84
85 def _BuildTableBody(self, test_list):
86 """Generate table body with test results in cells."""
87 table_body = []
88
89 for build in self._build_numbers:
90 chrome_version = self._build_info.GetChromeVersion(self._board_type,
91 build)
92 test_status_list = []
93 for test_name, experimental in test_list:
94 # Include either the good details or the details of the
95 # first failure in the list (last chronological failure).
96 cell_content = []
97 test_details = self._GetTestDetails(test_name, build)
98 if test_details:
99 total_tests = len(test_details)
100 passed_tests = 0
101 failed_tests = 0
102 for t in test_details:
103 current_fail = False
104 test_status = t['status']
105 if test_status == 'GOOD':
106 passed_tests += 1
107 query = '%(tag)s' % t
108 else:
109 failed_tests += 1
110 current_fail = True
111 query = '%(tag)s/%(test_name)s' % t
112 # Populate the detailed cell popups prudently.
113 host_info = []
114 chrome_version_attr = chrome_version
115 if chrome_version and len(chrome_version) == 2:
116 chrome_version_attr = '%s (%s)' % (chrome_version[0],
117 chrome_version[1])
118 priority_attrs = [
119 ('Chrome Version', 'chrome-version', chrome_version_attr),
120 ('ChromeOS Version', 'CHROMEOS_RELEASE_DESCRIPTION', None),
121 ('Platform', 'host-platform', None),
122 ('Kernel Version', 'sysinfo-uname', None),
123 ('Reason', 'reason', None)]
124 for popup_header, attr_key, default in priority_attrs:
125 attr_value = t['attr'].get(attr_key, default)
126 if attr_value:
127 host_info.append((popup_header, attr_value))
128 test_status = test_status[0].upper()
129 # Treat TEST_NA as WARNING.
130 if test_status == 'T':
131 test_status = 'W'
132 if (not cell_content) or (current_fail and failed_tests == 1):
133 cell_content = [test_name, t['hostname'], host_info, query,
134 test_status]
135 if cell_content:
136 test_summaries = [passed_tests, total_tests]
137 test_summaries.extend(
138 self._dash_view.GetCrashes().GetBuildTestCrashSummary(
139 self._netbook, self._board_type, build, test_name))
140 cell_content.extend(test_summaries)
141 test_status_list.append(cell_content)
142 popup = self._GetBuildMetadata(build)
143 table_body.append(('', build, popup, test_status_list, chrome_version))
144 return table_body
145
146 def BuildTables(self):
147 """Generate table body with test results in cells."""
148 good_table_header = self._BuildTableHeader(self._good_set)
149 good_table_body = self._BuildTableBody(self._good_set)
150 result = [{'label': 'Good Tests',
151 'header': good_table_header,
152 'body': good_table_body}]
153 if self._failed_list:
154 failed_table_header = self._BuildTableHeader(self._failed_list)
155 failed_table_body = self._BuildTableBody(self._failed_list)
156 result.insert(0, {'label': 'Failed Tests',
157 'header': failed_table_header,
158 'body': failed_table_body})
159 return result
160
161 def CountTestList(self):
162 """Count the number of tests and failed ones."""
163 if self._build_numbers:
164 return len(self._good_set)+len(self._failed_list), len(self._failed_list)
165 else:
166 return 0, 0