spec/lib/release_tools/pipeline_tracer/job_spec.rb (162 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
describe ReleaseTools::PipelineTracer::Job do
let(:job) do
build(
:job,
name: job_name,
allow_failure: true,
started_at: '2022-12-07T22:51:42.229Z',
finished_at: '2022-12-07T22:52:01.299Z',
duration: 19.069423,
queued_duration: 0.60046,
web_url: 'https://ops.gitlab.net/gitlab-org/release/tools/-/jobs/8694895'
)
end
let(:job_name) { 'job1' }
describe '#completed?' do
subject(:job) { described_class.new(job_attributes, ReleaseTools::GitlabOpsClient) }
let(:job_attributes) { Gitlab::ObjectifiedHash.new(status: status) }
context 'with non completed status' do
let(:status) { 'running' }
it { is_expected.not_to be_completed }
end
%w[success failed canceled].each do |status|
let(:status) { status }
context "with #{status} status" do
it { is_expected.to be_completed }
end
end
end
describe '#root_attributes' do
subject(:root_attributes) { described_class.new(job, ReleaseTools::GitlabOpsClient).root_attributes }
let(:job_attributes) do
{
job_name: job.name,
id: job.id,
web_url: job.web_url,
allow_failure: job.allow_failure,
user: job.user.username,
stage: job.stage,
started_at: job.started_at,
finished_at: job.finished_at,
status: job.status,
duration: job.duration,
queued_duration: job.queued_duration
}.stringify_keys
end
it 'returns root attributes' do
expect(root_attributes).to eq(job_attributes)
end
end
describe '#trace' do
subject(:trace) { described_class.new(job, ReleaseTools::GitlabOpsClient).trace }
let(:job_log) { 'correct' }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:job_trace).and_return(job_log)
allow(ReleaseTools::GitlabDevClient).to receive(:job_trace).and_return(job_log)
allow(ReleaseTools::GitlabClient).to receive(:job_trace).and_return(job_log)
end
it 'calls job_trace API' do
expect(ReleaseTools::GitlabOpsClient)
.to receive(:job_trace)
.with(job.pipeline.project_id, job.id)
expect(trace).to eq(job_log)
end
end
describe '#triggered_pipeline_url' do
subject(:triggered_pipeline_url) { described_class.new(job, ReleaseTools::GitlabOpsClient).triggered_pipeline_url }
let(:job_log) { instance_double(String, match: nil) }
let(:job_name) { 'wait:cng' }
before do
allow(ReleaseTools::GitlabOpsClient).to receive(:job_trace).and_return(job_log)
end
it 'memoizes nil return value' do
expect(job_log).to receive(:match).once
instance = described_class.new(job, ReleaseTools::GitlabOpsClient)
instance.triggered_pipeline_url
expect(instance.triggered_pipeline_url).to be_nil
end
it 'memoizes non-nil return value' do
allow(job_log).to receive(:match).and_return({ pipeline_url: 'url' })
expect(job_log).to receive(:match).once
instance = described_class.new(job, ReleaseTools::GitlabOpsClient)
instance.triggered_pipeline_url
expect(instance.triggered_pipeline_url).to eq('url')
end
context 'with different job name' do
let(:job_name) { 'job1' }
it 'ignores jobs whose names are not in trigger jobs list' do
expect(ReleaseTools::GitlabOpsClient).not_to receive(:job_trace)
expect(triggered_pipeline_url).to be_nil
end
end
context 'with log message from wait:cng' do
let(:job_log) { 'Checking status of pipeline -- {pipeline: "https://dev.gitlab.org/gitlab/omnibus-gitlab/-/pipelines/361107"}' }
it 'returns pipeline URL' do
expect(triggered_pipeline_url).to eq('https://dev.gitlab.org/gitlab/omnibus-gitlab/-/pipelines/361107')
end
end
end
describe '#triggered_downstream_pipeline?' do
subject(:instance) { described_class.new(job, ReleaseTools::GitlabOpsClient) }
let(:triggered_url) { nil }
let(:job_name) { 'wait:cng' }
before do
instance.instance_variable_set(:@triggered_pipeline_url, triggered_url)
end
context 'when triggered_pipeline_url is nil' do
let(:triggered_url) { nil }
it 'returns false' do
expect(instance.triggered_downstream_pipeline?).to be(false)
end
end
context 'when triggered_pipeline_url is not nil' do
let(:triggered_url) { 'url' }
it 'returns false' do
expect(instance.triggered_downstream_pipeline?).to be(true)
end
end
end
describe '#real_time_duration' do
subject(:instance) { described_class.new(job, ReleaseTools::GitlabOpsClient) }
it 'returns job duration' do
expect(instance.real_time_duration).to eq(job.duration)
end
end
describe '#environment_from_name' do
subject(:environment_from_name) { described_class.new(job, ReleaseTools::GitlabOpsClient).environment_from_name }
described_class::VALID_ENVIRONMENTS.each do |env|
context "with #{env} in name" do
let(:job_name) { "qa:smoke-main:#{env}" }
it 'returns environment derived from name' do
expect(environment_from_name).to eq(env)
end
end
end
context 'when name does not contain environment' do
let(:job_name) { 'qa:smoke-main' }
it 'returns nil' do
expect(environment_from_name).to be_nil
end
end
context 'when environment is in beginning of name' do
let(:job_name) { 'gstg-cny-prepare' }
it 'returns environment derived from name' do
expect(environment_from_name).to eq('gstg-cny')
end
end
end
describe '#name_without_environment' do
subject(:name_without_environment) { described_class.new(job, ReleaseTools::GitlabOpsClient).name_without_environment }
let(:job_name) { 'qa:smoke-main:gstg-cny' }
it 'returns job name without environment' do
expect(name_without_environment).to eq('qa:smoke-main:')
end
context 'with no environment in name' do
let(:job_name) { 'qa:smoke-main' }
it 'returns name' do
expect(name_without_environment).to eq(job_name)
end
end
end
end