summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/api/entities/project_import_failed_relation_spec.rb23
-rw-r--r--spec/lib/api/entities/project_import_status_spec.rb49
-rw-r--r--spec/lib/api/entities/user_spec.rb26
-rw-r--r--spec/lib/api/validations/validators/limit_spec.rb25
-rw-r--r--spec/lib/banzai/pipeline_spec.rb64
-rw-r--r--spec/lib/csv_builder_spec.rb109
-rw-r--r--spec/lib/gitlab/application_context_spec.rb12
-rw-r--r--spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/jwt_spec.rb124
-rw-r--r--spec/lib/gitlab/ci/status/bridge/factory_spec.rb72
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb27
-rw-r--r--spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb66
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb90
-rw-r--r--spec/lib/gitlab/data_builder/pipeline_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb6
-rw-r--r--spec/lib/gitlab/diff/formatters/text_formatter_spec.rb3
-rw-r--r--spec/lib/gitlab/diff/highlight_cache_spec.rb52
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb1
-rw-r--r--spec/lib/gitlab/elasticsearch/logs/lines_spec.rb (renamed from spec/lib/gitlab/elasticsearch/logs_spec.rb)2
-rw-r--r--spec/lib/gitlab/elasticsearch/logs/pods_spec.rb35
-rw-r--r--spec/lib/gitlab/file_hook_spec.rb2
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb9
-rw-r--r--spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb (renamed from spec/lib/gitlab/import_export/group/tree_restorer_spec.rb)2
-rw-r--r--spec/lib/gitlab/import_export/project/import_task_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/gitlab/instrumentation_helper_spec.rb10
-rw-r--r--spec/lib/gitlab/json_spec.rb91
-rw-r--r--spec/lib/gitlab/kubernetes/helm/base_command_spec.rb52
-rw-r--r--spec/lib/gitlab/kubernetes/helm/init_command_spec.rb52
-rw-r--r--spec/lib/gitlab/kubernetes/helm/install_command_spec.rb16
-rw-r--r--spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb16
-rw-r--r--spec/lib/gitlab/project_template_spec.rb1
-rw-r--r--spec/lib/gitlab/prometheus/adapter_spec.rb8
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb18
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb13
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb13
-rw-r--r--spec/lib/gitlab/sidekiq_middleware_spec.rb47
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb4
-rw-r--r--spec/lib/gitlab/utils_spec.rb18
-rw-r--r--spec/lib/marginalia_spec.rb30
43 files changed, 975 insertions, 229 deletions
diff --git a/spec/lib/api/entities/project_import_failed_relation_spec.rb b/spec/lib/api/entities/project_import_failed_relation_spec.rb
new file mode 100644
index 00000000000..f8330713480
--- /dev/null
+++ b/spec/lib/api/entities/project_import_failed_relation_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Entities::ProjectImportFailedRelation do
+ describe '#as_json' do
+ subject { entity.as_json }
+
+ let(:import_failure) { build(:import_failure) }
+ let(:entity) { described_class.new(import_failure) }
+
+ it 'includes basic fields', :aggregate_failures do
+ expect(subject).to eq(
+ id: import_failure.id,
+ created_at: import_failure.created_at,
+ exception_class: import_failure.exception_class,
+ exception_message: import_failure.exception_message,
+ relation_name: import_failure.relation_key,
+ source: import_failure.source
+ )
+ end
+ end
+end
diff --git a/spec/lib/api/entities/project_import_status_spec.rb b/spec/lib/api/entities/project_import_status_spec.rb
new file mode 100644
index 00000000000..650f9c156a3
--- /dev/null
+++ b/spec/lib/api/entities/project_import_status_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Entities::ProjectImportStatus do
+ describe '#as_json' do
+ subject { entity.as_json }
+
+ let(:correlation_id) { 'cid' }
+
+ context 'when import has not finished yet' do
+ let(:project) { create(:project, :import_scheduled, import_correlation_id: correlation_id) }
+ let(:entity) { described_class.new(project) }
+
+ it 'includes basic fields and no failures', :aggregate_failures do
+ expect(subject[:import_status]).to eq('scheduled')
+ expect(subject[:correlation_id]).to eq(correlation_id)
+ expect(subject[:import_error]).to be_nil
+ expect(subject[:failed_relations]).to eq([])
+ end
+ end
+
+ context 'when import has finished with failed relations' do
+ let(:project) { create(:project, :import_finished, import_correlation_id: correlation_id) }
+ let(:entity) { described_class.new(project) }
+
+ it 'includes basic fields with failed relations', :aggregate_failures do
+ create(:import_failure, :hard_failure, project: project, correlation_id_value: correlation_id)
+
+ expect(subject[:import_status]).to eq('finished')
+ expect(subject[:correlation_id]).to eq(correlation_id)
+ expect(subject[:import_error]).to be_nil
+ expect(subject[:failed_relations]).not_to be_empty
+ end
+ end
+
+ context 'when import has failed' do
+ let(:project) { create(:project, :import_failed, import_correlation_id: correlation_id, import_last_error: 'error') }
+ let(:entity) { described_class.new(project) }
+
+ it 'includes basic fields with import error', :aggregate_failures do
+ expect(subject[:import_status]).to eq('failed')
+ expect(subject[:correlation_id]).to eq(correlation_id)
+ expect(subject[:import_error]).to eq('error')
+ expect(subject[:failed_relations]).to eq([])
+ end
+ end
+ end
+end
diff --git a/spec/lib/api/entities/user_spec.rb b/spec/lib/api/entities/user_spec.rb
new file mode 100644
index 00000000000..20524b197e0
--- /dev/null
+++ b/spec/lib/api/entities/user_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Entities::User do
+ let(:user) { create(:user) }
+ let(:current_user) { create(:user) }
+
+ subject { described_class.new(user, current_user: current_user).as_json }
+
+ it 'exposes correct attributes' do
+ expect(subject).to include(:bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization, :job_title, :work_information)
+ end
+
+ it 'exposes created_at if the current user can read the user profile' do
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, user).and_return(true)
+
+ expect(subject).to include(:created_at)
+ end
+
+ it 'does not expose created_at if the current user cannot read the user profile' do
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, user).and_return(false)
+
+ expect(subject).not_to include(:created_at)
+ end
+end
diff --git a/spec/lib/api/validations/validators/limit_spec.rb b/spec/lib/api/validations/validators/limit_spec.rb
new file mode 100644
index 00000000000..600f74e1fb2
--- /dev/null
+++ b/spec/lib/api/validations/validators/limit_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Validations::Validators::Limit do
+ include ApiValidatorsHelpers
+
+ subject do
+ described_class.new(['test'], 255, false, scope.new)
+ end
+
+ context 'valid limit param' do
+ it 'does not raise a validation error' do
+ expect_no_validation_error('test' => '123-456')
+ expect_no_validation_error('test' => '00000000-ffff-0000-ffff-000000000000')
+ expect_no_validation_error('test' => "#{'a' * 255}")
+ end
+ end
+
+ context 'longer than limit param' do
+ it 'raises a validation error' do
+ expect_validation_error('test' => "#{'a' * 256}")
+ end
+ end
+end
diff --git a/spec/lib/banzai/pipeline_spec.rb b/spec/lib/banzai/pipeline_spec.rb
new file mode 100644
index 00000000000..eeff7287ff5
--- /dev/null
+++ b/spec/lib/banzai/pipeline_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Banzai::Pipeline do
+ describe '.[]' do
+ subject { described_class[name] }
+
+ shared_examples 'error' do |exception, message|
+ it do
+ expect { subject }.to raise_error(exception, message)
+ end
+ end
+
+ context 'for nil' do
+ let(:name) { nil }
+
+ it { is_expected.to eq(Banzai::Pipeline::FullPipeline) }
+ end
+
+ context 'for symbols' do
+ context 'when known' do
+ let(:name) { :full }
+
+ it { is_expected.to eq(Banzai::Pipeline::FullPipeline) }
+ end
+
+ context 'when unknown' do
+ let(:name) { :unknown }
+
+ it_behaves_like 'error', NameError,
+ 'uninitialized constant Banzai::Pipeline::UnknownPipeline'
+ end
+ end
+
+ context 'for classes' do
+ let(:name) { klass }
+
+ context 'subclassing Banzai::Pipeline::BasePipeline' do
+ let(:klass) { Class.new(Banzai::Pipeline::BasePipeline) }
+
+ it { is_expected.to eq(klass) }
+ end
+
+ context 'subclassing other types' do
+ let(:klass) { Class.new(Banzai::RenderContext) }
+
+ before do
+ stub_const('Foo', klass)
+ end
+
+ it_behaves_like 'error', ArgumentError,
+ 'unsupported pipeline name Foo (Class)'
+ end
+ end
+
+ context 'for other types' do
+ let(:name) { 'label' }
+
+ it_behaves_like 'error', ArgumentError,
+ 'unsupported pipeline name "label" (String)'
+ end
+ end
+end
diff --git a/spec/lib/csv_builder_spec.rb b/spec/lib/csv_builder_spec.rb
new file mode 100644
index 00000000000..0d5e2b81b16
--- /dev/null
+++ b/spec/lib/csv_builder_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe CsvBuilder do
+ let(:object) { double(question: :answer) }
+ let(:fake_relation) { FakeRelation.new([object]) }
+ let(:subject) { described_class.new(fake_relation, 'Q & A' => :question, 'Reversed' => -> (o) { o.question.to_s.reverse }) }
+ let(:csv_data) { subject.render }
+
+ before do
+ stub_const('FakeRelation', Array)
+
+ FakeRelation.class_eval do
+ def find_each(&block)
+ each(&block)
+ end
+ end
+ end
+
+ it 'generates a csv' do
+ expect(csv_data.scan(/(,|\n)/).join).to include ",\n,"
+ end
+
+ it 'uses a temporary file to reduce memory allocation' do
+ expect(CSV).to receive(:new).with(instance_of(Tempfile)).and_call_original
+
+ subject.render
+ end
+
+ it 'counts the number of rows' do
+ subject.render
+
+ expect(subject.rows_written).to eq 1
+ end
+
+ describe 'rows_expected' do
+ it 'uses rows_written if CSV rendered successfully' do
+ subject.render
+
+ expect(fake_relation).not_to receive(:count)
+ expect(subject.rows_expected).to eq 1
+ end
+
+ it 'falls back to calling .count before rendering begins' do
+ expect(subject.rows_expected).to eq 1
+ end
+ end
+
+ describe 'truncation' do
+ let(:big_object) { double(question: 'Long' * 1024) }
+ let(:row_size) { big_object.question.length * 2 }
+ let(:fake_relation) { FakeRelation.new([big_object, big_object, big_object]) }
+
+ it 'occurs after given number of bytes' do
+ expect(subject.render(row_size * 2).length).to be_between(row_size * 2, row_size * 3)
+ expect(subject).to be_truncated
+ expect(subject.rows_written).to eq 2
+ end
+
+ it 'is ignored by default' do
+ expect(subject.render.length).to be > row_size * 3
+ expect(subject.rows_written).to eq 3
+ end
+
+ it 'causes rows_expected to fall back to .count' do
+ subject.render(0)
+
+ expect(fake_relation).to receive(:count).and_call_original
+ expect(subject.rows_expected).to eq 3
+ end
+ end
+
+ it 'avoids loading all data in a single query' do
+ expect(fake_relation).to receive(:find_each)
+
+ subject.render
+ end
+
+ it 'uses hash keys as headers' do
+ expect(csv_data).to start_with 'Q & A'
+ end
+
+ it 'gets data by calling method provided as hash value' do
+ expect(csv_data).to include 'answer'
+ end
+
+ it 'allows lamdas to look up more complicated data' do
+ expect(csv_data).to include 'rewsna'
+ end
+
+ describe 'excel sanitization' do
+ let(:dangerous_title) { double(title: "=cmd|' /C calc'!A0 title", description: "*safe_desc") }
+ let(:dangerous_desc) { double(title: "*safe_title", description: "=cmd|' /C calc'!A0 desc") }
+ let(:fake_relation) { FakeRelation.new([dangerous_title, dangerous_desc]) }
+ let(:subject) { described_class.new(fake_relation, 'Title' => 'title', 'Description' => 'description') }
+ let(:csv_data) { subject.render }
+
+ it 'sanitizes dangerous characters at the beginning of a column' do
+ expect(csv_data).to include "'=cmd|' /C calc'!A0 title"
+ expect(csv_data).to include "'=cmd|' /C calc'!A0 desc"
+ end
+
+ it 'does not sanitize safe symbols at the beginning of a column' do
+ expect(csv_data).not_to include "'*safe_desc"
+ expect(csv_data).not_to include "'*safe_title"
+ end
+ end
+end
diff --git a/spec/lib/gitlab/application_context_spec.rb b/spec/lib/gitlab/application_context_spec.rb
index 0903ca6f9e8..6674ea059a0 100644
--- a/spec/lib/gitlab/application_context_spec.rb
+++ b/spec/lib/gitlab/application_context_spec.rb
@@ -42,6 +42,18 @@ describe Gitlab::ApplicationContext do
end
end
+ describe '.current_context_include?' do
+ it 'returns true if the key was present in the context' do
+ described_class.with_context(caller_id: "Hello") do
+ expect(described_class.current_context_include?(:caller_id)).to be(true)
+ end
+ end
+
+ it 'returns false if the key was not present in the current context' do
+ expect(described_class.current_context_include?(:caller_id)).to be(false)
+ end
+ end
+
describe '#to_lazy_hash' do
let(:user) { build(:user) }
let(:project) { build(:project) }
diff --git a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
index ff8b9dd1005..d4f52a11ce7 100644
--- a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
+++ b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
@@ -79,7 +79,7 @@ describe Gitlab::BackgroundMigration::UserMentions::CreateResourceUserMention, s
context 'migrate commit mentions' do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
- let(:commit) { Commit.new(RepoHelpers.sample_commit, project.becomes(Project)) }
+ let(:commit) { Commit.new(RepoHelpers.sample_commit, project) }
let(:commit_user_mentions) { table(:commit_user_mentions) }
let!(:note1) { notes.create!(commit_id: commit.id, noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: description_mentions) }
diff --git a/spec/lib/gitlab/ci/jwt_spec.rb b/spec/lib/gitlab/ci/jwt_spec.rb
new file mode 100644
index 00000000000..f2897708b08
--- /dev/null
+++ b/spec/lib/gitlab/ci/jwt_spec.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Jwt do
+ let(:namespace) { build_stubbed(:namespace) }
+ let(:project) { build_stubbed(:project, namespace: namespace) }
+ let(:user) { build_stubbed(:user) }
+ let(:pipeline) { build_stubbed(:ci_pipeline, ref: 'auto-deploy-2020-03-19') }
+ let(:build) do
+ build_stubbed(
+ :ci_build,
+ project: project,
+ user: user,
+ pipeline: pipeline
+ )
+ end
+
+ describe '#payload' do
+ subject(:payload) { described_class.new(build, ttl: 30).payload }
+
+ it 'has correct values for the standard JWT attributes' do
+ Timecop.freeze do
+ now = Time.now.to_i
+
+ aggregate_failures do
+ expect(payload[:iss]).to eq(Settings.gitlab.host)
+ expect(payload[:iat]).to eq(now)
+ expect(payload[:exp]).to eq(now + 30)
+ expect(payload[:sub]).to eq("job_#{build.id}")
+ end
+ end
+ end
+
+ it 'has correct values for the custom attributes' do
+ aggregate_failures do
+ expect(payload[:namespace_id]).to eq(namespace.id.to_s)
+ expect(payload[:namespace_path]).to eq(namespace.full_path)
+ expect(payload[:project_id]).to eq(project.id.to_s)
+ expect(payload[:project_path]).to eq(project.full_path)
+ expect(payload[:user_id]).to eq(user.id.to_s)
+ expect(payload[:user_email]).to eq(user.email)
+ expect(payload[:user_login]).to eq(user.username)
+ expect(payload[:pipeline_id]).to eq(pipeline.id.to_s)
+ expect(payload[:job_id]).to eq(build.id.to_s)
+ expect(payload[:ref]).to eq(pipeline.source_ref)
+ end
+ end
+
+ it 'skips user related custom attributes if build has no user assigned' do
+ allow(build).to receive(:user).and_return(nil)
+
+ expect { payload }.not_to raise_error
+ end
+
+ describe 'ref type' do
+ context 'branches' do
+ it 'is "branch"' do
+ expect(payload[:ref_type]).to eq('branch')
+ end
+ end
+
+ context 'tags' do
+ let(:build) { build_stubbed(:ci_build, :on_tag, project: project) }
+
+ it 'is "tag"' do
+ expect(payload[:ref_type]).to eq('tag')
+ end
+ end
+
+ context 'merge requests' do
+ let(:pipeline) { build_stubbed(:ci_pipeline, :detached_merge_request_pipeline) }
+
+ it 'is "branch"' do
+ expect(payload[:ref_type]).to eq('branch')
+ end
+ end
+ end
+
+ describe 'ref_protected' do
+ it 'is false when ref is not protected' do
+ expect(build).to receive(:protected).and_return(false)
+
+ expect(payload[:ref_protected]).to eq('false')
+ end
+
+ it 'is true when ref is protected' do
+ expect(build).to receive(:protected).and_return(true)
+
+ expect(payload[:ref_protected]).to eq('true')
+ end
+ end
+ end
+
+ describe '.for_build' do
+ let(:rsa_key) { OpenSSL::PKey::RSA.new(Rails.application.secrets.openid_connect_signing_key) }
+
+ subject(:jwt) { described_class.for_build(build) }
+
+ it 'generates JWT with key id' do
+ _payload, headers = JWT.decode(jwt, rsa_key.public_key, true, { algorithm: 'RS256' })
+
+ expect(headers['kid']).to eq(rsa_key.public_key.to_jwk['kid'])
+ end
+
+ it 'generates JWT for the given job with ttl equal to build timeout' do
+ expect(build).to receive(:metadata_timeout).and_return(3_600)
+
+ payload, _headers = JWT.decode(jwt, rsa_key.public_key, true, { algorithm: 'RS256' })
+ ttl = payload["exp"] - payload["iat"]
+
+ expect(ttl).to eq(3_600)
+ end
+
+ it 'generates JWT for the given job with default ttl if build timeout is not set' do
+ expect(build).to receive(:metadata_timeout).and_return(nil)
+
+ payload, _headers = JWT.decode(jwt, rsa_key.public_key, true, { algorithm: 'RS256' })
+ ttl = payload["exp"] - payload["iat"]
+
+ expect(ttl).to eq(5.minutes.to_i)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/status/bridge/factory_spec.rb b/spec/lib/gitlab/ci/status/bridge/factory_spec.rb
new file mode 100644
index 00000000000..1f417781988
--- /dev/null
+++ b/spec/lib/gitlab/ci/status/bridge/factory_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Status::Bridge::Factory do
+ let(:user) { create(:user) }
+ let(:project) { bridge.project }
+ let(:status) { factory.fabricate! }
+ let(:factory) { described_class.new(bridge, user) }
+
+ before do
+ stub_not_protect_default_branch
+
+ project.add_developer(user)
+ end
+
+ context 'when bridge is created' do
+ let(:bridge) { create(:ci_bridge) }
+
+ it 'matches correct core status' do
+ expect(factory.core_status).to be_a Gitlab::Ci::Status::Created
+ end
+
+ it 'fabricates status with correct details' do
+ expect(status.text).to eq s_('CiStatusText|created')
+ expect(status.icon).to eq 'status_created'
+ expect(status.favicon).to eq 'favicon_status_created'
+ expect(status.label).to be_nil
+ expect(status).not_to have_details
+ expect(status).not_to have_action
+ end
+ end
+
+ context 'when bridge is failed' do
+ let(:bridge) { create(:ci_bridge, :failed) }
+
+ it 'matches correct core status' do
+ expect(factory.core_status).to be_a Gitlab::Ci::Status::Failed
+ end
+
+ it 'matches correct extended statuses' do
+ expect(factory.extended_statuses)
+ .to eq [Gitlab::Ci::Status::Bridge::Failed]
+ end
+
+ it 'fabricates a failed bridge status' do
+ expect(status).to be_a Gitlab::Ci::Status::Bridge::Failed
+ end
+
+ it 'fabricates status with correct details' do
+ expect(status.text).to eq s_('CiStatusText|failed')
+ expect(status.icon).to eq 'status_failed'
+ expect(status.favicon).to eq 'favicon_status_failed'
+ expect(status.label).to be_nil
+ expect(status.status_tooltip).to eq "#{s_('CiStatusText|failed')} - (unknown failure)"
+ expect(status).not_to have_details
+ expect(status).not_to have_action
+ end
+
+ context 'failed with downstream_pipeline_creation_failed' do
+ before do
+ bridge.failure_reason = 'downstream_pipeline_creation_failed'
+ end
+
+ it 'fabricates correct status_tooltip' do
+ expect(status.status_tooltip).to eq(
+ "#{s_('CiStatusText|failed')} - (downstream pipeline can not be created)"
+ )
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index adbd7eabd18..bfd9980ee9c 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -49,20 +49,16 @@ describe Gitlab::CurrentSettings do
end
end
- context 'with DB unavailable' do
- context 'and settings in cache' do
- include_context 'with settings in cache'
-
- it 'fetches the settings from cache without issuing any query' do
- expect(ActiveRecord::QueryRecorder.new { described_class.current_application_settings }.count).to eq(0)
- end
+ context 'in a Rake task with DB unavailable' do
+ before do
+ allow(Gitlab::Runtime).to receive(:rake?).and_return(true)
+ # For some reason, `allow(described_class).to receive(:connect_to_db?).and_return(false)` causes issues
+ # during the initialization phase of the test suite, so instead let's mock the internals of it
+ allow(ActiveRecord::Base.connection).to receive(:active?).and_return(false)
end
context 'and no settings in cache' do
before do
- # For some reason, `allow(described_class).to receive(:connect_to_db?).and_return(false)` causes issues
- # during the initialization phase of the test suite, so instead let's mock the internals of it
- allow(ActiveRecord::Base.connection).to receive(:active?).and_return(false)
expect(ApplicationSetting).not_to receive(:current)
end
@@ -185,17 +181,6 @@ describe Gitlab::CurrentSettings do
expect(described_class.current_application_settings).to eq(:current_settings)
end
end
-
- context 'when the application_settings table does not exist' do
- it 'returns a FakeApplicationSettings object' do
- expect(Gitlab::Database)
- .to receive(:cached_table_exists?)
- .with('application_settings')
- .and_return(false)
-
- expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings)
- end
- end
end
end
end
diff --git a/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb
index 664009f140f..2242895f8ea 100644
--- a/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb
@@ -20,7 +20,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "finds the number of issues created after it" do
- expect(subject.first[:value]).to eq(2)
+ expect(subject.first[:value]).to eq('2')
end
context 'with subgroups' do
@@ -29,7 +29,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "finds issues from them" do
- expect(subject.first[:value]).to eq(3)
+ expect(subject.first[:value]).to eq('3')
end
end
@@ -41,7 +41,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
subject { described_class.new(group, options: { from: Time.now, current_user: user, projects: [project.id, project_2.id] }).data }
it 'finds issues from those projects' do
- expect(subject.first[:value]).to eq(2)
+ expect(subject.first[:value]).to eq('2')
end
end
@@ -49,7 +49,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
subject { described_class.new(group, options: { from: 10.days.ago, to: Time.now, current_user: user }).data }
it 'finds issues from 5 days ago' do
- expect(subject.first[:value]).to eq(2)
+ expect(subject.first[:value]).to eq('2')
end
end
end
@@ -62,7 +62,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "doesn't find issues from them" do
- expect(subject.first[:value]).to eq(2)
+ expect(subject.first[:value]).to eq('2')
end
end
end
@@ -77,7 +77,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "finds the number of deploys made created after it" do
- expect(subject.second[:value]).to eq(2)
+ expect(subject.second[:value]).to eq('2')
end
context 'with subgroups' do
@@ -88,7 +88,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "finds deploys from them" do
- expect(subject.second[:value]).to eq(3)
+ expect(subject.second[:value]).to eq('3')
end
end
@@ -102,7 +102,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
subject { described_class.new(group, options: { from: Time.now, current_user: user, projects: [project.id, project_2.id] }).data }
it 'shows deploys from those projects' do
- expect(subject.second[:value]).to eq(2)
+ expect(subject.second[:value]).to eq('2')
end
end
@@ -110,7 +110,7 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
subject { described_class.new(group, options: { from: 10.days.ago, to: Time.now, current_user: user }).data }
it 'finds deployments from 5 days ago' do
- expect(subject.second[:value]).to eq(2)
+ expect(subject.second[:value]).to eq('2')
end
end
end
@@ -123,7 +123,53 @@ describe Gitlab::CycleAnalytics::GroupStageSummary do
end
it "doesn't find deploys from them" do
- expect(subject.second[:value]).to eq(0)
+ expect(subject.second[:value]).to eq('-')
+ end
+ end
+ end
+
+ describe '#deployment_frequency' do
+ let(:from) { 6.days.ago }
+ let(:to) { nil }
+
+ subject do
+ described_class.new(group, options: {
+ from: from,
+ to: to,
+ current_user: user
+ }).data.third
+ end
+
+ it 'includes the unit: `per day`' do
+ expect(subject[:unit]).to eq(_('per day'))
+ end
+
+ before do
+ Timecop.freeze(5.days.ago) do
+ create(:deployment, :success, project: project)
+ end
+ end
+
+ context 'when `to` is nil' do
+ it 'includes range until now' do
+ # 1 deployment over 7 days
+ expect(subject[:value]).to eq('0.1')
+ end
+ end
+
+ context 'when `to` is given' do
+ let(:from) { 10.days.ago }
+ let(:to) { 10.days.from_now }
+
+ before do
+ Timecop.freeze(5.days.from_now) do
+ create(:deployment, :success, project: project)
+ end
+ end
+
+ it 'returns deployment frequency within `from` and `to` range' do
+ # 2 deployments over 20 days
+ expect(subject[:value]).to eq('0.1')
end
end
end
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index 94edef20296..a86278871ff 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -20,13 +20,13 @@ describe Gitlab::CycleAnalytics::StageSummary do
Timecop.freeze(5.days.ago) { create(:issue, project: project) }
Timecop.freeze(5.days.from_now) { create(:issue, project: project) }
- expect(subject).to eq(1)
+ expect(subject).to eq('1')
end
it "doesn't find issues from other projects" do
Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project)) }
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
context 'when `to` parameter is given' do
@@ -38,14 +38,14 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
- expect(subject).to eq(2)
+ expect(subject).to eq('2')
end
end
end
@@ -57,19 +57,19 @@ describe Gitlab::CycleAnalytics::StageSummary do
Timecop.freeze(5.days.ago) { create_commit("Test message", project, user, 'master') }
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master') }
- expect(subject).to eq(1)
+ expect(subject).to eq('1')
end
it "doesn't find commits from other projects" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", create(:project, :repository), user, 'master') }
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
- it "finds a large (> 100) snumber of commits if present" do
+ it "finds a large (> 100) number of commits if present" do
Timecop.freeze(5.days.from_now) { create_commit("Test message", project, user, 'master', count: 100) }
- expect(subject).to eq(100)
+ expect(subject).to eq('100')
end
context 'when `to` parameter is given' do
@@ -81,14 +81,14 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
- expect(subject).to eq(2)
+ expect(subject).to eq('2')
end
end
@@ -118,7 +118,7 @@ describe Gitlab::CycleAnalytics::StageSummary do
Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
- expect(subject).to eq(1)
+ expect(subject).to eq('1')
end
it "doesn't find commits from other projects" do
@@ -126,7 +126,7 @@ describe Gitlab::CycleAnalytics::StageSummary do
create(:deployment, :success, project: create(:project, :repository))
end
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
context 'when `to` parameter is given' do
@@ -138,14 +138,76 @@ describe Gitlab::CycleAnalytics::StageSummary do
it "doesn't find any record" do
options[:to] = Time.now
- expect(subject).to eq(0)
+ expect(subject).to eq('-')
end
it "finds records created between `from` and `to` range" do
options[:from] = 10.days.ago
options[:to] = 10.days.from_now
- expect(subject).to eq(2)
+ expect(subject).to eq('2')
+ end
+ end
+ end
+
+ describe '#deployment_frequency' do
+ subject { stage_summary.fourth[:value] }
+
+ it 'includes the unit: `per day`' do
+ expect(stage_summary.fourth[:unit]).to eq _('per day')
+ end
+
+ before do
+ Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) }
+ end
+
+ it 'returns 0.0 when there were deploys but the frequency was too low' do
+ options[:from] = 30.days.ago
+
+ # 1 deployment over 30 days
+ # frequency of 0.03, rounded off to 0.0
+ expect(subject).to eq('0')
+ end
+
+ it 'returns `-` when there were no deploys' do
+ options[:from] = 4.days.ago
+
+ # 0 deployment in the last 4 days
+ expect(subject).to eq('-')
+ end
+
+ context 'when `to` is nil' do
+ it 'includes range until now' do
+ options[:from] = 6.days.ago
+ options[:to] = nil
+
+ # 1 deployment over 7 days
+ expect(subject).to eq('0.1')
+ end
+ end
+
+ context 'when `to` is given' do
+ before do
+ Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) }
+ end
+
+ it 'finds records created between `from` and `to` range' do
+ options[:from] = 10.days.ago
+ options[:to] = 10.days.from_now
+
+ # 2 deployments over 20 days
+ expect(subject).to eq('0.1')
+ end
+
+ context 'when `from` and `to` are within a day' do
+ it 'returns the number of deployments made on that day' do
+ Timecop.freeze(Time.now) do
+ create(:deployment, :success, project: project)
+ options[:from] = options[:to] = Time.now
+
+ expect(subject).to eq('1')
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/data_builder/pipeline_spec.rb b/spec/lib/gitlab/data_builder/pipeline_spec.rb
index da22da8de0f..519f5873d75 100644
--- a/spec/lib/gitlab/data_builder/pipeline_spec.rb
+++ b/spec/lib/gitlab/data_builder/pipeline_spec.rb
@@ -83,7 +83,7 @@ describe Gitlab::DataBuilder::Pipeline do
expect(merge_request_attrs[:target_branch]).to eq(merge_request.target_branch)
expect(merge_request_attrs[:target_project_id]).to eq(merge_request.target_project_id)
expect(merge_request_attrs[:state]).to eq(merge_request.state)
- expect(merge_request_attrs[:merge_status]).to eq(merge_request.merge_status)
+ expect(merge_request_attrs[:merge_status]).to eq(merge_request.public_merge_status)
expect(merge_request_attrs[:url]).to eq("http://localhost/#{merge_request.target_project.full_path}/-/merge_requests/#{merge_request.iid}")
end
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 3db9320c021..3a0148615b9 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -215,6 +215,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'ON DELETE statements' do
context 'on_delete: :nullify' do
it 'appends ON DELETE SET NULL statement' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/)
@@ -230,6 +231,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'on_delete: :cascade' do
it 'appends ON DELETE CASCADE statement' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/)
@@ -245,6 +247,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'on_delete: nil' do
it 'appends no ON DELETE statement' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/)
@@ -261,6 +264,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'when no custom key name is supplied' do
it 'creates a concurrent foreign key and validates it' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/NOT VALID/)
@@ -287,6 +291,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'when a custom key name is supplied' do
context 'for creating a new foreign key for a column that does not presently exist' do
it 'creates a new foreign key' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/NOT VALID/)
@@ -314,6 +319,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'when the supplied key name is different from the existing foreign key name' do
it 'creates a new foreign key' do
+ expect(model).to receive(:with_lock_retries).and_call_original
expect(model).to receive(:disable_statement_timeout).and_call_original
expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/NOT VALID/)
diff --git a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
index 33d4994f5db..e275ebef2c9 100644
--- a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
@@ -9,7 +9,8 @@ describe Gitlab::Diff::Formatters::TextFormatter do
start_sha: 456,
head_sha: 789,
old_path: 'old_path.txt',
- new_path: 'new_path.txt'
+ new_path: 'new_path.txt',
+ line_range: nil
}
end
diff --git a/spec/lib/gitlab/diff/highlight_cache_spec.rb b/spec/lib/gitlab/diff/highlight_cache_spec.rb
index a16e5e185bb..3c128aad976 100644
--- a/spec/lib/gitlab/diff/highlight_cache_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_cache_spec.rb
@@ -113,7 +113,7 @@ describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
allow(redis).to receive(:info).and_return({ "redis_version" => "3.0.0" })
expect(described_class.gitlab_redis_diff_caching_memory_usage_bytes)
- .not_to receive(:observe).and_call_original
+ .not_to receive(:observe)
cache.send(:write_to_redis_hash, diff_hash)
end
@@ -163,6 +163,56 @@ describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
end
end
+ describe "GZip usage" do
+ let(:diff_file) do
+ diffs = merge_request.diffs
+ raw_diff = diffs.diffable.raw_diffs(diffs.diff_options.merge(paths: ['CHANGELOG'])).first
+ Gitlab::Diff::File.new(raw_diff,
+ repository: diffs.project.repository,
+ diff_refs: diffs.diff_refs,
+ fallback_diff_refs: diffs.fallback_diff_refs)
+ end
+
+ context "feature flag :gzip_diff_cache disabled" do
+ before do
+ stub_feature_flags(gzip_diff_cache: true)
+ end
+
+ it "uses ActiveSupport::Gzip when reading from the cache" do
+ expect(ActiveSupport::Gzip).to receive(:decompress).at_least(:once).and_call_original
+
+ cache.write_if_empty
+ cache.decorate(diff_file)
+ end
+
+ it "uses ActiveSupport::Gzip to compress data when writing to cache" do
+ expect(ActiveSupport::Gzip).to receive(:compress).and_call_original
+
+ cache.send(:write_to_redis_hash, diff_hash)
+ end
+ end
+
+ context "feature flag :gzip_diff_cache disabled" do
+ before do
+ stub_feature_flags(gzip_diff_cache: false)
+ end
+
+ it "doesn't use ActiveSupport::Gzip when reading from the cache" do
+ expect(ActiveSupport::Gzip).not_to receive(:decompress)
+
+ cache.write_if_empty
+ cache.decorate(diff_file)
+ end
+
+ it "doesn't use ActiveSupport::Gzip to compress data when writing to cache" do
+ expect(ActiveSupport::Gzip).not_to receive(:compress)
+
+ expect { cache.send(:write_to_redis_hash, diff_hash) }
+ .to change { Gitlab::Redis::Cache.with { |r| r.hgetall(cache_key) } }
+ end
+ end
+ end
+
describe 'metrics' do
it 'defines :gitlab_redis_diff_caching_memory_usage_bytes histogram' do
expect(described_class).to respond_to(:gitlab_redis_diff_caching_memory_usage_bytes)
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index 4b11ff16c38..a83c0f35d92 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -28,6 +28,7 @@ describe Gitlab::Diff::Position do
new_path: "files/ruby/popen.rb",
old_line: nil,
new_line: 14,
+ line_range: nil,
base_sha: nil,
head_sha: nil,
start_sha: nil,
diff --git a/spec/lib/gitlab/elasticsearch/logs_spec.rb b/spec/lib/gitlab/elasticsearch/logs/lines_spec.rb
index 6b9d1dbef99..8b6a19fa2c5 100644
--- a/spec/lib/gitlab/elasticsearch/logs_spec.rb
+++ b/spec/lib/gitlab/elasticsearch/logs/lines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::Elasticsearch::Logs do
+describe Gitlab::Elasticsearch::Logs::Lines do
let(:client) { Elasticsearch::Transport::Client }
let(:es_message_1) { { timestamp: "2019-12-13T14:35:34.034Z", pod: "production-6866bc8974-m4sk4", message: "10.8.2.1 - - [25/Oct/2019:08:03:22 UTC] \"GET / HTTP/1.1\" 200 13" } }
diff --git a/spec/lib/gitlab/elasticsearch/logs/pods_spec.rb b/spec/lib/gitlab/elasticsearch/logs/pods_spec.rb
new file mode 100644
index 00000000000..0a4ab0780c5
--- /dev/null
+++ b/spec/lib/gitlab/elasticsearch/logs/pods_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Elasticsearch::Logs::Pods do
+ let(:client) { Elasticsearch::Transport::Client }
+
+ let(:es_query) { JSON.parse(fixture_file('lib/elasticsearch/pods_query.json'), symbolize_names: true) }
+ let(:es_response) { JSON.parse(fixture_file('lib/elasticsearch/pods_response.json')) }
+ let(:namespace) { "autodevops-deploy-9-production" }
+
+ subject { described_class.new(client) }
+
+ describe '#pods' do
+ it 'returns the pods' do
+ expect(client).to receive(:search).with(body: es_query).and_return(es_response)
+
+ result = subject.pods(namespace)
+ expect(result).to eq([
+ {
+ name: "runner-gitlab-runner-7bbfb5dcb5-p6smb",
+ container_names: %w[runner-gitlab-runner]
+ },
+ {
+ name: "elastic-stack-elasticsearch-master-1",
+ container_names: %w[elasticsearch chown sysctl]
+ },
+ {
+ name: "ingress-nginx-ingress-controller-76449bcc8d-8qgl6",
+ container_names: %w[nginx-ingress-controller]
+ }
+ ])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/file_hook_spec.rb b/spec/lib/gitlab/file_hook_spec.rb
index d184eb483d4..fda3583289b 100644
--- a/spec/lib/gitlab/file_hook_spec.rb
+++ b/spec/lib/gitlab/file_hook_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Gitlab::FileHook do
- let(:file_hook) { Rails.root.join('plugins', 'test.rb') }
+ let(:file_hook) { Rails.root.join('file_hooks', 'test.rb') }
let(:tmp_file) { Tempfile.new('file_hook-dump') }
let(:file_hook_source) do
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index b03c1feb429..2c6aee58326 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -19,6 +19,15 @@ describe Gitlab::GitalyClient do
})
end
+ describe '.query_time', :request_store do
+ it 'increments query times' do
+ subject.query_time += 0.451
+ subject.query_time += 0.322
+
+ expect(subject.query_time).to eq(0.773)
+ end
+ end
+
describe '.long_timeout' do
context 'default case' do
it { expect(subject.long_timeout).to eq(6.hours) }
diff --git a/spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb b/spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb
index 6f20b8877e0..09ba4b89a1a 100644
--- a/spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb
+++ b/spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb
@@ -21,7 +21,7 @@ describe Gitlab::GrapeLogging::Loggers::PerfLogger do
payload = subject.parameters(mock_request, nil)
expect(payload[:redis_calls]).to eq(1)
- expect(payload[:redis_duration_ms]).to be >= 0
+ expect(payload[:redis_duration_s]).to be >= 0
end
end
end
diff --git a/spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb b/spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb
index c0762e9892b..17c0659327d 100644
--- a/spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb
+++ b/spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb
@@ -25,11 +25,11 @@ describe Gitlab::GrapeLogging::Loggers::QueueDurationLogger do
)
end
- it 'returns the correct duration in ms' do
+ it 'returns the correct duration in seconds' do
Timecop.freeze(start_time) do
subject.before
- expect(subject.parameters(mock_request, nil)).to eq( { 'queue_duration': 1.hour.to_f * 1000 })
+ expect(subject.parameters(mock_request, nil)).to eq( { 'queue_duration_s': 1.hour.to_f })
end
end
end
diff --git a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb
index fc7e4737d13..3030cdf4cf8 100644
--- a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::ImportExport::Group::TreeRestorer do
+describe Gitlab::ImportExport::Group::LegacyTreeRestorer do
include ImportExport::CommonUtil
let(:shared) { Gitlab::ImportExport::Shared.new(group) }
diff --git a/spec/lib/gitlab/import_export/project/import_task_spec.rb b/spec/lib/gitlab/import_export/project/import_task_spec.rb
index f7b9cbaa095..4f4fcd3ad8a 100644
--- a/spec/lib/gitlab/import_export/project/import_task_spec.rb
+++ b/spec/lib/gitlab/import_export/project/import_task_spec.rb
@@ -2,7 +2,7 @@
require 'rake_helper'
-describe Gitlab::ImportExport::Project::ImportTask do
+describe Gitlab::ImportExport::Project::ImportTask, :request_store do
let(:username) { 'root' }
let(:namespace_path) { username }
let!(:user) { create(:user, username: username) }
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index 80ae9a08257..04e8bd05666 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -6,7 +6,7 @@ def match_mr1_note(content_regex)
MergeRequest.find_by(title: 'MR1').notes.select { |n| n.note.match(/#{content_regex}/)}.first
end
-describe Gitlab::ImportExport::Project::TreeRestorer, quarantine: { flaky: 'https://gitlab.com/gitlab-org/gitlab/-/issues/213793' } do
+describe Gitlab::ImportExport::Project::TreeRestorer do
include ImportExport::CommonUtil
let(:shared) { project.import_export_shared }
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 55b907fff7c..88d7fdaef36 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -595,6 +595,7 @@ ProjectFeature:
- builds_access_level
- repository_access_level
- pages_access_level
+- metrics_dashboard_access_level
- created_at
- updated_at
ProtectedBranch::MergeAccessLevel:
@@ -811,6 +812,7 @@ ContainerExpirationPolicy:
- next_run_at
- project_id
- name_regex
+- name_regex_keep
- cadence
- older_than
- keep_n
diff --git a/spec/lib/gitlab/instrumentation_helper_spec.rb b/spec/lib/gitlab/instrumentation_helper_spec.rb
index 9788c9f4a3c..858fa044a52 100644
--- a/spec/lib/gitlab/instrumentation_helper_spec.rb
+++ b/spec/lib/gitlab/instrumentation_helper_spec.rb
@@ -26,7 +26,7 @@ describe Gitlab::InstrumentationHelper do
subject
expect(payload[:gitaly_calls]).to eq(1)
- expect(payload[:gitaly_duration]).to be >= 0
+ expect(payload[:gitaly_duration_s]).to be >= 0
expect(payload[:redis_calls]).to be_nil
expect(payload[:redis_duration_ms]).to be_nil
end
@@ -39,7 +39,7 @@ describe Gitlab::InstrumentationHelper do
subject
expect(payload[:redis_calls]).to eq(1)
- expect(payload[:redis_duration_ms]).to be >= 0
+ expect(payload[:redis_duration_s]).to be >= 0
expect(payload[:gitaly_calls]).to be_nil
expect(payload[:gitaly_duration]).to be_nil
end
@@ -49,12 +49,12 @@ describe Gitlab::InstrumentationHelper do
describe '.queue_duration_for_job' do
where(:enqueued_at, :created_at, :time_now, :expected_duration) do
"2019-06-01T00:00:00.000+0000" | nil | "2019-06-01T02:00:00.000+0000" | 2.hours.to_f
- "2019-06-01T02:00:00.000+0000" | nil | "2019-06-01T02:00:00.001+0000" | 0.001
+ "2019-06-01T02:00:00.000+0000" | nil | "2019-06-01T02:00:00.001+0000" | 0.0
"2019-06-01T02:00:00.000+0000" | "2019-05-01T02:00:00.000+0000" | "2019-06-01T02:00:01.000+0000" | 1
- nil | "2019-06-01T02:00:00.000+0000" | "2019-06-01T02:00:00.001+0000" | 0.001
+ nil | "2019-06-01T02:00:00.000+0000" | "2019-06-01T02:00:00.001+0000" | 0.0
nil | nil | "2019-06-01T02:00:00.001+0000" | nil
"2019-06-01T02:00:00.000+0200" | nil | "2019-06-01T02:00:00.000-0200" | 4.hours.to_f
- 1571825569.998168 | nil | "2019-10-23T12:13:16.000+0200" | 26.001832
+ 1571825569.998168 | nil | "2019-10-23T12:13:16.000+0200" | 26.00
1571825569 | nil | "2019-10-23T12:13:16.000+0200" | 27
"invalid_date" | nil | "2019-10-23T12:13:16.000+0200" | nil
"" | nil | "2019-10-23T12:13:16.000+0200" | nil
diff --git a/spec/lib/gitlab/json_spec.rb b/spec/lib/gitlab/json_spec.rb
new file mode 100644
index 00000000000..5186ab041da
--- /dev/null
+++ b/spec/lib/gitlab/json_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Gitlab::Json do
+ describe ".parse" do
+ it "parses an object" do
+ expect(subject.parse('{ "foo": "bar" }')).to eq({ "foo" => "bar" })
+ end
+
+ it "parses an array" do
+ expect(subject.parse('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }])
+ end
+
+ it "raises an error on a string" do
+ expect { subject.parse('"foo"') }.to raise_error(JSON::ParserError)
+ end
+
+ it "raises an error on a true bool" do
+ expect { subject.parse("true") }.to raise_error(JSON::ParserError)
+ end
+
+ it "raises an error on a false bool" do
+ expect { subject.parse("false") }.to raise_error(JSON::ParserError)
+ end
+ end
+
+ describe ".parse!" do
+ it "parses an object" do
+ expect(subject.parse!('{ "foo": "bar" }')).to eq({ "foo" => "bar" })
+ end
+
+ it "parses an array" do
+ expect(subject.parse!('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }])
+ end
+
+ it "raises an error on a string" do
+ expect { subject.parse!('"foo"') }.to raise_error(JSON::ParserError)
+ end
+
+ it "raises an error on a true bool" do
+ expect { subject.parse!("true") }.to raise_error(JSON::ParserError)
+ end
+
+ it "raises an error on a false bool" do
+ expect { subject.parse!("false") }.to raise_error(JSON::ParserError)
+ end
+ end
+
+ describe ".dump" do
+ it "dumps an object" do
+ expect(subject.dump({ "foo" => "bar" })).to eq('{"foo":"bar"}')
+ end
+
+ it "dumps an array" do
+ expect(subject.dump([{ "foo" => "bar" }])).to eq('[{"foo":"bar"}]')
+ end
+
+ it "dumps a string" do
+ expect(subject.dump("foo")).to eq('"foo"')
+ end
+
+ it "dumps a true bool" do
+ expect(subject.dump(true)).to eq("true")
+ end
+
+ it "dumps a false bool" do
+ expect(subject.dump(false)).to eq("false")
+ end
+ end
+
+ describe ".generate" do
+ it "delegates to the adapter" do
+ args = [{ foo: "bar" }]
+
+ expect(JSON).to receive(:generate).with(*args)
+
+ subject.generate(*args)
+ end
+ end
+
+ describe ".pretty_generate" do
+ it "delegates to the adapter" do
+ args = [{ foo: "bar" }]
+
+ expect(JSON).to receive(:pretty_generate).with(*args)
+
+ subject.pretty_generate(*args)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
index c59078449b8..a11a9d08503 100644
--- a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
@@ -61,4 +61,56 @@ describe Gitlab::Kubernetes::Helm::BaseCommand do
it { is_expected.to eq('install-test-class-name') }
end
+
+ describe '#service_account_resource' do
+ let(:resource) do
+ Kubeclient::Resource.new(metadata: { name: 'tiller', namespace: 'gitlab-managed-apps' })
+ end
+
+ subject { base_command.service_account_resource }
+
+ context 'rbac is enabled' do
+ let(:rbac) { true }
+
+ it 'generates a Kubeclient resource for the tiller ServiceAccount' do
+ is_expected.to eq(resource)
+ end
+ end
+
+ context 'rbac is not enabled' do
+ let(:rbac) { false }
+
+ it 'generates nothing' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe '#cluster_role_binding_resource' do
+ let(:resource) do
+ Kubeclient::Resource.new(
+ metadata: { name: 'tiller-admin' },
+ roleRef: { apiGroup: 'rbac.authorization.k8s.io', kind: 'ClusterRole', name: 'cluster-admin' },
+ subjects: [{ kind: 'ServiceAccount', name: 'tiller', namespace: 'gitlab-managed-apps' }]
+ )
+ end
+
+ subject { base_command.cluster_role_binding_resource }
+
+ context 'rbac is enabled' do
+ let(:rbac) { true }
+
+ it 'generates a Kubeclient resource for the ClusterRoleBinding for tiller' do
+ is_expected.to eq(resource)
+ end
+ end
+
+ context 'rbac is not enabled' do
+ let(:rbac) { false }
+
+ it 'generates nothing' do
+ is_expected.to be_nil
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
index f87ceb45766..13021a08f9f 100644
--- a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
@@ -83,56 +83,4 @@ describe Gitlab::Kubernetes::Helm::InitCommand do
end
end
end
-
- describe '#service_account_resource' do
- let(:resource) do
- Kubeclient::Resource.new(metadata: { name: 'tiller', namespace: 'gitlab-managed-apps' })
- end
-
- subject { init_command.service_account_resource }
-
- context 'rbac is enabled' do
- let(:rbac) { true }
-
- it 'generates a Kubeclient resource for the tiller ServiceAccount' do
- is_expected.to eq(resource)
- end
- end
-
- context 'rbac is not enabled' do
- let(:rbac) { false }
-
- it 'generates nothing' do
- is_expected.to be_nil
- end
- end
- end
-
- describe '#cluster_role_binding_resource' do
- let(:resource) do
- Kubeclient::Resource.new(
- metadata: { name: 'tiller-admin' },
- roleRef: { apiGroup: 'rbac.authorization.k8s.io', kind: 'ClusterRole', name: 'cluster-admin' },
- subjects: [{ kind: 'ServiceAccount', name: 'tiller', namespace: 'gitlab-managed-apps' }]
- )
- end
-
- subject { init_command.cluster_role_binding_resource }
-
- context 'rbac is enabled' do
- let(:rbac) { true }
-
- it 'generates a Kubeclient resource for the ClusterRoleBinding for tiller' do
- is_expected.to eq(resource)
- end
- end
-
- context 'rbac is not enabled' do
- let(:rbac) { false }
-
- it 'generates nothing' do
- is_expected.to be_nil
- end
- end
- end
end
diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
index f94ceae362a..a5ed8f57bf3 100644
--- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
@@ -305,20 +305,4 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
is_expected.to eq(resource)
end
end
-
- describe '#service_account_resource' do
- subject { install_command.service_account_resource }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
- end
-
- describe '#cluster_role_binding_resource' do
- subject { install_command.cluster_role_binding_resource }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
- end
end
diff --git a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
index 064efebdb96..e69570f5371 100644
--- a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
@@ -199,20 +199,4 @@ describe Gitlab::Kubernetes::Helm::PatchCommand do
is_expected.to eq(resource)
end
end
-
- describe '#service_account_resource' do
- subject { patch_command.service_account_resource }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
- end
-
- describe '#cluster_role_binding_resource' do
- subject { patch_command.cluster_role_binding_resource }
-
- it 'returns nothing' do
- is_expected.to be_nil
- end
- end
end
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index ddc41e64147..aa18a1a843c 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -19,6 +19,7 @@ describe Gitlab::ProjectTemplate do
described_class.new('plainhtml', 'Pages/Plain HTML', 'Everything you need to get started using a plain HTML Pages site.', 'https://gitlab.com/pages/plain-html'),
described_class.new('gitbook', 'Pages/GitBook', 'Everything you need to get started using a GitBook Pages site.', 'https://gitlab.com/pages/gitbook'),
described_class.new('hexo', 'Pages/Hexo', 'Everything you need to get started using a Hexo Pages site.', 'https://gitlab.com/pages/hexo'),
+ described_class.new('sse_middleman', 'Static Site Editor/Middleman', _('Middleman project with Static Site Editor support'), 'https://gitlab.com/gitlab-org/project-templates/static-site-editor-middleman'),
described_class.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhugo'),
described_class.new('nfjekyll', 'Netlify/Jekyll', _('A Jekyll site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfjekyll'),
described_class.new('nfplainhtml', 'Netlify/Plain HTML', _('A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfplain-html'),
diff --git a/spec/lib/gitlab/prometheus/adapter_spec.rb b/spec/lib/gitlab/prometheus/adapter_spec.rb
index 202bf65f92b..afee95467fa 100644
--- a/spec/lib/gitlab/prometheus/adapter_spec.rb
+++ b/spec/lib/gitlab/prometheus/adapter_spec.rb
@@ -19,6 +19,14 @@ describe Gitlab::Prometheus::Adapter do
it 'return prometheus service as prometheus adapter' do
expect(subject.prometheus_adapter).to eq(prometheus_service)
end
+
+ context 'with cluster with prometheus available' do
+ let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
+
+ it 'returns prometheus service' do
+ expect(subject.prometheus_adapter).to eq(prometheus_service)
+ end
+ end
end
context "prometheus service can't execute queries" do
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index db7c5f771b7..f4b939c3013 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -42,11 +42,10 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
start_payload.merge(
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: done: 0.0 sec',
'job_status' => 'done',
- 'duration' => 0.0,
+ 'duration_s' => 0.0,
'completed_at' => timestamp.to_f,
- 'cpu_s' => 1.111112,
- 'db_duration' => 0,
- 'db_duration_s' => 0
+ 'cpu_s' => 1.11,
+ 'db_duration_s' => 0.0
)
end
let(:exception_payload) do
@@ -160,11 +159,11 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
let(:timing_data) do
{
gitaly_calls: 10,
- gitaly_duration: 10000,
+ gitaly_duration_s: 10000,
rugged_calls: 1,
- rugged_duration_ms: 5000,
+ rugged_duration_s: 5000,
redis_calls: 3,
- redis_duration_ms: 1234
+ redis_duration_s: 1234
}
end
@@ -193,12 +192,11 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
let(:expected_start_payload) { start_payload.except('args') }
let(:expected_end_payload) do
- end_payload.except('args').merge('cpu_s' => a_value > 0)
+ end_payload.except('args').merge('cpu_s' => a_value >= 0)
end
let(:expected_end_payload_with_db) do
expected_end_payload.merge(
- 'db_duration' => a_value >= 100,
'db_duration_s' => a_value >= 0.1
)
end
@@ -226,7 +224,7 @@ describe Gitlab::SidekiqLogging::StructuredLogger do
let(:time) { { duration: 0.1231234, cputime: 1.2342345 } }
let(:payload) { { 'class' => 'my-class', 'message' => 'my-message', 'job_status' => 'my-job-status' } }
let(:current_utc_time) { Time.now.utc }
- let(:payload_with_time_keys) { { 'class' => 'my-class', 'message' => 'my-message', 'job_status' => 'my-job-status', 'duration' => 0.123123, 'cpu_s' => 1.234235, 'completed_at' => current_utc_time.to_f } }
+ let(:payload_with_time_keys) { { 'class' => 'my-class', 'message' => 'my-message', 'job_status' => 'my-job-status', 'duration_s' => 0.12, 'cpu_s' => 1.23, 'completed_at' => current_utc_time.to_f } }
subject { described_class.new }
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb
index 0ea248fbcf1..312ebd30a76 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/server_spec.rb
@@ -21,18 +21,9 @@ describe Gitlab::SidekiqMiddleware::DuplicateJobs::Server, :clean_gitlab_redis_q
end
around do |example|
- Sidekiq::Testing.inline! { example.run }
- end
-
- before(:context) do
- Sidekiq::Testing.server_middleware do |chain|
+ with_sidekiq_server_middleware do |chain|
chain.add described_class
- end
- end
-
- after(:context) do
- Sidekiq::Testing.server_middleware do |chain|
- chain.remove described_class
+ Sidekiq::Testing.inline! { example.run }
end
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb b/spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb
index f64ebece930..fdf643a8ad1 100644
--- a/spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb
@@ -41,18 +41,9 @@ describe Gitlab::SidekiqMiddleware::WorkerContext::Server do
end
around do |example|
- Sidekiq::Testing.inline! { example.run }
- end
-
- before(:context) do
- Sidekiq::Testing.server_middleware do |chain|
+ with_sidekiq_server_middleware do |chain|
chain.add described_class
- end
- end
-
- after(:context) do
- Sidekiq::Testing.server_middleware do |chain|
- chain.remove described_class
+ Sidekiq::Testing.inline! { example.run }
end
end
diff --git a/spec/lib/gitlab/sidekiq_middleware_spec.rb b/spec/lib/gitlab/sidekiq_middleware_spec.rb
index 32c1807ba6e..752ec6a0a3f 100644
--- a/spec/lib/gitlab/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware_spec.rb
@@ -28,11 +28,16 @@ describe Gitlab::SidekiqMiddleware do
# 2) yielding exactly once
describe '.server_configurator' do
around do |example|
- original = Sidekiq::Testing.server_middleware.dup
-
- example.run
-
- Sidekiq::Testing.instance_variable_set :@server_chain, original
+ with_sidekiq_server_middleware do |chain|
+ described_class.server_configurator(
+ metrics: metrics,
+ arguments_logger: arguments_logger,
+ memory_killer: memory_killer,
+ request_store: request_store
+ ).call(chain)
+
+ example.run
+ end
end
let(:middleware_expected_args) { [a_kind_of(worker_class), hash_including({ 'args' => job_args }), anything] }
@@ -54,21 +59,17 @@ describe Gitlab::SidekiqMiddleware do
end
let(:enabled_sidekiq_middlewares) { all_sidekiq_middlewares - disabled_sidekiq_middlewares }
- before do
- Sidekiq::Testing.server_middleware.clear
- Sidekiq::Testing.server_middleware(&described_class.server_configurator(
- metrics: metrics,
- arguments_logger: arguments_logger,
- memory_killer: memory_killer,
- request_store: request_store
- ))
-
- enabled_sidekiq_middlewares.each do |middleware|
- expect_any_instance_of(middleware).to receive(:call).with(*middleware_expected_args).once.and_call_original
- end
+ shared_examples "a server middleware chain" do
+ it "passes through the right server middlewares" do
+ enabled_sidekiq_middlewares.each do |middleware|
+ expect_any_instance_of(middleware).to receive(:call).with(*middleware_expected_args).once.and_call_original
+ end
- disabled_sidekiq_middlewares.each do |middleware|
- expect_any_instance_of(Gitlab::SidekiqMiddleware::ArgumentsLogger).not_to receive(:call)
+ disabled_sidekiq_middlewares.each do |middleware|
+ expect_any_instance_of(middleware).not_to receive(:call)
+ end
+
+ worker_class.perform_async(*job_args)
end
end
@@ -86,9 +87,7 @@ describe Gitlab::SidekiqMiddleware do
]
end
- it "passes through server middlewares" do
- worker_class.perform_async(*job_args)
- end
+ it_behaves_like "a server middleware chain"
end
context "all optional middlewares on" do
@@ -98,9 +97,7 @@ describe Gitlab::SidekiqMiddleware do
let(:request_store) { true }
let(:disabled_sidekiq_middlewares) { [] }
- it "passes through server middlewares" do
- worker_class.perform_async(*job_args)
- end
+ it_behaves_like "a server middleware chain"
context "server metrics" do
let(:gitaly_histogram) { double(:gitaly_histogram) }
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
index 56d6bf1c788..47b9a67f54f 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueShow do
- let(:project) { create(:project) }
+ let(:user) { create(:user, :with_avatar) }
+ let(:project) { create(:project, creator: user) }
let(:issue) { create(:issue, project: project) }
let(:attachment) { subject[:attachments].first }
@@ -15,6 +16,7 @@ describe Gitlab::SlashCommands::Presenters::IssueShow do
expect(subject[:response_type]).to be(:in_channel)
expect(subject).to have_key(:attachments)
expect(attachment[:title]).to start_with(issue.title)
+ expect(attachment[:author_icon]).to eq(user.avatar_url(only_path: false))
end
context 'with upvotes' do
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index d3780d22241..e34367cbbf9 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe Gitlab::Utils do
delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, :which,
:ensure_array_from_string, :to_exclusive_sentence, :bytes_to_megabytes,
- :append_path, :check_path_traversal!, to: :described_class
+ :append_path, :check_path_traversal!, :ms_to_round_sec, to: :described_class
describe '.check_path_traversal!' do
it 'detects path traversal at the start of the string' do
@@ -55,6 +55,22 @@ describe Gitlab::Utils do
end
end
+ describe '.ms_to_round_sec' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:original, :expected) do
+ 1999.8999 | 2
+ 12384 | 12.38
+ 333 | 0.33
+ end
+
+ with_them do
+ it "returns rounded seconds" do
+ expect(ms_to_round_sec(original)).to eq(expected)
+ end
+ end
+ end
+
describe '.to_exclusive_sentence' do
it 'calls #to_sentence on the array' do
array = double
diff --git a/spec/lib/marginalia_spec.rb b/spec/lib/marginalia_spec.rb
index d4b84c5cdc4..2f446694083 100644
--- a/spec/lib/marginalia_spec.rb
+++ b/spec/lib/marginalia_spec.rb
@@ -24,20 +24,6 @@ describe 'Marginalia spec' do
end
end
- def add_sidekiq_middleware
- # Reference: https://github.com/mperham/sidekiq/wiki/Testing#testing-server-middlewaresidekiq
- # Sidekiq test harness fakes worker without its server middlewares, so include instrumentation to 'Sidekiq::Testing' server middleware.
- Sidekiq::Testing.server_middleware do |chain|
- chain.add Marginalia::SidekiqInstrumentation::Middleware
- end
- end
-
- def remove_sidekiq_middleware
- Sidekiq::Testing.server_middleware do |chain|
- chain.remove Marginalia::SidekiqInstrumentation::Middleware
- end
- end
-
def stub_feature(value)
allow(Gitlab::Marginalia).to receive(:cached_feature_enabled?).and_return(value)
end
@@ -88,20 +74,16 @@ describe 'Marginalia spec' do
end
describe 'for Sidekiq worker jobs' do
- before(:all) do
- add_sidekiq_middleware
-
- # Because of faking, 'Sidekiq.server?' does not work so implicitly set application name which is done in config/initializers/0_marginalia.rb
- Marginalia.application_name = "sidekiq"
+ around do |example|
+ with_sidekiq_server_middleware do |chain|
+ chain.add Marginalia::SidekiqInstrumentation::Middleware
+ Marginalia.application_name = "sidekiq"
+ example.run
+ end
end
after(:all) do
MarginaliaTestJob.clear
- remove_sidekiq_middleware
- end
-
- around do |example|
- Sidekiq::Testing.fake! { example.run }
end
before do