Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions apiserver/dora/service/deployments/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ def _get_deployment_frequency_metrics(
self, successful_deployments: List[Deployment], interval: Interval
) -> DeploymentFrequencyMetrics:

successful_deployments = list(
filter(
lambda x: x.conducted_at >= interval.from_time
and x.conducted_at <= interval.to_time,
successful_deployments,
)
)

team_daily_deployments = generate_expanded_buckets(
successful_deployments, interval, "conducted_at", "daily"
)
Expand Down Expand Up @@ -230,6 +238,14 @@ def _get_weekly_deployment_frequency_trends(
self, successful_deployments: List[Deployment], interval: Interval
) -> Dict[datetime, int]:

successful_deployments = list(
filter(
lambda x: x.conducted_at >= interval.from_time
and x.conducted_at <= interval.to_time,
successful_deployments,
)
)

team_weekly_deployments = generate_expanded_buckets(
successful_deployments, interval, "conducted_at", "weekly"
)
Expand Down
16 changes: 16 additions & 0 deletions apiserver/tests/factories/models/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from uuid import uuid4
from dora.service.deployments.models.models import (
Deployment,
DeploymentFrequencyMetrics,
DeploymentStatus,
DeploymentType,
)
Expand Down Expand Up @@ -174,3 +175,18 @@ def get_deployment(
html_url=html_url or "",
meta=meta or {},
)


def get_deployment_frequency_metrics(
total_deployments=0,
daily_deployment_frequency=0,
avg_weekly_deployment_frequency=0,
avg_monthly_deployment_frequency=0,
) -> DeploymentFrequencyMetrics:

return DeploymentFrequencyMetrics(
total_deployments=total_deployments or 0,
daily_deployment_frequency=daily_deployment_frequency or 0,
avg_weekly_deployment_frequency=avg_weekly_deployment_frequency or 0,
avg_monthly_deployment_frequency=avg_monthly_deployment_frequency or 0,
)
181 changes: 181 additions & 0 deletions apiserver/tests/service/deployments/test_deployment_frequency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
from datetime import datetime, timedelta

import pytz
from dora.service.deployments.analytics import DeploymentAnalyticsService
from dora.utils.time import Interval
from tests.factories.models.code import get_deployment, get_deployment_frequency_metrics

first_week_2024 = datetime(2024, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
second_week_2024 = datetime(2024, 1, 8, 0, 0, 0, tzinfo=pytz.UTC)
third_week_2024 = datetime(2024, 1, 15, 0, 0, 0, tzinfo=pytz.UTC)
fourth_week_2024 = datetime(2024, 1, 22, 0, 0, 0, tzinfo=pytz.UTC)


def test_deployment_frequency_for_no_deployments():

from_time = first_week_2024 + timedelta(days=1)
to_time = third_week_2024 + timedelta(days=2)

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert (
deployment_analytics_service._get_deployment_frequency_metrics(
[], Interval(from_time, to_time)
)
== get_deployment_frequency_metrics()
)


def test_deployment_frequency_for_deployments_across_days():

from_time = first_week_2024 + timedelta(days=1)
to_time = first_week_2024 + timedelta(days=4)

deployment_1 = get_deployment(conducted_at=from_time + timedelta(hours=12))
deployment_2 = get_deployment(conducted_at=from_time + timedelta(days=1))
deployment_3 = get_deployment(conducted_at=from_time + timedelta(days=2))

deployment_outside_interval = get_deployment(
conducted_at=to_time + timedelta(days=20)
)

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert deployment_analytics_service._get_deployment_frequency_metrics(
[deployment_1, deployment_2, deployment_3, deployment_outside_interval],
Interval(from_time, to_time),
) == get_deployment_frequency_metrics(3, 0, 3, 3)


def test_deployment_frequency_for_deployments_across_weeks():

from_time = first_week_2024 + timedelta(days=1)
to_time = fourth_week_2024 + timedelta(days=1)

# Week 1

deployment_1 = get_deployment(conducted_at=from_time + timedelta(hours=12))
deployment_2 = get_deployment(conducted_at=from_time + timedelta(hours=24))

# Week 3
deployment_3 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=4))
deployment_4 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=2))
deployment_5 = get_deployment(conducted_at=fourth_week_2024 - timedelta(hours=6))
deployment_6 = get_deployment(conducted_at=fourth_week_2024 - timedelta(minutes=30))

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert deployment_analytics_service._get_deployment_frequency_metrics(
[
deployment_1,
deployment_2,
deployment_3,
deployment_4,
deployment_5,
deployment_6,
],
Interval(from_time, to_time),
) == get_deployment_frequency_metrics(6, 0, 1, 6)


def test_deployment_frequency_for_deployments_across_months():

from_time = first_week_2024 + timedelta(days=1)
to_time = datetime(2024, 3, 31, 0, 0, 0, tzinfo=pytz.UTC)

second_month_2024 = datetime(2024, 2, 1, 0, 0, 0, tzinfo=pytz.UTC)

print((to_time - from_time).days)

# Month 1

deployment_1 = get_deployment(conducted_at=from_time + timedelta(hours=12))
deployment_2 = get_deployment(conducted_at=from_time + timedelta(hours=24))
deployment_3 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=4))
deployment_4 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=2))
deployment_5 = get_deployment(conducted_at=fourth_week_2024 - timedelta(hours=6))
deployment_6 = get_deployment(conducted_at=fourth_week_2024 - timedelta(minutes=30))

# Month 2

deployment_7 = get_deployment(conducted_at=second_month_2024 + timedelta(days=3))
deployment_8 = get_deployment(conducted_at=second_month_2024 + timedelta(days=2))
deployment_9 = get_deployment(
conducted_at=second_month_2024 + timedelta(minutes=30)
)

# Month 3

deployment_10 = get_deployment(conducted_at=to_time - timedelta(days=3))
deployment_11 = get_deployment(conducted_at=to_time - timedelta(days=2))
deployment_12 = get_deployment(conducted_at=to_time - timedelta(days=1))
deployment_13 = get_deployment(conducted_at=to_time - timedelta(days=1))

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert deployment_analytics_service._get_deployment_frequency_metrics(
[
deployment_1,
deployment_2,
deployment_3,
deployment_4,
deployment_5,
deployment_6,
deployment_7,
deployment_8,
deployment_9,
deployment_10,
deployment_11,
deployment_12,
deployment_13,
],
Interval(from_time, to_time),
) == get_deployment_frequency_metrics(13, 0, 1, 4)


def test_weekly_deployment_frequency_trends_for_no_deployments():

from_time = first_week_2024 + timedelta(days=1)
to_time = third_week_2024 + timedelta(days=2)

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert deployment_analytics_service._get_weekly_deployment_frequency_trends(
[], Interval(from_time, to_time)
) == {first_week_2024: 0, second_week_2024: 0, third_week_2024: 0}


def test_weekly_deployment_frequency_trends_for_deployments():

from_time = first_week_2024 + timedelta(days=1)
to_time = fourth_week_2024 + timedelta(days=1)

# Week 1

deployment_1 = get_deployment(conducted_at=from_time + timedelta(hours=12))
deployment_2 = get_deployment(conducted_at=from_time + timedelta(hours=24))

# Week 3
deployment_3 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=4))
deployment_4 = get_deployment(conducted_at=fourth_week_2024 - timedelta(days=2))
deployment_5 = get_deployment(conducted_at=fourth_week_2024 - timedelta(hours=6))
deployment_6 = get_deployment(conducted_at=fourth_week_2024 - timedelta(minutes=30))

deployment_analytics_service = DeploymentAnalyticsService(None, None)

assert deployment_analytics_service._get_weekly_deployment_frequency_trends(
[
deployment_1,
deployment_2,
deployment_3,
deployment_4,
deployment_5,
deployment_6,
],
Interval(from_time, to_time),
) == {
first_week_2024: 2,
second_week_2024: 0,
third_week_2024: 4,
fourth_week_2024: 0,
}