diff --git a/changelogs/unreleased/13055-show-the-sync-information-for-design-repositories.yml b/changelogs/unreleased/13055-show-the-sync-information-for-design-repositories.yml new file mode 100644 index 0000000000000000000000000000000000000000..2f807170f172af530ba157a411214e9a57a8c259 --- /dev/null +++ b/changelogs/unreleased/13055-show-the-sync-information-for-design-repositories.yml @@ -0,0 +1,5 @@ +--- +title: 'Geo: Add resigns-related fields to Geo Node Status table' +merge_request: 18379 +author: +type: other diff --git a/db/migrate/20191009100244_add_geo_design_repository_counters.rb b/db/migrate/20191009100244_add_geo_design_repository_counters.rb new file mode 100644 index 0000000000000000000000000000000000000000..26387453f8868ce7d3db663a0912d0f83bdd5aa0 --- /dev/null +++ b/db/migrate/20191009100244_add_geo_design_repository_counters.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddGeoDesignRepositoryCounters < ActiveRecord::Migration[5.1] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + change_table :geo_node_statuses do |t| + t.column :design_repositories_count, :integer + t.column :design_repositories_synced_count, :integer + t.column :design_repositories_failed_count, :integer + t.column :design_repositories_registry_count, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 237f5ab47328151e8bec1386c73903d8d77c3f82..36f7bba904bedd2b2bc394c081ef8a947f6207a5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1650,6 +1650,10 @@ t.integer "container_repositories_synced_count" t.integer "container_repositories_failed_count" t.integer "container_repositories_registry_count" + t.integer "design_repositories_count" + t.integer "design_repositories_synced_count" + t.integer "design_repositories_failed_count" + t.integer "design_repositories_registry_count" t.index ["geo_node_id"], name: "index_geo_node_statuses_on_geo_node_id", unique: true end diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md index 5eba7f038eddb4d794af6d373a70e7421f255b81..e44d69f14192820e3f5faebe1f7f47160ca1a418 100644 --- a/doc/api/geo_nodes.md +++ b/doc/api/geo_nodes.md @@ -237,6 +237,10 @@ Example response: "container_repositories_synced_count": nil, "container_repositories_failed_count": nil, "container_repositories_synced_in_percentage": "0.00%", + "design_repositories_count": 3, + "design_repositories_synced_count": nil, + "design_repositories_failed_count": nil, + "design_repositories_synced_in_percentage": "0.00%", "projects_count": 41, "repositories_failed_count": nil, "repositories_synced_count": nil, @@ -304,6 +308,10 @@ Example response: "container_repositories_synced_count": nil, "container_repositories_failed_count": nil, "container_repositories_synced_in_percentage": "0.00%", + "design_repositories_count": 3, + "design_repositories_synced_count": nil, + "design_repositories_failed_count": nil, + "design_repositories_synced_in_percentage": "0.00%", "projects_count": 41, "repositories_failed_count": 1, "repositories_synced_count": 40, @@ -387,6 +395,10 @@ Example response: "container_repositories_synced_count": nil, "container_repositories_failed_count": nil, "container_repositories_synced_in_percentage": "0.00%", + "design_repositories_count": 3, + "design_repositories_synced_count": nil, + "design_repositories_failed_count": nil, + "design_repositories_synced_in_percentage": "0.00%", "projects_count": 41, "repositories_failed_count": 1, "repositories_synced_count": 40, diff --git a/ee/app/assets/javascripts/geo_nodes/components/geo_node_detail_item.vue b/ee/app/assets/javascripts/geo_nodes/components/geo_node_detail_item.vue index f2fa507ec099a9b47a41234b10d5b79833ba607f..e0f0c063756541224e11ccd96c6fd97d75023d48 100644 --- a/ee/app/assets/javascripts/geo_nodes/components/geo_node_detail_item.vue +++ b/ee/app/assets/javascripts/geo_nodes/components/geo_node_detail_item.vue @@ -79,6 +79,11 @@ export default { required: false, default: false, }, + featureDisabled: { + type: Boolean, + required: false, + default: false, + }, }, computed: { hasHelpInfo() { @@ -121,9 +126,9 @@ export default { </script> <template> - <div class="prepend-top-15 prepend-left-10 node-detail-item"> + <div v-if="!featureDisabled" class="prepend-top-15 prepend-left-10 node-detail-item"> <div class="node-detail-title"> - <span> {{ itemTitle }} </span> + <span>{{ itemTitle }}</span> <icon v-if="hasHelpInfo" v-popover="popoverConfig" diff --git a/ee/app/assets/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync.vue b/ee/app/assets/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync.vue index e467f778b8ebe0f99ecfbb3ed024f0c65a4367b0..db02689b56ef4dc3d0f9df47515395f22dba92f4 100644 --- a/ee/app/assets/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync.vue +++ b/ee/app/assets/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync.vue @@ -61,6 +61,12 @@ export default { itemValue: this.nodeDetails.containerRepositories, itemValueType: VALUE_TYPE.GRAPH, }, + { + itemTitle: s__('GeoNodes|Design repositories'), + itemValue: this.nodeDetails.designRepositories, + itemValueType: VALUE_TYPE.GRAPH, + featureDisabled: !gon.features.enableGeoDesignSync, + }, { itemTitle: s__('GeoNodes|Data replication lag'), itemValue: this.dbReplicationLag(), @@ -146,6 +152,7 @@ export default { :item-value-stale-tooltip="statusInfoStaleMessage" :custom-type="nodeDetailItem.customType" :event-type-log-status="nodeDetailItem.eventTypeLogStatus" + :feature-disabled="nodeDetailItem.featureDisabled" /> </div> </div> diff --git a/ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js b/ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js index 4593ac3255ecb77267c309cea6b15b7df54ecaac..e7a4618bb59509f6bdaf71451e20c78b5fd045a6 100644 --- a/ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js +++ b/ee/app/assets/javascripts/geo_nodes/store/geo_nodes_store.js @@ -124,6 +124,11 @@ export default class GeoNodesStore { successCount: rawNodeDetails.container_repositories_synced_count || 0, failureCount: rawNodeDetails.container_repositories_failed_count || 0, }, + designRepositories: { + totalCount: rawNodeDetails.design_repositories_count || 0, + successCount: rawNodeDetails.design_repositories_synced_count || 0, + failureCount: rawNodeDetails.design_repositories_failed_count || 0, + }, attachments: { totalCount: rawNodeDetails.attachments_count || 0, successCount: rawNodeDetails.attachments_synced_count || 0, diff --git a/ee/app/controllers/admin/geo/nodes_controller.rb b/ee/app/controllers/admin/geo/nodes_controller.rb index 64374567a6cead967ad02aade113a9d60614cbfd..8e2b2de78222a36ec35c025342439a0faca585da 100644 --- a/ee/app/controllers/admin/geo/nodes_controller.rb +++ b/ee/app/controllers/admin/geo/nodes_controller.rb @@ -3,6 +3,9 @@ class Admin::Geo::NodesController < Admin::Geo::ApplicationController before_action :check_license!, except: :index before_action :load_node, only: [:edit, :update] + before_action only: [:index] do + push_frontend_feature_flag(:enable_geo_design_sync) + end # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/ee/app/finders/geo/design_registry_finder.rb b/ee/app/finders/geo/design_registry_finder.rb new file mode 100644 index 0000000000000000000000000000000000000000..ccd4b7d7a16d75d743155e80d4c9bde276cf306f --- /dev/null +++ b/ee/app/finders/geo/design_registry_finder.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Geo + class DesignRegistryFinder < RegistryFinder + def count_syncable + designs_repositories.count + end + + def count_synced + registries_for_design_repositories + .merge(Geo::DesignRegistry.synced).count + end + + def count_failed + registries_for_design_repositories + .merge(Geo::DesignRegistry.failed).count + end + + def count_registry + registries_for_design_repositories.count + end + + private + + def designs_repositories + current_node.projects.inner_join_design_management + end + + def registries_for_design_repositories + designs_repositories + .inner_join_design_registry + end + end +end diff --git a/ee/app/models/geo/fdw/design_management_design.rb b/ee/app/models/geo/fdw/design_management_design.rb new file mode 100644 index 0000000000000000000000000000000000000000..4e2b9ab44317115568de18b11989ce4d9bc258d8 --- /dev/null +++ b/ee/app/models/geo/fdw/design_management_design.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Geo + module Fdw + class DesignManagementDesign < ::Geo::BaseFdw + self.table_name = Gitlab::Geo::Fdw.foreign_table_name('design_management_designs') + self.primary_key = :id + end + end +end diff --git a/ee/app/models/geo/fdw/project.rb b/ee/app/models/geo/fdw/project.rb index d15f536e30c16aac0be58319ffea13ea61ad810a..87799d7c0a80d54c51b02c7d1987e9b245bbf91e 100644 --- a/ee/app/models/geo/fdw/project.rb +++ b/ee/app/models/geo/fdw/project.rb @@ -15,6 +15,7 @@ class Project < ::Geo::BaseFdw has_many :container_repositories, class_name: 'Geo::Fdw::ContainerRepository' belongs_to :namespace, class_name: 'Geo::Fdw::Namespace' + belongs_to :design_management_designs, class_name: 'Geo::Fdw::DesignManagementDesign' scope :outside_shards, -> (shard_names) { where.not(repository_storage: Array(shard_names)) } @@ -80,6 +81,24 @@ def inner_join_project_registry joins(join_statement.join_sources) end + def inner_join_design_registry + join_statement = + arel_table + .join(Geo::DesignRegistry.arel_table, Arel::Nodes::InnerJoin) + .on(arel_table[:id].eq(Geo::DesignRegistry.arel_table[:project_id])) + + joins(join_statement.join_sources) + end + + def inner_join_design_management + join_statement = + arel_table + .join(Geo::Fdw::DesignManagementDesign.arel_table, Arel::Nodes::InnerJoin) + .on(arel_table[:id].eq(Geo::Fdw::DesignManagementDesign.arel_table[:project_id])) + + joins(join_statement.join_sources) + end + private def left_outer_join_project_registry diff --git a/ee/app/models/geo_node_status.rb b/ee/app/models/geo_node_status.rb index 18bde9eba2fe3c471baf0be0edd6513f3b789a72..765b12746be77962141abe3c3c2710ca83686a4d 100644 --- a/ee/app/models/geo_node_status.rb +++ b/ee/app/models/geo_node_status.rb @@ -91,7 +91,11 @@ class GeoNodeStatus < ApplicationRecord container_repositories_count: 'Total number of syncable container repositories available on primary', container_repositories_synced_count: 'Number of syncable container repositories synced on secondary', container_repositories_failed_count: 'Number of syncable container repositories failed to sync on secondary', - container_repositories_registry_count: 'Number of container repositories in the registry' + container_repositories_registry_count: 'Number of container repositories in the registry', + design_repositories_count: 'Total number of syncable design repositories available on primary', + design_repositories_synced_count: 'Number of syncable design repositories synced on secondary', + design_repositories_failed_count: 'Number of syncable design repositories failed to sync on secondary', + design_repositories_registry_count: 'Number of design repositories in the registry' }.freeze EXPIRATION_IN_MINUTES = 5 @@ -240,6 +244,7 @@ def self.attr_in_percentage(attr_name, count, total) attr_in_percentage :attachments_synced, :attachments_synced_count, :attachments_count attr_in_percentage :replication_slots_used, :replication_slots_used_count, :replication_slots_count attr_in_percentage :container_repositories_synced, :container_repositories_synced_count, :container_repositories_count + attr_in_percentage :design_repositories_synced, :design_repositories_synced_count, :design_repositories_count def storage_shards_match? return true if geo_node.primary? @@ -303,6 +308,7 @@ def load_secondary_data load_job_artifacts_data load_attachments_data load_container_registry_data + load_designs_data end def load_lfs_objects_data @@ -330,10 +336,17 @@ def load_attachments_data end def load_container_registry_data - self.container_repositories_count = container_repository_finder.count_syncable - self.container_repositories_synced_count = container_repository_finder.count_synced - self.container_repositories_failed_count = container_repository_finder.count_failed - self.container_repositories_registry_count = container_repository_finder.count_registry + self.container_repositories_count = container_registry_finder.count_syncable + self.container_repositories_synced_count = container_registry_finder.count_synced + self.container_repositories_failed_count = container_registry_finder.count_failed + self.container_repositories_registry_count = container_registry_finder.count_registry + end + + def load_designs_data + self.design_repositories_count = design_registry_finder.count_syncable + self.design_repositories_synced_count = design_registry_finder.count_synced + self.design_repositories_failed_count = design_registry_finder.count_failed + self.design_repositories_registry_count = design_registry_finder.count_registry end def load_repository_check_data @@ -382,8 +395,12 @@ def job_artifacts_finder @job_artifacts_finder ||= Geo::JobArtifactRegistryFinder.new(current_node_id: geo_node.id) end - def container_repository_finder - @container_repository_finder ||= Geo::ContainerRepositoryRegistryFinder.new(current_node_id: geo_node.id) + def container_registry_finder + @container_registry_finder ||= Geo::ContainerRepositoryRegistryFinder.new(current_node_id: geo_node.id) + end + + def design_registry_finder + @design_registry_finder ||= Geo::DesignRegistryFinder.new(current_node_id: geo_node.id) end def registries_for_synced_projects(type) diff --git a/ee/lib/ee/api/entities.rb b/ee/lib/ee/api/entities.rb index c24bd72aacf64a0ca26c5b74c3cb9672b89ad5ff..f55cc150bc2cc4ef437d7fdcdbd9c1bfa5b5e50d 100644 --- a/ee/lib/ee/api/entities.rb +++ b/ee/lib/ee/api/entities.rb @@ -649,6 +649,13 @@ class GeoNodeStatus < Grape::Entity number_to_percentage(node.container_repositories_synced_in_percentage, precision: 2) end + expose :design_repositories_count + expose :design_repositories_synced_count + expose :design_repositories_failed_count + expose :design_repositories_synced_in_percentage do |node| + number_to_percentage(node.design_repositories_synced_in_percentage, precision: 2) + end + expose :projects_count expose :repositories_failed_count diff --git a/ee/lib/tasks/geo.rake b/ee/lib/tasks/geo.rake index ef931898aca16e22f3ccde46b8a94840656d7898..b26e7ed9fb7d8c454d8a4309af5f3232ce0a28a4 100644 --- a/ee/lib/tasks/geo.rake +++ b/ee/lib/tasks/geo.rake @@ -339,6 +339,13 @@ namespace :geo do puts using_percentage(current_node_status.container_repositories_synced_in_percentage) end + if Feature.enabled?(:enable_geo_design_sync) + print 'Design repositories: '.rjust(GEO_STATUS_COLUMN_WIDTH) + show_failed_value(current_node_status.design_repositories_failed_count) + print "#{current_node_status.design_repositories_synced_count || 0}/#{current_node_status.design_repositories_count || 0} " + puts using_percentage(current_node_status.design_repositories_synced_in_percentage) + end + if Gitlab::CurrentSettings.repository_checks_enabled print 'Repositories Checked: '.rjust(GEO_STATUS_COLUMN_WIDTH) show_failed_value(current_node_status.repositories_checked_failed_count) diff --git a/ee/spec/factories/geo/design_registry.rb b/ee/spec/factories/geo/design_registry.rb index 5f4858df1636d0740f0f563d120bc6de27693bb1..e5361f0a7b9b667b41cfed3ad29dba0ebf46b7d0 100644 --- a/ee/spec/factories/geo/design_registry.rb +++ b/ee/spec/factories/geo/design_registry.rb @@ -7,6 +7,10 @@ last_synced_at { nil } state { :pending } + after(:create) do |registry, evaluator| + create(:design, project: registry.project) + end + trait :synced do state { :synced } last_synced_at { 5.days.ago } diff --git a/ee/spec/factories/geo_node_statuses.rb b/ee/spec/factories/geo_node_statuses.rb index da260c66ce8e3accffda578ff76ffcf3d4690418..ea1827b8ffe590cacf7e1c58445b74cc7d114195 100644 --- a/ee/spec/factories/geo_node_statuses.rb +++ b/ee/spec/factories/geo_node_statuses.rb @@ -22,6 +22,9 @@ container_repositories_count { 400 } container_repositories_failed_count { 3 } container_repositories_synced_count { 200 } + design_repositories_count { 400 } + design_repositories_failed_count { 3 } + design_repositories_synced_count { 200 } projects_count { 10 } repositories_synced_count { 5 } repositories_failed_count { 0 } diff --git a/ee/spec/finders/geo/design_registry_finder_spec.rb b/ee/spec/finders/geo/design_registry_finder_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..df55f5921f5db33082ecf0756b489da9c6521078 --- /dev/null +++ b/ee/spec/finders/geo/design_registry_finder_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Geo::DesignRegistryFinder, :geo, :geo_fdw do + include ::EE::GeoHelpers + + let!(:secondary) { create(:geo_node) } + let!(:failed_registry) { create(:geo_design_registry, :sync_failed) } + let!(:synced_registry) { create(:geo_design_registry, :synced) } + + let(:synced_group) { create(:group) } + let(:unsynced_group) { create(:group) } + let(:synced_project) { create(:project, group: synced_group) } + let(:unsynced_project) { create(:project, :broken_storage, group: unsynced_group) } + + subject { described_class.new(current_node_id: secondary.id) } + + before do + stub_current_geo_node(secondary) + end + + context 'count all the things' do + describe '#count_syncable' do + it 'returns number of container repositories' do + result = subject.count_syncable + + expect(result).to eq(2) + end + end + + describe '#count_synced' do + it 'returns only synced registry' do + result = subject.count_synced + + expect(result).to eq(1) + end + end + + describe '#count_failed' do + it 'returns only failed registry' do + result = subject.count_failed + + expect(result).to eq(1) + end + end + + describe '#count_registry' do + it 'returns number of all registries' do + result = subject.count_registry + + expect(result).to eq(2) + end + end + + context 'selective sync' do + let(:unsynced_project2) { create(:project, group: unsynced_group) } + let(:synced_project2) { create(:project, group: synced_group) } + + before do + create(:geo_design_registry, :synced, project: synced_project) + create(:geo_design_registry, :sync_failed, project: synced_project2) + create(:geo_design_registry, :synced, project: unsynced_project) + create(:geo_design_registry, :sync_failed, project: unsynced_project2) + + secondary.update!(selective_sync_type: 'namespaces', namespaces: [synced_group]) + end + + context 'count all the things' do + describe '#count_syncable' do + it 'returns number of container repositories' do + result = subject.count_syncable + + expect(result).to eq(2) + end + end + + describe '#count_synced' do + it 'returns only synced registry' do + result = subject.count_synced + + expect(result).to eq(1) + end + end + + describe '#count_failed' do + it 'returns only failed registry' do + result = subject.count_failed + + expect(result).to eq(1) + end + end + + describe '#count_registry' do + it 'returns number of all registries' do + result = subject.count_registry + + expect(result).to eq(2) + end + end + end + end + end +end diff --git a/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json b/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json index 09e5902d7c1e27def067b27963e11aad36048789..0dfd2b24d3824a97e845f3603cee9086b2684ef2 100644 --- a/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json +++ b/ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json @@ -22,6 +22,9 @@ "container_repositories_count", "container_repositories_failed_count", "container_repositories_synced_count", + "design_repositories_count", + "design_repositories_failed_count", + "design_repositories_synced_count", "projects_count", "repositories_failed_count", "repositories_synced_count", @@ -88,6 +91,10 @@ "container_repositories_failed_count": { "type": ["integer", "null"] }, "container_repositories_synced_count": { "type": ["integer", "null"] }, "container_repositories_synced_in_percentage": { "type": "string" }, + "design_repositories_count": { "type": "integer" }, + "design_repositories_failed_count": { "type": ["integer", "null"] }, + "design_repositories_synced_count": { "type": ["integer", "null"] }, + "design_repositories_synced_in_percentage": { "type": "string" }, "projects_count": { "type": "integer" }, "repositories_failed_count": { "type": ["integer", "null"] }, "repository_verification_enabled": { "type": "boolean" }, diff --git a/ee/spec/javascripts/geo_nodes/components/geo_node_detail_item_spec.js b/ee/spec/javascripts/geo_nodes/components/geo_node_detail_item_spec.js index 1b7de74da79ef9eb52058151e3a333c6600b648a..73b58ea874685a8cbf4b3390baa4bc8bebac76cc 100644 --- a/ee/spec/javascripts/geo_nodes/components/geo_node_detail_item_spec.js +++ b/ee/spec/javascripts/geo_nodes/components/geo_node_detail_item_spec.js @@ -117,5 +117,14 @@ describe('GeoNodeDetailItemComponent', () => { expect(vm.$el.querySelectorAll('.event-status-timestamp').length).not.toBe(0); vm.$destroy(); }); + + it('does not render if featureDisabled is true', () => { + const vm = createComponent({ + featureDisabled: true, + }); + + expect(vm.$el.innerHTML).toBeUndefined(); + vm.$destroy(); + }); }); }); diff --git a/ee/spec/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync_spec.js b/ee/spec/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync_spec.js index 4acb4819515c100f81c3717f103f355024c100d9..08b2d67f1cae8ea9db162a2b1f1098fa3b72edcf 100644 --- a/ee/spec/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync_spec.js +++ b/ee/spec/javascripts/geo_nodes/components/node_detail_sections/node_details_section_sync_spec.js @@ -16,6 +16,7 @@ describe('NodeDetailsSectionSync', () => { let vm; beforeEach(() => { + gon.features = gon.features || {}; vm = createComponent(); }); diff --git a/ee/spec/javascripts/geo_nodes/mock_data.js b/ee/spec/javascripts/geo_nodes/mock_data.js index d000f22dfca3b0c3ab4dbcd77d4a7042e5dd4768..13fe80eb3480e86a8b44cf19d98e47231b25626f 100644 --- a/ee/spec/javascripts/geo_nodes/mock_data.js +++ b/ee/spec/javascripts/geo_nodes/mock_data.js @@ -83,6 +83,10 @@ export const rawMockNodeDetails = { container_repositories_synced_count: 0, container_repositories_failed_count: 0, container_repositories_synced_in_percentage: '0.00%', + design_repositories_count: 0, + design_repositories_synced_count: 0, + design_repositories_failed_count: 0, + design_repositories_synced_in_percentage: '0.00%', repositories_failed_count: 0, repositories_synced_count: 12, repositories_synced_in_percentage: '100.00%', @@ -193,6 +197,11 @@ export const mockNodeDetails = { successCount: 0, failureCount: 0, }, + designRepositories: { + totalCount: 0, + successCount: 0, + failureCount: 0, + }, attachments: { totalCount: 0, successCount: 0, diff --git a/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb b/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb index 52f91a290a9df19c856b5f71bd3cbbb53881c799..48e02ae26f04f94c12bfe036a572b3387d1bbfb7 100644 --- a/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb +++ b/ee/spec/lib/ee/api/entities/geo_node_status_spec.rb @@ -97,6 +97,18 @@ end end + describe '#design_repositories_synced_in_percentage' do + it 'formats as percentage' do + geo_node_status.assign_attributes( + design_repositories_count: 256, + design_repositories_failed_count: 12, + design_repositories_synced_count: 123 + ) + + expect(subject[:design_repositories_synced_in_percentage]).to eq '48.05%' + end + end + describe '#repositories_synced_in_percentage' do it 'formats as percentage' do geo_node_status.assign_attributes(projects_count: 10, diff --git a/ee/spec/models/geo_node_status_spec.rb b/ee/spec/models/geo_node_status_spec.rb index 389b47a723bc51ce528a667860c8bdf3858ca294..92ee083f78b4e02f780338eae4334ad3ff155bf4 100644 --- a/ee/spec/models/geo_node_status_spec.rb +++ b/ee/spec/models/geo_node_status_spec.rb @@ -705,6 +705,67 @@ end end + describe '#design_repositories_count' do + it 'counts all the designs' do + create(:design) + create(:design) + + expect(subject.design_repositories_count).to eq(2) + end + end + + describe '#design_repositories_synced_count' do + it 'counts synced repositories' do + create(:geo_design_registry, :synced) + create(:geo_design_registry, :sync_failed) + + expect(subject.design_repositories_synced_count).to eq(1) + end + end + + describe '#design_repositories_failed_count' do + it 'counts failed to sync repositories' do + create(:geo_design_registry, :sync_failed) + create(:geo_design_registry, :synced) + + expect(subject.design_repositories_failed_count).to eq(1) + end + end + + describe '#design_repositories_registry_count' do + it 'counts number of registries for repositories' do + create(:geo_design_registry, :sync_failed) + create(:geo_design_registry) + create(:geo_design_registry, :synced) + + expect(subject.design_repositories_registry_count).to eq(3) + end + end + + describe '#design_repositories_synced_in_percentage' do + it 'returns 0 when no objects are available' do + expect(subject.design_repositories_synced_in_percentage).to eq(0) + end + + it 'returns the right percentage with no group restrictions' do + create(:geo_design_registry, :synced) + create(:geo_design_registry, :sync_failed) + + expect(subject.design_repositories_synced_in_percentage).to be_within(0.0001).of(50) + end + + it 'returns the right percentage with group restrictions' do + secondary.update!(selective_sync_type: 'namespaces', namespaces: [group]) + + create(:geo_design_registry, :synced, project: project_1) + create(:geo_design_registry, :sync_failed, project: project_2) + create(:geo_design_registry, :sync_failed, project: project_3) + create(:geo_design_registry, :sync_failed, project: project_4) + + expect(subject.design_repositories_synced_in_percentage).to be_within(0.0001).of(50) + end + end + describe '#repositories_verified_count' do before do stub_current_geo_node(secondary) diff --git a/ee/spec/requests/api/geo_spec.rb b/ee/spec/requests/api/geo_spec.rb index b191dae2d68905490952f87ca08a4046128199ed..ea300557a1f63c9c92249138e9293b8180b5f7d5 100644 --- a/ee/spec/requests/api/geo_spec.rb +++ b/ee/spec/requests/api/geo_spec.rb @@ -270,6 +270,9 @@ container_repositories_count: 100, container_repositories_synced_count: 50, container_repositories_failed_count: 12, + design_repositories_count: 100, + design_repositories_synced_count: 50, + design_repositories_failed_count: 12, attachments_count: 30, attachments_synced_count: 30, attachments_failed_count: 25, diff --git a/ee/spec/services/geo/design_repository_sync_service_spec.rb b/ee/spec/services/geo/design_repository_sync_service_spec.rb index 0bec547efac0dc37b441e58d453491dd6d236bf0..dcc078d612fe11d2119f63c304f0217dd35b99f1 100644 --- a/ee/spec/services/geo/design_repository_sync_service_spec.rb +++ b/ee/spec/services/geo/design_repository_sync_service_spec.rb @@ -40,6 +40,9 @@ allow_any_instance_of(Geo::ProjectHousekeepingService).to receive(:execute) .and_return(nil) + + allow_any_instance_of(Users::RefreshAuthorizedProjectsService).to receive(:execute) + .and_return(nil) end include_context 'lease handling' diff --git a/ee/spec/services/geo/metrics_update_service_spec.rb b/ee/spec/services/geo/metrics_update_service_spec.rb index 53a5856104fc7003ef78117046f4f257a0938b4e..7f14df4c2d35f2c69e5f706d986fde0faec400c8 100644 --- a/ee/spec/services/geo/metrics_update_service_spec.rb +++ b/ee/spec/services/geo/metrics_update_service_spec.rb @@ -33,6 +33,9 @@ container_repositories_count: 100, container_repositories_synced_count: 50, container_repositories_failed_count: 12, + design_repositories_count: 100, + design_repositories_synced_count: 50, + design_repositories_failed_count: 12, attachments_count: 30, attachments_synced_count: 30, attachments_failed_count: 25, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e6146b9e5202d1c6e8ce02111b149bba17862abe..083e8f2a7fdb0e7eac7368147b581d758f554674 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -7493,6 +7493,9 @@ msgstr "" msgid "GeoNodes|Data replication lag" msgstr "" +msgid "GeoNodes|Design repositories" +msgstr "" + msgid "GeoNodes|Does not match the primary storage configuration" msgstr ""