Ejemplo n.º 1
0
 def test_fetching_release_sessions_time_bounds_for_different_release_with_no_sessions(self):
     """
     Test that ensures if no sessions are available for a specific release then the bounds
     should be returned as None
     """
     data = get_release_sessions_time_bounds(
         project_id=self.project.id,
         release="different_release",
         org_id=self.organization.id,
         environments=["prod"],
     )
     assert data == {
         "sessions_lower_bound": None,
         "sessions_upper_bound": None,
     }
Ejemplo n.º 2
0
    def get(self, request, organization, version):
        """
        Retrieve an Organization's Release
        ``````````````````````````````````

        Return details on an individual release.

        :pparam string organization_slug: the slug of the organization the
                                          release belongs to.
        :pparam string version: the version identifier of the release.
        :auth: required
        """
        # Dictionary responsible for storing selected project meta data
        current_project_meta = {}
        project_id = request.GET.get("project")
        with_health = request.GET.get("health") == "1"
        summary_stats_period = request.GET.get("summaryStatsPeriod") or "14d"
        health_stats_period = request.GET.get("healthStatsPeriod") or ("24h" if with_health else "")
        sort = request.GET.get("sort") or "date"

        if summary_stats_period not in STATS_PERIODS:
            raise ParseError(detail=get_stats_period_detail("summaryStatsPeriod", STATS_PERIODS))
        if health_stats_period and health_stats_period not in STATS_PERIODS:
            raise ParseError(detail=get_stats_period_detail("healthStatsPeriod", STATS_PERIODS))

        try:
            release = Release.objects.get(organization_id=organization.id, version=version)
        except Release.DoesNotExist:
            raise ResourceDoesNotExist

        if not self.has_release_permission(request, organization, release):
            raise ResourceDoesNotExist

        if with_health and project_id:
            try:
                project = Project.objects.get_from_cache(id=int(project_id))
            except (ValueError, Project.DoesNotExist):
                raise ParseError(detail="Invalid project")
            release._for_project_id = project.id

        if project_id:
            # Add sessions time bound to current project meta data
            environments = set(request.GET.getlist("environment")) or None
            current_project_meta.update(
                {
                    **get_release_sessions_time_bounds(
                        project_id=int(project_id),
                        release=release.version,
                        org_id=organization.id,
                        environments=environments,
                    )
                }
            )

            # Get prev and next release to current release
            try:
                filter_params = self.get_filter_params(request, organization)
                current_project_meta.update(
                    {
                        **self.get_adjacent_releases_to_current_release(
                            org=organization,
                            release=release,
                            filter_params=filter_params,
                            stats_period=summary_stats_period,
                            sort=sort,
                        )
                    }
                )
            except InvalidSortException:
                return Response({"detail": "invalid sort"}, status=400)

        return Response(
            serialize(
                release,
                request.user,
                with_health_data=with_health,
                summary_stats_period=summary_stats_period,
                health_stats_period=health_stats_period,
                current_project_meta=current_project_meta,
            )
        )
Ejemplo n.º 3
0
    def test_fetching_release_sessions_time_bounds_for_different_release(self):
        """
        Test that ensures only session bounds for releases are calculated according
        to their respective release
        """
        # Same release session
        self.store_session(
            {
                "session_id": "5e910c1a-6941-460e-9843-24103fb6a63c",
                "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102666",
                "status": "exited",
                "seq": 1,
                "release": self.session_release,
                "environment": "prod",
                "retention_days": 90,
                "org_id": self.project.organization_id,
                "project_id": self.project.id,
                "duration": 30.0,
                "errors": 0,
                "started": self.session_started - 3600 * 2,
                "received": self.received - 3600 * 2,
            }
        )
        # Different release session
        self.store_session(
            {
                "session_id": "a148c0c5-06a2-423b-8901-6b43b812cf82",
                "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102666",
                "status": "crashed",
                "seq": 0,
                "release": self.session_crashed_release,
                "environment": "prod",
                "retention_days": 90,
                "org_id": self.project.organization_id,
                "project_id": self.project.id,
                "duration": 60.0,
                "errors": 0,
                "started": self.session_started - 3600 * 2,
                "received": self.received - 3600 * 2,
            }
        )

        expected_formatted_lower_bound = format_timestamp(
            datetime.utcfromtimestamp(self.session_started - 3600 * 2).replace(minute=0)
        )
        expected_formatted_upper_bound = format_timestamp(
            datetime.utcfromtimestamp(self.session_started).replace(minute=0)
        )

        # Test for self.session_release
        data = get_release_sessions_time_bounds(
            project_id=self.project.id,
            release=self.session_release,
            org_id=self.organization.id,
            environments=["prod"],
        )
        assert data == {
            "sessions_lower_bound": expected_formatted_lower_bound,
            "sessions_upper_bound": expected_formatted_upper_bound,
        }

        # Test for self.session_crashed_release
        data = get_release_sessions_time_bounds(
            project_id=self.project.id,
            release=self.session_crashed_release,
            org_id=self.organization.id,
            environments=["prod"],
        )
        assert data == {
            "sessions_lower_bound": expected_formatted_lower_bound,
            "sessions_upper_bound": expected_formatted_upper_bound,
        }
    def get(self, request, organization, version):
        """
        Retrieve an Organization's Release's Associated Meta Data
        `````````````````````````````````````````````````````````

        The data returned from here is auxiliary meta data that the UI uses.

        :pparam string organization_slug: the slug of the organization the
                                          release belongs to.
        :pparam string version: the version identifier of the release.
        :auth: required
        """
        try:
            release = Release.objects.get(organization_id=organization.id,
                                          version=version)
        except Release.DoesNotExist:
            raise ResourceDoesNotExist

        if not self.has_release_permission(request, organization, release):
            raise ResourceDoesNotExist

        commit_files_changed = (CommitFileChange.objects.filter(
            commit_id__in=ReleaseCommit.objects.filter(
                release=release).values_list("commit_id", flat=True)).values(
                    "filename").distinct().count())

        project_releases = ReleaseProject.objects.filter(
            release=release).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)

        environments = set(request.GET.getlist("environment")) or None

        # This must match what is returned from the `Release` serializer
        projects = [{
            "id":
            pr["project__id"],
            "slug":
            pr["project__slug"],
            "name":
            pr["project__name"],
            "newGroups":
            pr["new_groups"],
            "platform":
            pr["project__platform"],
            "platforms":
            platforms_by_project.get(pr["project__id"]) or [],
            **get_release_sessions_time_bounds(
                project_id=pr["project__id"],
                release=release.version,
                org_id=organization.id,
                environments=environments,
            ),
        } for pr in project_releases]

        release_file_count = ReleaseFile.objects.filter(
            release=release).count()

        return Response({
            "version":
            release.version,
            "versionInfo":
            expose_version_info(release.version_info),
            "projects":
            projects,
            "newGroups":
            release.new_groups,
            "deployCount":
            release.total_deploys,
            "commitCount":
            release.commit_count,
            "released":
            release.date_released or release.date_added,
            "commitFilesChanged":
            commit_files_changed,
            "releaseFileCount":
            release_file_count,
        })