Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/ci/build_spec.rb')
-rw-r--r--spec/models/ci/build_spec.rb162
1 files changed, 107 insertions, 55 deletions
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 5b07bd8923f..339dffa507f 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -585,6 +585,68 @@ RSpec.describe Ci::Build do
is_expected.to be_falsey
end
end
+
+ context 'with runners_cached_states feature flag enabled' do
+ before do
+ stub_feature_flags(runners_cached_states: true)
+ end
+
+ it 'caches the result in Redis' do
+ expect(Rails.cache).to receive(:fetch).with(['has-online-runners', build.id], expires_in: 1.minute)
+
+ build.any_runners_online?
+ end
+ end
+
+ context 'with runners_cached_states feature flag disabled' do
+ before do
+ stub_feature_flags(runners_cached_states: false)
+ end
+
+ it 'does not cache' do
+ expect(Rails.cache).not_to receive(:fetch).with(['has-online-runners', build.id], expires_in: 1.minute)
+
+ build.any_runners_online?
+ end
+ end
+ end
+
+ describe '#any_runners_available?' do
+ subject { build.any_runners_available? }
+
+ context 'when no runners' do
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when there are runners' do
+ let!(:runner) { create(:ci_runner, :project, projects: [build.project]) }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'with runners_cached_states feature flag enabled' do
+ before do
+ stub_feature_flags(runners_cached_states: true)
+ end
+
+ it 'caches the result in Redis' do
+ expect(Rails.cache).to receive(:fetch).with(['has-available-runners', build.project.id], expires_in: 1.minute)
+
+ build.any_runners_available?
+ end
+ end
+
+ context 'with runners_cached_states feature flag disabled' do
+ before do
+ stub_feature_flags(runners_cached_states: false)
+ end
+
+ it 'does not cache' do
+ expect(Rails.cache).not_to receive(:fetch).with(['has-available-runners', build.project.id], expires_in: 1.minute)
+
+ build.any_runners_available?
+ end
+ end
end
describe '#artifacts?' do
@@ -821,45 +883,6 @@ RSpec.describe Ci::Build do
{ cache: [{ key: "key", paths: ["public"], policy: "pull-push" }] }
end
- context 'with multiple_cache_per_job FF disabled' do
- before do
- stub_feature_flags(multiple_cache_per_job: false)
- end
- let(:options) { { cache: { key: "key", paths: ["public"], policy: "pull-push" } } }
-
- subject { build.cache }
-
- context 'when build has cache' do
- before do
- allow(build).to receive(:options).and_return(options)
- end
-
- context 'when project has jobs_cache_index' do
- before do
- allow_any_instance_of(Project).to receive(:jobs_cache_index).and_return(1)
- end
-
- it { is_expected.to be_an(Array).and all(include(key: "key-1")) }
- end
-
- context 'when project does not have jobs_cache_index' do
- before do
- allow_any_instance_of(Project).to receive(:jobs_cache_index).and_return(nil)
- end
-
- it { is_expected.to eq([options[:cache]]) }
- end
- end
-
- context 'when build does not have cache' do
- before do
- allow(build).to receive(:options).and_return({})
- end
-
- it { is_expected.to eq([]) }
- end
- end
-
subject { build.cache }
context 'when build has cache' do
@@ -1174,6 +1197,8 @@ RSpec.describe Ci::Build do
end
describe 'state transition as a deployable' do
+ subject { build.send(event) }
+
let!(:build) { create(:ci_build, :with_deployment, :start_review_app, project: project, pipeline: pipeline) }
let(:deployment) { build.deployment }
let(:environment) { deployment.environment }
@@ -1188,54 +1213,78 @@ RSpec.describe Ci::Build do
expect(environment.name).to eq('review/master')
end
- context 'when transits to running' do
- before do
- build.run!
+ shared_examples_for 'avoid deadlock' do
+ it 'executes UPDATE in the right order' do
+ recorded = ActiveRecord::QueryRecorder.new { subject }
+
+ index_for_build = recorded.log.index { |l| l.include?("UPDATE \"ci_builds\"") }
+ index_for_deployment = recorded.log.index { |l| l.include?("UPDATE \"deployments\"") }
+
+ expect(index_for_build).to be < index_for_deployment
end
+ end
+
+ context 'when transits to running' do
+ let(:event) { :run! }
+
+ it_behaves_like 'avoid deadlock'
it 'transits deployment status to running' do
+ subject
+
expect(deployment).to be_running
end
end
context 'when transits to success' do
+ let(:event) { :success! }
+
before do
allow(Deployments::UpdateEnvironmentWorker).to receive(:perform_async)
allow(Deployments::ExecuteHooksWorker).to receive(:perform_async)
- build.success!
end
+ it_behaves_like 'avoid deadlock'
+
it 'transits deployment status to success' do
+ subject
+
expect(deployment).to be_success
end
end
context 'when transits to failed' do
- before do
- build.drop!
- end
+ let(:event) { :drop! }
+
+ it_behaves_like 'avoid deadlock'
it 'transits deployment status to failed' do
+ subject
+
expect(deployment).to be_failed
end
end
context 'when transits to skipped' do
- before do
- build.skip!
- end
+ let(:event) { :skip! }
+
+ it_behaves_like 'avoid deadlock'
it 'transits deployment status to skipped' do
+ subject
+
expect(deployment).to be_skipped
end
end
context 'when transits to canceled' do
- before do
- build.cancel!
- end
+ let(:event) { :cancel! }
+
+ it_behaves_like 'avoid deadlock'
it 'transits deployment status to canceled' do
+ subject
+
expect(deployment).to be_canceled
end
end
@@ -2500,6 +2549,7 @@ RSpec.describe Ci::Build do
{ key: 'CI_COMMIT_DESCRIPTION', value: pipeline.git_commit_description, public: true, masked: false },
{ key: 'CI_COMMIT_REF_PROTECTED', value: (!!pipeline.protected_ref?).to_s, public: true, masked: false },
{ key: 'CI_COMMIT_TIMESTAMP', value: pipeline.git_commit_timestamp, public: true, masked: false },
+ { key: 'CI_COMMIT_AUTHOR', value: pipeline.git_author_full_text, public: true, masked: false },
{ key: 'CI_BUILD_REF', value: build.sha, public: true, masked: false },
{ key: 'CI_BUILD_BEFORE_SHA', value: build.before_sha, public: true, masked: false },
{ key: 'CI_BUILD_REF_NAME', value: build.ref, public: true, masked: false },
@@ -3620,10 +3670,10 @@ RSpec.describe Ci::Build do
end
describe 'state transition when build fails' do
- let(:service) { MergeRequests::AddTodoWhenBuildFailsService.new(project, user) }
+ let(:service) { ::MergeRequests::AddTodoWhenBuildFailsService.new(project, user) }
before do
- allow(MergeRequests::AddTodoWhenBuildFailsService).to receive(:new).and_return(service)
+ allow(::MergeRequests::AddTodoWhenBuildFailsService).to receive(:new).and_return(service)
allow(service).to receive(:close)
end
@@ -3708,7 +3758,7 @@ RSpec.describe Ci::Build do
subject.drop!
end
- it 'creates a todo' do
+ it 'creates a todo async', :sidekiq_inline do
project.add_developer(user)
expect_next_instance_of(TodoService) do |todo_service|
@@ -3741,6 +3791,7 @@ RSpec.describe Ci::Build do
describe '.matches_tag_ids' do
let_it_be(:build, reload: true) { create(:ci_build, project: project, user: user) }
+
let(:tag_ids) { ::ActsAsTaggableOn::Tag.named_any(tag_list).ids }
subject { described_class.where(id: build).matches_tag_ids(tag_ids) }
@@ -4192,6 +4243,7 @@ RSpec.describe Ci::Build do
describe '#artifacts_metadata_entry' do
let_it_be(:build) { create(:ci_build, project: project) }
+
let(:path) { 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' }
around do |example|