def setUp(self, *args): mock, = args self.check_data = deepcopy(CHECK_TEST_DATA) self.check = CheckInstance(self.check_data) self.trigger = self.check.triggers[0] self.notification = Mock() self.alerter = AlamoAlerter(mock, self.notification, StatsClient())
class AlerterTest(unittest.TestCase): @patch("alamo_alerter.backend.cassandra.CassandraDriver") def setUp(self, *args): mock, = args self.check_data = deepcopy(CHECK_TEST_DATA) self.check = CheckInstance(self.check_data) self.trigger = self.check.triggers[0] self.notification = Mock() self.alerter = AlamoAlerter(mock, self.notification, StatsClient()) def test_retrieve_cached_result_by_rebuilding_cache(self): self.alerter.driver.get_result = MagicMock(return_value=[]) result = self.alerter.get_cached_result(self.check.uuid, self.trigger.uuid, 1) self.assertEqual(len(result), 0) def test_retrieve_cached_result(self): self.alerter.driver.get_result = MagicMock(return_value=[1, 1, 0]) result = self.alerter.get_cached_result(self.check.uuid, self.trigger.uuid, 3) self.assertEqual(len(result), 3) @unpack @data( ([3, 0], 1, "resolve"), ([1, 0], 1, "resolve"), ([1, 3, 0], 2, "resolve"), ([1, 1, 0], 2, "resolve"), ([0, 0, 0, 0], 3, None), ([0, 0, 0, 1], 3, None), ([0, 0, 1, 1], 3, None), ([1, 1, 1], 3, "trigger"), ([0, 1, 1, 1], 3, "trigger"), ([2, 1, 1, 1], 3, "trigger"), ([2, 1, 3, 1], 3, "trigger"), ([2, 1, 3, 3], 3, "trigger"), ([1, 1, 1, 1], 3, None), ([1, 1, 1, 0], 3, "resolve"), ([1, 1, 3, 0], 3, "resolve"), ([3, 1, 3, 0], 3, "resolve"), ([0, 0, 1, 0], 3, None), ([2, 2, 2, 2], 3, None), ([0, 1, 0, 0], 3, None), ([1, 0, 0, 0], 3, None), ([1, 1, 2, 0], 3, None), ([0, 2, 0, 2], 3, None), ([1, 2, 1, 1], 3, None), ([0, 0, 2, 2], 3, None), ([1, 1, 1, 2], 3, None), ([0, 1, 1], 5, None), ([0, 1, 1, 1], 5, None), ([0, 1, 1, 1, 1], 5, None), ([1, 1, 1, 1, 1], 5, "trigger"), ) def test_analyze_result(self, results, debounce, expected): results = [CachedResult(r, 0, False, "") for r in results] repeat = 0 _, event_type = self.alerter.analyze_result(deque(results, debounce + 1), debounce, repeat) self.assertEqual(event_type, expected) @patch( "alamo_alerter.alerter.AlamoAlerter.get_cached_result", MagicMock( return_value=deque( [CachedResult(0, 0, False, ""), CachedResult(0, 0, False, ""), CachedResult(1, 1, False, "")], 3 ) ), ) @patch("alamo_alerter.alerter.AlamoAlerter.send_alert") def test_execution_process(self, send_alert_mock): self.check_data["triggers"][0]["result"]["status"] = 1 self.alerter.execute(self.check_data) self.assertTrue(send_alert_mock.called) @unpack @data( ([(0, False)], 2, 2), ([(1, False)], 2, 3), ([(3, False)], 2, 3), ([], 2, 2), # ok and failed status are skipped ([], 1, 1), ([], 0, 0), ([(1, False)], 1, 1), ([(1, False)], 0, 0), ) def test_unknown_status_transformation(self, results, status, expected): results = [CachedResult(r[0], 0, r[1], "") for r in results] self.trigger.result.status = status self.alerter.translate_unknown_status(results, self.trigger) self.assertEqual(self.trigger.result.status, expected) @unpack @data( ([(0, False)], 2, False), # OK -> Unknown, should not copy ([(1, False)], 2, True), # FAIL -> Unknown, should copy ([(2, False)], 2, False), # UNK_OK -> Unknown, should not copy ([(3, False)], 2, True), # UNK_FAIL -> Unknown, should copy ([(3, False), (3, False)], 2, True), # chaining test ) def test_message_copying_for_unknown(self, results, status, should_copy): results = [CachedResult(r[0], 0, r[1], "message") for r in results] self.trigger.result.status = status self.alerter.translate_unknown_status(results, self.trigger) is_equal = self.trigger.result.message == "message" self.assertEqual(is_equal, should_copy) @unpack @data( ([(0, False)], 1, 0, None), ([(1, False)], 1, 0, "trigger"), ([(1, False)], 1, 1, "trigger"), ([(1, False)], 1, 3, "trigger"), ([(0, False), (0, False)], 1, 0, None), ([(1, False), (0, False)], 1, 0, "resolve"), ([(1, True), (0, False)], 1, 1, "resolve"), ([(0, False), (1, False)], 1, 0, "trigger"), ([(1, True), (1, False)], 1, 1, "trigger"), ([(1, True), (1, False)], 1, 0, None), ([(1, False), (1, True)], 1, 2, None), ([(1, True), (1, False), (1, True)], 1, 2, "trigger"), ([(1, True), (1, False), (1, False)], 1, 2, "trigger"), ([(0, False), (1, False), (1, False)], 2, 1, "trigger"), ([(1, False), (1, True), (1, False)], 1, 2, None), ([(1, True), (0, False), (0, False)], 1, 2, None), ([(1, False), (0, False), (1, False), (1, False)], 2, 3, "trigger"), ([(1, False), (1, True), (0, False), (0, False)], 2, 3, None), ([(1, True), (1, False), (0, False), (0, False)], 2, 3, None), ([(1, False), (1, True), (0, False), (1, False)], 2, 3, None), ) def test_repeat_trigger(self, results, debounce, repeat, expected): # trigger status is the same as hysteresis status results = [(v[0], v[0], v[1], "") for v in results] results = [CachedResult(*r) for r in results] _, event_type = self.alerter.analyze_result(deque(results, max(debounce, repeat) + 1), debounce, repeat) self.assertEqual(event_type, expected) @unpack @data( # [cached_result(status, alert sent)], # new_check(status, hysteresis), analyze_result, debounce ([(0, False)], (0, 0), (0, None), 1), ([(0, True)], (0, 0), (0, None), 1), ([(0, False)], (0, 1), (0, None), 1), ([(0, True)], (0, 1), (0, None), 1), ([(0, False)], (1, 1), (1, "trigger"), 1), ([(1, False)], (1, 1), (1, None), 1), ([(1, True)], (1, 1), (1, None), 1), ([(1, False)], (0, 1), (1, None), 1), ([(1, True)], (0, 0), (0, "resolve"), 1), ([(0, False), (0, False)], (0, 0), (0, None), 2), ([(0, False), (0, False)], (0, 1), (0, None), 2), ([(0, False), (0, False)], (1, 1), (1, None), 2), ([(0, False), (1, False)], (1, 1), (1, "trigger"), 2), ([(0, False), (1, False)], (0, 1), (0, None), 2), ([(1, False), (1, False)], (0, 1), (1, None), 2), ([(1, False), (1, True)], (0, 1), (1, None), 2), ([(1, False), (1, False)], (0, 0), (0, "resolve"), 2), ([(1, False), (0, False)], (0, 1), (0, None), 2), ([(1, False), (0, False)], (1, 1), (1, None), 2), ) @patch("alamo_alerter.alerter.AlamoAlerter.send_alert") @patch("alamo_alerter.alerter.AlamoAlerter.get_cached_result") def test_hysteresis_overrides_status( self, cached_result, new_check, analyze_result, debounce, mock_get_cached_result, mock_send_alert ): mock_get_cached_result.return_value = deque( [CachedResult(r[0], 0, r[1], "") for r in cached_result], (debounce + 1) ) self.check_data["triggers"][0]["result"]["status"] = new_check[0] self.check_data["triggers"][0]["result"]["hysteresis"] = new_check[1] self.check_data["fields"]["debounce"] = debounce should_send_alert = True if analyze_result[1] else False returned_values = self.alerter.execute(self.check_data) self.assertTupleEqual(returned_values, analyze_result) self.assertTrue(self.alerter.driver.save_result.called) status = self.alerter.driver.save_result.call_args[0][1].result.status self.assertEqual(status, returned_values[0]) self.assertEqual(mock_send_alert.called, should_send_alert)