Ejemplo n.º 1
0
    def test_line_notify(self, mock_post):
        response = self.fireAlert()
        self.assertRoute(response, rest.AlertReceiver, 202)

        # Swap the status to test our resolved alert
        SAMPLE = tests.Data("examples", "alertmanager.json").json()
        SAMPLE["status"] = "resolved"
        SAMPLE["commonLabels"]["service"] = "other-service"
        SAMPLE["commonLabels"].pop("project")
        response = self.fireAlert(data=SAMPLE)
        self.assertRoute(response, rest.AlertReceiver, 202)

        _MESSAGE = tests.Data("notification",
                              "linenotify.body.txt").raw().strip()
        _RESOLVED = tests.Data("notification",
                               "linenotify.resolved.txt").raw().strip()

        mock_post.assert_has_calls(
            [
                mock.call(
                    "https://notify.example",
                    data={"message": _MESSAGE},
                    headers={"Authorization": "Bearer hogehoge"},
                ),
                mock.call(
                    "https://notify.example",
                    data={"message": _RESOLVED},
                    headers={"Authorization": "Bearer asdfasdf"},
                ),
            ],
            any_order=True,
        )
Ejemplo n.º 2
0
    def test_ikasan(self, mock_post):
        self.client.post(reverse('alert'),
            data=TEST_ALERT,
            content_type='application/json'
        )

        # Swap the status to test our resolved alert
        SAMPLE = tests.Data('examples', 'alertmanager.json').json()
        SAMPLE['status'] = 'resolved'
        self.client.post(reverse('alert'),
            data=json.dumps(SAMPLE),
            content_type='application/json'
        )

        _MESSAGE = tests.Data('notification', 'ikasan.body.txt').raw().strip()
        _RESOLVED = tests.Data('notification', 'ikasan.resolved.txt').raw().strip()

        mock_post.assert_has_calls([
            mock.call(
                'http://ikasan.example', {
                'color': 'red',
                'channel': '#1',
                'message_format': 'text',
                'message': _MESSAGE.format(service=self.service, project=self.project)}
            ),
            mock.call(
                'http://ikasan.example', {
                'color': 'green',
                'channel': '#1',
                'message_format': 'text',
                'message': _RESOLVED}
            ),
        ], any_order=True)
Ejemplo n.º 3
0
    def test_slack(self, mock_post):
        self.client.post(reverse('alert'),
                         data=TEST_ALERT,
                         content_type='application/json')

        # Swap the status to test our resolved alert
        SAMPLE = tests.Data('examples', 'alertmanager.json').json()
        SAMPLE['status'] = 'resolved'
        SAMPLE['commonLabels']['service'] = self.service2.name
        SAMPLE['commonLabels'].pop('project')
        self.client.post(reverse('alert'),
                         data=json.dumps(SAMPLE),
                         content_type='application/json')

        _MESSAGE = tests.Data('notification', 'slack.body.txt').raw().strip()
        _RESOLVED = tests.Data('notification',
                               'slack.resolved.txt').raw().strip()

        mock_post.assert_has_calls([
            mock.call(
                self.TestHook1,
                json={
                    'text':
                    _MESSAGE.format(service=self.service, project=self.project)
                },
            ),
            mock.call(
                self.TestHook2,
                json={'text': _RESOLVED},
            ),
        ],
                                   any_order=True)
Ejemplo n.º 4
0
    def test_slack(self, mock_post):
        response = self.fireAlert()
        self.assertRoute(response, rest.AlertReceiver, 202)
        self.assertCount(models.AlertError, 0)

        # Swap the status to test our resolved alert
        SAMPLE = tests.Data("examples", "alertmanager.json").json()
        SAMPLE["status"] = "resolved"
        SAMPLE["commonLabels"]["service"] = "other-service"
        SAMPLE["commonLabels"].pop("project")
        response = self.fireAlert(data=SAMPLE)
        self.assertRoute(response, rest.AlertReceiver, 202)
        self.assertCount(models.AlertError, 0)

        _MESSAGE = tests.Data("notification", "slack.body.txt").raw().strip()
        _RESOLVED = tests.Data("notification",
                               "slack.resolved.txt").raw().strip()

        mock_post.assert_has_calls(
            [
                mock.call(
                    self.TestHook1,
                    json={"text": _MESSAGE},
                ),
                mock.call(
                    self.TestHook2,
                    json={"text": _RESOLVED},
                ),
            ],
            any_order=True,
        )
Ejemplo n.º 5
0
    def test_line_notify(self, mock_post):
        self.client.post(reverse('alert'),
                         data=TEST_ALERT,
                         content_type='application/json')

        # Swap the status to test our resolved alert
        SAMPLE = tests.Data('examples', 'alertmanager.json').json()
        SAMPLE['status'] = 'resolved'
        SAMPLE['commonLabels']['service'] = self.service2.name
        SAMPLE['commonLabels'].pop('project')
        self.client.post(reverse('alert'),
                         data=json.dumps(SAMPLE),
                         content_type='application/json')

        _MESSAGE = tests.Data('notification',
                              'linenotify.body.txt').raw().strip()
        _RESOLVED = tests.Data('notification',
                               'linenotify.resolved.txt').raw().strip()

        mock_post.assert_has_calls([
            mock.call(
                'https://notify.example',
                data={
                    'message':
                    _MESSAGE.format(service=self.service, project=self.project)
                },
                headers={'Authorization': 'Bearer hogehoge'},
            ),
            mock.call(
                'https://notify.example',
                data={'message': _RESOLVED},
                headers={'Authorization': 'Bearer asdfasdf'},
            ),
        ],
                                   any_order=True)
Ejemplo n.º 6
0
class Command(BaseCommand):
    data = tests.Data("examples", "alertmanager.json").json()

    def add_arguments(self, parser):
        parser.add_argument("--shard", default="Test Shard")
        parser.add_argument("--service",
                            default=self.data["commonLabels"]["service"])
        parser.add_argument("--project",
                            default=self.data["commonLabels"]["project"])

    @override_settings(CELERY_TASK_ALWAYS_EAGER=True)
    def handle(self, shard, service, project, **kwargs):
        logging._handlers = []
        logging.basicConfig(level=logging.DEBUG)

        shard, _ = models.Shard.objects.get_or_create(name=shard)
        service, _ = models.Service.objects.get_or_create(name=service)
        project, _ = models.Project.objects.get_or_create(name=project,
                                                          defaults={
                                                              "shard": shard,
                                                              "service":
                                                              service
                                                          })

        alert = models.Alert.objects.create(body=json.dumps(self.data),
                                            error_count=1)

        tasks.process_alert(alert.pk)

        alert.alerterror_set.create(message="Test from CLI")
Ejemplo n.º 7
0
    def test_missing_permission(self, mock_post):
        self.client.post(
            reverse('rule-import'),
            {'rules': tests.Data('examples', 'import.rule.yml').raw()})

        # Should only be a single rule from our initial setup
        self.assertCount(models.Rule, 1, 'Missing Rule')
Ejemplo n.º 8
0
    def test_email(self, mock_email):
        self.fireAlert()

        _SUBJECT = tests.Data("notification",
                              "email.subject.txt").raw().strip()
        _MESSAGE = tests.Data("notification", "email.body.txt").raw().strip()

        mock_email.assert_has_calls(
            [
                mock.call(_SUBJECT, _MESSAGE, "*****@*****.**",
                          ["*****@*****.**"]),
                mock.call(_SUBJECT, _MESSAGE, "*****@*****.**",
                          ["*****@*****.**"]),
            ],
            any_order=True,
        )
        # Three senders are registered but only two should trigger
        self.assertTrue(mock_email.call_count == 2)
Ejemplo n.º 9
0
    def test_email(self, mock_email):
        response = self.fireAlert()
        self.assertRoute(response, rest.AlertReceiver, 202)
        self.assertCount(models.AlertError, 0, "No failed alerts")

        _SUBJECT = tests.Data("notification", "email.subject.txt").raw().strip()
        _MESSAGE = tests.Data("notification", "email.body.txt").raw().strip()

        mock_email.assert_has_calls(
            [
                mock.call(
                    _SUBJECT, _MESSAGE, "*****@*****.**", ["*****@*****.**"]
                ),
                mock.call(
                    _SUBJECT, _MESSAGE, "*****@*****.**", ["*****@*****.**"]
                ),
            ],
            any_order=True,
        )
        # Three senders are registered but only two should trigger
        self.assertTrue(mock_email.call_count == 2)
Ejemplo n.º 10
0
    def test_import_v2(self, mock_post):
        self.add_user_permissions("promgen.change_rule", "promgen.change_site")
        response = self.client.post(
            reverse("rule-import"),
            {"rules": tests.Data("examples", "import.rule.yml").raw()},
            follow=True,
        )

        # Includes count of our setUp rule + imported rules
        self.assertRoute(response, views.RuleImport, status=200)
        self.assertCount(models.Rule, 3, "Missing Rule")
        self.assertCount(models.RuleLabel, 4, "Missing labels")
        self.assertCount(models.RuleAnnotation, 9, "Missing annotations")
Ejemplo n.º 11
0
 def test_import_service_rule(self, mock_post):
     self.add_user_permissions("promgen.add_rule", "promgen.change_service")
     response = self.client.post(
         reverse(
             "rule-new",
             kwargs={"content_type": "service", "object_id": self.service.id},
         ),
         {"rules": tests.Data("examples", "import.rule.yml").raw()},
         follow=True,
     )
     self.assertRoute(response, views.ServiceDetail, status=200)
     self.assertCount(models.Rule, 3, "Missing Rule")
     self.assertCount(models.RuleLabel, 4, "Missing labels")
     self.assertCount(models.RuleAnnotation, 9, "Missing annotations")
Ejemplo n.º 12
0
    def test(self):
        '''
        Test sender plugin

        Uses the same test json from our unittests but subs in the currently
        tested object as part of the test data
        '''
        data = tests.Data("examples", "alertmanager.json").json()
        if hasattr(self.content_object, 'name'):
            data['commonLabels'][self.content_type.name] = self.content_object.name
            for alert in data.get('alerts', []):
                alert['labels'][self.content_type.name] = self.content_object.name

        from promgen import tasks
        tasks.send_alert(self.sender, self.value, data)
Ejemplo n.º 13
0
 def test_import_project_rule(self, mock_post):
     self.add_user_permissions("promgen.add_rule", "promgen.change_project")
     project = models.Project.objects.create(
         name="Project 1", service=self.service, shard=self.shard
     )
     response = self.client.post(
         reverse(
             "rule-new", kwargs={"content_type": "project", "object_id": project.id}
         ),
         {"rules": tests.Data("examples", "import.rule.yml").raw()},
         follow=True,
     )
     self.assertRoute(response, views.ProjectDetail, status=200)
     self.assertCount(models.Rule, 3, "Missing Rule")
     self.assertCount(models.RuleLabel, 4, "Missing labels")
     self.assertCount(models.RuleAnnotation, 9, "Missing annotations")
Ejemplo n.º 14
0
    def test_webhook(self, mock_post):
        response = self.testAlert()

        self.assertRoute(response, views.Alert, 202)
        self.assertCount(models.Alert, 1, "Alert should be queued")
        self.assertEqual(mock_post.call_count, 2, "Two alerts should be sent")

        # Our sample is the same as the original, with some annotations added
        _SAMPLE = tests.Data("notification", "webhook.json").json()

        mock_post.assert_has_calls(
            [
                mock.call("http://webhook.example.com/project", json=_SAMPLE),
                mock.call("http://webhook.example.com/service", json=_SAMPLE),
            ],
            any_order=True,
        )
Ejemplo n.º 15
0
    def test_webhook(self, mock_post):
        response = self.client.post(reverse("alert"),
                                    data=TEST_ALERT,
                                    content_type="application/json")

        self.assertRoute(response, views.Alert, 202)
        self.assertCount(models.Alert, 1, "Alert should be queued")
        self.assertEqual(mock_post.call_count, 2, "Two alerts should be sent")

        # Our sample is the same as the original, with some annotations added
        _SAMPLE = tests.Data("notification", "webhook.json").json()

        mock_post.assert_has_calls(
            [
                mock.call("http://project.example.com", json=_SAMPLE),
                mock.call("http://service.example.com", json=_SAMPLE),
            ],
            any_order=True,
        )
Ejemplo n.º 16
0
    def test_webhook(self, mock_post):
        response = self.fireAlert()
        self.assertRoute(response, rest.AlertReceiver, 202)
        self.assertCount(models.AlertError, 0, "No failed alerts")

        self.assertCount(models.Alert, 1, "Alert should be queued")
        self.assertEqual(mock_post.call_count, 2, "Two alerts should be sent")

        # Our sample is the same as the original, with some annotations added
        _SAMPLE = tests.Data("notification", "webhook.json").json()
        # External URL is depended on test order
        _SAMPLE["externalURL"] = mock.ANY

        mock_post.assert_has_calls(
            [
                mock.call("http://webhook.example.com/project", json=_SAMPLE),
                mock.call("http://webhook.example.com/service", json=_SAMPLE),
            ],
            any_order=True,
        )
Ejemplo n.º 17
0
_RULE_V2 = '''
groups:
- name: example.com
  rules:
  - alert: RuleName
    annotations:
      rule: https://example.com/rule/%d
      summary: Test case
    expr: up==0
    for: 1s
    labels:
      severity: severe
'''.lstrip().encode('utf-8')

TEST_SETTINGS = tests.Data('examples', 'promgen.yml').yaml()


class RuleTest(tests.PromgenTest):
    @mock.patch('django.dispatch.dispatcher.Signal.send')
    def setUp(self, mock_signal):
        self.user = self.add_force_login(id=999, username="******")
        self.site = models.Site.objects.get_current()
        self.shard = models.Shard.objects.create(name='Shard 1')
        self.service = models.Service.objects.create(id=999, name='Service 1')
        self.rule = models.Rule.objects.create(name='RuleName',
                                               clause='up==0',
                                               duration='1s',
                                               obj=self.site)
        models.RuleLabel.objects.create(name='severity',
                                        value='severe',
Ejemplo n.º 18
0
# Copyright (c) 2017 LINE Corporation
# These sources are released under the terms of the MIT license: see LICENSE
from unittest import mock

import requests

from django.test import override_settings
from django.urls import reverse

from promgen import models, views, tests

TEST_SETTINGS = tests.Data('examples', 'promgen.yml').yaml()
TEST_IMPORT = tests.Data('examples', 'import.json').raw()
TEST_REPLACE = tests.Data('examples', 'replace.json').raw()


class RouteTests(tests.PromgenTest):
    longMessage = True

    @mock.patch('django.dispatch.dispatcher.Signal.send')
    def setUp(self, mock_signal):
        self.user = self.add_force_login(id=999, username="******")

    @override_settings(PROMGEN=TEST_SETTINGS)
    @override_settings(CELERY_TASK_ALWAYS_EAGER=True)
    @mock.patch('promgen.signals._trigger_write_config')
    @mock.patch('promgen.tasks.reload_prometheus')
    def test_import(self, mock_write, mock_reload):
        self.add_user_permissions("promgen.change_rule", "promgen.change_site",
                                  "promgen.change_exporter")
        response = self.client.post(reverse("import"), {"config": TEST_IMPORT})
Ejemplo n.º 19
0
# Copyright (c) 2017 LINE Corporation
# These sources are released under the terms of the MIT license: see LICENSE

import datetime
from unittest import mock

from django.test import override_settings
from django.urls import reverse

from promgen import tests

TEST_SETTINGS = tests.Data('examples', 'promgen.yml').yaml()
TEST_DURATION = tests.Data('examples', 'silence.duration.json').json()
TEST_RANGE = tests.Data('examples', 'silence.range.json').json()

# Explicitly set a timezone for our test to try to catch conversion errors
TEST_SETTINGS['timezone'] = 'Asia/Tokyo'


class SilenceTest(tests.PromgenTest):
    @mock.patch("django.dispatch.dispatcher.Signal.send")
    def setUp(self, mock_signal):
        self.user = self.add_force_login(id=999, username="******")

    @override_settings(PROMGEN=TEST_SETTINGS)
    @mock.patch('promgen.util.post')
    def test_duration(self, mock_post):
        mock_post.return_value.status_code = 200

        with mock.patch('django.utils.timezone.now') as mock_now:
            mock_now.return_value = datetime.datetime(
Ejemplo n.º 20
0
# Copyright (c) 2018 LINE Corporation
# These sources are released under the terms of the MIT license: see LICENSE


from django.test import override_settings
from django.urls import reverse

from promgen import models, tests, views

TEST_ALERT = tests.Data("examples", "alertmanager.json").raw()
TEST_HEARTBEAT = tests.Data("examples", "heartbeat.json").raw()
TEST_SETTINGS = tests.Data("examples", "promgen.yml").yaml()


class RestAPITest(tests.PromgenTest):
    @override_settings(PROMGEN=TEST_SETTINGS)
    @override_settings(CELERY_TASK_ALWAYS_EAGER=True)
    def test_alert_blackhole(self):
        response = self.client.post(
            reverse("alert"), data=TEST_HEARTBEAT, content_type="application/json"
        )
        self.assertRoute(response, views.Alert, 202)
        self.assertCount(models.Alert, 0, "Heartbeat alert should be deleted")

    @override_settings(PROMGEN=TEST_SETTINGS)
    @override_settings(CELERY_TASK_ALWAYS_EAGER=True)
    def test_alert(self):
        response = self.client.post(
            reverse("alert"), data=TEST_ALERT, content_type="application/json"
        )
        self.assertEqual(response.status_code, 202)
Ejemplo n.º 21
0
# Copyright (c) 2017 LINE Corporation
# These sources are released under the terms of the MIT license: see LICENSE

import json
from unittest import mock

from django.test import override_settings
from django.urls import reverse

from promgen import models, tests
from promgen.notification.slack import NotificationSlack

TEST_SETTINGS = tests.Data('examples', 'promgen.yml').yaml()
TEST_ALERT = tests.Data('examples', 'alertmanager.json').raw()


class SlackTest(tests.PromgenTest):
    TestHook1 = 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'
    TestHook2 = 'https://hooks.slack.com/services/YYYYYYYYY/YYYYYYYYY/YYYYYYYYYYYYYYYYYYYYYYYY'

    @mock.patch('django.dispatch.dispatcher.Signal.send')
    def setUp(self, mock_signal):
        self.shard = models.Shard.objects.create(name='test.shard')
        self.service = models.Service.objects.create(name='test.service')
        self.project = models.Project.objects.create(name='test.project',
                                                     service=self.service,
                                                     shard=self.shard)

        self.sender = models.Sender.objects.create(
            obj=self.project,
            sender=NotificationSlack.__module__,