135 lines
4.5 KiB
Ruby
135 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe ::Ci::CollectAggregatePipelineAnalyticsService, :click_house, :enable_admin_mode,
|
|
feature_category: :fleet_visibility do
|
|
include ClickHouseHelpers
|
|
|
|
include_context 'with pipelines executed on different projects'
|
|
|
|
let(:project) { project1 }
|
|
let(:status_groups) { [:any] }
|
|
let(:duration_percentiles) { [] }
|
|
let(:from_time) { starting_time }
|
|
let(:to_time) { ending_time }
|
|
|
|
let(:service) do
|
|
described_class.new(
|
|
current_user: current_user,
|
|
container: project,
|
|
from_time: from_time,
|
|
to_time: to_time,
|
|
status_groups: status_groups,
|
|
duration_percentiles: duration_percentiles)
|
|
end
|
|
|
|
subject(:result) { service.execute }
|
|
|
|
before do
|
|
insert_ci_pipelines_to_click_house(pipelines)
|
|
end
|
|
|
|
shared_examples 'a service returning aggregate analytics' do
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
where(:status_groups, :duration_percentiles, :expected_aggregate) do
|
|
%i[any] | [] | { count: { any: 8 } }
|
|
%i[any] | [50, 75] | { count: { any: 8 }, duration_statistics: { p50: 30.minutes, p75: 63.75.minutes } }
|
|
%i[any success] | [] | { count: { any: 8, success: 2 } }
|
|
%i[success other] | [] | { count: { success: 2, other: 3 } }
|
|
%i[failed] | [50, 75] |
|
|
{ count: { failed: 2 }, duration_statistics: { p50: 30.minutes, p75: 63.75.minutes } }
|
|
end
|
|
|
|
with_them do
|
|
it 'returns aggregate analytics' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(expected_aggregate)
|
|
end
|
|
end
|
|
|
|
context 'when dates are not specified' do
|
|
let(:from_time) { nil }
|
|
let(:to_time) { nil }
|
|
let(:duration_percentiles) { [50, 99] }
|
|
|
|
context 'and there are pipelines in the last week', time_travel_to: '2023-01-08' do
|
|
it 'returns aggregate analytics from last week' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(
|
|
count: { any: 8 }, duration_statistics: { p50: 30.minutes, p99: 4026.minutes }
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'and there are no pipelines in the last week', time_travel_to: '2023-01-15 00:00:01' do
|
|
it 'returns empty aggregate analytics' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(count: { any: 0 }, duration_statistics: { p50: 0, p99: 0 })
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when requesting statistics starting one second before beginning of week' do
|
|
let(:from_time) { 1.second.before(starting_time) }
|
|
let(:to_time) { 1.second.before(ending_time) }
|
|
|
|
it 'does not include job starting 1 second before start of week' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(count: { any: 8 })
|
|
end
|
|
end
|
|
|
|
context 'when requesting statistics starting one hour before beginning of week' do
|
|
let(:from_time) { 1.hour.before(starting_time) }
|
|
let(:to_time) { 1.second.before(ending_time) }
|
|
|
|
it 'includes job starting 1 second before start of week' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(count: { any: 9 })
|
|
end
|
|
end
|
|
|
|
context 'when requesting statistics that span more than one year' do
|
|
let(:from_time) { (366.days + 1.second).before(starting_time) }
|
|
|
|
it 'returns an error' do
|
|
expect(result.errors).to contain_exactly("Maximum of 366 days can be requested")
|
|
expect(result.error?).to be true
|
|
end
|
|
end
|
|
|
|
context 'when a different project is specified' do
|
|
let(:project) { project2 }
|
|
let(:status_groups) { %i[any success failed] }
|
|
|
|
before do
|
|
insert_ci_pipelines_to_click_house([
|
|
create_pipeline(project2, :failed, 1.week.before(ending_time), 45.minutes)
|
|
])
|
|
end
|
|
|
|
it 'returns aggregate analytics for specified project only' do
|
|
expect(result).to be_success
|
|
expect(result.errors).to eq([])
|
|
expect(result.payload[:aggregate]).to eq(count: { any: 1, success: 0, failed: 1 })
|
|
end
|
|
end
|
|
end
|
|
|
|
it_behaves_like 'a pipeline analytics service'
|
|
it_behaves_like 'a service returning aggregate analytics'
|
|
|
|
context 'when user is an admin' do
|
|
let_it_be(:current_user) { create(:admin) }
|
|
|
|
it_behaves_like 'a service returning aggregate analytics'
|
|
end
|
|
end
|