Exemple #1
0
 def test_send_notification_on_change_only_with_no_changes(self):
     self.project.notification_strategy = Project.NOTIFY_ON_CHANGE
     self.project.save()
     self.project.subscriptions.create(email='*****@*****.**')
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
 def test_no_recipients_no_email_mark_as_notified(self, diff):
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
     status.refresh_from_db()
     self.assertTrue(status.notified)
Exemple #3
0
 def test_send_notification_on_regression_only_with_no_regressions(self):
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_REGRESSION)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
 def test_send_notification_on_regression_only_with_no_regressions(self):
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_REGRESSION)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
Exemple #5
0
    def handle(self, *args, **options):
        g, p = options['PROJECT'].split('/')

        group = Group.objects.get(slug=g)
        project = group.projects.get(slug=p)
        build = project.builds.get(version=options['BUILD'])
        send_status_notification(build.status)
Exemple #6
0
    def handle(self, *args, **options):
        g, p = options['PROJECT'].split('/')

        group = Group.objects.get(slug=g)
        project = group.projects.get(slug=p)
        build = project.builds.get(version=options['BUILD'])
        send_status_notification(build.status)
Exemple #7
0
 def test_send_notification_on_regression_only(self, regressions):
     regressions.return_value = OrderedDict({'key': 'value'})
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_REGRESSION)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #8
0
 def test_send_notification_on_change_only(self, diff):
     diff.return_value = fake_diff()
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_CHANGE)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
 def test_send_notification_on_regression_only(self, regressions):
     regressions.return_value = OrderedDict({'key': 'value'})
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_REGRESSION)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
 def test_send_notification_on_change_only(self, diff):
     diff.return_value = fake_diff()
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_CHANGE)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #11
0
    def test_send_plain_text_only(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        status = ProjectStatus.create_or_update(self.build2)

        send_status_notification(status)
        msg = mail.outbox[0]
        self.assertEqual(0, len(msg.alternatives))
    def test_send_plain_text_only(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        status = ProjectStatus.create_or_update(self.build2)

        send_status_notification(status)
        msg = mail.outbox[0]
        self.assertEqual(0, len(msg.alternatives))
    def test_subject_from_custom_template(self):
        template = EmailTemplate.objects.create(subject='lalala', plain_text='foo', html='bar')
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertEqual('lalala', msg.subject)
Exemple #14
0
def notify_project_status(self, status_id):
    try:
        status = ProjectStatus.objects.get(pk=status_id)
        send_status_notification(status)
    except ProjectStatus.DoesNotExist as not_found:
        last_id = ProjectStatus.objects.all().aggregate(Max('id'))['id__max']
        if not last_id or status_id > last_id:
            # our id is larger than the latest, the object was probably created
            # by another process but not commited to the database yet.
            raise self.retry(exc=not_found, countdown=30)  # retry in 30s
Exemple #15
0
def notification_timeout(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    if not projectstatus.notified and not projectstatus.notified_on_timeout:
        send_status_notification(projectstatus)
        projectstatus.notified_on_timeout = True

        if projectstatus.build.project.force_finishing_builds_on_timeout:
            projectstatus.finished = True

        projectstatus.save()
Exemple #16
0
def maybe_notify_project_status(status_id):
    """
        This is invoked for every new TestRun a build receives.
        Notifications tasks work like the following:

        1. First notification attempt with `maybe_notify_project_status`,
           it uses the attribute `Project.wait_before_notification` which
           waits for this number of seconds AFTER `Build.datetime`. This means
           that if the build date keeps changing, notification will delay accordingly.
           NOTE: the notification will be sent only if `ProjectStatus.finished=True`,
           even after timeout expiration.

        2. Second notifcation attempt is achieved at `notification_timeout`, which
           waits for an absolute number of seconds, e.g. `Project.notification_timeout`,
           before trying to send the notification. This serves as a fallback option to
           send out notifications, even if `ProjectStatus.finished=False`.
    """

    with transaction.atomic():
        projectstatus = ProjectStatus.objects.select_for_update().get(
            pk=status_id)
        build = projectstatus.build
        project = build.project

        if projectstatus.notified_on_timeout is None and project.notification_timeout:
            notification_timeout.apply_async(
                args=[status_id], countdown=project.notification_timeout)
            projectstatus.notified_on_timeout = False
            projectstatus.save()

    if project.wait_before_notification:
        to_wait = project.wait_before_notification
        time_passed = timezone.now() - build.datetime
        if time_passed.seconds < to_wait:
            # wait time did not pass yet; try again later
            remaining_time = to_wait - time_passed.seconds + 1
            maybe_notify_project_status.apply_async(
                args=[status_id],
                countdown=remaining_time,
            )
            return

    if projectstatus.finished and not projectstatus.notified:
        # check if there are any outstanding PluginScratch objects
        if not projectstatus.build.pluginscratch_set.all():
            send_status_notification(projectstatus)

            build_id = build.id
            with transaction.atomic():
                atomic_build = Build.objects.select_for_update().get(
                    pk=build_id)
                if atomic_build.patch_notified is False:
                    notify_patch_build_finished.delay(build_id)
                    atomic_build.patch_notified = True
                    atomic_build.save()
Exemple #17
0
    def test_subject_from_custom_template(self):
        template = EmailTemplate.objects.create(subject='lalala', plain_text='foo', html='bar')
        self.project.use_custom_email_template = True
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertEqual('lalala', msg.subject)
Exemple #18
0
    def test_dont_html_escape_metadata_for_plain_text(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        env = self.project.environments.create(slug='myenv')
        self.build2.test_runs.create(environment=env, metadata_file='{"foo": "foo\'bar"}')

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertIn("foo'bar", msg.body)
    def test_dont_html_escape_metadata_for_plain_text(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        env = self.project.environments.create(slug='myenv')
        self.build2.test_runs.create(environment=env, metadata_file='{"foo": "foo\'bar"}')

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertIn("foo'bar", msg.body)
Exemple #20
0
    def test_send_notification_for_all_builds(self, diff):
        self.project.subscriptions.create(email='*****@*****.**')
        diff.return_value = fake_diff()

        status1 = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status1)
        self.assertEqual(1, len(mail.outbox))

        t = timezone.now() - relativedelta(hours=2.5)
        build = self.project.builds.create(version='3', datetime=t)
        status2 = ProjectStatus.create_or_update(build)
        send_status_notification(status2)

        self.assertEqual(2, len(mail.outbox))
    def test_send_notification_for_all_builds(self, diff):
        self.project.subscriptions.create(email='*****@*****.**')
        diff.return_value = fake_diff()

        status1 = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status1)
        self.assertEqual(1, len(mail.outbox))

        t = timezone.now() - relativedelta(hours=2.5)
        build = self.project.builds.create(version='3', datetime=t)
        status2 = ProjectStatus.create_or_update(build)
        send_status_notification(status2)

        self.assertEqual(2, len(mail.outbox))
    def test_custom_template(self):
        template = EmailTemplate.objects.create(plain_text='foo', html='bar')
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        txt = msg.body
        html = msg.alternatives[0][0]

        self.assertEqual('foo', txt)
        self.assertEqual('bar', html)
    def test_avoid_big_emails(self):
        _1MB = 1024 * 1024
        self.project.subscriptions.create(email='*****@*****.**')
        template = EmailTemplate.objects.create(plain_text='dummy string' * _1MB)
        self.project.custom_email_template = template
        self.project.html_mail = False
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertNotIn('dummy string', msg.body)
        self.assertIn('The email got too big', msg.body)
Exemple #24
0
    def test_parse_metadata_list_of_ints(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        env = self.project.environments.create(slug='myenv')
        self.build2.test_runs.create(environment=env,
                                     metadata_file='{"duration": [11,22,33]}')

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertIn("11", msg.body)
        self.assertIn("22", msg.body)
        self.assertIn("33", msg.body)
Exemple #25
0
    def test_custom_template(self):
        template = EmailTemplate.objects.create(plain_text='foo', html='bar')
        self.project.use_custom_email_template = True
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        txt = msg.body
        html = msg.alternatives[0][0]

        self.assertEqual('foo', txt)
        self.assertEqual('bar', html)
Exemple #26
0
    def test_parse_metadata_list_of_lists(self):
        self.project.subscriptions.create(email='*****@*****.**')
        self.project.html_mail = False
        self.project.save()
        env = self.project.environments.create(slug='myenv')
        self.build2.test_runs.create(
            environment=env,
            metadata_file=
            '{"foo": [["list of list value 1"],["list of list value 2"]]}')

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        self.assertIn("[['list of list value 1'], ['list of list value 2']]",
                      msg.body)
Exemple #27
0
 def test_send_notification_on_errors_only(self):
     backend = Backend.objects.create(
         url='http://example.com',
         username='******',
         token='mypassword',
     )
     self.build2.test_jobs.create(backend=backend,
                                  target=self.project,
                                  job_status="Incomplete")
     self.project.project_settings = yaml.dump(
         {'CI_LAVA_JOB_ERROR_STATUS': "Incomplete"})
     self.project.save()
     self.project.subscriptions.create(
         email='*****@*****.**',
         notification_strategy=Subscription.NOTIFY_ON_ERROR)
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #28
0
    def test_context_custom_template(self):
        expose_context_vars = """
            build={{build.version}}
            important_metadata={{important_metadata}}
            metadata={{metadata}}
            notification={{notification}}
            previous_build={{previous_build}}
            regressions_grouped_by_suite={{regressions_grouped_by_suite}}
            fixes_grouped_by_suite={{fixes_grouped_by_suite}}
            known_issues={{known_issues}}
            regressions={{regressions}}
            fixes={{fixes}}
            thresholds={{thresholds}}
            settings={{settings}}
            summary={{summary}}
            metrics={{metrics}}
        """
        template = EmailTemplate.objects.create(plain_text=expose_context_vars,
                                                html=expose_context_vars)
        self.project.use_custom_email_template = True
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        txt = msg.body

        self.assertIn('build=2', txt)
        self.assertIn('important_metadata={}', txt)
        self.assertIn('metadata=OrderedDict()', txt)
        self.assertIn('notification=<squad.core.notification.Notification',
                      txt)
        self.assertIn('previous_build=1', txt)
        self.assertIn('regressions_grouped_by_suite=OrderedDict()', txt)
        self.assertIn('fixes_grouped_by_suite=OrderedDict()', txt)
        self.assertIn('known_issues=<QuerySet []>', txt)
        self.assertIn('regressions=OrderedDict()', txt)
        self.assertIn('fixes=OrderedDict()', txt)
        self.assertIn('thresholds=[]', txt)
        self.assertIn('settings=<Settings "test.settings">', txt)
        self.assertIn('summary=<squad.core.models.TestSummary', txt)
        self.assertIn('metrics=<QuerySet []>', txt)
    def test_escaping_custom_template(self):
        template = EmailTemplate.objects.create(
            subject='subject: {{ project.name }}',
            plain_text='foo: {{ notification.project.name }}',
            html='{% autoescape True %}bar: {{ notification.project.name }}{% endautoescape %}')
        self.project.name = "Project's name"
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        subject = msg.subject
        txt = msg.body
        html = msg.alternatives[0][0]

        self.assertEqual("subject: Project's name", subject)
        self.assertEqual("foo: Project's name", txt)
        self.assertEqual("bar: Project&#39;s name", html)
Exemple #30
0
    def test_escaping_custom_template(self):
        template = EmailTemplate.objects.create(
            subject='subject: {{ project.name }}',
            plain_text='foo: {{ notification.project.name }}',
            html='{% autoescape True %}bar: {{ notification.project.name }}{% endautoescape %}')
        self.project.name = "Project's name"
        self.project.use_custom_email_template = True
        self.project.custom_email_template = template
        self.project.save()

        status = ProjectStatus.create_or_update(self.build2)
        send_status_notification(status)

        msg = mail.outbox[0]
        subject = msg.subject
        txt = msg.body
        html = msg.alternatives[0][0]

        self.assertEqual("subject: Project's name", subject)
        self.assertEqual("foo: Project's name", txt)
        self.assertEqual("bar: Project&#39;s name", html)
Exemple #31
0
def maybe_notify_project_status(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    build = projectstatus.build
    project = build.project

    timeout = project.notification_timeout
    if timeout:
        notification_timeout.apply_async(args=[status_id], countdown=timeout)

    if project.wait_before_notification:
        to_wait = project.wait_before_notification
        time_passed = timezone.now() - build.datetime
        if time_passed.seconds < to_wait:
            # wait time did not pass yet; try again later
            remaining_time = to_wait - time_passed.seconds + 1
            maybe_notify_project_status.apply_async(
                args=[status_id],
                countdown=remaining_time,
            )
            return

    if projectstatus.finished and not projectstatus.notified:
        send_status_notification(projectstatus)
Exemple #32
0
def maybe_notify_project_status(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    build = projectstatus.build
    project = build.project

    timeout = project.notification_timeout
    if timeout:
        notification_timeout.apply_async(args=[status_id], countdown=timeout)

    if project.wait_before_notification:
        to_wait = project.wait_before_notification
        time_passed = timezone.now() - build.datetime
        if time_passed.seconds < to_wait:
            # wait time did not pass yet; try again later
            remaining_time = to_wait - time_passed.seconds + 1
            maybe_notify_project_status.apply_async(
                args=[status_id],
                countdown=remaining_time,
            )
            return

    if projectstatus.finished and not projectstatus.notified:
        notify_patch_build_finished.delay(projectstatus.build_id)
        send_status_notification(projectstatus)
Exemple #33
0
def notification_timeout(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    if not projectstatus.notified and not projectstatus.notified_on_timeout:
        send_status_notification(projectstatus)
        projectstatus.notified_on_timeout = True
        projectstatus.save()
Exemple #34
0
def notify_project_status(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    send_status_notification(projectstatus)
 def setUp(self):
     super(TestSendUnmoderatedNotification, self).setUp()
     send_status_notification(self.status)
 def setUp(self):
     super(TestSendApprovedNotification, self).setUp()
     self.status.approved = True
     self.status.save()
     send_status_notification(self.status)
Exemple #37
0
def notify_project_status(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    send_status_notification(projectstatus)
Exemple #38
0
 def test_dont_send_if_notifying_on_regression(self):
     self.subscription.notification_strategy = Subscription.NOTIFY_ON_REGRESSION
     self.subscription.save()
     status = ProjectStatus.create_or_update(self.build)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
 def test_send_a_single_notification_email(self):
     self.project.subscriptions.create(email='*****@*****.**')
     self.project.subscriptions.create(email='*****@*****.**')
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #40
0
 def test_send_a_single_notification_email(self):
     self.project.subscriptions.create(email='*****@*****.**')
     self.project.subscriptions.create(email='*****@*****.**')
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #41
0
 def setUp(self):
     super(TestSendUnmoderatedNotification, self).setUp()
     send_status_notification(self.status)
 def test_send_notification_to_user(self, diff):
     self.project.subscriptions.create(user=self.user)
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
 def test_no_recipients_no_email(self, diff):
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
Exemple #44
0
 def setUp(self):
     super(TestSendApprovedNotification, self).setUp()
     self.status.approved = True
     self.status.save()
     send_status_notification(self.status)
Exemple #45
0
 def test_send_if_notifying_all_builds(self):
     status = ProjectStatus.create_or_update(self.build)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
 def test_send_if_notifying_all_builds(self):
     status = ProjectStatus.create_or_update(self.build)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
Exemple #47
0
 def test_send_notification_to_user(self, diff):
     self.project.subscriptions.create(user=self.user)
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))
 def test_dont_send_if_notifying_on_error(self):
     self.subscription.notification_strategy = Subscription.NOTIFY_ON_ERROR
     self.subscription.save()
     status = ProjectStatus.create_or_update(self.build)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
Exemple #49
0
 def test_no_recipients_no_email(self, diff):
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(0, len(mail.outbox))
Exemple #50
0
def notification_timeout(status_id):
    projectstatus = ProjectStatus.objects.get(pk=status_id)
    if not projectstatus.notified and not projectstatus.notified_on_timeout:
        send_status_notification(projectstatus)
        projectstatus.notified_on_timeout = True
        projectstatus.save()
Exemple #51
0
 def test_send_notification(self, diff):
     self.project.subscriptions.create(email='*****@*****.**')
     diff.return_value = fake_diff()
     status = ProjectStatus.create_or_update(self.build2)
     send_status_notification(status)
     self.assertEqual(1, len(mail.outbox))