diff options
Diffstat (limited to 'spec/models/ci/build_spec.rb')
-rw-r--r-- | spec/models/ci/build_spec.rb | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 673b9e5f076..bdaecea2089 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -37,8 +37,6 @@ describe Ci::Build do it { is_expected.to delegate_method(:merge_request_ref?).to(:pipeline) } it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) } - it { is_expected.to include_module(Ci::PipelineDelegator) } - describe 'associations' do it 'has a bidirectional relationship with projects' do expect(described_class.reflect_on_association(:project).has_inverse?).to eq(:builds) @@ -1818,64 +1816,65 @@ describe Ci::Build do end describe '#merge_request' do - def create_mr(build, pipeline, factory: :merge_request, created_at: Time.now) - create(factory, source_project: pipeline.project, - target_project: pipeline.project, - source_branch: build.ref, - created_at: created_at) - end + subject { pipeline.builds.take.merge_request } - context 'when a MR has a reference to the pipeline' do - before do - @merge_request = create_mr(build, pipeline, factory: :merge_request) + context 'on a branch pipeline' do + let!(:pipeline) { create(:ci_pipeline, :with_job, project: project, ref: 'fix') } - commits = [double(id: pipeline.sha)] - allow(@merge_request).to receive(:commits).and_return(commits) - allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request]) + context 'with no merge request' do + it { is_expected.to be_nil } end - it 'returns the single associated MR' do - expect(build.merge_request.id).to eq(@merge_request.id) - end - end + context 'with an open merge request from the same ref name' do + let!(:merge_request) { create(:merge_request, source_project: project, source_branch: 'fix') } - context 'when there is not a MR referencing the pipeline' do - it 'returns nil' do - expect(build.merge_request).to be_nil - end - end + # If no diff exists, the pipeline commit was not part of the merge + # request and may have simply incidentally used the same ref name. + context 'without a merge request diff containing the pipeline commit' do + it { is_expected.to be_nil } + end - context 'when more than one MR have a reference to the pipeline' do - before do - @merge_request = create_mr(build, pipeline, factory: :merge_request) - @merge_request.close! - @merge_request2 = create_mr(build, pipeline, factory: :merge_request) + # If the merge request was truly opened from the branch that the + # pipeline ran on, that head sha will be present in a diff. + context 'with a merge request diff containing the pipeline commit' do + let!(:mr_diff) { create(:merge_request_diff, merge_request: merge_request) } + let!(:mr_diff_commit) { create(:merge_request_diff_commit, sha: build.sha, merge_request_diff: mr_diff) } - commits = [double(id: pipeline.sha)] - allow(@merge_request).to receive(:commits).and_return(commits) - allow(@merge_request2).to receive(:commits).and_return(commits) - allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request, @merge_request2]) + it { is_expected.to eq(merge_request) } + end end - it 'returns the first MR' do - expect(build.merge_request.id).to eq(@merge_request.id) + context 'with multiple open merge requests' do + let!(:merge_request) { create(:merge_request, source_project: project, source_branch: 'fix') } + let!(:mr_diff) { create(:merge_request_diff, merge_request: merge_request) } + let!(:mr_diff_commit) { create(:merge_request_diff_commit, sha: build.sha, merge_request_diff: mr_diff) } + + let!(:new_merge_request) { create(:merge_request, source_project: project, source_branch: 'fix', target_branch: 'staging') } + let!(:new_mr_diff) { create(:merge_request_diff, merge_request: new_merge_request) } + let!(:new_mr_diff_commit) { create(:merge_request_diff_commit, sha: build.sha, merge_request_diff: new_mr_diff) } + + it 'returns the first merge request' do + expect(subject).to eq(merge_request) + end end end - context 'when a Build is created after the MR' do - before do - @merge_request = create_mr(build, pipeline, factory: :merge_request_with_diffs) - pipeline2 = create(:ci_pipeline, project: project) - @build2 = create(:ci_build, pipeline: pipeline2) + context 'on a detached merged request pipeline' do + let(:pipeline) { create(:ci_pipeline, :detached_merge_request_pipeline, :with_job) } - allow(@merge_request).to receive(:commit_shas) - .and_return([pipeline.sha, pipeline2.sha]) - allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request]) - end + it { is_expected.to eq(pipeline.merge_request) } + end - it 'returns the current MR' do - expect(@build2.merge_request.id).to eq(@merge_request.id) - end + context 'on a legacy detached merged request pipeline' do + let(:pipeline) { create(:ci_pipeline, :legacy_detached_merge_request_pipeline, :with_job) } + + it { is_expected.to eq(pipeline.merge_request) } + end + + context 'on a pipeline for merged results' do + let(:pipeline) { create(:ci_pipeline, :merged_result_pipeline, :with_job) } + + it { is_expected.to eq(pipeline.merge_request) } end end @@ -2281,6 +2280,7 @@ describe Ci::Build do { key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true, masked: false }, { key: 'CI_REGISTRY_PASSWORD', value: 'my-token', public: false, masked: true }, { key: 'CI_REPOSITORY_URL', value: build.repo_url, public: false, masked: false }, + { key: 'CI_JOB_JWT', value: 'ci.job.jwt', public: false, masked: true }, { key: 'CI_JOB_NAME', value: 'test', public: true, masked: false }, { key: 'CI_JOB_STAGE', value: 'test', public: true, masked: false }, { key: 'CI_NODE_TOTAL', value: '1', public: true, masked: false }, @@ -2333,23 +2333,36 @@ describe Ci::Build do end before do + allow(Gitlab::Ci::Jwt).to receive(:for_build).with(build).and_return('ci.job.jwt') build.set_token('my-token') build.yaml_variables = [] end it { is_expected.to eq(predefined_variables) } + context 'when ci_job_jwt feature flag is disabled' do + before do + stub_feature_flags(ci_job_jwt: false) + end + + it 'CI_JOB_JWT is not included' do + expect(subject.pluck(:key)).not_to include('CI_JOB_JWT') + end + end + describe 'variables ordering' do context 'when variables hierarchy is stubbed' do let(:build_pre_var) { { key: 'build', value: 'value', public: true, masked: false } } let(:project_pre_var) { { key: 'project', value: 'value', public: true, masked: false } } let(:pipeline_pre_var) { { key: 'pipeline', value: 'value', public: true, masked: false } } let(:build_yaml_var) { { key: 'yaml', value: 'value', public: true, masked: false } } + let(:job_jwt_var) { { key: 'CI_JOB_JWT', value: 'ci.job.jwt', public: false, masked: true } } before do allow(build).to receive(:predefined_variables) { [build_pre_var] } allow(build).to receive(:yaml_variables) { [build_yaml_var] } allow(build).to receive(:persisted_variables) { [] } + allow(build).to receive(:job_jwt_variables) { [job_jwt_var] } allow_any_instance_of(Project) .to receive(:predefined_variables) { [project_pre_var] } @@ -2362,7 +2375,8 @@ describe Ci::Build do it 'returns variables in order depending on resource hierarchy' do is_expected.to eq( - [build_pre_var, + [job_jwt_var, + build_pre_var, project_pre_var, pipeline_pre_var, build_yaml_var, |