def testEmailSheriff_ContentAndRecipientAreCorrect(self): email_sheriff.EmailSheriff(**self._GetDefaultMailArgs()) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) self.assertEqual('*****@*****.**', messages[0].sender) self.assertEqual('[email protected],[email protected]', messages[0].to) name = 'dromaeo/dom on Win7' expected_subject = '100.0%% regression in %s at 10002:10004' % name self.assertEqual(expected_subject, messages[0].subject) body = str(messages[0].body) self.assertIn('10002 - 10004', body) self.assertIn('100.0%', body) self.assertIn('ChromiumPerf', body) self.assertIn('Win7', body) self.assertIn('dromaeo/dom', body) html = str(messages[0].html) self.assertIn('<b>10002 - 10004</b>', html) self.assertIn('<b>100.0%</b>', html) self.assertIn('<b>ChromiumPerf</b>', html) self.assertIn('<b>Win7</b>', html) self.assertIn('<b>dromaeo/dom</b>', html) # Bug links self.assertIn(urllib.quote(expected_subject), body) self.assertIn( 'labels=Type-Bug-Regression,Pri-2,Performance-Sheriff,label1', html) # Sheriff link self.assertIn( '/alerts?sheriff=%s' % urllib.quote('Chromium Perf Sheriff'), html)
def testEmailSheriff_ContentAndRecipientAreCorrect(self): email_sheriff.EmailSheriff(**self._GetDefaultMailArgs()) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) self.assertEqual('*****@*****.**', messages[0].sender) self.assertEqual( set(['*****@*****.**', '*****@*****.**']), set([s.strip() for s in messages[0].to.split(',')])) name = 'dromaeo/dom on Win7' expected_subject = '100.0%% regression in %s at 10002:10004' % name self.assertEqual(expected_subject, messages[0].subject) body = str(messages[0].body) self.assertIn('10002 - 10004', body) self.assertIn('100.0%', body) self.assertIn('ChromiumPerf', body) self.assertIn('Win7', body) self.assertIn('dromaeo/dom', body) html = str(messages[0].html) self.assertIn('<b>10002 - 10004</b>', html) self.assertIn('<b>100.0%</b>', html) self.assertIn('<b>ChromiumPerf</b>', html) self.assertIn('<b>Win7</b>', html) self.assertIn('<b>dromaeo/dom</b>', html)
def _ProcessTest(test_key): """Processes a test to find new anomalies. Args: test_key: The ndb.Key for a TestMetadata. """ test = yield test_key.get_async() sheriff = yield _GetSheriffForTest(test) if not sheriff: logging.error('No sheriff for %s', test_key) raise ndb.Return(None) config = yield anomaly_config.GetAnomalyConfigDictAsync(test) max_num_rows = config.get('max_window_size', DEFAULT_NUM_POINTS) rows = yield GetRowsToAnalyzeAsync(test, max_num_rows) # If there were no rows fetched, then there's nothing to analyze. if not rows: # In some cases (e.g. if some points are deleted) it might be possible # that last_alerted_revision is incorrect. In this case, reset it. highest_rev = yield _HighestRevision(test_key) if test.last_alerted_revision > highest_rev: logging.error('last_alerted_revision %d is higher than highest rev %d ' 'for test %s; setting last_alerted_revision to None.', test.last_alerted_revision, highest_rev, test.test_path) test.last_alerted_revision = None yield test.put_async() logging.error('No rows fetched for %s', test.test_path) raise ndb.Return(None) # Get anomalies and check if they happen in ref build also. change_points = FindChangePointsForTest(rows, config) change_points = yield _FilterAnomaliesFoundInRef( change_points, test_key, len(rows)) anomalies = yield [_MakeAnomalyEntity(c, test, rows) for c in change_points] # If no new anomalies were found, then we're done. if not anomalies: return logging.info('Created %d anomalies', len(anomalies)) logging.info(' Test: %s', test_key.id()) logging.info(' Sheriff: %s', test.sheriff.id()) # Update the last_alerted_revision property of the test. test.last_alerted_revision = anomalies[-1].end_revision yield test.put_async() yield ndb.put_multi_async(anomalies) # TODO(simonhatch): email_sheriff.EmailSheriff() isn't a tasklet yet, so this # code will run serially. # Email sheriff about any new regressions. for anomaly_entity in anomalies: if (anomaly_entity.bug_id is None and not anomaly_entity.is_improvement and not sheriff.summarize): email_sheriff.EmailSheriff(sheriff, test, anomaly_entity)
def testEmailSheriff_RotationUrlHasInvalidContent_EmailStillSent(self): """Tests the email to list when the rotation URL returns garbage.""" args = self._GetDefaultMailArgs() email_sheriff.EmailSheriff(**args) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) # An email is only sent to the general sheriff rotation email. self.assertEqual('*****@*****.**', messages[0].to)
def testEmailSheriff_MultipleSheriffs_AllGetEmailed(self): email_sheriff.EmailSheriff(**self._GetDefaultMailArgs()) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) self.assertEqual('*****@*****.**', messages[0].sender) self.assertEqual( '[email protected],[email protected],[email protected]', messages[0].to)
def ProcessTest(test_key): """Processes a test to find new anomalies. Args: test_key: The ndb.Key for a TestMetadata. """ test = test_key.get() config = anomaly_config.GetAnomalyConfigDict(test) max_num_rows = config.get('max_window_size', DEFAULT_NUM_POINTS) rows = GetRowsToAnalyze(test, max_num_rows) # If there were no rows fetched, then there's nothing to analyze. if not rows: # In some cases (e.g. if some points are deleted) it might be possible # that last_alerted_revision is incorrect. In this case, reset it. highest_rev = _HighestRevision(test_key) if test.last_alerted_revision > highest_rev: logging.error( 'last_alerted_revision %d is higher than highest rev %d ' 'for test %s; setting last_alerted_revision to None.', test.last_alerted_revision, highest_rev, test.test_path) test.last_alerted_revision = None test.put() logging.error('No rows fetched for %s', test.test_path) return test = test_key.get() sheriff = _GetSheriffForTest(test) if not sheriff: logging.error('No sheriff for %s', test_key) return # Get anomalies and check if they happen in ref build also. change_points = FindChangePointsForTest(rows, config) change_points = _FilterAnomaliesFoundInRef(change_points, test_key, len(rows)) anomalies = [_MakeAnomalyEntity(c, test, rows) for c in change_points] # If no new anomalies were found, then we're done. if not anomalies: return logging.info('Found at least one anomaly in: %s', test.test_path) # Update the last_alerted_revision property of the test. test.last_alerted_revision = anomalies[-1].end_revision test.put() alert_group.GroupAlerts(anomalies, utils.TestSuiteName(test.key), 'Anomaly') # Email sheriff about any new regressions. for anomaly_entity in anomalies: if (anomaly_entity.bug_id is None and not anomaly_entity.is_improvement and not sheriff.summarize): email_sheriff.EmailSheriff(sheriff, test, anomaly_entity) ndb.put_multi(anomalies)
def testEmail_NoSheriffUrl_EmailSentToSheriffRotationEmailAddress(self): args = self._GetDefaultMailArgs() args['subscriptions'][0].rotation_url = None email_sheriff.EmailSheriff(**args) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) # An email is only sent to the general sheriff rotation email; # There is no other specific sheriff to send it to. self.assertEqual('*****@*****.**', messages[0].to)
def testEmailSheriff_MultipleSheriffs_AllGetEmailed(self): email_sheriff.EmailSheriff(**self._GetDefaultMailArgs()) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) self.assertEqual('*****@*****.**', messages[0].sender) self.assertEqual( set(['*****@*****.**', '*****@*****.**', '*****@*****.**']), set([s.strip() for s in messages[0].to.split(',')]))
def testEmailSheriff_PercentChangeMaxFloat_ContentSaysAlertSize(self): """Tests the email content for "freakin huge" alert.""" args = self._GetDefaultMailArgs() args['subscriptions'][0].rotation_url = None args['anomaly'].median_before_anomaly = 0.0 email_sheriff.EmailSheriff(**args) messages = self.mail_stub.get_sent_messages() self.assertEqual(1, len(messages)) self.assertIn(anomaly.FREAKIN_HUGE, str(messages[0].subject)) self.assertNotIn(str(sys.float_info.max), str(messages[0].body)) self.assertIn(anomaly.FREAKIN_HUGE, str(messages[0].body)) self.assertNotIn(str(sys.float_info.max), str(messages[0].html)) self.assertIn(anomaly.FREAKIN_HUGE, str(messages[0].html))
def _EmailSheriff(sheriff, test_key, anomaly_key): test_entity = test_key.get() anomaly_entity = anomaly_key.get() email_sheriff.EmailSheriff(sheriff, test_entity, anomaly_entity)