From e849dc56b1f4317805ba5c0c5fa91b4f9a56fad9 Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Mon, 20 Oct 2025 16:03:57 +0800 Subject: [PATCH 1/5] Expose state names for checksum_state in Data management API --- ee/app/graphql/types/geo/registry_type.rb | 6 +----- ee/app/models/concerns/geo/verification_state_definition.rb | 4 ++++ ee/lib/api/entities/admin/model.rb | 5 ++++- ee/spec/lib/api/entities/admin/model_spec.rb | 4 ++-- .../requests/api/graphql/geo/registries_shared_examples.rb | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ee/app/graphql/types/geo/registry_type.rb b/ee/app/graphql/types/geo/registry_type.rb index 11c88cdacb11b9..8aaa73867df36f 100644 --- a/ee/app/graphql/types/geo/registry_type.rb +++ b/ee/app/graphql/types/geo/registry_type.rb @@ -31,12 +31,8 @@ module RegistryType field :verification_retry_at, Types::TimeType, null: true, description: "Timestamp after which the #{graphql_name} is reverified" field :verification_retry_count, GraphQL::Types::Int, null: true, description: "Number of consecutive failed verification attempts of the #{graphql_name}" field :verification_started_at, Types::TimeType, null: true, description: "Timestamp when the verification of #{graphql_name} started" - field :verification_state, Types::Geo::VerificationStateEnum, null: true, resolver_method: :verification_state_name_value, description: "Verification state of the #{graphql_name}" + field :verification_state, Types::Geo::VerificationStateEnum, null: true, resolver_method: :verification_state_name_no_prefix, description: "Verification state of the #{graphql_name}" field :verified_at, Types::TimeType, null: true, description: "Timestamp of the most recent successful verification of the #{graphql_name}" - - def verification_state_name_value - object.verification_state_name.to_s.gsub('verification_', '') - end end end end diff --git a/ee/app/models/concerns/geo/verification_state_definition.rb b/ee/app/models/concerns/geo/verification_state_definition.rb index 23582f73a2da32..6ad695119d778f 100644 --- a/ee/app/models/concerns/geo/verification_state_definition.rb +++ b/ee/app/models/concerns/geo/verification_state_definition.rb @@ -132,5 +132,9 @@ def verification_transition_details(object, transition) result: transition.result } end + + def verification_state_name_no_prefix + verification_state_name.to_s.gsub('verification_', '') + end end end diff --git a/ee/lib/api/entities/admin/model.rb b/ee/lib/api/entities/admin/model.rb index 9753750714de9d..7462411aabe1e9 100644 --- a/ee/lib/api/entities/admin/model.rb +++ b/ee/lib/api/entities/admin/model.rb @@ -34,10 +34,13 @@ class Model < Grape::Entity if: ->(model) { verification_enabled?(model) } do expose :verification_checksum, as: :checksum expose :verified_at, as: :last_checksum - expose :verification_state, as: :checksum_state expose :verification_retry_count, as: :checksum_retry_count expose :verification_retry_at, as: :checksum_retry_at expose :verification_failure, as: :checksum_failure + + expose :verification_state, as: :checksum_state do |model| + model.verification_state_object&.verification_state_name_no_prefix + end end private diff --git a/ee/spec/lib/api/entities/admin/model_spec.rb b/ee/spec/lib/api/entities/admin/model_spec.rb index 71aded6d60625a..fe46ae1a92e803 100644 --- a/ee/spec/lib/api/entities/admin/model_spec.rb +++ b/ee/spec/lib/api/entities/admin/model_spec.rb @@ -28,9 +28,9 @@ expect(result[:record_identifier]).to eq(model.id) expect(result[:model_class]).to eq(model_classes.name) expect(result[:created_at]).to eq(model.respond_to?(:created_at) ? model.created_at : nil) - - expect(result.dig(:checksum_information, :checksum_state)).to eq(model.verification_state) expect(result[:file_size]).to eq(model.attributes.has_key?('size') ? model.size : nil) + expect(result.dig(:checksum_information, :checksum_state)) + .to eq(model.verification_state_object.verification_state_name_no_prefix) end end diff --git a/ee/spec/support/shared_examples/requests/api/graphql/geo/registries_shared_examples.rb b/ee/spec/support/shared_examples/requests/api/graphql/geo/registries_shared_examples.rb index cff972ce0b4ce8..364e13997a8bfa 100644 --- a/ee/spec/support/shared_examples/requests/api/graphql/geo/registries_shared_examples.rb +++ b/ee/spec/support/shared_examples/requests/api/graphql/geo/registries_shared_examples.rb @@ -174,7 +174,7 @@ def registry_to_graphql_data_hash(registry) 'verificationFailure' => registry.verification_failure, 'verificationRetryCount' => registry.verification_retry_count, 'verificationStartedAt' => registry.verification_started_at, - 'verificationState' => registry.verification_state_name.to_s.gsub('verification_', '').upcase + 'verificationState' => registry.verification_state_name_no_prefix.upcase } return data unless verification_enabled -- GitLab From d6e73fa2e247c5ddefee216361217dc330d5e591 Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Mon, 20 Oct 2025 16:10:34 +0800 Subject: [PATCH 2/5] Update docs example response --- doc/api/admin/data_management.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/api/admin/data_management.md b/doc/api/admin/data_management.md index 11d300f3fc5e54..90feb10c94d1e1 100644 --- a/doc/api/admin/data_management.md +++ b/doc/api/admin/data_management.md @@ -95,10 +95,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", - "checksum_state": 2, "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null + "checksum_failure": null, + "checksum_state": "succeeded" } }, { @@ -109,10 +109,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.214Z", - "checksum_state": 2, "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null + "checksum_failure": null, + "checksum_state": "succeeded" } } ] @@ -155,10 +155,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", - "checksum_state": 2, "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null + "checksum_failure": null, + "checksum_state": "succeeded" } } ``` @@ -187,10 +187,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", - "checksum_state": 2, "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null + "checksum_failure": null, + "checksum_state": "succeeded" } } ``` -- GitLab From a576a1d087a26b76973b1307d1f00a34d9a1f3d2 Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Wed, 22 Oct 2025 17:43:20 +0800 Subject: [PATCH 3/5] Delegate verification_state_name_no_prefix to model --- doc/api/admin/data_management.md | 16 ++++++++-------- ee/app/models/concerns/geo/verification_state.rb | 7 +++++-- ee/lib/api/entities/admin/model.rb | 5 +---- ee/spec/lib/api/entities/admin/model_spec.rb | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/api/admin/data_management.md b/doc/api/admin/data_management.md index 90feb10c94d1e1..00885363b13be3 100644 --- a/doc/api/admin/data_management.md +++ b/doc/api/admin/data_management.md @@ -95,10 +95,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", + "checksum_state": "succeeded", "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null, - "checksum_state": "succeeded" + "checksum_failure": null } }, { @@ -109,10 +109,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.214Z", + "checksum_state": "succeeded", "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null, - "checksum_state": "succeeded" + "checksum_failure": null } } ] @@ -155,10 +155,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", + "checksum_state": "succeeded", "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null, - "checksum_state": "succeeded" + "checksum_failure": null } } ``` @@ -187,10 +187,10 @@ Example response: "checksum_information": { "checksum": "", "last_checksum": "2025-07-24T14:22:18.643Z", + "checksum_state": "succeeded", "checksum_retry_count": 0, "checksum_retry_at": null, - "checksum_failure": null, - "checksum_state": "succeeded" + "checksum_failure": null } } ``` diff --git a/ee/app/models/concerns/geo/verification_state.rb b/ee/app/models/concerns/geo/verification_state.rb index 1307c329096735..200fa7ced440c6 100644 --- a/ee/app/models/concerns/geo/verification_state.rb +++ b/ee/app/models/concerns/geo/verification_state.rb @@ -20,7 +20,9 @@ module VerificationState }.freeze VERIFICATION_TIMEOUT = 8.hours - VERIFICATION_METHODS = [:verification_retry_at, :verification_retry_at=, + VERIFICATION_METHODS = [ + :verification_state_name_no_prefix, + :verification_retry_at, :verification_retry_at=, :verified_at, :verified_at=, :verification_failed?, :verification_checksum, :verification_checksum=, :verification_failure, :verification_failure=, @@ -34,7 +36,8 @@ module VerificationState :verification_succeeded?, :verification_failed, :verification_pending, :verification_disabled, :verification_disabled!, :verification_disabled?, - :verification_pending?].freeze + :verification_pending? + ].freeze included do sha_attribute :verification_checksum diff --git a/ee/lib/api/entities/admin/model.rb b/ee/lib/api/entities/admin/model.rb index 7462411aabe1e9..833bfb4816d5fe 100644 --- a/ee/lib/api/entities/admin/model.rb +++ b/ee/lib/api/entities/admin/model.rb @@ -34,13 +34,10 @@ class Model < Grape::Entity if: ->(model) { verification_enabled?(model) } do expose :verification_checksum, as: :checksum expose :verified_at, as: :last_checksum + expose :verification_state_name_no_prefix, as: :checksum_state expose :verification_retry_count, as: :checksum_retry_count expose :verification_retry_at, as: :checksum_retry_at expose :verification_failure, as: :checksum_failure - - expose :verification_state, as: :checksum_state do |model| - model.verification_state_object&.verification_state_name_no_prefix - end end private diff --git a/ee/spec/lib/api/entities/admin/model_spec.rb b/ee/spec/lib/api/entities/admin/model_spec.rb index fe46ae1a92e803..46c6edd7b83e24 100644 --- a/ee/spec/lib/api/entities/admin/model_spec.rb +++ b/ee/spec/lib/api/entities/admin/model_spec.rb @@ -30,7 +30,7 @@ expect(result[:created_at]).to eq(model.respond_to?(:created_at) ? model.created_at : nil) expect(result[:file_size]).to eq(model.attributes.has_key?('size') ? model.size : nil) expect(result.dig(:checksum_information, :checksum_state)) - .to eq(model.verification_state_object.verification_state_name_no_prefix) + .to eq(model.verification_state_name_no_prefix) end end -- GitLab From bf26567bb01283d2c92b7bf6b7e0fe018bd1b511 Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Wed, 22 Oct 2025 19:49:15 +0800 Subject: [PATCH 4/5] Fix specs --- ee/app/graphql/types/geo/registry_type.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ee/app/graphql/types/geo/registry_type.rb b/ee/app/graphql/types/geo/registry_type.rb index 8aaa73867df36f..983d265c87dfab 100644 --- a/ee/app/graphql/types/geo/registry_type.rb +++ b/ee/app/graphql/types/geo/registry_type.rb @@ -31,8 +31,12 @@ module RegistryType field :verification_retry_at, Types::TimeType, null: true, description: "Timestamp after which the #{graphql_name} is reverified" field :verification_retry_count, GraphQL::Types::Int, null: true, description: "Number of consecutive failed verification attempts of the #{graphql_name}" field :verification_started_at, Types::TimeType, null: true, description: "Timestamp when the verification of #{graphql_name} started" - field :verification_state, Types::Geo::VerificationStateEnum, null: true, resolver_method: :verification_state_name_no_prefix, description: "Verification state of the #{graphql_name}" + field :verification_state, Types::Geo::VerificationStateEnum, null: true, resolver_method: :verification_state_name_value, description: "Verification state of the #{graphql_name}" field :verified_at, Types::TimeType, null: true, description: "Timestamp of the most recent successful verification of the #{graphql_name}" + + def verification_state_name_value + object.verification_state_name_no_prefix + end end end end -- GitLab From 7941ad34a2de0b6fdc6d56460b74e31518b6c04d Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Thu, 23 Oct 2025 10:53:26 +0800 Subject: [PATCH 5/5] Add verification_state_name_no_prefix specs --- .../geo/verification_state_definition_spec.rb | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 ee/spec/models/concerns/geo/verification_state_definition_spec.rb diff --git a/ee/spec/models/concerns/geo/verification_state_definition_spec.rb b/ee/spec/models/concerns/geo/verification_state_definition_spec.rb new file mode 100644 index 00000000000000..50d564ffdf2dac --- /dev/null +++ b/ee/spec/models/concerns/geo/verification_state_definition_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Geo::VerificationStateDefinition, feature_category: :geo_replication do + using RSpec::Parameterized::TableSyntax + + include ::EE::GeoHelpers + + before_all do + create_dummy_model_table + end + + after(:all) do + drop_dummy_model_table + end + + let_it_be(:dummy_model_class) do + Class.new(ActiveRecord::Base) do + self.table_name = '_test_dummy_models' + include Geo::VerificationStateDefinition + end + end + + let(:dummy_model) { dummy_model_class.new } + + describe '#verification_state_name_no_prefix' do + where(:raw_state, :expected_result) do + :verification_pending | 'pending' + :verification_started | 'started' + :verification_succeeded | 'succeeded' + :verification_failed | 'failed' + :verification_disabled | 'disabled' + end + + with_them do + it 'removes verification_ prefix from state name' do + dummy_model.verification_state = ::Geo::VerificationState::VERIFICATION_STATE_VALUES[raw_state] + + expect(dummy_model.verification_state_name_no_prefix).to eq(expected_result) + end + end + end + + def create_dummy_model_table + ActiveRecord::Schema.define do + create_table :_test_dummy_models, force: true do |t| + t.binary :verification_checksum + t.integer :verification_state + t.datetime_with_timezone :verification_started_at + t.datetime_with_timezone :verified_at + t.datetime_with_timezone :verification_retry_at + t.integer :verification_retry_count + t.text :verification_failure + end + end + end + + def drop_dummy_model_table + ActiveRecord::Schema.define do + drop_table :_test_dummy_models, force: true + end + end +end -- GitLab