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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 09:08:05 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 09:08:05 +0300
commit2bc11b8442e9f68800cfed57f9abad3f2dfc0b78 (patch)
tree373aa469b310bbd2f30dfa60ebdc2c6e18c4e4e9 /spec
parent21de0d5578ba4b6e4f7ad0667ecdaaf0810f4235 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/diffs/components/app_spec.js2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/concurrency_limit/client_spec.rb58
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/concurrency_limit/concurrency_limit_service_spec.rb190
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/concurrency_limit/server_spec.rb107
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_concurrency_spec.rb93
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_map_spec.rb75
-rw-r--r--spec/lib/gitlab/tracking/event_definition_spec.rb8
7 files changed, 528 insertions, 5 deletions
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 813db12e83f..4676f56c47e 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -47,8 +47,6 @@ const ENDPOINT_METADATA_URL = `${TEST_HOST}/diff/endpointMetadata`;
Vue.use(Vuex);
Vue.use(VueApollo);
-Vue.config.ignoredElements = ['copy-code'];
-
function getCollapsedFilesWarning(wrapper) {
return wrapper.findComponent(CollapsedFilesWarning);
}
diff --git a/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/client_spec.rb b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/client_spec.rb
new file mode 100644
index 00000000000..53bb3bda0ce
--- /dev/null
+++ b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/client_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SidekiqMiddleware::ConcurrencyLimit::Client, :clean_gitlab_redis_queues, feature_category: :global_search do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'TestConcurrencyLimitWorker'
+ end
+
+ include ApplicationWorker
+
+ concurrency_limit -> { 5 }
+
+ def perform(*)
+ self.class.work
+ end
+
+ def self.work; end
+ end
+ end
+
+ before do
+ stub_const('TestConcurrencyLimitWorker', worker_class)
+ end
+
+ describe '#call' do
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(sidekiq_concurrency_limit_middleware: false)
+ end
+
+ it 'schedules the job' do
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).not_to receive(:add_to_queue!)
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+
+ expect(TestConcurrencyLimitWorker.jobs.size).to eq(1)
+ end
+ end
+
+ context 'when there are jobs in the queue' do
+ before do
+ allow(::Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).to receive(:has_jobs_in_queue?)
+ .and_return(true)
+ end
+
+ it 'defers the job' do
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).to receive(:add_to_queue!).once
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+
+ expect(TestConcurrencyLimitWorker.jobs.size).to eq(0)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/concurrency_limit_service_spec.rb b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/concurrency_limit_service_spec.rb
new file mode 100644
index 00000000000..a3922aed3a5
--- /dev/null
+++ b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/concurrency_limit_service_spec.rb
@@ -0,0 +1,190 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService, :clean_gitlab_redis_shared_state, feature_category: :global_search do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'DummyWorker'
+ end
+
+ include ApplicationWorker
+ end
+ end
+
+ let(:worker_class_name) { worker_class.name }
+
+ let(:worker_context) do
+ { 'correlation_id' => 'context_correlation_id',
+ 'meta.project' => 'gitlab-org/gitlab' }
+ end
+
+ let(:stored_context) do
+ {
+ "#{Gitlab::ApplicationContext::LOG_KEY}.project" => 'gitlab-org/gitlab',
+ "correlation_id" => 'context_correlation_id'
+ }
+ end
+
+ let(:worker_args) { [1, 2] }
+
+ subject(:service) { described_class.new(worker_class_name) }
+
+ before do
+ stub_const(worker_class_name, worker_class)
+ end
+
+ describe '.add_to_queue!' do
+ subject(:add_to_queue!) { described_class.add_to_queue!(worker_class_name, worker_args, worker_context) }
+
+ it 'calls an instance method' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:add_to_queue!).with(worker_args, worker_context)
+ end
+
+ add_to_queue!
+ end
+ end
+
+ describe '.has_jobs_in_queue?' do
+ it 'calls an instance method' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:has_jobs_in_queue?)
+ end
+
+ described_class.has_jobs_in_queue?(worker_class_name)
+ end
+ end
+
+ describe '.resume_processing!' do
+ subject(:resume_processing!) { described_class.resume_processing!(worker_class_name, limit: 10) }
+
+ it 'calls an instance method' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:resume_processing!)
+ end
+
+ resume_processing!
+ end
+ end
+
+ describe '.queue_size' do
+ it 'reports the queue size' do
+ expect(described_class.queue_size(worker_class_name)).to eq(0)
+
+ service.add_to_queue!(worker_args, worker_context)
+
+ expect(described_class.queue_size(worker_class_name)).to eq(1)
+
+ expect { service.resume_processing!(limit: 1) }.to change { described_class.queue_size(worker_class_name) }.by(-1)
+ end
+ end
+
+ describe '#add_to_queue!' do
+ subject(:add_to_queue!) { service.add_to_queue!(worker_args, worker_context) }
+
+ it 'adds a job to the set' do
+ expect { add_to_queue! }
+ .to change { service.queue_size }
+ .from(0).to(1)
+ end
+
+ it 'adds only one unique job to the set' do
+ expect do
+ 2.times { add_to_queue! }
+ end.to change { service.queue_size }.from(0).to(1)
+ end
+
+ it 'stores context information' do
+ add_to_queue!
+
+ service.send(:with_redis) do |r|
+ set_key = service.send(:redis_key)
+ stored_job = service.send(:deserialize, r.lrange(set_key, 0, -1).first)
+
+ expect(stored_job['context']).to eq(stored_context)
+ end
+ end
+ end
+
+ describe '#has_jobs_in_queue?' do
+ it 'uses queue_size' do
+ expect { service.add_to_queue!(worker_args, worker_context) }
+ .to change { service.has_jobs_in_queue? }
+ .from(false).to(true)
+ end
+ end
+
+ describe '#resume_processing!' do
+ let(:jobs) { [[1], [2], [3]] }
+ let(:expected_context) { stored_context.merge(related_class: described_class.name) }
+
+ it 'puts jobs back into the queue and respects order' do
+ jobs.each do |j|
+ service.add_to_queue!(j, worker_context)
+ end
+
+ expect(worker_class).to receive(:perform_async).with(1).ordered
+ expect(worker_class).to receive(:perform_async).with(2).ordered
+ expect(worker_class).not_to receive(:perform_async).with(3).ordered
+
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance)
+ .to receive(:resumed_log)
+ .with(worker_class_name, [1])
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance)
+ .to receive(:resumed_log)
+ .with(worker_class_name, [2])
+
+ service.resume_processing!(limit: 2)
+ end
+
+ it 'drops a set after execution' do
+ jobs.each do |j|
+ service.add_to_queue!(j, worker_context)
+ end
+
+ expect(Gitlab::ApplicationContext).to receive(:with_raw_context)
+ .with(expected_context)
+ .exactly(jobs.count).times.and_call_original
+ expect(worker_class).to receive(:perform_async).exactly(jobs.count).times
+
+ expect { service.resume_processing!(limit: jobs.count) }
+ .to change { service.has_jobs_in_queue? }.from(true).to(false)
+ end
+ end
+
+ context 'with concurrent changes to different queues' do
+ let(:second_worker_class) do
+ Class.new do
+ def self.name
+ 'SecondDummyIndexingWorker'
+ end
+
+ include ApplicationWorker
+ end
+ end
+
+ let(:other_subject) { described_class.new(second_worker_class.name) }
+
+ before do
+ stub_const(second_worker_class.name, second_worker_class)
+ end
+
+ it 'allows to use queues independently of each other' do
+ expect { service.add_to_queue!(worker_args, worker_context) }
+ .to change { service.queue_size }
+ .from(0).to(1)
+
+ expect { other_subject.add_to_queue!(worker_args, worker_context) }
+ .to change { other_subject.queue_size }
+ .from(0).to(1)
+
+ expect { service.resume_processing!(limit: 1) }.to change { service.has_jobs_in_queue? }
+ .from(true).to(false)
+
+ expect { other_subject.resume_processing!(limit: 1) }.to change { other_subject.has_jobs_in_queue? }
+ .from(true).to(false)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/server_spec.rb b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/server_spec.rb
new file mode 100644
index 00000000000..d2c1f345b1a
--- /dev/null
+++ b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/server_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SidekiqMiddleware::ConcurrencyLimit::Server, feature_category: :global_search do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'TestConcurrencyLimitWorker'
+ end
+
+ include ApplicationWorker
+
+ concurrency_limit -> { 5 }
+
+ def perform(*)
+ self.class.work
+ end
+
+ def self.work; end
+ end
+ end
+
+ before do
+ stub_const('TestConcurrencyLimitWorker', worker_class)
+ end
+
+ around do |example|
+ with_sidekiq_server_middleware do |chain|
+ chain.add described_class
+ Sidekiq::Testing.inline! { example.run }
+ end
+ end
+
+ describe '#call' do
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(sidekiq_concurrency_limit_middleware: false)
+ end
+
+ it 'executes the job' do
+ expect(TestConcurrencyLimitWorker).to receive(:work)
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance).not_to receive(:deferred_log)
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).not_to receive(:add_to_queue!)
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+ end
+ end
+
+ context 'when there are jobs in the queue' do
+ before do
+ allow(::Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).to receive(:has_jobs_in_queue?)
+ .and_return(true)
+ end
+
+ it 'defers the job' do
+ expect(TestConcurrencyLimitWorker).not_to receive(:work)
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance).to receive(:deferred_log).and_call_original
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).to receive(:add_to_queue!)
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+ end
+
+ it 'executes the job if resumed' do
+ expect(TestConcurrencyLimitWorker).to receive(:work)
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance).not_to receive(:deferred_log)
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).not_to receive(:add_to_queue!)
+
+ related_class = 'Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService'
+ Gitlab::ApplicationContext.with_raw_context(related_class: related_class) do
+ TestConcurrencyLimitWorker.perform_async('foo')
+ end
+ end
+ end
+
+ context 'when sidekiq_workers are stubbed' do
+ before do
+ allow(::Gitlab::SidekiqMiddleware::ConcurrencyLimit::WorkersMap).to receive(:over_the_limit?)
+ .and_return(over_the_limit)
+ end
+
+ context 'when under the limit' do
+ let(:over_the_limit) { false }
+
+ it 'executes the job' do
+ expect(TestConcurrencyLimitWorker).to receive(:work)
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance).not_to receive(:deferred_log)
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).not_to receive(:add_to_queue!)
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+ end
+ end
+
+ context 'when over the limit' do
+ let(:over_the_limit) { true }
+
+ it 'defers the job' do
+ expect(TestConcurrencyLimitWorker).not_to receive(:work)
+ expect(Gitlab::SidekiqLogging::ConcurrencyLimitLogger.instance).to receive(:deferred_log).and_call_original
+ expect(Gitlab::SidekiqMiddleware::ConcurrencyLimit::ConcurrencyLimitService).to receive(:add_to_queue!)
+
+ TestConcurrencyLimitWorker.perform_async('foo')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_concurrency_spec.rb b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_concurrency_spec.rb
new file mode 100644
index 00000000000..69747dfceeb
--- /dev/null
+++ b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_concurrency_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SidekiqMiddleware::ConcurrencyLimit::WorkersConcurrency, feature_category: :global_search do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'TestConcurrencyLimitWorker'
+ end
+
+ include ApplicationWorker
+
+ concurrency_limit -> { 60 }
+
+ def perform(*); end
+ end
+ end
+
+ let(:current_concurrency) { 10 }
+ let(:sidekiq_worker) do
+ [
+ 'process_id',
+ 'thread_id',
+ {
+ 'queue' => 'default',
+ 'payload' => {
+ 'class' => 'TestConcurrencyLimitWorker'
+ }.to_json
+ }
+ ]
+ end
+
+ before do
+ stub_const('TestConcurrencyLimitWorker', worker_class)
+ allow(described_class).to receive(:sidekiq_workers).and_return([sidekiq_worker] * current_concurrency)
+ end
+
+ describe '.current_for' do
+ subject(:current_for) { described_class.current_for(worker: TestConcurrencyLimitWorker, skip_cache: skip_cache) }
+
+ context 'without cache' do
+ let(:skip_cache) { true }
+
+ it 'returns the current concurrency' do
+ expect(described_class).to receive(:workers_uncached).and_call_original
+ expect(current_for).to eq(current_concurrency)
+ end
+ end
+
+ context 'with cache' do
+ let(:skip_cache) { false }
+ let(:cached_value) { { "TestConcurrencyLimitWorker" => 20 } }
+
+ before do
+ allow(Rails.cache).to receive(:fetch).and_return(cached_value)
+ end
+
+ it 'returns cached current_for' do
+ expect(described_class).not_to receive(:workers_uncached)
+
+ expect(current_for).to eq(20)
+ end
+ end
+ end
+
+ describe '.workers' do
+ subject(:workers) { described_class.workers(skip_cache: skip_cache) }
+
+ context 'without cache' do
+ let(:skip_cache) { true }
+
+ it 'returns current_workers' do
+ expect(workers).to eq('TestConcurrencyLimitWorker' => 10)
+ end
+ end
+
+ context 'with cache' do
+ let(:skip_cache) { false }
+ let(:cached_value) { { "TestConcurrencyLimitWorker" => 20 } }
+
+ before do
+ allow(Rails.cache).to receive(:fetch).and_return(cached_value)
+ end
+
+ it 'returns cached workers' do
+ expect(described_class).not_to receive(:workers_uncached)
+
+ expect(workers).to eq(cached_value)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_map_spec.rb b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_map_spec.rb
new file mode 100644
index 00000000000..3836b7f1690
--- /dev/null
+++ b/spec/lib/gitlab/sidekiq_middleware/concurrency_limit/workers_map_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SidekiqMiddleware::ConcurrencyLimit::WorkersMap, feature_category: :global_search do
+ let(:worker_class) do
+ Class.new do
+ def self.name
+ 'TestConcurrencyLimitWorker'
+ end
+
+ include ApplicationWorker
+
+ concurrency_limit -> { 60 }
+
+ def perform(*); end
+ end
+ end
+
+ before do
+ stub_const('TestConcurrencyLimitWorker', worker_class)
+ end
+
+ describe '.limit_for' do
+ let(:expected_limit) { 60 }
+
+ it 'accepts worker instance' do
+ expect(described_class.limit_for(worker: worker_class.new).call).to eq(expected_limit)
+ end
+
+ it 'accepts worker class' do
+ expect(described_class.limit_for(worker: worker_class).call).to eq(expected_limit)
+ end
+
+ it 'returns nil for unknown worker' do
+ expect(described_class.limit_for(worker: described_class)).to be_nil
+ end
+
+ it 'returns nil if the feature flag is disabled' do
+ stub_feature_flags(sidekiq_concurrency_limit_middleware: false)
+
+ expect(described_class.limit_for(worker: worker_class)).to be_nil
+ end
+ end
+
+ describe '.over_the_limit?' do
+ subject(:over_the_limit?) { described_class.over_the_limit?(worker: worker_class) }
+
+ it 'returns false if no limit is set' do
+ expect(described_class).to receive(:limit_for).and_return(nil)
+
+ expect(over_the_limit?).to be_falsey
+ end
+
+ it 'returns false if under the limit' do
+ allow(::Gitlab::SidekiqMiddleware::ConcurrencyLimit::WorkersConcurrency).to receive(:current_for).and_return(50)
+
+ expect(over_the_limit?).to be_falsey
+ end
+
+ it 'returns true if over the limit' do
+ allow(::Gitlab::SidekiqMiddleware::ConcurrencyLimit::WorkersConcurrency).to receive(:current_for).and_return(100)
+
+ expect(over_the_limit?).to be_truthy
+ end
+ end
+
+ describe '.workers' do
+ subject(:workers) { described_class.workers }
+
+ it 'includes the worker' do
+ expect(workers).to include(worker_class)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/tracking/event_definition_spec.rb b/spec/lib/gitlab/tracking/event_definition_spec.rb
index 7c5047dc0c6..2bdf7e17c0d 100644
--- a/spec/lib/gitlab/tracking/event_definition_spec.rb
+++ b/spec/lib/gitlab/tracking/event_definition_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Tracking::EventDefinition do
+RSpec.describe Gitlab::Tracking::EventDefinition, feature_category: :service_ping do
let(:attributes) do
{
description: 'Created issues',
@@ -15,8 +15,10 @@ RSpec.describe Gitlab::Tracking::EventDefinition do
product_stage: 'growth',
product_section: 'dev',
product_group: 'group::product analytics',
- distribution: %w[ee ce],
- tier: %w[free premium ultimate]
+ distributions: %w[ee ce],
+ tiers: %w[free premium ultimate],
+ introduced_by_url: "https://gitlab.com/example/-/merge_requests/123",
+ milestone: '1.6'
}
end