Commit 58f27851 authored by Adam Hegyi's avatar Adam Hegyi

Use aggregated DORA API for DF

Use aggregated DORA API for deployment frequency and count in VSA.
parent 4cd14988
......@@ -35,6 +35,10 @@ module Dora
return error(_('Container must be a project or a group.'), :bad_request)
end
if group_project_ids.present? && !group?
return error(_('The group_project_ids parameter is only allowed for a group'), :bad_request)
end
unless ::Dora::DailyMetrics::AVAILABLE_INTERVALS.include?(interval)
return error(_("The interval must be one of %{intervals}.") % { intervals: ::Dora::DailyMetrics::AVAILABLE_INTERVALS.join(',') },
:bad_request)
......@@ -72,7 +76,9 @@ module Dora
# - In the subsequent projects, the assigned role at the group-level
# can't be lowered. For example, if the user is reporter at group-level,
# the user can be developer in subsequent projects, but can't be guest.
container.all_projects
projects = container.all_projects
projects = projects.id_in(group_project_ids) if group_project_ids.any?
projects
end
end
......@@ -103,5 +109,9 @@ module Dora
def metric
params[:metric]
end
def group_project_ids
Array(params[:group_project_ids])
end
end
end
---
name: dora_deployment_frequency_in_vsa
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60367
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329178
milestone: '13.12'
type: development
group: group::optimize
default_enabled: false
......@@ -18,9 +18,16 @@ module Gitlab
private
# rubocop: disable CodeReuse/ActiveRecord
def deployments_count
@deployments_count ||= begin
@deployments_count ||= if Feature.enabled?(:dora_deployment_frequency_in_vsa)
deployment_count_via_dora_api
else
deployment_count_via_finder
end
end
# rubocop: disable CodeReuse/ActiveRecord
def deployment_count_via_finder
deployments = DeploymentsFinder
.new(group: group, finished_after: options[:from], finished_before: options[:to], status: :success)
.execute
......@@ -28,8 +35,31 @@ module Gitlab
deployments = deployments.where(project_id: options[:projects]) if options[:projects].present?
deployments.count
end
end
# rubocop: enable CodeReuse/ActiveRecord
def deployment_count_via_dora_api
result = Dora::AggregateMetricsService.new(
container: group,
current_user: options[:current_user],
params: dora_aggregate_metrics_params
).execute
result[:status] == :success ? (result[:data] || 0) : 0
end
def dora_aggregate_metrics_params
params = {
start_date: options[:from].to_date,
end_date: (options[:to] || Date.today).to_date,
interval: 'all',
environment_tier: 'production',
metric: 'deployment_frequency'
}
params[:group_project_ids] = options[:projects] if options[:projects].present?
params
end
end
end
end
......
......@@ -127,13 +127,38 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
end
def create_deployment(args)
project = args[:project]
environment = project.environments.production.first || create(:environment, :production, project: project)
create(:deployment, :success, args.merge(environment: environment))
# this is needed for the dora_deployment_frequency_in_vsa feature flag so we have aggregated data
::Dora::DailyMetrics::RefreshWorker.new.perform(environment.id, Time.current.to_date.to_s)
end
shared_examples 'VSA deployment related metrics' do
describe "#deploys" do
let(:current_time) { Time.current }
let(:one_day_ago) { current_time - 1.day }
let(:two_days_ago) { current_time - 2.days }
let(:five_days_ago) { current_time - 5.days }
let(:ten_days_ago) { current_time - 10.days }
context 'with from date' do
subject { described_class.new(group, options: { from: two_days_ago, current_user: user }).data }
before do
travel_to(5.days.ago) { create(:deployment, :success, project: project, finished_at: Time.zone.now) }
travel_to(5.days.from_now) { create(:deployment, :success, project: project, finished_at: Time.zone.now) }
travel_to(5.days.ago) { create(:deployment, :success, project: project_2, finished_at: Time.zone.now) }
travel_to(5.days.from_now) { create(:deployment, :success, project: project_2, finished_at: Time.zone.now) }
stub_licensed_features(dora4_analytics: true)
travel_to(five_days_ago) do
create_deployment(project: project, finished_at: Time.current)
create_deployment(project: project_2, finished_at: Time.current)
end
travel_to(current_time) do
create_deployment(project: project, finished_at: Time.current)
create_deployment(project: project_2, finished_at: Time.current)
end
end
it "finds the number of deploys made created after it" do
......@@ -148,8 +173,8 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
context 'with subgroups' do
before do
travel_to(5.days.from_now) do
create(:deployment, :success, finished_at: Time.zone.now, project: create(:project, :repository, namespace: create(:group, parent: group)))
travel_to(current_time) do
create_deployment(project: project, finished_at: Time.current)
end
end
......@@ -160,12 +185,12 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
context 'with projects specified in options' do
before do
travel_to(5.days.from_now) do
create(:deployment, :success, finished_at: Time.zone.now, project: create(:project, :repository, namespace: group, name: 'not_applicable'))
travel_to(Date.today) do
create_deployment(finished_at: current_time, project: create(:project, :repository, namespace: group, name: 'not_applicable'))
end
end
subject { described_class.new(group, options: { from: Time.now, current_user: user, projects: [project.id, project_2.id] }).data }
subject { described_class.new(group, options: { from: one_day_ago, current_user: user, projects: [project.id, project_2.id] }).data }
it 'shows deploys from those projects' do
expect(subject.second[:value]).to eq('2')
......@@ -173,7 +198,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
context 'when `from` and `to` parameters are provided' do
subject { described_class.new(group, options: { from: 10.days.ago, to: Time.now, current_user: user }).data }
subject { described_class.new(group, options: { from: ten_days_ago, to: one_day_ago, current_user: user }).data }
it 'finds deployments from 5 days ago' do
expect(subject.second[:value]).to eq('2')
......@@ -183,8 +208,8 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
context 'with other projects' do
before do
travel_to(5.days.from_now) do
create(:deployment, :success, finished_at: Time.zone.now, project: create(:project, :repository, namespace: create(:group)))
travel_to(one_day_ago) do
create_deployment(finished_at: Time.current, project: create(:project, :repository, namespace: create(:group)))
end
end
......@@ -194,7 +219,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
describe '#deployment_frequency' do
let(:from) { 6.days.ago }
let(:from) { ten_days_ago }
let(:to) { nil }
subject do
......@@ -210,8 +235,10 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
before do
travel_to(5.days.ago) do
create(:deployment, :success, finished_at: Time.zone.now, project: project)
stub_licensed_features(dora4_analytics: true)
travel_to(five_days_ago) do
create_deployment(finished_at: Time.current, project: project)
end
end
......@@ -223,12 +250,12 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
context 'when `to` is given' do
let(:from) { 10.days.ago }
let(:from) { ten_days_ago }
let(:to) { 10.days.from_now }
before do
travel_to(5.days.from_now) do
create(:deployment, :success, finished_at: Time.zone.now, project: project)
travel_to(Date.yesterday) do
create_deployment(finished_at: Time.current, project: project)
end
end
......@@ -239,4 +266,25 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
end
end
end
context 'when dora_deployment_frequency_in_vsa feature flag is enabled' do
before do
stub_feature_flags(dora_deployment_frequency_in_vsa: true)
expect(Dora::AggregateMetricsService).to receive(:new).and_call_original
end
it_behaves_like 'VSA deployment related metrics'
end
context 'when dora_deployment_frequency_in_vsa feature flag is disabled' do
before do
stub_feature_flags(dora_deployment_frequency_in_vsa: false)
expect(Dora::AggregateMetricsService).not_to receive(:new)
end
it_behaves_like 'VSA deployment related metrics'
end
end
......@@ -27,8 +27,13 @@ RSpec.describe Analytics::CycleAnalytics::GroupLevel do
describe '#summary' do
before do
stub_licensed_features(dora4_analytics: true)
create_cycle(user, project, issue, mr, milestone, pipeline)
deploy_master(user, project)
environment = project.environments.production.first
::Dora::DailyMetrics::RefreshWorker.new.perform(environment.id, pipeline.created_at.to_date.to_s)
end
it 'returns medians for each stage for a specific group' do
......
......@@ -144,6 +144,15 @@ RSpec.describe Dora::AggregateMetricsService do
expect(subject[:data]).to eq([{ Time.current.to_date.to_s => 1, 'date' => Time.current.to_date.to_s, 'value' => 1 }])
end
end
context 'when group_project_ids parameter is given' do
let(:extra_params) { { interval: Dora::DailyMetrics::INTERVAL_ALL, group_project_ids: [1] } }
it_behaves_like 'request failure' do
let(:message) { 'The group_project_ids parameter is only allowed for a group' }
let(:http_status) { :bad_request }
end
end
end
context 'when container is a group' do
......@@ -196,6 +205,15 @@ RSpec.describe Dora::AggregateMetricsService do
expect(subject[:data]).to eq(3)
end
end
context 'when group_project_ids parameter is given' do
let(:extra_params) { { interval: Dora::DailyMetrics::INTERVAL_ALL, group_project_ids: [project_2.id] } }
it 'returns the aggregated data' do
expect(subject[:status]).to eq(:success)
expect(subject[:data]).to eq(1)
end
end
end
context 'when container is nil' do
......
......@@ -31862,6 +31862,9 @@ msgstr ""
msgid "The group will be placed in 'pending removal' state"
msgstr ""
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment