diff options
Diffstat (limited to 'spec/services')
-rw-r--r-- | spec/services/ci/create_pipeline_service_spec.rb | 223 | ||||
-rw-r--r-- | spec/services/merge_requests/create_service_spec.rb | 72 | ||||
-rw-r--r-- | spec/services/merge_requests/refresh_service_spec.rb | 88 |
3 files changed, 375 insertions, 8 deletions
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index a4582d1bc64..7bc990f05c2 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -18,7 +18,8 @@ describe Ci::CreatePipelineService do message: 'Message', ref: ref_name, trigger_request: nil, - variables_attributes: nil) + variables_attributes: nil, + merge_request: nil) params = { ref: ref, before: '00000000', after: after, @@ -26,7 +27,7 @@ describe Ci::CreatePipelineService do variables_attributes: variables_attributes } described_class.new(project, user, params).execute( - source, trigger_request: trigger_request) + source, trigger_request: trigger_request, merge_request: merge_request) end context 'valid params' do @@ -60,10 +61,10 @@ describe Ci::CreatePipelineService do context 'when merge requests already exist for this source branch' do let(:merge_request_1) do - create(:merge_request, source_branch: 'master', target_branch: "branch_1", source_project: project) + create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project) end let(:merge_request_2) do - create(:merge_request, source_branch: 'master', target_branch: "branch_2", source_project: project) + create(:merge_request, source_branch: 'feature', target_branch: "v1.1.0", source_project: project) end context 'when related merge request is already merged' do @@ -83,7 +84,7 @@ describe Ci::CreatePipelineService do merge_request_1 merge_request_2 - head_pipeline = execute_service + head_pipeline = execute_service(ref: 'feature', after: nil) expect(merge_request_1.reload.head_pipeline).to eq(head_pipeline) expect(merge_request_2.reload.head_pipeline).to eq(head_pipeline) @@ -123,12 +124,12 @@ describe Ci::CreatePipelineService do let!(:target_project) { create(:project, :repository) } it 'updates head pipeline for merge request' do - merge_request = create(:merge_request, source_branch: 'master', - target_branch: "branch_1", + merge_request = create(:merge_request, source_branch: 'feature', + target_branch: "master", source_project: project, target_project: target_project) - head_pipeline = execute_service + head_pipeline = execute_service(ref: 'feature', after: nil) expect(merge_request.reload.head_pipeline).to eq(head_pipeline) end @@ -656,6 +657,212 @@ describe Ci::CreatePipelineService do end end end + + describe 'Merge request pipelines' do + let(:pipeline) do + execute_service(source: source, merge_request: merge_request, ref: ref_name) + end + + before do + stub_ci_pipeline_yaml_file(YAML.dump(config)) + end + + let(:ref_name) { 'feature' } + + context 'when source is merge request' do + let(:source) { :merge_request } + + context "when config has merge_requests keywords" do + let(:config) do + { + build: { + stage: 'build', + script: 'echo' + }, + test: { + stage: 'test', + script: 'echo', + only: ['merge_requests'] + }, + pages: { + stage: 'deploy', + script: 'echo', + except: ['merge_requests'] + } + } + end + + context 'when merge request is specified' do + let(:merge_request) do + create(:merge_request, + source_project: project, + source_branch: ref_name, + target_project: project, + target_branch: 'master') + end + + it 'creates a merge request pipeline' do + expect(pipeline).to be_persisted + expect(pipeline).to be_merge_request + expect(pipeline.merge_request).to eq(merge_request) + expect(pipeline.builds.order(:stage_id).map(&:name)).to eq(%w[test]) + end + + context 'when ref is tag' do + let(:ref_name) { 'v1.1.0' } + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + expect(pipeline.errors[:tag]).to eq(["is not included in the list"]) + end + end + + context 'when merge request is created from a forked project' do + let(:merge_request) do + create(:merge_request, + source_project: project, + source_branch: ref_name, + target_project: target_project, + target_branch: 'master') + end + + let!(:project) { fork_project(target_project, nil, repository: true) } + let!(:target_project) { create(:project, :repository) } + + it 'creates a merge request pipeline in the forked project' do + expect(pipeline).to be_persisted + expect(project.pipelines).to eq([pipeline]) + expect(target_project.pipelines).to be_empty + end + end + + context "when there are no matched jobs" do + let(:config) do + { + test: { + stage: 'test', + script: 'echo', + except: ['merge_requests'] + } + } + end + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + expect(pipeline.errors[:base]).to eq(["No stages / jobs for this pipeline."]) + end + end + end + + context 'when merge request is not specified' do + let(:merge_request) { nil } + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + expect(pipeline.errors[:merge_request]).to eq(["can't be blank"]) + end + end + end + + context "when config does not have merge_requests keywords" do + let(:config) do + { + build: { + stage: 'build', + script: 'echo' + }, + test: { + stage: 'test', + script: 'echo' + }, + pages: { + stage: 'deploy', + script: 'echo' + } + } + end + + context 'when merge request is specified' do + let(:merge_request) do + create(:merge_request, + source_project: project, + source_branch: ref_name, + target_project: project, + target_branch: 'master') + end + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + + expect(pipeline.errors[:base]) + .to eq(['No stages / jobs for this pipeline.']) + end + end + + context 'when merge request is not specified' do + let(:merge_request) { nil } + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + + expect(pipeline.errors[:base]) + .to eq(['No stages / jobs for this pipeline.']) + end + end + end + end + + context 'when source is web' do + let(:source) { :web } + + context "when config has merge_requests keywords" do + let(:config) do + { + build: { + stage: 'build', + script: 'echo' + }, + test: { + stage: 'test', + script: 'echo', + only: ['merge_requests'] + }, + pages: { + stage: 'deploy', + script: 'echo', + except: ['merge_requests'] + } + } + end + + context 'when merge request is specified' do + let(:merge_request) do + create(:merge_request, + source_project: project, + source_branch: ref_name, + target_project: project, + target_branch: 'master') + end + + it 'does not create a merge request pipeline' do + expect(pipeline).not_to be_persisted + expect(pipeline.errors[:merge_request]).to eq(["must be blank"]) + end + end + + context 'when merge request is not specified' do + let(:merge_request) { nil } + + it 'creates a branch pipeline' do + expect(pipeline).to be_persisted + expect(pipeline).to be_web + expect(pipeline.merge_request).to be_nil + expect(pipeline.builds.order(:stage_id).map(&:name)).to eq(%w[build pages]) + end + end + end + end + end end describe '#execute!' do diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index 74bcc15f912..5a3ecb1019b 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -159,6 +159,78 @@ describe MergeRequests::CreateService do end end end + + describe 'Merge request pipelines' do + before do + stub_ci_pipeline_yaml_file(YAML.dump(config)) + end + + context "when .gitlab-ci.yml has merge_requests keywords" do + let(:config) do + { + test: { + stage: 'test', + script: 'echo', + only: ['merge_requests'] + } + } + end + + it 'creates a merge request pipeline and sets it as a head pipeline' do + expect(merge_request).to be_persisted + + merge_request.reload + expect(merge_request.merge_request_pipelines.count).to eq(1) + expect(merge_request.actual_head_pipeline).to be_merge_request + end + + context "when branch pipeline was created before a merge request pipline has been created" do + before do + create(:ci_pipeline, project: merge_request.source_project, + sha: merge_request.diff_head_sha, + ref: merge_request.source_branch, + tag: false) + + merge_request + end + + it 'sets the latest merge request pipeline as the head pipeline' do + expect(merge_request.actual_head_pipeline).to be_merge_request + end + end + + context "when the 'ci_merge_request_pipeline' feature flag is disabled" do + before do + stub_feature_flags(ci_merge_request_pipeline: false) + end + + it 'does not create a merge request pipeline' do + expect(merge_request).to be_persisted + + merge_request.reload + expect(merge_request.merge_request_pipelines.count).to eq(0) + end + end + end + + context "when .gitlab-ci.yml does not have merge_requests keywords" do + let(:config) do + { + test: { + stage: 'test', + script: 'echo' + } + } + end + + it 'does not create a merge request pipeline' do + expect(merge_request).to be_persisted + + merge_request.reload + expect(merge_request.merge_request_pipelines.count).to eq(0) + end + end + end end it_behaves_like 'new issuable record that supports quick actions' do diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index 61c6ba7d550..d29a1091d95 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -132,6 +132,94 @@ describe MergeRequests::RefreshService do end end + describe 'Merge request pipelines' do + before do + stub_ci_pipeline_yaml_file(YAML.dump(config)) + end + + subject { service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') } + + context "when .gitlab-ci.yml has merge_requests keywords" do + let(:config) do + { + test: { + stage: 'test', + script: 'echo', + only: ['merge_requests'] + } + } + end + + it 'create merge request pipeline' do + expect { subject } + .to change { @merge_request.merge_request_pipelines.count }.by(1) + .and change { @fork_merge_request.merge_request_pipelines.count }.by(1) + .and change { @another_merge_request.merge_request_pipelines.count }.by(1) + end + + context "when branch pipeline was created before a merge request pipline has been created" do + before do + create(:ci_pipeline, project: @merge_request.source_project, + sha: @merge_request.diff_head_sha, + ref: @merge_request.source_branch, + tag: false) + + subject + end + + it 'sets the latest merge request pipeline as a head pipeline' do + @merge_request.reload + expect(@merge_request.actual_head_pipeline).to be_merge_request + end + + it 'returns pipelines in correct order' do + @merge_request.reload + expect(@merge_request.all_pipelines.first).to be_merge_request + expect(@merge_request.all_pipelines.second).to be_push + end + end + + context "when MergeRequestUpdateWorker is retried by an exception" do + it 'does not re-create a duplicate merge request pipeline' do + expect do + service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') + end.to change { @merge_request.merge_request_pipelines.count }.by(1) + + expect do + service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') + end.not_to change { @merge_request.merge_request_pipelines.count } + end + end + + context "when the 'ci_merge_request_pipeline' feature flag is disabled" do + before do + stub_feature_flags(ci_merge_request_pipeline: false) + end + + it 'does not create a merge request pipeline' do + expect { subject } + .not_to change { @merge_request.merge_request_pipelines.count } + end + end + end + + context "when .gitlab-ci.yml does not have merge_requests keywords" do + let(:config) do + { + test: { + stage: 'test', + script: 'echo' + } + } + end + + it 'does not create a merge request pipeline' do + expect { subject } + .not_to change { @merge_request.merge_request_pipelines.count } + end + end + end + context 'push to origin repo source branch when an MR was reopened' do let(:refresh_service) { service.new(@project, @user) } let(:notification_service) { spy('notification_service') } |