Beispiel #1
0
    def test_when_current_release_version_is_set_incorrect_inputs_fallback_to_older_model(
            self):
        """
        Test that ensures in a project that follows semver and where current_release_version is
        set, wrong release input (non semver) comparison does not break the method, but rather
        fallsback to the older model of comparison
        """
        old_random_release = self.create_release(date_added=timezone.now() -
                                                 timedelta(minutes=45),
                                                 version="doggo")

        GroupResolution.objects.create(
            release=old_random_release,
            current_release_version=old_random_release.version,
            group=self.group,
            type=GroupResolution.Type.in_next_release,
        )

        for release in [
                self.old_release,
                self.new_release,
                self.old_semver_release,
                self.new_semver_release,
        ]:
            assert not GroupResolution.has_resolution(self.group, release)
Beispiel #2
0
 def test_no_release_with_resolution(self):
     GroupResolution.objects.create(
         release=self.new_release,
         group=self.group,
         type=GroupResolution.Type.in_release,
     )
     assert GroupResolution.has_resolution(self.group, None)
Beispiel #3
0
 def test_in_release_with_current_release(self):
     GroupResolution.objects.create(
         release=self.old_release,
         group=self.group,
         type=GroupResolution.Type.in_release,
     )
     assert not GroupResolution.has_resolution(self.group, self.old_release)
 def test_in_release_with_old_release(self):
     GroupResolution.objects.create(
         release=self.new_release,
         group=self.group,
         type=GroupResolution.Type.in_release,
     )
     assert GroupResolution.has_resolution(self.group, self.old_release)
Beispiel #5
0
    def test_when_current_release_version_is_set_with_old_release(self):
        for grp_res_type in [
                GroupResolution.Type.in_release,
                GroupResolution.Type.in_next_release
        ]:
            grp_resolution = GroupResolution.objects.create(
                release=self.new_release,
                current_release_version=self.new_release.version,
                group=self.group,
                type=grp_res_type,
            )
            assert GroupResolution.has_resolution(self.group, self.old_release)

            grp_resolution.delete()
Beispiel #6
0
    def test_for_semver_when_current_release_version_is_set_with_new_semver_release(
            self):
        # Behaviour should be the same in both `in_release` and `in_next_release` because if
        # `current_release_version` is set then comparison will be > current_release_version
        # should not have a resolution
        for grp_res_type in [
                GroupResolution.Type.in_release,
                GroupResolution.Type.in_next_release
        ]:
            grp_resolution = GroupResolution.objects.create(
                release=self.old_semver_release,
                current_release_version=self.old_semver_release.version,
                group=self.group,
                type=grp_res_type,
            )
            assert not GroupResolution.has_resolution(self.group,
                                                      self.new_semver_release)

            grp_resolution.delete()
Beispiel #7
0
    def test_when_current_release_version_is_set_but_does_not_exist_fallback_to_older_model(
            self):
        """
        Test that ensures in a project that does not follows semver, and current_release_version
        is set but no corresponding Release instance exists for that release version then
        comparison does not break the method, but rather fallsback to the older model
        """
        GroupResolution.objects.create(
            release=self.old_release,
            current_release_version="kittie 12",
            group=self.group,
            type=GroupResolution.Type.in_next_release,
        )

        for release in [
                self.new_release, self.old_semver_release,
                self.new_semver_release
        ]:
            assert not GroupResolution.has_resolution(self.group, release)
Beispiel #8
0
    def _handle_regression(self, group, event, release):
        if not group.is_resolved():
            return

        # we only mark it as a regression if the event's release is newer than
        # the release which we originally marked this as resolved
        elif GroupResolution.has_resolution(group, release):
            return

        if not plugin_is_regression(group, event):
            return

        # we now think its a regression, rely on the database to validate that
        # no one beat us to this
        date = max(event.datetime, group.last_seen)
        is_regression = bool(
            Group.objects.filter(
                id=group.id,
                # ensure we cant update things if the status has been set to
                # ignored
                status__in=[GroupStatus.RESOLVED, GroupStatus.UNRESOLVED],
            ).exclude(
                # add to the regression window to account for races here
                active_at__gte=date - timedelta(seconds=5),
            ).update(
                active_at=date,
                # explicitly set last_seen here as ``is_resolved()`` looks
                # at the value
                last_seen=date,
                status=GroupStatus.UNRESOLVED
            )
        )

        group.active_at = date
        group.status = GroupStatus.UNRESOLVED

        if is_regression and release:
            # resolutions are only valid if the state of the group is still
            # resolved -- if it were to change the resolution should get removed
            try:
                resolution = GroupResolution.objects.get(
                    group=group,
                )
            except GroupResolution.DoesNotExist:
                affected = False
            else:
                cursor = connection.cursor()
                # delete() API does not return affected rows
                cursor.execute("DELETE FROM sentry_groupresolution WHERE id = %s", [resolution.id])
                affected = cursor.rowcount > 0

            if affected:
                # if we had to remove the GroupResolution (i.e. we beat the
                # the queue to handling this) then we need to also record
                # the corresponding event
                try:
                    activity = Activity.objects.filter(
                        group=group,
                        type=Activity.SET_RESOLVED_IN_RELEASE,
                        ident=resolution.id,
                    ).order_by('-datetime')[0]
                except IndexError:
                    # XXX: handle missing data, as its not overly important
                    pass
                else:
                    activity.update(data={
                        'version': release.version,
                    })

        if is_regression:
            activity = Activity.objects.create(
                project=group.project,
                group=group,
                type=Activity.SET_REGRESSION,
                data={
                    'version': release.version if release else '',
                }
            )
            activity.send_notification()

        return is_regression
Beispiel #9
0
def _handle_regression(group, event, release):
    if not group.is_resolved():
        return

    # we only mark it as a regression if the event's release is newer than
    # the release which we originally marked this as resolved
    elif GroupResolution.has_resolution(group, release):
        return

    elif has_pending_commit_resolution(group):
        return

    if not plugin_is_regression(group, event):
        return

    # we now think its a regression, rely on the database to validate that
    # no one beat us to this
    date = max(event.datetime, group.last_seen)
    is_regression = bool(
        Group.objects.filter(
            id=group.id,
            # ensure we cant update things if the status has been set to
            # ignored
            status__in=[GroupStatus.RESOLVED, GroupStatus.UNRESOLVED],
        ).exclude(
            # add to the regression window to account for races here
            active_at__gte=date - timedelta(seconds=5)).
        update(
            active_at=date,
            # explicitly set last_seen here as ``is_resolved()`` looks
            # at the value
            last_seen=date,
            status=GroupStatus.UNRESOLVED,
        ))

    group.active_at = date
    group.status = GroupStatus.UNRESOLVED

    if is_regression and release:
        # resolutions are only valid if the state of the group is still
        # resolved -- if it were to change the resolution should get removed
        try:
            resolution = GroupResolution.objects.get(group=group)
        except GroupResolution.DoesNotExist:
            affected = False
        else:
            cursor = connection.cursor()
            # delete() API does not return affected rows
            cursor.execute("DELETE FROM sentry_groupresolution WHERE id = %s",
                           [resolution.id])
            affected = cursor.rowcount > 0

        if affected:
            # if we had to remove the GroupResolution (i.e. we beat the
            # the queue to handling this) then we need to also record
            # the corresponding event
            try:
                activity = Activity.objects.filter(
                    group=group,
                    type=Activity.SET_RESOLVED_IN_RELEASE,
                    ident=resolution.id).order_by("-datetime")[0]
            except IndexError:
                # XXX: handle missing data, as its not overly important
                pass
            else:
                activity.update(data={"version": release.version})

    if is_regression:
        activity = Activity.objects.create(
            project_id=group.project_id,
            group=group,
            type=Activity.SET_REGRESSION,
            data={"version": release.version if release else ""},
        )
        activity.send_notification()

        kick_off_status_syncs.apply_async(kwargs={
            "project_id": group.project_id,
            "group_id": group.id
        })

    return is_regression
Beispiel #10
0
 def test_no_release_with_no_resolution(self):
     assert not GroupResolution.has_resolution(self.group, None)
Beispiel #11
0
 def test_in_next_release_with_old_release(self):
     GroupResolution.objects.create(
         release=self.new_release, group=self.group, type=GroupResolution.Type.in_next_release
     )
     assert GroupResolution.has_resolution(self.group, self.old_release)
Beispiel #12
0
 def test_for_semver_in_release_with_new_release(self):
     GroupResolution.objects.create(release=self.old_semver_release,
                                    group=self.group,
                                    type=GroupResolution.Type.in_release)
     assert not GroupResolution.has_resolution(self.group,
                                               self.new_semver_release)
Beispiel #13
0
 def test_no_release_with_no_resolution(self):
     assert not GroupResolution.has_resolution(self.group, None)