blob: e45b9250c6f5054fa8eef236edb0fb4224da3e1f [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Provides a web interface for seeing recently added points."""
from dashboard import list_tests
from dashboard import request_handler
from dashboard import utils
from dashboard.models import graph_data
# Number of points to list if no number of points is specified.
_DEFAULT_NUM_POINTS = 100
# Max number of tests to use that match a user-specified pattern.
_MAX_MATCHING_TESTS = 5
class NewPointsHandler(request_handler.RequestHandler):
"""Shows a page with a list of recently added points."""
def get(self):
"""Gets the page for viewing recently added points.
Request parameters:
pattern: A test path pattern with asterisk wildcards (optional).
Outputs:
A page showing recently added points.
"""
# Construct a query for recently added Row entities.
query = graph_data.Row.query()
query = query.order(-graph_data.Row.timestamp)
# If a maximum number of tests was specified, use it; fall back on default.
try:
max_tests = int(self.request.get('max_tests', _MAX_MATCHING_TESTS))
except ValueError:
max_tests = _MAX_MATCHING_TESTS
# If a test path pattern was specified, filter the query to include only
# Row entities that belong to a test that matches the pattern.
test_pattern = self.request.get('pattern')
num_originally_matching_tests = 0
if test_pattern:
test_paths = list_tests.GetTestsMatchingPattern(
test_pattern, only_with_rows=True)
if not test_paths:
self.RenderHtml('new_points.html', {
'pattern': test_pattern,
'error': 'No tests matching pattern: %s' % test_pattern,
})
return
# If test_keys contains too many tests, then this query will exceed a
# memory limit or time out. So, limit the number of tests and let the
# user know that this has happened.
num_originally_matching_tests = len(test_paths)
if num_originally_matching_tests > max_tests:
test_paths = test_paths[:max_tests]
test_keys = map(utils.TestKey, test_paths)
query = query.filter(graph_data.Row.parent_test.IN(test_keys))
# If a valid number of points was given, use it. Otherwise use the default.
try:
num_points = int(self.request.get('num_points', _DEFAULT_NUM_POINTS))
except ValueError:
num_points = _DEFAULT_NUM_POINTS
# Fetch the Row entities.
rows = query.fetch(limit=num_points)
# Make a list of dicts which will be passed to the template.
row_dicts = []
for row in rows:
row_dicts.append({
'test': utils.TestPath(row.parent_test),
'added_time': row.timestamp.strftime('%Y-%m-%d %H:%M:%S %Z'),
'revision': row.revision,
'value': row.value,
'error': row.error,
})
error_message = ''
if num_originally_matching_tests > max_tests:
error_message = ('Pattern originally matched %s tests; only showing '
'points from the first %s tests.' %
(num_originally_matching_tests, max_tests))
# Render the template with the row information that was fetched.
self.RenderHtml('new_points.html', {
'pattern': test_pattern,
'num_points': num_points,
'max_tests': max_tests,
'rows': row_dicts,
'error': error_message,
})