def _VerifyAnomaliesOverlap(self, alerts, bug_id): """Checks whether the alerts' revision ranges intersect. Args: alerts: A list of Alert entities to verify. bug_id: Bug ID number. Returns: A string with warning message, or None if there's no warning. """ if not utils.MinimumAlertRange(alerts): return 'Selected alerts do not have overlapping revision range.' else: anomalies_with_bug = anomaly.Anomaly.query( anomaly.Anomaly.bug_id == bug_id).fetch() stoppage_alerts_with_bug = stoppage_alert.StoppageAlert.query( stoppage_alert.StoppageAlert.bug_id == bug_id).fetch() alerts_with_bug = anomalies_with_bug + stoppage_alerts_with_bug if not alerts_with_bug: return None if not utils.MinimumAlertRange(alerts_with_bug): return ('Alerts in bug %s do not have overlapping revision ' 'range.' % bug_id) elif not utils.MinimumAlertRange(alerts + alerts_with_bug): return ('Selected alerts do not have overlapping revision ' 'range with alerts in bug %s.' % bug_id) return None
def _ShowAlertsForKeys(self, keys): """Show alerts for |keys|. Query for anomalies with overlapping revision. The |keys| parameter for group_report is a comma-separated list of urlsafe strings for Keys for Anomaly entities. (Each key corresponds to an alert) Args: keys: Comma-separated list of urlsafe strings for Anomaly keys. """ urlsafe_keys = keys.split(',') try: keys = [ndb.Key(urlsafe=k) for k in urlsafe_keys] # Errors that can be thrown here include ProtocolBufferDecodeError # in google.net.proto.ProtocolBuffer. We want to catch any errors here # because they're almost certainly urlsafe key decoding errors. except Exception: raise request_handler.InvalidInputError( 'Invalid Anomaly key given.') requested_anomalies = utils.GetMulti(keys) for i, anomaly_entity in enumerate(requested_anomalies): if anomaly_entity is None: raise request_handler.InvalidInputError( 'No Anomaly found for key %s.' % urlsafe_keys[i]) if not requested_anomalies: raise request_handler.InvalidInputError('No anomalies found.') sheriff_key = requested_anomalies[0].sheriff min_range = utils.MinimumAlertRange(requested_anomalies) if min_range: query = anomaly.Anomaly.query( anomaly.Anomaly.sheriff == sheriff_key) query = query.order(-anomaly.Anomaly.timestamp) anomalies = query.fetch(limit=_QUERY_LIMIT) # Filter out anomalies that have been marked as invalid or ignore. # Include all anomalies with an overlapping revision range that have # been associated with a bug, or are not yet triaged. anomalies = [ a for a in anomalies if a.bug_id is None or a.bug_id > 0 ] anomalies = _GetOverlaps(anomalies, min_range[0], min_range[1]) # Make sure alerts in specified param "keys" are included. key_set = {a.key for a in anomalies} for anomaly_entity in requested_anomalies: if anomaly_entity.key not in key_set: anomalies.append(anomaly_entity) else: anomalies = requested_anomalies self._ShowAlerts(anomalies)
def UpdateRevisionRange(self, grouped_alerts): """Sets this group's revision range the minimum of the given group. Args: grouped_alerts: Alert entities that belong to this group. These are only given here so that they don't need to be fetched. """ min_rev_range = utils.MinimumAlertRange(grouped_alerts) start, end = min_rev_range if min_rev_range else (None, None) if self.start_revision != start or self.end_revision != end: self.start_revision = start self.end_revision = end self.put()