blob: 68476efbbcceab2f61d89eba5f46f8bf06e27bbd [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.
"""The datastore model for alerts when data is no longer received for a test."""
import logging
from google.appengine.ext import ndb
from dashboard import utils
from dashboard.models import alert
from dashboard.models import alert_group
_MAX_GROUP_SIZE = 20
class StoppageAlert(alert.Alert):
"""A stoppage alert is an alert for a Test no longer receiving new points.
Each StoppageAlert is associated with one Test, so if a test suite gets
deprecated or renamed, there may be a set of related StoppageAlerts created.
The key for a StoppageAlert is of the form:
[("StoppageAlertParent", <test_path>), ("StoppageAlert", <revision>)].
Thus, two StoppageAlert entities can not be created for the same stoppage
event.
"""
# Whether a mail notification has been sent for this alert.
mail_sent = ndb.BooleanProperty(indexed=True, default=False)
# Whether new points have been received for the test after this alert.
recovered = ndb.BooleanProperty(indexed=True, default=False)
@ndb.ComputedProperty
def revision(self):
return self.key.id()
@ndb.ComputedProperty
def test(self):
return utils.TestKey(self.key.parent().string_id())
@ndb.ComputedProperty
def row(self):
test_container = utils.GetTestContainerKey(self.test)
return ndb.Key('Row', self.revision, parent=test_container)
@ndb.ComputedProperty
def start_revision(self):
return self.revision
@ndb.ComputedProperty
def end_revision(self):
return self.revision
@ndb.ComputedProperty
def last_row_date(self):
row = self.row.get()
if not row:
logging.warning('No Row with key %s', self.row)
return None
return row.timestamp
def GetStoppageAlert(test_path, revision):
"""Gets a StoppageAlert entity if it already exists.
Args:
test_path: The test path string of the Test associated with the alert.
revision: The ID of the last point before the stoppage.
Returns:
A StoppageAlert entity or None.
"""
return ndb.Key(
'StoppageAlertParent', test_path, 'StoppageAlert', revision).get()
def CreateStoppageAlert(test, row):
"""Creates a new StoppageAlert entity.
Args:
test: A Test entity.
row: A Row entity; the last Row that was put before the stoppage.
Returns:
A new StoppageAlert entity which has not been put, or None,
if we don't want to create a new StoppageAlert.
"""
new_alert = StoppageAlert(
parent=ndb.Key('StoppageAlertParent', test.test_path),
id=row.revision,
internal_only=test.internal_only,
sheriff=test.sheriff)
alert_group.GroupAlerts([new_alert], test.suite_name, 'StoppageAlert')
grouped_alert_keys = StoppageAlert.query(
StoppageAlert.group == new_alert.group).fetch(keys_only=True)
if len(grouped_alert_keys) >= _MAX_GROUP_SIZE:
# Too many stoppage alerts in this group; we don't want to put any more.
return None
test.stoppage_alert = new_alert.key
test.put()
return new_alert