Exemplo n.º 1
0
    def safe_delete(self):
        """Deletes a release if possible or raises a `UnsafeReleaseDeletion`
        exception.
        """
        from sentry.models import Group, ReleaseFile
        from sentry.snuba.sessions import check_has_health_data

        # we don't want to remove the first_release metadata on the Group, and
        # while people might want to kill a release (maybe to remove files),
        # removing the release is prevented
        if Group.objects.filter(first_release=self).exists():
            raise UnsafeReleaseDeletion(ERR_RELEASE_REFERENCED)

        # We do not allow releases with health data to be deleted because
        # the upserting from snuba data would create the release again.
        # We would need to be able to delete this data from snuba which we
        # can't do yet.
        project_ids = list(self.projects.values_list("id").all())
        if check_has_health_data([(p[0], self.version) for p in project_ids]):
            raise UnsafeReleaseDeletion(ERR_RELEASE_HEALTH_DATA)

        # TODO(dcramer): this needs to happen in the queue as it could be a long
        # and expensive operation
        file_list = ReleaseFile.objects.filter(
            release=self).select_related("file")
        for releasefile in file_list:
            releasefile.file.delete()
            releasefile.delete()
        self.delete()
Exemplo n.º 2
0
    def get_session_stats(self, project_ids):
        segments, interval = STATS_PERIOD_CHOICES[self.stats_period]

        now = timezone.now()
        current_interval_start = now - (segments * interval)
        previous_interval_start = now - (2 * segments * interval)

        project_health_data_dict = releasehealth.get_current_and_previous_crash_free_rates(
            project_ids=project_ids,
            current_start=current_interval_start,
            current_end=now,
            previous_start=previous_interval_start,
            previous_end=current_interval_start,
            rollup=int(interval.total_seconds()),
        )

        # list that contains ids of projects that has both `currentCrashFreeRate` and
        # `previousCrashFreeRate` set to None and so we are not sure if they have health data or
        # not and so we add those ids to this list to check later
        check_has_health_data_ids = []

        for project_id in project_ids:
            current_crash_free_rate = project_health_data_dict[project_id][
                "currentCrashFreeRate"]
            previous_crash_free_rate = project_health_data_dict[project_id][
                "previousCrashFreeRate"]

            if [current_crash_free_rate, previous_crash_free_rate
                ] != [None, None]:
                project_health_data_dict[project_id]["hasHealthData"] = True
            else:
                project_health_data_dict[project_id]["hasHealthData"] = False
                check_has_health_data_ids.append(project_id)

        # For project ids we are not sure if they have health data in the last 90 days we
        # call -> check_has_data with those ids and then update our `project_health_data_dict`
        # accordingly
        if check_has_health_data_ids:
            projects_with_health_data = check_has_health_data(
                check_has_health_data_ids)
            for project_id in projects_with_health_data:
                project_health_data_dict[project_id]["hasHealthData"] = True

        return project_health_data_dict
Exemplo n.º 3
0
    def get_attrs(self, item_list, user, **kwargs):
        project = kwargs.get("project")

        # Some code paths pass an environment object, other pass a list of
        # environment names.
        environment = kwargs.get("environment")
        environments = kwargs.get("environments")
        if not environments:
            if environment:
                environments = [environment.name]
            else:
                environments = None

        with_health_data = kwargs.get("with_health_data", False)
        health_stat = kwargs.get("health_stat", None)
        health_stats_period = kwargs.get("health_stats_period")
        summary_stats_period = kwargs.get("summary_stats_period")
        no_snuba = kwargs.get("no_snuba")
        if with_health_data and no_snuba:
            raise TypeError("health data requires snuba")

        if environments is None:
            first_seen, last_seen, issue_counts_by_release = self.__get_release_data_no_environment(
                project, item_list)
        else:
            (
                first_seen,
                last_seen,
                issue_counts_by_release,
            ) = self.__get_release_data_with_environments(
                project, item_list, environments)

        owners = {
            d["id"]: d
            for d in serialize({i.owner
                                for i in item_list if i.owner_id}, user)
        }

        release_metadata_attrs = self._get_commit_metadata(item_list, user)
        deploy_metadata_attrs = self._get_deploy_metadata(item_list, user)

        release_projects = defaultdict(list)
        project_releases = ReleaseProject.objects.filter(
            release__in=item_list).values(
                "new_groups",
                "release_id",
                "release__version",
                "project__slug",
                "project__name",
                "project__id",
                "project__platform",
            )

        platforms = ProjectPlatform.objects.filter(
            project_id__in={x["project__id"]
                            for x in project_releases}).values_list(
                                "project_id", "platform")
        platforms_by_project = defaultdict(list)
        for project_id, platform in platforms:
            platforms_by_project[project_id].append(platform)

        if with_health_data:
            health_data = get_release_health_data_overview(
                [(pr["project__id"], pr["release__version"])
                 for pr in project_releases],
                health_stats_period=health_stats_period,
                summary_stats_period=summary_stats_period,
                environments=environments,
                stat=health_stat,
            )
            has_health_data = None
        else:
            health_data = None
            if no_snuba:
                has_health_data = {}
            else:
                has_health_data = check_has_health_data([
                    (pr["project__id"], pr["release__version"])
                    for pr in project_releases
                ])

        for pr in project_releases:
            pr_rv = {
                "id": pr["project__id"],
                "slug": pr["project__slug"],
                "name": pr["project__name"],
                "new_groups": pr["new_groups"],
                "platform": pr["project__platform"],
                "platforms": platforms_by_project.get(pr["project__id"]) or [],
            }
            if health_data is not None:
                pr_rv["health_data"] = health_data.get(
                    (pr["project__id"], pr["release__version"]))
                pr_rv["has_health_data"] = (pr_rv["health_data"]
                                            or {}).get("has_health_data",
                                                       False)
            else:
                pr_rv["has_health_data"] = (
                    pr["project__id"],
                    pr["release__version"],
                ) in has_health_data
            release_projects[pr["release_id"]].append(pr_rv)

        result = {}
        for item in item_list:
            single_release_projects = release_projects.get(item.id, [])

            if item._for_project_id is not None:
                single_release_projects = [
                    x for x in single_release_projects
                    if x["id"] == item._for_project_id
                ]
                release_new_groups = (issue_counts_by_release.get(item.id)
                                      or {}).get(item._for_project_id) or 0
            else:
                release_new_groups = sum((issue_counts_by_release.get(item.id)
                                          or {}).values())

            p = {
                "owner": owners[str(item.owner_id)] if item.owner_id else None,
                "new_groups": release_new_groups,
                "projects": single_release_projects,
                "first_seen": first_seen.get(item.version),
                "last_seen": last_seen.get(item.version),
            }

            p.update(release_metadata_attrs[item])
            p.update(deploy_metadata_attrs[item])

            result[item] = p
        return result
Exemplo n.º 4
0
 def test_check_has_health_data(self):
     data = check_has_health_data([(self.project.id, self.session_release),
                                   (self.project.id, "dummy-release")])
     assert data == {(self.project.id, self.session_release)}