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/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-19 06:08:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-19 06:08:19 +0300
commitec1f0dd7f46a6d25e4a47c8254ac67b720f81e89 (patch)
treecea26c43c6a48b785eba0e97a20592e4545028e1 /spec/lib
parent1f9bddaf87f0b6c93a9617bad0ae731baf16d268 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/gitlab/gl_repository/repo_type_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml5
-rw-r--r--spec/lib/gitlab/patch/redis_cache_store_spec.rb177
4 files changed, 179 insertions, 6 deletions
diff --git a/spec/lib/gitlab/gl_repository/repo_type_spec.rb b/spec/lib/gitlab/gl_repository/repo_type_spec.rb
index 2ac2fc1fd4b..4345df1b018 100644
--- a/spec/lib/gitlab/gl_repository/repo_type_spec.rb
+++ b/spec/lib/gitlab/gl_repository/repo_type_spec.rb
@@ -136,7 +136,7 @@ RSpec.describe Gitlab::GlRepository::RepoType do
describe Gitlab::GlRepository::DESIGN do
it_behaves_like 'a repo type' do
let(:expected_repository) { project.design_repository }
- let(:expected_container) { project.design_management_repository }
+ let(:expected_container) { expected_repository.container }
let(:expected_id) { expected_container.id }
let(:expected_identifier) { "design-#{expected_id}" }
let(:expected_suffix) { '.design' }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 34f9948b9dc..e6829363922 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -798,6 +798,7 @@ project:
- analytics_dashboards_configuration_project
- analytics_dashboards_pointer
- design_management_repository
+- design_management_repository_state
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index faf345e8f78..9e5b5ccd64a 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -932,11 +932,6 @@ DesignManagement::Version:
- created_at
- sha
- author_id
-DesignManagement::Repository:
-- id
-- project_id
-- created_at
-- updated_at
ZoomMeeting:
- id
- project_id
diff --git a/spec/lib/gitlab/patch/redis_cache_store_spec.rb b/spec/lib/gitlab/patch/redis_cache_store_spec.rb
new file mode 100644
index 00000000000..e1bf774d157
--- /dev/null
+++ b/spec/lib/gitlab/patch/redis_cache_store_spec.rb
@@ -0,0 +1,177 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Patch::RedisCacheStore, :use_clean_rails_redis_caching, feature_category: :scalability do
+ before do
+ Rails.cache.write('x', 1)
+ Rails.cache.write('y', 2)
+ Rails.cache.write('z', 3)
+
+ Rails.cache.write('{user1}:x', 1)
+ Rails.cache.write('{user1}:y', 2)
+ Rails.cache.write('{user1}:z', 3)
+ end
+
+ describe '#read_multi_mget' do
+ it 'runs multi-key command if no cross-slot command is expected' do
+ Rails.cache.redis.with do |redis|
+ expect(redis).not_to receive(:pipelined)
+ end
+
+ expect(
+ Rails.cache.fetch_multi('{user1}:x', '{user1}:y', '{user1}:z') { |key| key }
+ ).to eq({ '{user1}:x' => 1, '{user1}:y' => 2, '{user1}:z' => 3 })
+ end
+
+ it 'skips patch if input is above 100' do
+ Rails.cache.redis.with do |redis|
+ expect(redis).not_to receive(:pipelined)
+ end
+
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ Rails.cache.read_multi(*Array.new(101) { |i| i })
+ end
+ end
+
+ shared_examples "fetches multiple keys" do |patched|
+ it 'reads multiple keys' do
+ if patched
+ Rails.cache.redis.with do |redis|
+ expect(redis).to receive(:pipelined).once.and_call_original
+ end
+ end
+
+ expect(::Feature).to receive(:enabled?)
+ .with(:feature_flag_state_logs, { default_enabled_if_undefined: nil, type: :ops })
+ .exactly(:once)
+ .and_call_original
+
+ expect(::Feature).to receive(:enabled?)
+ .with(:enable_rails_cache_pipeline_patch)
+ .exactly(:once)
+ .and_call_original
+
+ expect(
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ # fetch_multi requires a block and we have to specifically test it
+ # as it is used in the Gitlab project
+ Rails.cache.fetch_multi('x', 'y', 'z') { |key| key }
+ end
+ ).to eq({ 'x' => 1, 'y' => 2, 'z' => 3 })
+ end
+ end
+
+ shared_examples 'reading using non redis cache stores' do |klass|
+ it 'does not affect non Redis::Cache cache stores' do
+ klass.cache_store.redis.with do |redis|
+ expect(redis).not_to receive(:pipelined)
+ end
+
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ klass.cache_store.fetch_multi('x', 'y', 'z') { |key| key }
+ end
+ end
+ end
+
+ context 'when reading from non redis-cache stores' do
+ it_behaves_like 'reading using non redis cache stores', Gitlab::Redis::RepositoryCache
+ it_behaves_like 'reading using non redis cache stores', Gitlab::Redis::FeatureFlag
+ it_behaves_like 'reading using non redis cache stores', Gitlab::Redis::RateLimiting
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(enable_rails_cache_pipeline_patch: false)
+ end
+
+ it_behaves_like 'fetches multiple keys'
+ end
+
+ it_behaves_like 'fetches multiple keys', true
+ end
+
+ describe '#delete_multi_entries' do
+ shared_examples "deletes multiple keys" do |patched|
+ it 'deletes multiple keys' do
+ if patched
+ Rails.cache.redis.with do |redis|
+ expect(redis).to receive(:pipelined).once.and_call_original
+ end
+ end
+
+ expect(::Feature).to receive(:enabled?)
+ .with(:feature_flag_state_logs, { default_enabled_if_undefined: nil, type: :ops })
+ .exactly(:once)
+ .and_call_original
+
+ expect(::Feature).to receive(:enabled?)
+ .with(:enable_rails_cache_pipeline_patch)
+ .exactly(:once)
+ .and_call_original
+
+ expect(
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ Rails.cache.delete_multi(%w[x y z])
+ end
+ ).to eq(3)
+ end
+ end
+
+ shared_examples 'deleting using non redis cache stores' do |klass|
+ it 'does not affect non Redis::Cache cache stores' do
+ klass.cache_store.redis.with do |redis|
+ expect(redis).not_to receive(:pipelined)
+ end
+
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ klass.cache_store.delete_multi(%w[x y z])
+ end
+ end
+ end
+
+ context 'when deleting from non redis-cache stores' do
+ it_behaves_like 'deleting using non redis cache stores', Gitlab::Redis::RepositoryCache
+ it_behaves_like 'deleting using non redis cache stores', Gitlab::Redis::FeatureFlag
+ it_behaves_like 'deleting using non redis cache stores', Gitlab::Redis::RateLimiting
+ end
+
+ context 'when deleting large amount of keys' do
+ before do
+ 200.times { |i| Rails.cache.write(i, i) }
+ end
+
+ it 'calls pipeline multiple times' do
+ Rails.cache.redis.with do |redis|
+ expect(redis).to receive(:pipelined).twice.and_call_original
+ end
+
+ expect(
+ Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
+ Rails.cache.delete_multi(Array(0..199))
+ end
+ ).to eq(200)
+ end
+ end
+
+ it 'runs multi-key command if no cross-slot command is expected' do
+ Rails.cache.redis.with do |redis|
+ expect(redis).not_to receive(:pipelined)
+ end
+
+ expect(
+ Rails.cache.delete_multi(%w[{user1}:x {user1}:y {user1}:z])
+ ).to eq(3)
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(enable_rails_cache_pipeline_patch: false)
+ end
+
+ it_behaves_like 'deletes multiple keys'
+ end
+
+ it_behaves_like 'deletes multiple keys', true
+ end
+end