spec/lib/release_tools/pipeline_tracer/pipeline_spec.rb (324 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
describe ReleaseTools::PipelineTracer::Pipeline do
describe '.from_url' do
it 'create instance' do
instance = described_class.from_url('https://ops.gitlab.net/gitlab-org/release/tools/-/pipelines/1590941')
expect(instance.gitlab_instance).to eq('ops.gitlab.net')
expect(instance.project).to eq('gitlab-org/release/tools')
expect(instance.id).to eq('1590941')
end
end
describe '#details' do
subject(:details) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').details }
let(:pipeline_details) { Gitlab::ObjectifiedHash.new({ kind: 'correct' }) }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline).and_return(pipeline_details)
end
it 'calls pipeline API' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(details).to eq(pipeline_details)
end
end
describe '#bridge_jobs' do
subject(:bridge_jobs) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').bridge_jobs }
let(:pipeline_bridge_jobs) { [Gitlab::ObjectifiedHash.new({ kind: 'correct' })] }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline_bridges).and_return(pipeline_bridge_jobs)
end
it 'calls pipeline bridge API' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline_bridges)
.with('gitlab-org/release/tools', '1590941')
expect(bridge_jobs).to eq(pipeline_bridge_jobs)
end
end
describe '#jobs' do
subject(:jobs) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').jobs }
let(:pipeline_jobs) { [Gitlab::ObjectifiedHash.new({ kind: 'correct' })] }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline_jobs).and_return(pipeline_jobs)
end
it 'calls pipeline jobs API' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline_jobs)
.with('gitlab-org/release/tools', '1590941', { include_retried: true, per_page: 100 })
expect(jobs).to eq(pipeline_jobs)
end
end
describe '#url' do
subject(:url) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').url }
it 'returns URL' do
expect(url).to eq('https://ops.gitlab.net/gitlab-org/release/tools/-/pipelines/1590941')
end
end
describe '#start_time' do
subject(:start_time) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').start_time }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline).and_return(pipeline_details)
end
context 'with started_at available' do
let(:pipeline_details) { Gitlab::ObjectifiedHash.new({ created_at: '2022-12-07T16:21:00.557Z', started_at: '2022-12-07T16:21:03.514Z' }) }
it 'returns started_at' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(start_time).to eq('2022-12-07T16:21:03.514Z')
end
end
context 'with started_at nil' do
let(:pipeline_details) { Gitlab::ObjectifiedHash.new({ created_at: '2022-12-07T16:21:00.557Z', started_at: nil }) }
it 'returns created_at' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(start_time).to eq('2022-12-07T16:21:00.557Z')
end
end
end
describe '#end_time' do
subject(:end_time) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').end_time }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline).and_return(pipeline_details)
end
context 'with complete pipeline' do
let(:pipeline_details) do
build(
:pipeline,
:success,
{
updated_at: '2022-12-07T16:21:00.557Z',
finished_at: '2022-12-07T16:21:03.514Z'
}
)
end
it 'returns finished_at' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(end_time).to eq('2022-12-07T16:21:03.514Z')
end
context 'when finished_at is nil' do
let(:pipeline_details) do
build(
:pipeline,
:success,
{
updated_at: '2022-12-07T16:21:00.557Z',
finished_at: nil
}
)
end
it 'returns updated_at' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(end_time).to eq('2022-12-07T16:21:00.557Z')
end
end
end
context 'with incomplete pipeline' do
let(:pipeline_details) do
build(
:pipeline,
:running,
{
updated_at: '2022-12-07T16:21:00.557Z',
finished_at: '2022-12-07T16:21:03.514Z'
}
)
end
let(:pipeline_jobs) do
[build(:job, :success, finished_at: '2022-12-07T17:21:03Z'), build(:job, finished_at: nil)]
end
let(:pipeline_bridge_jobs) do
[build(:bridge_job, :success, finished_at: '2022-12-07T18:21:03Z'), build(:bridge_job, finished_at: nil)]
end
before do
allow(ReleaseTools::GitlabOpsClient)
.to receive_messages(pipeline_jobs: Gitlab::PaginatedResponse.new(pipeline_jobs), pipeline_bridges: Gitlab::PaginatedResponse.new(pipeline_bridge_jobs))
end
it 'returns last job finished_at' do
expect(end_time).to eq(pipeline_bridge_jobs[0].finished_at)
end
context 'when there are no bridge jobs' do
let(:pipeline_bridge_jobs) { [] }
it 'returns last job finished_at' do
expect(end_time).to eq(pipeline_jobs[0].finished_at)
end
end
context 'with no complete jobs' do
let(:pipeline_bridge_jobs) { [build(:bridge_job, :running, finished_at: nil)] }
let(:pipeline_jobs) do
[build(:job, :running, finished_at: nil), build(:job, finished_at: nil)]
end
it 'returns nil' do
expect(end_time).to be_nil
end
end
context 'with ignored job' do
let(:pipeline_bridge_jobs) { [] }
let(:pipeline_jobs) do
[
build(:job, :success, finished_at: '2022-12-07T17:21:03Z'),
build(:job, name: 'metrics:trace-pipeline', finished_at: '2022-12-07T18:21:03Z')
]
end
it 'returns correct finished_at' do
expect(end_time).to eq(pipeline_jobs[0].finished_at)
end
end
end
end
describe '#valid_finished_at?' do
subject(:pipeline) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941') }
let(:pipeline_details) { build(:pipeline, status) }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline).and_return(pipeline_details)
end
context 'with non completed status' do
let(:status) { 'running' }
it { is_expected.not_to be_valid_finished_at }
end
%w[success failed canceled].each do |status|
let(:status) { status }
context "with #{status} status" do
it { is_expected.to be_valid_finished_at }
end
end
end
describe '#real_time_duration' do
subject(:real_time_duration) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').real_time_duration }
context 'with running pipeline' do
let(:pipeline_details) do
build(
:pipeline,
:running,
{
started_at: '2022-12-07T16:21:00Z',
finished_at: nil
}
)
end
let(:pipeline_jobs) do
[build(:job, :success, finished_at: '2022-12-07T17:21:00Z'), build(:job, finished_at: nil)]
end
let(:pipeline_bridge_jobs) do
[build(:bridge_job, :success, finished_at: '2022-12-07T18:21:00Z'), build(:bridge_job, finished_at: nil)]
end
before do
allow(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
.and_return(pipeline_details)
allow(ReleaseTools::GitlabOpsClient)
.to receive_messages(pipeline_jobs: Gitlab::PaginatedResponse.new(pipeline_jobs), pipeline_bridges: Gitlab::PaginatedResponse.new(pipeline_bridge_jobs))
end
it 'returns duration calculated from latest completed job' do
expect(real_time_duration).to eq(7200.0)
end
end
context 'with finished_at' do
let(:pipeline_details) do
build(
:pipeline,
:success,
{
started_at: '2022-12-07T16:21:00.557Z',
finished_at: '2022-12-07T17:21:00.557Z'
}
)
end
it 'returns duration calculated from finished_at' do
allow(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
.and_return(pipeline_details)
expect(real_time_duration).to eq(3600)
end
end
end
describe '#root_attributes' do
let(:pipeline_details) do
Gitlab::ObjectifiedHash.new({ "id" => 1_590_941,
"iid" => 407_638,
"project_id" => 130,
"sha" => "b1a943132a61095f6284bba885322fc8a5c71309",
"ref" => "15.7.202212071620",
"status" => "success",
"source" => "push",
"created_at" => "2022-12-07T16:21:00.557Z",
"updated_at" => "2022-12-07T22:52:01.402Z",
"web_url" => "https://ops.gitlab.net/gitlab-org/release/tools/-/pipelines/1590941",
"before_sha" => "0000000000000000000000000000000000000000",
"tag" => true,
"yaml_errors" => nil,
"user" =>
{ "id" => 49,
"username" => "gitlab-release-tools-bot",
"name" => "GitLab Release Tools Bot",
"state" => "active",
"avatar_url" => "https://ops.gitlab.net/uploads/-/system/user/avatar/49/avatar.png",
"web_url" => "https://ops.gitlab.net/gitlab-release-tools-bot" },
"started_at" => "2022-12-07T16:21:03.514Z",
"finished_at" => "2022-12-07T22:52:01.395Z",
"committed_at" => nil,
"duration" => 1034,
"queued_duration" => 2,
"coverage" => nil,
"detailed_status" =>
{ "icon" => "status_success",
"text" => "passed",
"label" => "passed",
"group" => "success",
"tooltip" => "passed",
"has_details" => false,
"details_path" => "/gitlab-org/release/tools/-/pipelines/1590941",
"illustration" => nil,
"favicon" => "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png" } })
end
subject(:root_attributes) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').root_attributes }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:pipeline).and_return(pipeline_details)
end
context 'with started_at available' do
it 'returns finished_at' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline)
.with('gitlab-org/release/tools', '1590941')
expect(root_attributes).to eq(
user: "gitlab-release-tools-bot",
web_url: "https://ops.gitlab.net/gitlab-org/release/tools/-/pipelines/1590941",
created_at: "2022-12-07T16:21:00.557Z",
updated_at: "2022-12-07T22:52:01.402Z",
status: "success",
ref: "15.7.202212071620",
duration: 1034,
queued_duration: 2,
started_at: "2022-12-07T16:21:03.514Z",
finished_at: "2022-12-07T22:52:01.395Z"
)
end
end
end
describe 'deploy_environment' do
subject(:deploy_environment) { described_class.new('ops.gitlab.net', 'gitlab-org/release/tools', '1590941').deploy_environment }
it 'calls pipeline_variables' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline_variables)
.with('gitlab-org/release/tools', '1590941')
.and_return([build(:gitlab_response, key: 'DEPLOY_ENVIRONMENT', value: 'gstg-cny')])
expect(deploy_environment).to eq('gstg-cny')
end
context 'when DEPLOY_ENVIRONMENT does not exist' do
it 'calls pipeline_variables' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:pipeline_variables)
.with('gitlab-org/release/tools', '1590941')
.and_return([])
expect(deploy_environment).to be_nil
end
end
end
end