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