Commit aed403db authored by Mike Kozono's avatar Mike Kozono

Refactor container repo event specs

To prepare for reuse in design repository event specs.
parent 3b69d66f
......@@ -22,6 +22,11 @@ FactoryBot.define do
trait :local_storage_only do
sync_object_storage { false }
end
trait :selective_sync_excludes_all_projects do
selective_sync_type { 'shards' }
selective_sync_shards { ['non-existent'] }
end
end
factory :geo_node_with_selective_sync_for, parent: :geo_node do
......
......@@ -6,18 +6,19 @@ RSpec.describe Gitlab::Geo::LogCursor::Events::ContainerRepositoryUpdatedEvent,
include ::EE::GeoHelpers
let_it_be(:secondary) { create(:geo_node) }
let_it_be(:selective_sync_secondary) { create(:geo_node, selective_sync_type: 'shards', selective_sync_shards: ['non-existent']) }
let_it_be(:secondary_excludes_all_projects) { create(:geo_node, :selective_sync_excludes_all_projects) }
let(:logger) { Gitlab::Geo::LogCursor::Logger.new(described_class, Logger::INFO) }
let(:event_log) { create(:geo_event_log, :container_repository_updated_event) }
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
let(:container_repository_updated_event) { event_log.container_repository_updated_event }
let(:container_repository) { container_repository_updated_event.container_repository }
let(:sync_worker_class) { ::Geo::ContainerRepositorySyncWorker }
let(:registry_class) { ::Geo::ContainerRepositoryRegistry }
let(:registry_factory) { :geo_container_repository_registry }
let(:registry_factory_args) { [:synced, container_repository: container_repository] }
let(:sync_worker_expected_arg) { container_repository.id }
subject { described_class.new(container_repository_updated_event, Time.now, logger) }
around do |example|
Sidekiq::Testing.fake! { example.run }
end
subject(:event) { described_class.new(container_repository_updated_event, Time.now, logger) }
before do
stub_current_geo_node(secondary)
......@@ -29,57 +30,46 @@ RSpec.describe Gitlab::Geo::LogCursor::Events::ContainerRepositoryUpdatedEvent,
stub_config(geo: { registry_replication: { enabled: true } })
end
context 'when a registry does not yet exist' do
context "when the container repository's project is not excluded by selective sync" do
# TODO: Fix the bug and un-x the test https://gitlab.com/gitlab-org/gitlab/-/issues/233514
xit 'creates a registry' do
expect { subject.process }.to change(Geo::ContainerRepositoryRegistry, :count).by(1)
end
it_behaves_like 'event schedules a sync worker', ::Geo::ContainerRepositorySyncWorker do
let(:expected_id) { container_repository.id }
end
context "when the container repository's project is not excluded by selective sync" do
# TODO: Fix https://gitlab.com/gitlab-org/gitlab/-/issues/233514 and
# use this test, and remove the other tests in this context.
# it_behaves_like 'event should trigger a sync'
context 'when a registry does not yet exist' do
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
context "when the container repository's project is excluded by selective sync" do
before do
stub_current_geo_node(selective_sync_secondary)
end
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
it_behaves_like 'event does not create a registry', ::Geo::ContainerRepositoryRegistry
it_behaves_like 'event does not schedule a sync worker', ::Geo::ContainerRepositorySyncWorker
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
end
context 'when a registry exists' do
let!(:registry) { create(:geo_container_repository_registry, :synced) }
context "when the container repository's project is not excluded by selective sync" do
# TODO: Fix the bug and un-x the test https://gitlab.com/gitlab-org/gitlab/-/issues/233514
xit 'transitions the registry to pending' do
expect { subject.process }.to change(registry, :pending?).to(true)
end
it_behaves_like 'event schedules a sync worker', ::Geo::ContainerRepositorySyncWorker do
let(:expected_id) { container_repository.id }
end
context "when the container repository's project is excluded by selective sync" do
before do
stub_current_geo_node(secondary_excludes_all_projects)
end
context 'when a registry does not exist' do
it_behaves_like 'event does not create a registry'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
context "when the container repository's project is excluded by selective sync" do
before do
stub_current_geo_node(selective_sync_secondary)
end
it 'does not transition the registry to pending state' do
expect { subject.process }.not_to change(registry, :pending?)
end
it_behaves_like 'event does not schedule a sync worker', ::Geo::ContainerRepositorySyncWorker
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
# This describes an optimization to avoid double-checking a heavy
# (330ms is heavy for the log cursor) selective sync query too often:
# If the registry exists, then we assume it *should* exist. This will
# usually be accurate. The responsibility falls to proper handling of
# delete events as well as the `RegistryConsistencyWorker` to remove
# registries.
it_behaves_like 'event transitions a registry to pending'
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
end
......@@ -90,9 +80,17 @@ RSpec.describe Gitlab::Geo::LogCursor::Events::ContainerRepositoryUpdatedEvent,
stub_config(geo: { registry_replication: { enabled: false } })
end
context "even when the container repository's project is not excluded by selective sync" do
it_behaves_like 'event does not create a registry', ::Geo::ContainerRepositoryRegistry
it_behaves_like 'event does not schedule a sync worker', ::Geo::ContainerRepositorySyncWorker
context 'when a registry does not exist' do
it_behaves_like 'event does not create a registry'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
it_behaves_like 'event does not transition a registry to pending'
it_behaves_like 'event does not schedule a sync worker'
it_behaves_like 'logs event source info'
end
end
......
# frozen_string_literal: true
RSpec.shared_examples 'event does not create a registry' do |registry_class|
# Let variables required:
#
# - event
# - registry_class
#
RSpec.shared_examples 'event creates a registry' do
it 'creates a registry with pending state' do
expect { event.process }.to change(registry_class.with_state(:pending), :count).by(1)
end
end
# Let variables required:
#
# - event
# - registry_class
#
RSpec.shared_examples 'event does not create a registry' do
it 'does not create a registry' do
expect { subject.process }.not_to change(registry_class, :count)
expect { event.process }.not_to change(registry_class, :count)
end
end
# Let variables required:
#
# - expected_id
# - event
# - registry
#
RSpec.shared_examples 'event schedules a sync worker' do |sync_worker|
RSpec.shared_examples 'event transitions a registry to pending' do
it 'transitions the registry to pending' do
event.process
expect(registry.reload.pending?).to be_truthy
end
end
# Let variables required:
#
# - event
# - registry
#
RSpec.shared_examples 'event does not transition a registry to pending' do
it 'does not transition a registry to pending' do
event.process
expect(registry.reload.pending?).to be_falsey
end
end
# Let variables required:
#
# - event
# - sync_worker_expected_arg
# - sync_worker_class
#
RSpec.shared_examples 'event schedules a sync worker' do
it 'schedules a sync worker' do
expect(sync_worker).to receive(:perform_async).with(expected_id)
expect(sync_worker_class).to receive(:perform_async).with(sync_worker_expected_arg)
subject.process
event.process
end
end
RSpec.shared_examples 'event does not schedule a sync worker' do |sync_worker|
# Let variables required:
#
# - event
# - sync_worker_class
#
RSpec.shared_examples 'event does not schedule a sync worker' do
it 'does not schedule a sync worker' do
expect(sync_worker).not_to receive(:perform_async)
expect(sync_worker_class).not_to receive(:perform_async)
event.process
end
end
# Let variables required:
#
# - event
# - registry_factory
# - registry_factory_args
# - sync_worker_class
# - sync_worker_expected_arg
#
RSpec.shared_examples 'event should trigger a sync' do
context 'when a registry does not yet exist' do
it_behaves_like 'event creates a registry'
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
context 'when a registry exists' do
let!(:registry) { create(registry_factory, *registry_factory_args) }
subject.process
it_behaves_like 'event transitions a registry to pending'
it_behaves_like 'event schedules a sync worker'
it_behaves_like 'logs event source info'
end
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