Commit 9a90e5d2 authored by Michael Kozono's avatar Michael Kozono

Merge branch '8798-refactor-project-registry-finder' into 'master'

Geo - Refactor the `Geo::ProjectRegistryFinder` class

See merge request gitlab-org/gitlab-ee!10529
parents c3292e65 f04739cd
......@@ -22,30 +22,16 @@ module Geo
end
def execute
if selective_sync?
mismatch_registries_for_selective_sync
else
mismatch_registries
end
end
private
attr_reader :type
def mismatch_registries
Geo::ProjectRegistry.mismatch(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def mismatch_registries_for_selective_sync
legacy_inner_join_registry_ids(
mismatch_registries,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.mismatch(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
......@@ -22,30 +22,16 @@ module Geo
end
def execute
if selective_sync?
registries_retrying_verification_for_selective_sync
else
registries_retrying_verification
end
end
private
attr_reader :type
def registries_retrying_verification
Geo::ProjectRegistry.retrying_verification(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def registries_retrying_verification_for_selective_sync
legacy_inner_join_registry_ids(
registries_retrying_verification,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.retrying_verification(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
......@@ -2,7 +2,7 @@
# Finder for retrieving project registries that synchronization have
# failed scoped to a type (repository or wiki) using cross-database
# joins for selective sync.
# joins.
#
# Basic usage:
#
......@@ -22,30 +22,16 @@ module Geo
end
def execute
if selective_sync?
failed_registries_for_selective_sync
else
failed_registries
end
end
private
attr_reader :type
def failed_registries
Geo::ProjectRegistry.sync_failed(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def failed_registries_for_selective_sync
legacy_inner_join_registry_ids(
failed_registries,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.sync_failed(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
# frozen_string_literal: true
# Finder for retrieving project registries that have been synced
# scoped to a type (repository or wiki) using cross-database joins
# for selective sync.
# scoped to a type (repository or wiki) using cross-database joins.
#
# Basic usage:
#
......@@ -22,30 +21,16 @@ module Geo
end
def execute
if selective_sync?
synced_registries_for_selective_sync
else
synced_registries
end
end
private
attr_reader :type
def synced_registries
Geo::ProjectRegistry.synced(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def synced_registries_for_selective_sync
legacy_inner_join_registry_ids(
synced_registries,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.synced(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
......@@ -22,30 +22,16 @@ module Geo
end
def execute
if selective_sync?
failed_registries_for_selective_sync
else
failed_registries
end
end
private
attr_reader :type
def failed_registries
Geo::ProjectRegistry.verification_failed(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def failed_registries_for_selective_sync
legacy_inner_join_registry_ids(
failed_registries,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.verification_failed(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
# frozen_string_literal: true
# Finder for retrieving project registries that have been verified
# scoped to a type (repository or wiki) using cross-database joins
# for selective sync.
# scoped to a type (repository or wiki) using cross-database joins.
#
# Basic usage:
#
......@@ -22,30 +21,16 @@ module Geo
end
def execute
if selective_sync?
verified_registries_for_selective_sync
else
verified_registries
end
end
private
attr_reader :type
def verified_registries
Geo::ProjectRegistry.verified(type)
end
# rubocop: disable CodeReuse/ActiveRecord
def verified_registries_for_selective_sync
legacy_inner_join_registry_ids(
verified_registries,
current_node.projects.pluck(:id),
Geo::ProjectRegistry.verified(type),
current_node.projects.pluck_primary_key,
Geo::ProjectRegistry,
foreign_key: :project_id
)
end
# rubocop: enable CodeReuse/ActiveRecord
private
attr_reader :type
end
end
......@@ -163,15 +163,19 @@ module Geo
private
def fdw_disabled?
!Gitlab::Geo::Fdw.enabled?
end
def use_legacy_queries_for_selective_sync?
selective_sync? && !Gitlab::Geo::Fdw.enabled_for_selective_sync?
fdw_disabled? || selective_sync? && !Gitlab::Geo::Fdw.enabled_for_selective_sync?
end
def finder_klass_for_synced_registries
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistrySyncedFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistrySyncedFinder
else
Geo::ProjectRegistrySyncedFinder
end
end
......@@ -182,10 +186,10 @@ module Geo
end
def finder_klass_for_failed_registries
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistrySyncFailedFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistrySyncFailedFinder
else
Geo::ProjectRegistrySyncFailedFinder
end
end
......@@ -196,10 +200,10 @@ module Geo
end
def finder_klass_for_verified_registries
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistryVerifiedFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistryVerifiedFinder
else
Geo::ProjectRegistryVerifiedFinder
end
end
......@@ -210,10 +214,10 @@ module Geo
end
def finder_klass_for_verification_failed_registries
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistryVerificationFailedFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistryVerificationFailedFinder
else
Geo::ProjectRegistryVerificationFailedFinder
end
end
......@@ -224,10 +228,10 @@ module Geo
end
def finder_klass_for_registries_retrying_verification
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistryRetryingVerificationFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistryRetryingVerificationFinder
else
Geo::ProjectRegistryRetryingVerificationFinder
end
end
......@@ -238,10 +242,10 @@ module Geo
end
def finder_klass_for_mismatch_registries
if Gitlab::Geo::Fdw.enabled_for_selective_sync?
Geo::ProjectRegistryMismatchFinder
else
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistryMismatchFinder
else
Geo::ProjectRegistryMismatchFinder
end
end
......@@ -252,7 +256,7 @@ module Geo
end
def finder_klass_for_registries_pending_verification
if !Gitlab::Geo::Fdw.enabled? || use_legacy_queries_for_selective_sync?
if use_legacy_queries_for_selective_sync?
Geo::LegacyProjectRegistryPendingVerificationFinder
else
Geo::ProjectRegistryPendingVerificationFinder
......
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistryMismatchFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,102 +20,82 @@ describe Geo::LegacyProjectRegistryMismatchFinder, :geo do
let!(:registry_repository_mismatch_broken_shard) { create(:geo_project_registry, :repository_checksum_mismatch, :wiki_verified, project: project_5) }
let!(:registry_verified) { create(:geo_project_registry, :repository_verified, :wiki_verified) }
shared_examples 'finds mismatch registries' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_repository_mismatch_broken_shard)
end
end
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch)
end
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_repository_mismatch_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_repository_mismatch_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch)
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_wiki_mismatch, registry_wiki_mismatch_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_repository_mismatch_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to contain_exactly(registry_mismatch, registry_wiki_mismatch)
end
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_wiki_mismatch, registry_wiki_mismatch_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_wiki_mismatch_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_mismatch, registry_wiki_mismatch)
end
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_wiki_mismatch, registry_repository_mismatch_broken_shard, registry_wiki_mismatch_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_wiki_mismatch_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns all mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_wiki_mismatch)
end
context 'without selective sync' do
it 'returns all mismatch registries' do
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_wiki_mismatch, registry_repository_mismatch_broken_shard, registry_wiki_mismatch_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns all mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns all mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_repository_mismatch_broken_shard, registry_wiki_mismatch_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_wiki_mismatch)
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
include_examples 'finds mismatch registries'
end
context 'with selective sync by shard' do
it 'returns all mismatch registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'Legacy' do
before do
stub_fdw_disabled
expect(subject.execute).to contain_exactly(registry_repository_mismatch_broken_shard, registry_wiki_mismatch_broken_shard)
end
end
include_examples 'finds mismatch registries'
end
end
end
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistryPendingVerificationFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
......@@ -145,7 +143,7 @@ describe Geo::LegacyProjectRegistryPendingVerificationFinder, :geo do
registry_outdated_secondary = create(:geo_project_registry, :synced, :repository_verification_outdated, :wiki_verification_outdated, project: project_2)
create(:geo_project_registry, :synced, :repository_verification_outdated, :wiki_verified, project: project_3)
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute)
.to contain_exactly(
......
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistryRetryingVerificationFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,98 +20,78 @@ describe Geo::LegacyProjectRegistryRetryingVerificationFinder, :geo do
let!(:repository_retrying_verification_broken_shard) { create(:geo_project_registry, :repository_retrying_verification, :wiki_verified, project: project_5) }
let!(:verified) { create(:geo_project_registry, :repository_verified, :wiki_verified) }
shared_examples 'finds registries retrying verification' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all registries retrying verification' do
expect(subject.execute).to contain_exactly(retrying_verification, repository_retrying_verification, repository_retrying_verification_broken_shard)
end
end
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
expect(subject.execute).to contain_exactly(retrying_verification, repository_retrying_verification)
end
context 'without selective sync' do
it 'returns all registries retrying verification' do
expect(subject.execute).to contain_exactly(retrying_verification, repository_retrying_verification, repository_retrying_verification_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns registries retrying verification where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(repository_retrying_verification_broken_shard)
end
expect(subject.execute).to contain_exactly(retrying_verification, repository_retrying_verification)
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns registries retrying verification where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all registries retrying verification' do
expect(subject.execute).to contain_exactly(retrying_verification, wiki_retrying_verification, wiki_retrying_verification_broken_shard)
end
expect(subject.execute).to contain_exactly(repository_retrying_verification_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to contain_exactly(retrying_verification, wiki_retrying_verification)
end
context 'without selective sync' do
it 'returns all registries retrying verification' do
expect(subject.execute).to contain_exactly(retrying_verification, wiki_retrying_verification, wiki_retrying_verification_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns registries retrying verification where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(wiki_retrying_verification_broken_shard)
end
expect(subject.execute).to contain_exactly(retrying_verification, wiki_retrying_verification)
end
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns registries retrying verification where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
expect(subject.execute).to contain_exactly(wiki_retrying_verification_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
context 'without selective sync' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
context 'with selective sync by namespace' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
end
include_examples 'finds registries retrying verification'
end
context 'Legacy' do
before do
stub_fdw_disabled
context 'with selective sync by shard' do
it 'returns nothing' do
expect(subject.execute).to be_empty
end
end
include_examples 'finds registries retrying verification'
end
end
end
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistrySyncFailedFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,102 +20,82 @@ describe Geo::LegacyProjectRegistrySyncFailedFinder, :geo do
let!(:registry_repository_failed_broken_shard) { create(:geo_project_registry, :synced, :repository_sync_failed, project: project_5) }
let!(:registry_synced) { create(:geo_project_registry, :synced) }
shared_examples 'finds failed registries' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_repository_failed_broken_shard])
end
end
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
expect(subject.execute).to match_array([registry_failed, registry_repository_failed])
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_repository_failed_broken_shard])
end
end
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_repository_failed_broken_shard])
end
expect(subject.execute).to match_array([registry_failed, registry_repository_failed])
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_wiki_failed, registry_wiki_failed_broken_shard])
end
expect(subject.execute).to match_array([registry_repository_failed_broken_shard])
end
end
end
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to match_array([registry_failed, registry_wiki_failed])
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_wiki_failed, registry_wiki_failed_broken_shard])
end
end
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_wiki_failed_broken_shard])
end
expect(subject.execute).to match_array([registry_failed, registry_wiki_failed])
end
end
context 'with no type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_wiki_failed, registry_repository_failed_broken_shard, registry_wiki_failed_broken_shard])
end
expect(subject.execute).to match_array([registry_wiki_failed_broken_shard])
end
end
end
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with no type' do
subject { described_class.new(current_node: node, type: :invalid) }
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_wiki_failed])
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_wiki_failed, registry_repository_failed_broken_shard, registry_wiki_failed_broken_shard])
end
end
context 'with selective sync by shard' do
it 'returns all failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_repository_failed_broken_shard, registry_wiki_failed_broken_shard])
end
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_wiki_failed])
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
include_examples 'finds failed registries'
end
context 'with selective sync by shard' do
it 'returns all failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'Legacy' do
before do
stub_fdw_disabled
expect(subject.execute).to match_array([registry_repository_failed_broken_shard, registry_wiki_failed_broken_shard])
end
end
include_examples 'finds failed registries'
end
end
end
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistrySyncedFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,84 +20,64 @@ describe Geo::LegacyProjectRegistrySyncedFinder, :geo do
let!(:registry_repository_dirty_broken_shard) { create(:geo_project_registry, :synced, :repository_dirty, project: project_5) }
let!(:registry_sync_failed) { create(:geo_project_registry, :sync_failed) }
shared_examples 'finds synced registries' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all synced registries' do
expect(subject.execute).to match_array([registry_synced, registry_wiki_dirty, registry_wiki_dirty_broken_shard])
end
end
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
expect(subject.execute).to match_array([registry_synced, registry_wiki_dirty])
end
context 'without selective sync' do
it 'returns all synced registries' do
expect(subject.execute).to match_array([registry_synced, registry_wiki_dirty, registry_wiki_dirty_broken_shard])
end
end
context 'with selective sync by shard' do
it 'returns synced registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_wiki_dirty_broken_shard])
end
expect(subject.execute).to match_array([registry_synced, registry_wiki_dirty])
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns synced registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all synced registries' do
expect(subject.execute).to match_array([registry_synced, registry_repository_dirty, registry_repository_dirty_broken_shard])
end
expect(subject.execute).to match_array([registry_wiki_dirty_broken_shard])
end
end
end
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to match_array([registry_synced, registry_repository_dirty])
end
context 'without selective sync' do
it 'returns all synced registries' do
expect(subject.execute).to match_array([registry_synced, registry_repository_dirty, registry_repository_dirty_broken_shard])
end
end
context 'with selective sync by shard' do
it 'returns synced registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_repository_dirty_broken_shard])
end
expect(subject.execute).to match_array([registry_synced, registry_repository_dirty])
end
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns synced registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
it 'returns nothing' do
expect(subject.execute).to be_empty
expect(subject.execute).to match_array([registry_repository_dirty_broken_shard])
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
include_examples 'finds synced registries'
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'Legacy' do
before do
stub_fdw_disabled
it 'returns nothing' do
expect(subject.execute).to be_empty
end
include_examples 'finds synced registries'
end
end
end
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistryVerificationFailedFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,102 +20,82 @@ describe Geo::LegacyProjectRegistryVerificationFailedFinder, :geo do
let!(:registry_repository_verification_failed_broken_shard) { create(:geo_project_registry, :repository_verification_failed, :wiki_verified, project: project_5) }
let!(:registry_verified) { create(:geo_project_registry, :repository_verified, :wiki_verified) }
shared_examples 'finds registries that verification failed' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_repository_verification_failed_broken_shard)
end
end
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed)
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_repository_verification_failed_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed)
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_wiki_verification_failed, registry_wiki_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_wiki_verification_failed)
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_wiki_verification_failed, registry_wiki_verification_failed_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_wiki_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_wiki_verification_failed)
end
end
context 'with no type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_wiki_verification_failed, registry_repository_verification_failed_broken_shard, registry_wiki_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_wiki_verification_failed_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with no type' do
subject { described_class.new(current_node: node, type: :invalid) }
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_wiki_verification_failed)
end
context 'without selective sync' do
it 'returns all failed registries' do
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_wiki_verification_failed, registry_repository_verification_failed_broken_shard, registry_wiki_verification_failed_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns all failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard, registry_wiki_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_wiki_verification_failed)
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
include_examples 'finds registries that verification failed'
end
context 'with selective sync by shard' do
it 'returns all failed registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'Legacy' do
before do
stub_fdw_disabled
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard, registry_wiki_verification_failed_broken_shard)
end
end
include_examples 'finds registries that verification failed'
end
end
end
......@@ -3,8 +3,6 @@
require 'spec_helper'
describe Geo::LegacyProjectRegistryVerifiedFinder, :geo do
include EE::GeoHelpers
describe '#execute' do
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
......@@ -22,84 +20,64 @@ describe Geo::LegacyProjectRegistryVerifiedFinder, :geo do
let!(:registry_wiki_verification_failed_broken_shard) { create(:geo_project_registry, :repository_verified, :wiki_verification_failed, project: project_4) }
let!(:registry_verification_failed) { create(:geo_project_registry, :repository_verification_failed, :wiki_verification_failed) }
shared_examples 'finds verified registries' do
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
context 'without selective sync' do
it 'returns all verified registries' do
expect(subject.execute).to contain_exactly(registry_verified, registry_wiki_verification_failed, registry_wiki_verification_failed_broken_shard)
end
end
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with repository type' do
subject { described_class.new(current_node: node, type: :repository) }
expect(subject.execute).to contain_exactly(registry_verified, registry_wiki_verification_failed)
end
context 'without selective sync' do
it 'returns all verified registries' do
expect(subject.execute).to contain_exactly(registry_verified, registry_wiki_verification_failed, registry_wiki_verification_failed_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns verified registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_wiki_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_verified, registry_wiki_verification_failed)
end
end
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
context 'with selective sync by shard' do
it 'returns verified registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'without selective sync' do
it 'returns all verified registries' do
expect(subject.execute).to contain_exactly(registry_verified, registry_repository_verification_failed, registry_repository_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_wiki_verification_failed_broken_shard)
end
end
end
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
context 'with wiki type' do
subject { described_class.new(current_node: node, type: :wiki) }
expect(subject.execute).to contain_exactly(registry_verified, registry_repository_verification_failed)
end
context 'without selective sync' do
it 'returns all verified registries' do
expect(subject.execute).to contain_exactly(registry_verified, registry_repository_verification_failed, registry_repository_verification_failed_broken_shard)
end
end
context 'with selective sync by shard' do
it 'returns verified registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard)
end
expect(subject.execute).to contain_exactly(registry_verified, registry_repository_verification_failed)
end
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'with selective sync by shard' do
it 'returns verified registries where projects belongs to the shards' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: ['broken'])
it 'returns nothing' do
expect(subject.execute).to be_empty
expect(subject.execute).to contain_exactly(registry_repository_verification_failed_broken_shard)
end
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
context 'FDW', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
include_examples 'finds verified registries'
end
context 'with invalid type' do
subject { described_class.new(current_node: node, type: :invalid) }
context 'Legacy' do
before do
stub_fdw_disabled
it 'returns nothing' do
expect(subject.execute).to be_empty
end
include_examples 'finds verified registries'
end
end
end
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistryMismatchFinder, :geo do
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch)
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistryMismatchFinder, :geo do
context 'with selective sync by namespace' do
it 'returns mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_mismatch, registry_wiki_mismatch)
end
......@@ -89,7 +89,7 @@ describe Geo::ProjectRegistryMismatchFinder, :geo do
context 'with selective sync by namespace' do
it 'returns all mismatch registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_mismatch, registry_repository_mismatch, registry_wiki_mismatch)
end
......
......@@ -149,7 +149,7 @@ describe Geo::ProjectRegistryPendingVerificationFinder, :geo do
registry_outdated_secondary = create(:geo_project_registry, :synced, :repository_verification_outdated, :wiki_verification_outdated, project: project_2)
create(:geo_project_registry, :synced, :repository_verification_outdated, :wiki_verified, project: project_3)
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute)
.to contain_exactly(
......
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistryRetryingVerificationFinder, :geo do
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(retrying_verification, repository_retrying_verification)
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistryRetryingVerificationFinder, :geo do
context 'with selective sync by namespace' do
it 'returns registries retrying verification where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(retrying_verification, wiki_retrying_verification)
end
......
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistrySyncFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_failed, registry_repository_failed])
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistrySyncFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_failed, registry_wiki_failed])
end
......@@ -89,7 +89,7 @@ describe Geo::ProjectRegistrySyncFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_failed, registry_repository_failed, registry_wiki_failed])
end
......
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistrySyncedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_synced, registry_wiki_dirty])
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistrySyncedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns synced registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to match_array([registry_synced, registry_repository_dirty])
end
......
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistryVerificationFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed)
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistryVerificationFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_wiki_verification_failed)
end
......@@ -89,7 +89,7 @@ describe Geo::ProjectRegistryVerificationFailedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns all failed registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_verification_failed, registry_repository_verification_failed, registry_wiki_verification_failed)
end
......
......@@ -37,7 +37,7 @@ describe Geo::ProjectRegistryVerifiedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_verified, registry_wiki_verification_failed)
end
......@@ -63,7 +63,7 @@ describe Geo::ProjectRegistryVerifiedFinder, :geo do
context 'with selective sync by namespace' do
it 'returns verified registries where projects belongs to the namespaces' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.execute).to contain_exactly(registry_verified, registry_repository_verification_failed)
end
......
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