示例#1
0
    def _VerifyAnomaliesOverlap(self, alerts, bug_id, project_id):
        """Checks whether the alerts' revision ranges intersect.

    Args:
      alerts: A list of Alert entities to verify.
      bug_id: Bug ID number.
      project_id: Monorail project ID.

    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:
            alerts_with_bug, _, _ = anomaly.Anomaly.QueryAsync(
                bug_id=bug_id, project_id=project_id, limit=500).get_result()

            if not alerts_with_bug:
                return None
            if not utils.MinimumAlertRange(alerts_with_bug):
                return ('Alerts in bug %s:%s do not have overlapping revision '
                        'range.' % (project_id, bug_id))
            elif not utils.MinimumAlertRange(alerts + alerts_with_bug):
                return ('Selected alerts do not have overlapping revision '
                        'range with alerts in bug %s:%s.' %
                        (project_id, bug_id))
        return None
示例#2
0
    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
示例#3
0
def GetAlertsForKeys(keys):
    """Get 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.

  Returns:
    tuple (alerts, extra_columns)
  """
    urlsafe_keys = keys

    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)

    extra_columns = None
    for i, anomaly_entity in enumerate(requested_anomalies):
        if isinstance(anomaly_entity, anomaly.Anomaly):
            extra_columns = 'anomalies'
        elif (isinstance(anomaly_entity, stoppage_alert.StoppageAlert)
              and extra_columns is None):
            extra_columns = 'stoppage_alerts'
        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
    return anomalies, extra_columns
示例#4
0
def GetAlertsForKeys(keys):
    """Get 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.

  Returns:
    list of anomaly.Anomaly
  """
    urlsafe_keys = keys

    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.')

    # Just an optimization because we can't fetch anomalies directly based
    # on revisions. Apply some filters to reduce unrelated anomalies.
    subscriptions = []
    for anomaly_entity in requested_anomalies:
        subscriptions.extend(anomaly_entity.subscription_names)
    subscriptions = list(set(subscriptions))
    min_range = utils.MinimumAlertRange(requested_anomalies)
    if min_range:
        anomalies, _, _ = anomaly.Anomaly.QueryAsync(
            subscriptions=subscriptions, limit=_QUERY_LIMIT).get_result()

        # 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.
        requested_anomalies_set = set([a.key for a in requested_anomalies])

        def _IsValidAlert(a):
            if a.key in requested_anomalies_set:
                return False
            return a.bug_id is None or a.bug_id > 0

        anomalies = [a for a in anomalies if _IsValidAlert(a)]
        anomalies = _GetOverlaps(anomalies, min_range[0], min_range[1])
        anomalies = requested_anomalies + anomalies
    else:
        anomalies = requested_anomalies
    return anomalies
示例#5
0
def GetAlertsForKeys(keys):
    """Get 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.

  Returns:
    list of anomaly.Anomaly
  """
    urlsafe_keys = keys

    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.
        requested_anomalies_set = set([a.key for a in requested_anomalies])

        def _IsValidAlert(a):
            if a.key in requested_anomalies_set:
                return False
            return a.bug_id is None or a.bug_id > 0

        anomalies = [a for a in anomalies if _IsValidAlert(a)]
        anomalies = _GetOverlaps(anomalies, min_range[0], min_range[1])

        # Make sure alerts in specified param "keys" are included.
        # We actually only send the first _DISPLAY_LIMIT alerts to the UI, so we
        # need to include those keys at the start of the list.
        anomalies = requested_anomalies + anomalies
    else:
        anomalies = requested_anomalies
    return anomalies
示例#6
0
    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()