Commit 02e16190 authored by Gabriel Mazetto's avatar Gabriel Mazetto Committed by Nick Thomas

FDW status of Geo secondaries in Geo Node screen

parent dcb0fe88
---
title: 'Geo: FDW issues are displayed in the Geo Node Admin UI'
merge_request: 4266
author:
type: added
module Geo
class ExpireUploadsFinder
def find_project_uploads(project)
if Gitlab::Geo.fdw?
if Gitlab::Geo::Fdw.enabled?
fdw_find_project_uploads(project)
else
legacy_find_project_uploads(project)
......@@ -9,7 +9,7 @@ module Geo
end
def find_file_registries_uploads(project)
if Gitlab::Geo.fdw?
if Gitlab::Geo::Fdw.enabled?
fdw_find_file_registries_uploads(project)
else
legacy_find_file_registries_uploads(project)
......
......@@ -15,13 +15,13 @@ module Geo
# slow COUNT queries on large tables. For more details, see this link:
# https://www.enterprisedb.com/blog/postgresql-aggregate-push-down-postgresfdw
def aggregate_pushdown_supported?
Gitlab::Geo.fdw? && Gitlab::Database.version.to_f >= 10.0
Gitlab::Geo::Fdw.enabled? && Gitlab::Database.version.to_f >= 10.0
end
def use_legacy_queries?
# Selective project replication adds a wrinkle to FDW
# queries, so we fallback to the legacy version for now.
!Gitlab::Geo.fdw? || selective_sync?
!Gitlab::Geo::Fdw.enabled? || selective_sync?
end
def legacy_inner_join_registry_ids(objects, registry_ids, klass, foreign_key: :id)
......
......@@ -2,7 +2,7 @@ module Geo
module Fdw
module Ci
class JobArtifact < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('ci_job_artifacts')
self.table_name = Gitlab::Geo::Fdw.table('ci_job_artifacts')
scope :with_files_stored_locally, -> { where(file_store: [nil, JobArtifactUploader::Store::LOCAL]) }
end
......
module Geo
module Fdw
class LfsObject < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('lfs_objects')
self.table_name = Gitlab::Geo::Fdw.table('lfs_objects')
scope :with_files_stored_locally, -> { where(file_store: [nil, LfsObjectUploader::Store::LOCAL]) }
end
......
module Geo
module Fdw
class Project < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('projects')
self.table_name = Gitlab::Geo::Fdw.table('projects')
end
end
end
module Geo
module Fdw
class ProjectFeature < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('project_features')
self.table_name = Gitlab::Geo::Fdw.table('project_features')
end
end
end
module Geo
module Fdw
class Upload < ::Geo::BaseFdw
self.table_name = Gitlab::Geo.fdw_table('uploads')
self.table_name = Gitlab::Geo::Fdw.table('uploads')
scope :with_files_stored_locally, -> { where(store: [nil, ObjectStorage::Store::LOCAL]) }
end
......
......@@ -12,8 +12,6 @@ module Gitlab
geo_oauth_application
).freeze
FDW_SCHEMA = 'gitlab_secondary'.freeze
def self.current_node
self.cache_value(:geo_node_current) { GeoNode.current_node }
end
......@@ -65,26 +63,6 @@ module Gitlab
::License.feature_available?(:geo)
end
def self.fdw_capable?
self.cache_value(:geo_fdw_capable?) do
::Geo::TrackingBase.connection.execute(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '#{FDW_SCHEMA}' AND table_type = 'FOREIGN TABLE'"
).first.fetch('count').to_i.positive?
end
end
def self.fdw?
return false unless self.fdw_capable?
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value = Rails.configuration.geo_database['fdw']
value.nil? ? true : value
end
def self.fdw_table(table_name)
FDW_SCHEMA + ".#{table_name}"
end
def self.configure_cron_jobs!
manager = CronManager.new
manager.create_watcher!
......
module Gitlab
module Geo
module Fdw
DEFAULT_SCHEMA = 'public'.freeze
FDW_SCHEMA = 'gitlab_secondary'.freeze
# Return full table name with FDW schema
#
# @param [String] table_name
def self.table(table_name)
FDW_SCHEMA + ".#{table_name}"
end
# Return if FDW is enabled for this instance
#
# @return [Boolean] whether FDW is enabled
def self.enabled?
return false unless fdw_capable?
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value = Rails.configuration.geo_database['fdw']
value.nil? ? true : value
end
def self.fdw_capable?
has_foreign_schema? && connection_exist? && count_tables.positive?
end
def self.fdw_up_to_date?
has_foreign_schema? && foreign_schema_tables_match?
end
def self.has_foreign_schema?
Gitlab::Geo.cache_value(:geo_fdw_schema_exist) do
sql = <<~SQL
SELECT 1
FROM information_schema.schemata
WHERE schema_name='#{FDW_SCHEMA}'
SQL
::Geo::TrackingBase.connection.execute(sql).count.positive?
end
end
# Check if there is at least one FDW connection configured
#
# @return [Boolean] whether any FDW connection exists
def self.connection_exist?
::Geo::TrackingBase.connection.execute(
"SELECT 1 FROM pg_foreign_server"
).count.positive?
end
# Number of existing tables
#
# @return [Integer] number of tables
def self.count_tables
Gitlab::Geo.cache_value(:geo_fdw_count_tables) do
sql = <<~SQL
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '#{FDW_SCHEMA}'
AND table_type = 'FOREIGN TABLE'
SQL
::Geo::TrackingBase.connection.execute(sql).first.fetch('count').to_i
end
end
# Check if foreign schema has exact the same tables and fields defined on secondary database
#
# @return [Boolean] whether schemas match and are not empty
def self.foreign_schema_tables_match?
Gitlab::Geo.cache_value(:geo_fdw_schema_tables_match) do
secondary = retrieve_schema_tables(ActiveRecord::Base, ActiveRecord::Base.connection_config[:database], DEFAULT_SCHEMA)
fdw = retrieve_schema_tables(::Geo::TrackingBase, Rails.configuration.geo_database['database'], FDW_SCHEMA)
s = secondary.to_a
f = fdw.to_a
s.present? && s == f
end
end
def self.count_tables_match?
ActiveRecord::Schema.tables.count == count_tables
end
def self.retrieve_schema_tables(adapter, database, schema)
sql = <<~SQL
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_catalog = '#{database}'
AND table_schema = '#{schema}'
ORDER BY table_name, column_name, data_type
SQL
adapter.connection.execute(sql)
end
private_class_method :retrieve_schema_tables
end
end
end
......@@ -53,7 +53,7 @@ module Gitlab
sql = <<~SQL
SELECT count(1)
FROM pg_foreign_server
WHERE srvname = '#{Gitlab::Geo::FDW_SCHEMA}';
WHERE srvname = '#{Gitlab::Geo::Fdw::FDW_SCHEMA}';
SQL
Gitlab::Geo::DatabaseTasks.with_geo_db do
......
......@@ -13,11 +13,19 @@ module Gitlab
migration_version = self.get_migration_version.to_i
if database_version != migration_version
"Current Geo database version (#{database_version}) does not match latest migration (#{migration_version}).\n"\
"You may have to run `gitlab-rake geo:db:migrate` as root on the secondary."
else
''
return "Current Geo database version (#{database_version}) does not match latest migration (#{migration_version}).\n"\
'You may have to run `gitlab-rake geo:db:migrate` as root on the secondary.'
end
return 'The Geo database is not configured to use Foreign Data Wrapper.' unless Gitlab::Geo::Fdw.enabled?
unless Gitlab::Geo::Fdw.fdw_up_to_date?
return "The Geo database has an outdated FDW remote schema.".tap do |output|
output << " It contains #{Gitlab::Geo::Fdw.count_tables} of #{ActiveRecord::Schema.tables.count} expected tables." unless Gitlab::Geo::Fdw.count_tables_match?
end
end
return ''
rescue => e
e.message
end
......
module SystemCheck
module Geo
class FdwEnabledCheck < SystemCheck::BaseCheck
set_name 'GitLab Geo tracking database is configured to use Foreign Data Wrapper?'
set_skip_reason 'Geo is not enabled'
def skip?
!Gitlab::Geo.enabled?
end
def check?
Gitlab::Geo::Fdw.enabled?
end
def show_error
try_fixing_it(
'Follow Geo setup instructions to configure secondary nodes with FDW support',
'If you upgraded recently check for any new step required to enable FDW'
)
for_more_information('doc/gitlab-geo/database.md')
end
end
end
end
module SystemCheck
module Geo
class FdwSchemaUptoDateCheck < SystemCheck::BaseCheck
set_name 'GitLab Geo tracking database is configured to use Foreign Data Wrapper?'
set_skip_reason 'Geo is not enabled'
def skip?
unless Gitlab::Geo.enabled?
self.skip_reason = 'Geo is not enabled'
return true
end
unless Gitlab::Geo::Fdw.enabled?
self.skip_reason = 'Foreign Data Wrapper is not configured'
return true
end
false
end
def check?
Gitlab::Geo::Fdw.fdw_up_to_date?
end
def show_error
try_fixing_it(
'Follow Geo setup instructions to configure secondary nodes with FDW support',
'If you upgraded recently check for any new step required to enable FDW',
'If you are using Omnibus GitLab try running:',
'gitlab-ctl reconfigure',
'If installing from source, try running:',
'bundle exec rake geo:db:refresh_foreign_tables'
)
for_more_information('doc/gitlab-geo/database.md')
end
end
end
end
......@@ -58,7 +58,7 @@ namespace :geo do
desc 'Refresh Foreign Tables definition in Geo Secondary node'
task refresh_foreign_tables: [:environment] do
if Gitlab::Geo::GeoTasks.foreign_server_configured?
print "\nRefreshing foreign tables for FDW: #{Gitlab::Geo::FDW_SCHEMA} ... "
print "\nRefreshing foreign tables for FDW: #{Gitlab::Geo::Fdw::FDW_SCHEMA} ... "
Gitlab::Geo::GeoTasks.refresh_foreign_tables!
puts 'Done!'
else
......@@ -153,6 +153,7 @@ namespace :geo do
Gitlab::Geo::DatabaseTasks::Test.purge
end
desc 'Refresh Foreign Tables definition for test environment'
task refresh_foreign_tables: [:environment] do
old_env = ActiveRecord::Tasks::DatabaseTasks.env
ActiveRecord::Tasks::DatabaseTasks.env = 'test'
......
......@@ -453,6 +453,8 @@ namespace :gitlab do
SystemCheck::Geo::EnabledCheck,
SystemCheck::Geo::GeoDatabaseConfiguredCheck,
SystemCheck::Geo::DatabaseReplicationCheck,
SystemCheck::Geo::FdwEnabledCheck,
SystemCheck::Geo::FdwSchemaUptoDateCheck,
SystemCheck::Geo::HttpConnectionCheck,
SystemCheck::Geo::HTTPCloneEnabledCheck,
SystemCheck::Geo::ClocksSynchronizationCheck,
......
......@@ -32,7 +32,7 @@ describe Geo::AttachmentRegistryFinder, :geo do
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe '#find_synced_attachments' do
......@@ -132,7 +132,7 @@ describe Geo::AttachmentRegistryFinder, :geo do
context 'Legacy' do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
describe '#find_synced_attachments' do
......
......@@ -7,7 +7,7 @@ describe Geo::ExpireUploadsFinder, :geo do
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe '#find_project_uploads' do
......@@ -75,7 +75,7 @@ describe Geo::ExpireUploadsFinder, :geo do
context 'Legacy' do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
describe '#find_project_uploads' do
......
......@@ -100,7 +100,7 @@ describe Geo::JobArtifactRegistryFinder, :geo do
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe '#find_unsynced_job_artifacts' do
......@@ -132,7 +132,7 @@ describe Geo::JobArtifactRegistryFinder, :geo do
context 'Legacy' do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
describe '#find_unsynced_job_artifacts' do
......
......@@ -107,7 +107,7 @@ describe Geo::LfsObjectRegistryFinder, :geo do
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe '#find_unsynced_lfs_objects' do
......@@ -139,7 +139,7 @@ describe Geo::LfsObjectRegistryFinder, :geo do
context 'Legacy' do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
describe '#find_unsynced_lfs_objects' do
......
......@@ -243,7 +243,7 @@ describe Geo::ProjectRegistryFinder, :geo do
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
skip('FDW is not configured') if Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe '#fdw_find_enabled_wikis' do
......@@ -313,7 +313,7 @@ describe Geo::ProjectRegistryFinder, :geo do
context 'Legacy' do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
describe '#find_unsynced_projects' do
......
require 'spec_helper'
describe Gitlab::Geo::Fdw, :geo do
include ::EE::GeoHelpers
describe 'enabled?' do
it 'returns false when PostgreSQL FDW is not enabled' do
expect(described_class).to receive(:count_tables).and_return(0)
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.enabled?).to be_falsey
end
context 'with fdw capable' do
before do
allow(described_class).to receive(:fdw_capable?).and_return(true)
end
it 'returns true by default' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => nil)
expect(described_class.enabled?).to be_truthy
end
it 'returns false if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => false)
expect(described_class.enabled?).to be_falsey
end
it 'returns true if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.enabled?).to be_truthy
end
end
end
describe 'fdw_capable?' do
context 'with mocked FDW environment' do
it 'returns true when PostgreSQL FDW is enabled' do
expect(described_class).to receive(:has_foreign_schema?).and_return(true)
expect(described_class).to receive(:count_tables).and_return(1)
expect(described_class.fdw_capable?).to be_truthy
end
it 'returns false when PostgreSQL FDW is not enabled' do
expect(described_class).to receive(:has_foreign_schema?).and_return(false)
expect(described_class.fdw_capable?).to be_falsey
end
it 'returns false when PostgreSQL FDW is enabled but remote tables are empty' do
expect(described_class).to receive(:has_foreign_schema?).and_return(true)
expect(described_class).to receive(:count_tables).and_return(0)
expect(described_class.fdw_capable?).to be_falsey
end
it 'returns false when PostgreSQL FDW is enabled but no remote connection is defined' do
expect(described_class).to receive(:has_foreign_schema?).and_return(true)
expect(described_class).to receive(:connection_exist?).and_return(false)
expect(described_class.fdw_capable?).to be_falsey
end
end
context 'with functional FDW environment' do
it 'returns true' do
expect(described_class.fdw_capable?).to be_truthy
end
end
end
describe 'fdw_up_to_date?' do
context 'with mocked FDW environment' do
it 'returns true when FDW is enabled and foreign schema has same tables as secondary database' do
expect(described_class).to receive(:has_foreign_schema?).and_return(true)
expect(described_class).to receive(:foreign_schema_tables_match?).and_return(true)
expect(described_class.fdw_up_to_date?).to be_truthy
end
it 'returns false when FDW is enabled but tables in schema doesnt match' do
expect(described_class).to receive(:has_foreign_schema?).and_return(true)
expect(described_class).to receive(:foreign_schema_tables_match?).and_return(false)
expect(described_class.fdw_up_to_date?).to be_falsey
end
it 'returns false when FDW is disabled' do
expect(described_class).to receive(:has_foreign_schema?).and_return(false)
expect(described_class.fdw_up_to_date?).to be_falsey
end
end
context 'with functional FDW environment' do
it 'returns true' do
expect(described_class.fdw_up_to_date?).to be_truthy
end
end
end
describe 'has_foreign_schema?' do
context 'with functional FDW environment' do
it 'returns true' do
# When testing it locally, make sure you have FDW setup correctly.
# If you are using GDK, you can run, from GDK root folder:
#
# make postgresql/geo-fdw/test
expect(described_class.has_foreign_schema?).to be_truthy
end
end
end
describe 'count_tables' do
context 'with functional FDW environment' do
it 'returns same amount as defined in schema migration' do
# When testing it locally, you may need to refresh FDW with:
#
# rake geo:db:test:refresh_foreign_tables
expect(described_class.count_tables).to eq(ActiveRecord::Schema.tables.count)
end
end
end
describe 'connection_exist?' do
context 'with functional FDW environment' do
it 'returns true' do
# When testing it locally, make sure you have FDW setup correctly.
# If you are using GDK, you can run, from GDK root folder:
#
# make postgresql/geo-fdw/test
expect(described_class.connection_exist?).to be_truthy
end
end
end
describe 'foreign_schema_tables_match?' do
context 'with functional FDW environment' do
it 'returns true' do
# When testing it locally, you may need to refresh FDW with:
#
# rake geo:db:test:refresh_foreign_tables
expect(described_class.foreign_schema_tables_match?).to be_truthy
end
end
end
end
require 'spec_helper'
describe Gitlab::Geo::HealthCheck, :postgresql do
describe Gitlab::Geo::HealthCheck, :geo do
set(:secondary) { create(:geo_node) }
subject { described_class }
......@@ -82,6 +82,35 @@ describe Gitlab::Geo::HealthCheck, :postgresql do
expect(subject.perform_checks).to be_empty
end
it 'returns an error when FDW is disabled' do
allow(described_class).to receive(:database_secondary?) { true }
allow(described_class).to receive(:streaming_active?) { true }
allow(Gitlab::Geo::Fdw).to receive(:enabled?) { false }
expect(subject.perform_checks).to match(/The Geo database is not configured to use Foreign Data Wrapper/)
end
it 'returns an error when FDW remote table is not in sync but has same amount of tables' do
allow(described_class).to receive(:database_secondary?) { true }
allow(described_class).to receive(:streaming_active?) { true }
allow(Gitlab::Geo::Fdw).to receive(:fdw_up_to_date?) { false }
allow(Gitlab::Geo::Fdw).to receive(:count_tables_match?) { true }
expect(subject.perform_checks).to match(/The Geo database has an outdated FDW remote schema\./)
end
it 'returns an error when FDW remote table is not in sync and has same different amount of tables' do
allow(described_class).to receive(:database_secondary?) { true }
allow(described_class).to receive(:streaming_active?) { true }
allow(Gitlab::Geo::Fdw).to receive(:fdw_up_to_date?) { false }
allow(Gitlab::Geo::Fdw).to receive(:count_tables_match?) { false }
expect(subject.perform_checks).to match(/The Geo database has an outdated FDW remote schema\. It contains [0-9]+ of [0-9]+ expected tables/)
end
end
describe 'MySQL checks' do
......
......@@ -18,59 +18,6 @@ describe Gitlab::Geo, :geo do
end
end
describe 'fdw_capable?' do
let(:fdw_check) { "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'gitlab_secondary' AND table_type = 'FOREIGN TABLE'" }
before do
allow(::Geo::TrackingBase.connection).to receive(:execute).with(anything).and_call_original
end
it 'returns true when PostgreSQL FDW is enabled' do
expect(::Geo::TrackingBase.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 1 }])
expect(described_class.fdw_capable?).to be_truthy
end
it 'returns false when PostgreSQL FDW is not enabled' do
expect(::Geo::TrackingBase.connection).to receive(:execute).with(fdw_check).and_return([{ 'count' => 0 }])
expect(described_class.fdw_capable?).to be_falsey
end
end
describe 'fdw?' do
it 'returns false when PostgreSQL FDW is not enabled' do
allow(::Geo::TrackingBase.connection).to receive(:execute).and_return([{ 'count' => 0 }])
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.fdw?).to be_falsey
end
context 'with fdw capable' do
before do
allow(described_class).to receive(:fdw_capable?).and_return(true)
end
it 'returns true by default' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => nil)
expect(described_class.fdw?).to be_truthy
end
it 'returns false if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => false)
expect(described_class.fdw?).to be_falsey
end
it 'returns true if configured in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.fdw?).to be_truthy
end
end
end
describe 'primary?' do
context 'when current node is a primary node' do
it 'returns true' do
......
......@@ -226,12 +226,12 @@ describe Geo::FileDownloadDispatchWorker, :geo do
# can't see changes inside a transaction of a different connection.
describe 'when PostgreSQL FDW is available', :geo, :delete do
# Skip if FDW isn't activated on this database
it_behaves_like '#perform', Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
it_behaves_like '#perform', Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe 'when PostgreSQL FDW is not enabled', :geo do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
it_behaves_like '#perform', false
......
......@@ -188,12 +188,12 @@ describe Geo::RepositoryShardSyncWorker, :geo, :delete, :clean_gitlab_redis_cach
describe 'when PostgreSQL FDW is available', :geo do
# Skip if FDW isn't activated on this database
it_behaves_like '#perform', Gitlab::Database.postgresql? && !Gitlab::Geo.fdw?
it_behaves_like '#perform', Gitlab::Database.postgresql? && !Gitlab::Geo::Fdw.enabled?
end
describe 'when PostgreSQL FDW is not enabled', :geo do
before do
allow(Gitlab::Geo).to receive(:fdw?).and_return(false)
allow(Gitlab::Geo::Fdw).to receive(:enabled?).and_return(false)
end
it_behaves_like '#perform', false
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment