Commit 58afb804 authored by Mike Kozono's avatar Mike Kozono

Add object storage consideration to job_artifacts

To centralize the scoping of job artifacts that a Geo secondary should
attempt to sync.
parent cc3e91a1
......@@ -238,6 +238,16 @@ class GeoNode < ApplicationRecord
end
def job_artifacts
selective_sync_scope.merge(object_storage_scope)
end
def object_storage_scope
return Ci::JobArtifact.all if sync_object_storage?
Ci::JobArtifact.with_files_stored_locally
end
def selective_sync_scope
return Ci::JobArtifact.all unless selective_sync?
query = Ci::JobArtifact.project_id_in(projects).select(:id)
......
......@@ -831,6 +831,76 @@ RSpec.describe GeoNode, :request_store, :geo, type: :model do
end
end
describe '#job_artifacts' do
# Selective sync is configured relative to the job artifact's project.
#
# Permutations of sync_object_storage combined with object-stored-uploads
# are tested in code, because the logic is simple, and to do it in the table
# would quadruple its size and have too much duplication.
where(:selective_sync_namespaces, :selective_sync_shards, :project_factory, :include_expectation) do
nil | nil | [:project] | true
# selective sync by shard
nil | :model | [:project] | true
nil | :other | [:project] | false
# selective sync by namespace
:model_parent | nil | [:project] | true
:model_parent_parent | nil | [:project, :in_subgroup] | true
:other | nil | [:project] | false
:other | nil | [:project, :in_subgroup] | false
end
with_them do
subject(:upload_included) { node.job_artifacts.include?(upload) }
let(:factory) { [:ci_job_artifact]}
let(:project) { create(*project_factory) }
let(:ci_build) { create(:ci_build, project: project) }
let(:node) do
create_geo_node_to_test_replicables_for_geo_node(
project,
selective_sync_namespaces: selective_sync_namespaces,
selective_sync_shards: selective_sync_shards,
sync_object_storage: sync_object_storage)
end
before do
stub_artifacts_object_storage
end
context 'when sync object storage is enabled' do
let(:sync_object_storage) { true }
context 'when the upload is locally stored' do
let(:upload) { create(*factory, job: ci_build) }
it { is_expected.to eq(include_expectation) }
end
context 'when the upload is object stored' do
let(:upload) { create(*factory, :remote_store, job: ci_build) }
it { is_expected.to eq(include_expectation) }
end
end
context 'when sync object storage is disabled' do
let(:sync_object_storage) { false }
context 'when the upload is locally stored' do
let(:upload) { create(*factory, job: ci_build) }
it { is_expected.to eq(include_expectation) }
end
context 'when the upload is object stored' do
let(:upload) { create(*factory, :remote_store, job: ci_build) }
it { is_expected.to be_falsey }
end
end
end
end
describe '#lfs_objects' do
let_it_be(:synced_group) { create(:group) }
let_it_be(:nested_group) { create(:group, parent: synced_group) }
......
......@@ -40,7 +40,13 @@ RSpec.describe Upload do
subject(:upload_included) { described_class.replicables_for_geo_node.include?(upload) }
let(:model) { create(*model_factory) }
let(:node) { create_geo_node(model, sync_object_storage: sync_object_storage) }
let(:node) do
create_geo_node_to_test_replicables_for_geo_node(
model,
selective_sync_namespaces: selective_sync_namespaces,
selective_sync_shards: selective_sync_shards,
sync_object_storage: sync_object_storage)
end
before do
stub_current_geo_node(node)
......@@ -78,42 +84,6 @@ RSpec.describe Upload do
end
end
end
def create_geo_node(model, sync_object_storage:)
node = build(:geo_node)
if selective_sync_namespaces
node.selective_sync_type = 'namespaces'
elsif selective_sync_shards
node.selective_sync_type = 'shards'
end
case selective_sync_namespaces
when :model
node.namespaces = [model]
when :model_parent
node.namespaces = [model.parent]
when :model_parent_parent
node.namespaces = [model.parent.parent]
when :other
node.namespaces = [create(:group)]
end
case selective_sync_shards
when :model
node.selective_sync_shards = [model.repository_storage]
when :model_project
project = create(:project, namespace: model)
node.selective_sync_shards = [project.repository_storage]
when :other
node.selective_sync_shards = ['other_shard_name']
end
node.sync_object_storage = sync_object_storage
node.save!
node
end
end
describe '#destroy' do
......
......@@ -117,5 +117,41 @@ module EE
drop_table :dummy_models, force: true
end
end
def create_geo_node_to_test_replicables_for_geo_node(model, selective_sync_namespaces: nil, selective_sync_shards: nil, sync_object_storage:)
node = build(:geo_node)
if selective_sync_namespaces
node.selective_sync_type = 'namespaces'
elsif selective_sync_shards
node.selective_sync_type = 'shards'
end
case selective_sync_namespaces
when :model
node.namespaces = [model]
when :model_parent
node.namespaces = [model.parent]
when :model_parent_parent
node.namespaces = [model.parent.parent]
when :other
node.namespaces = [create(:group)]
end
case selective_sync_shards
when :model
node.selective_sync_shards = [model.repository_storage]
when :model_project
project = create(:project, namespace: model)
node.selective_sync_shards = [project.repository_storage]
when :other
node.selective_sync_shards = ['other_shard_name']
end
node.sync_object_storage = sync_object_storage
node.save!
node
end
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