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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/initializers')
-rw-r--r--spec/initializers/00_rails_disable_joins_spec.rb288
-rw-r--r--spec/initializers/0_log_deprecations_spec.rb74
-rw-r--r--spec/initializers/database_config_spec.rb57
-rw-r--r--spec/initializers/lograge_spec.rb3
-rw-r--r--spec/initializers/rails_asset_host_spec.rb38
5 files changed, 422 insertions, 38 deletions
diff --git a/spec/initializers/00_rails_disable_joins_spec.rb b/spec/initializers/00_rails_disable_joins_spec.rb
new file mode 100644
index 00000000000..78e78b6810b
--- /dev/null
+++ b/spec/initializers/00_rails_disable_joins_spec.rb
@@ -0,0 +1,288 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'DisableJoins' do
+ let(:primary_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_primary_records'
+
+ def self.name
+ 'TestPrimary'
+ end
+ end
+ end
+
+ let(:bridge_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_bridge_records'
+
+ def self.name
+ 'TestBridge'
+ end
+ end
+ end
+
+ let(:secondary_model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_secondary_records'
+
+ def self.name
+ 'TestSecondary'
+ end
+ end
+ end
+
+ context 'passing disable_joins as an association option' do
+ context 'when the association is a bare has_one' do
+ it 'disallows the disable_joins option' do
+ expect do
+ primary_model.has_one :test_bridge, disable_joins: true
+ end.to raise_error(ArgumentError, /Unknown key: :disable_joins/)
+ end
+ end
+
+ context 'when the association is a belongs_to' do
+ it 'disallows the disable_joins option' do
+ expect do
+ bridge_model.belongs_to :test_secondary, disable_joins: true
+ end.to raise_error(ArgumentError, /Unknown key: :disable_joins/)
+ end
+ end
+
+ context 'when the association is has_one :through' do
+ it 'allows the disable_joins option' do
+ primary_model.has_one :test_bridge
+ bridge_model.belongs_to :test_secondary
+
+ expect do
+ primary_model.has_one :test_secondary, through: :test_bridge, disable_joins: true
+ end.not_to raise_error
+ end
+ end
+
+ context 'when the association is a bare has_many' do
+ it 'disallows the disable_joins option' do
+ expect do
+ primary_model.has_many :test_bridges, disable_joins: true
+ end.to raise_error(ArgumentError, /Unknown key: :disable_joins/)
+ end
+ end
+
+ context 'when the association is a has_many :through' do
+ it 'allows the disable_joins option' do
+ primary_model.has_many :test_bridges
+ bridge_model.belongs_to :test_secondary
+
+ expect do
+ primary_model.has_many :test_secondaries, through: :test_bridges, disable_joins: true
+ end.not_to raise_error
+ end
+ end
+ end
+
+ context 'querying has_one :through when disable_joins is set' do
+ before do
+ create_tables(<<~SQL)
+ CREATE TABLE _test_primary_records (
+ id serial NOT NULL PRIMARY KEY);
+
+ CREATE TABLE _test_bridge_records (
+ id serial NOT NULL PRIMARY KEY,
+ primary_record_id int NOT NULL,
+ secondary_record_id int NOT NULL);
+
+ CREATE TABLE _test_secondary_records (
+ id serial NOT NULL PRIMARY KEY);
+ SQL
+
+ primary_model.has_one :test_bridge, anonymous_class: bridge_model, foreign_key: :primary_record_id
+ bridge_model.belongs_to :test_secondary, anonymous_class: secondary_model, foreign_key: :secondary_record_id
+ primary_model.has_one :test_secondary, through: :test_bridge, anonymous_class: secondary_model,
+ disable_joins: -> { joins_disabled_flag }
+
+ primary_record = primary_model.create!
+ secondary_record = secondary_model.create!
+ bridge_model.create!(primary_record_id: primary_record.id, secondary_record_id: secondary_record.id)
+ end
+
+ context 'when disable_joins evaluates to true' do
+ let(:joins_disabled_flag) { true }
+
+ it 'executes separate queries' do
+ primary_record = primary_model.first
+
+ query_count = ActiveRecord::QueryRecorder.new { primary_record.test_secondary }.count
+
+ expect(query_count).to eq(2)
+ end
+ end
+
+ context 'when disable_joins evalutes to false' do
+ let(:joins_disabled_flag) { false }
+
+ it 'executes a single query' do
+ primary_record = primary_model.first
+
+ query_count = ActiveRecord::QueryRecorder.new { primary_record.test_secondary }.count
+
+ expect(query_count).to eq(1)
+ end
+ end
+ end
+
+ context 'querying has_many :through when disable_joins is set' do
+ before do
+ create_tables(<<~SQL)
+ CREATE TABLE _test_primary_records (
+ id serial NOT NULL PRIMARY KEY);
+
+ CREATE TABLE _test_bridge_records (
+ id serial NOT NULL PRIMARY KEY,
+ primary_record_id int NOT NULL);
+
+ CREATE TABLE _test_secondary_records (
+ id serial NOT NULL PRIMARY KEY,
+ bridge_record_id int NOT NULL);
+ SQL
+
+ primary_model.has_many :test_bridges, anonymous_class: bridge_model, foreign_key: :primary_record_id
+ bridge_model.has_many :test_secondaries, anonymous_class: secondary_model, foreign_key: :bridge_record_id
+ primary_model.has_many :test_secondaries, through: :test_bridges, anonymous_class: secondary_model,
+ disable_joins: -> { disabled_join_flag }
+
+ primary_record = primary_model.create!
+ bridge_record = bridge_model.create!(primary_record_id: primary_record.id)
+ secondary_model.create!(bridge_record_id: bridge_record.id)
+ end
+
+ context 'when disable_joins evaluates to true' do
+ let(:disabled_join_flag) { true }
+
+ it 'executes separate queries' do
+ primary_record = primary_model.first
+
+ query_count = ActiveRecord::QueryRecorder.new { primary_record.test_secondaries.first }.count
+
+ expect(query_count).to eq(2)
+ end
+ end
+
+ context 'when disable_joins evalutes to false' do
+ let(:disabled_join_flag) { false }
+
+ it 'executes a single query' do
+ primary_record = primary_model.first
+
+ query_count = ActiveRecord::QueryRecorder.new { primary_record.test_secondaries.first }.count
+
+ expect(query_count).to eq(1)
+ end
+ end
+ end
+
+ context 'querying STI relationships' do
+ let(:child_bridge_model) do
+ Class.new(bridge_model) do
+ def self.name
+ 'ChildBridge'
+ end
+ end
+ end
+
+ let(:child_secondary_model) do
+ Class.new(secondary_model) do
+ def self.name
+ 'ChildSecondary'
+ end
+ end
+ end
+
+ before do
+ create_tables(<<~SQL)
+ CREATE TABLE _test_primary_records (
+ id serial NOT NULL PRIMARY KEY);
+
+ CREATE TABLE _test_bridge_records (
+ id serial NOT NULL PRIMARY KEY,
+ primary_record_id int NOT NULL,
+ type text);
+
+ CREATE TABLE _test_secondary_records (
+ id serial NOT NULL PRIMARY KEY,
+ bridge_record_id int NOT NULL,
+ type text);
+ SQL
+
+ primary_model.has_many :child_bridges, anonymous_class: child_bridge_model, foreign_key: :primary_record_id
+ child_bridge_model.has_one :child_secondary, anonymous_class: child_secondary_model, foreign_key: :bridge_record_id
+ primary_model.has_many :child_secondaries, through: :child_bridges, anonymous_class: child_secondary_model, disable_joins: true
+
+ primary_record = primary_model.create!
+ parent_bridge_record = bridge_model.create!(primary_record_id: primary_record.id)
+ child_bridge_record = child_bridge_model.create!(primary_record_id: primary_record.id)
+
+ secondary_model.create!(bridge_record_id: child_bridge_record.id)
+ child_secondary_model.create!(bridge_record_id: parent_bridge_record.id)
+ child_secondary_model.create!(bridge_record_id: child_bridge_record.id)
+ end
+
+ it 'filters correctly by the STI type across multiple queries' do
+ primary_record = primary_model.first
+
+ query_recorder = ActiveRecord::QueryRecorder.new do
+ expect(primary_record.child_secondaries.count).to eq(1)
+ end
+
+ expect(query_recorder.count).to eq(2)
+ end
+ end
+
+ context 'querying polymorphic relationships' do
+ before do
+ create_tables(<<~SQL)
+ CREATE TABLE _test_primary_records (
+ id serial NOT NULL PRIMARY KEY);
+
+ CREATE TABLE _test_bridge_records (
+ id serial NOT NULL PRIMARY KEY,
+ primaryable_id int NOT NULL,
+ primaryable_type text NOT NULL);
+
+ CREATE TABLE _test_secondary_records (
+ id serial NOT NULL PRIMARY KEY,
+ bridgeable_id int NOT NULL,
+ bridgeable_type text NOT NULL);
+ SQL
+
+ primary_model.has_many :test_bridges, anonymous_class: bridge_model, foreign_key: :primaryable_id, as: :primaryable
+ bridge_model.has_one :test_secondaries, anonymous_class: secondary_model, foreign_key: :bridgeable_id, as: :bridgeable
+ primary_model.has_many :test_secondaries, through: :test_bridges, anonymous_class: secondary_model, disable_joins: true
+
+ primary_record = primary_model.create!
+ primary_bridge_record = bridge_model.create!(primaryable_id: primary_record.id, primaryable_type: 'TestPrimary')
+ nonprimary_bridge_record = bridge_model.create!(primaryable_id: primary_record.id, primaryable_type: 'NonPrimary')
+
+ secondary_model.create!(bridgeable_id: primary_bridge_record.id, bridgeable_type: 'TestBridge')
+ secondary_model.create!(bridgeable_id: nonprimary_bridge_record.id, bridgeable_type: 'TestBridge')
+ secondary_model.create!(bridgeable_id: primary_bridge_record.id, bridgeable_type: 'NonBridge')
+ end
+
+ it 'filters correctly by the polymorphic type across multiple queries' do
+ primary_record = primary_model.first
+
+ query_recorder = ActiveRecord::QueryRecorder.new do
+ expect(primary_record.test_secondaries.count).to eq(1)
+ end
+
+ expect(query_recorder.count).to eq(2)
+ end
+ end
+
+ def create_tables(table_sql)
+ ApplicationRecord.connection.execute(table_sql)
+
+ bridge_model.reset_column_information
+ secondary_model.reset_column_information
+ end
+end
diff --git a/spec/initializers/0_log_deprecations_spec.rb b/spec/initializers/0_log_deprecations_spec.rb
new file mode 100644
index 00000000000..35bceb2f132
--- /dev/null
+++ b/spec/initializers/0_log_deprecations_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe '0_log_deprecations' do
+ def load_initializer
+ load Rails.root.join('config/initializers/0_log_deprecations.rb')
+ end
+
+ let(:env_var) { '1' }
+
+ before do
+ stub_env('GITLAB_LOG_DEPRECATIONS', env_var)
+ load_initializer
+ end
+
+ after do
+ # reset state changed by initializer
+ Warning.clear
+ ActiveSupport::Notifications.unsubscribe('deprecation.rails')
+ end
+
+ context 'for Ruby deprecations' do
+ context 'when catching deprecations through Kernel#warn' do
+ it 'also logs them to deprecation logger' do
+ expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
+ message: 'ABC gem is deprecated',
+ source: 'ruby'
+ )
+
+ expect { warn('ABC gem is deprecated') }.to output.to_stderr
+ end
+ end
+
+ context 'for other messages from Kernel#warn' do
+ it 'does not log them to deprecation logger' do
+ expect(Gitlab::DeprecationJsonLogger).not_to receive(:info)
+
+ expect { warn('Sure is hot today') }.to output.to_stderr
+ end
+ end
+
+ context 'when disabled via environment' do
+ let(:env_var) { '0' }
+
+ it 'does not log them to deprecation logger' do
+ expect(Gitlab::DeprecationJsonLogger).not_to receive(:info)
+
+ expect { warn('ABC gem is deprecated') }.to output.to_stderr
+ end
+ end
+ end
+
+ context 'for Rails deprecations' do
+ it 'logs them to deprecation logger' do
+ expect(Gitlab::DeprecationJsonLogger).to receive(:info).with(
+ message: match(/^DEPRECATION WARNING: ABC will be removed/),
+ source: 'rails'
+ )
+
+ expect { ActiveSupport::Deprecation.warn('ABC will be removed') }.to output.to_stderr
+ end
+
+ context 'when disabled via environment' do
+ let(:env_var) { '0' }
+
+ it 'does not log them to deprecation logger' do
+ expect(Gitlab::DeprecationJsonLogger).not_to receive(:info)
+
+ expect { ActiveSupport::Deprecation.warn('ABC will be removed') }.to output.to_stderr
+ end
+ end
+ end
+end
diff --git a/spec/initializers/database_config_spec.rb b/spec/initializers/database_config_spec.rb
index f1b353d4012..5ddfbd64c23 100644
--- a/spec/initializers/database_config_spec.rb
+++ b/spec/initializers/database_config_spec.rb
@@ -21,37 +21,31 @@ RSpec.describe 'Database config initializer' do
let(:max_threads) { 8 }
- context "no existing pool size is set" do
- before do
- stub_database_config(pool_size: nil)
- end
+ it 'retains the correct database name for the connection' do
+ previous_db_name = Gitlab::Database.main.scope.connection.pool.db_config.name
- it "sets it based on the max number of worker threads" do
- expect { subject }.to change { Gitlab::Database.config['pool'] }.from(nil).to(18)
+ subject
- expect(ActiveRecord::Base.connection_db_config.pool).to eq(18)
- end
+ expect(Gitlab::Database.main.scope.connection.pool.db_config.name).to eq(previous_db_name)
end
- context "the existing pool size is smaller than the max number of worker threads" do
- before do
- stub_database_config(pool_size: 1)
- end
+ context 'when no custom headroom is specified' do
+ it 'sets the pool size based on the number of worker threads' do
+ old = ActiveRecord::Base.connection_db_config.pool
- it "sets it based on the max number of worker threads" do
- expect { subject }.to change { Gitlab::Database.config['pool'] }.from(1).to(18)
+ expect(old).not_to eq(18)
- expect(ActiveRecord::Base.connection_db_config.pool).to eq(18)
+ expect { subject }
+ .to change { ActiveRecord::Base.connection_db_config.pool }
+ .from(old)
+ .to(18)
end
- end
- context "and the existing pool size is larger than the max number of worker threads" do
- before do
- stub_database_config(pool_size: 100)
- end
+ it 'overwrites custom pool settings' do
+ config = Gitlab::Database.main.config.merge(pool: 42)
- it "sets it based on the max number of worker threads" do
- expect { subject }.to change { Gitlab::Database.config['pool'] }.from(100).to(18)
+ allow(Gitlab::Database.main).to receive(:config).and_return(config)
+ subject
expect(ActiveRecord::Base.connection_db_config.pool).to eq(18)
end
@@ -61,25 +55,16 @@ RSpec.describe 'Database config initializer' do
let(:headroom) { 15 }
before do
- stub_database_config(pool_size: 1)
stub_env("DB_POOL_HEADROOM", headroom)
end
it "adds headroom on top of the calculated size" do
- expect { subject }.to change { Gitlab::Database.config['pool'] }
- .from(1)
- .to(max_threads + headroom)
+ old = ActiveRecord::Base.connection_db_config.pool
- expect(ActiveRecord::Base.connection_db_config.pool).to eq(max_threads + headroom)
+ expect { subject }
+ .to change { ActiveRecord::Base.connection_db_config.pool }
+ .from(old)
+ .to(23)
end
end
-
- def stub_database_config(pool_size:)
- original_config = Gitlab::Database.config
-
- config = original_config.dup
- config['pool'] = pool_size
-
- allow(Gitlab::Database).to receive(:config).and_return(config)
- end
end
diff --git a/spec/initializers/lograge_spec.rb b/spec/initializers/lograge_spec.rb
index a1fd9be299b..4d2aa6e74de 100644
--- a/spec/initializers/lograge_spec.rb
+++ b/spec/initializers/lograge_spec.rb
@@ -120,7 +120,6 @@ RSpec.describe 'lograge', type: :request do
context 'with a log subscriber' do
include_context 'parsed logs'
- include_context 'clear DB Load Balancing configuration'
let(:subscriber) { Lograge::LogSubscribers::ActionController.new }
@@ -212,7 +211,7 @@ RSpec.describe 'lograge', type: :request do
end
before do
- ActiveRecord::Base.connection.execute('SELECT pg_sleep(0.1);')
+ ApplicationRecord.connection.execute('SELECT pg_sleep(0.1);')
end
context 'when RequestStore is enabled', :request_store do
diff --git a/spec/initializers/rails_asset_host_spec.rb b/spec/initializers/rails_asset_host_spec.rb
new file mode 100644
index 00000000000..eb69c1fa85b
--- /dev/null
+++ b/spec/initializers/rails_asset_host_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Rails asset host initializer' do
+ def load_initializer
+ load Rails.root.join('config/initializers/rails_asset_host.rb')
+ end
+
+ around do |example|
+ old_asset_host = Rails.application.config.action_controller.asset_host
+
+ example.run
+
+ Rails.application.config.action_controller.asset_host = old_asset_host
+ ActionController::Base.asset_host = old_asset_host
+ end
+
+ subject { Rails.application.config.action_controller.asset_host }
+
+ it 'uses no asset host by default' do
+ load_initializer
+
+ expect(subject).to be nil
+ end
+
+ context 'with cdn_host defined in gitlab.yml' do
+ before do
+ stub_config_setting(cdn_host: 'https://gitlab.example.com')
+ end
+
+ it 'returns https://gitlab.example.com' do
+ load_initializer
+
+ expect(subject).to eq('https://gitlab.example.com')
+ end
+ end
+end