From 58937ba01ae938929f0451a72667245f973f537c Mon Sep 17 00:00:00 2001 From: Bojan Marjanovic Date: Wed, 22 Oct 2025 08:39:46 +0200 Subject: [PATCH 1/2] Add logic to OutstandingLease Changelog: added --- app/models/cells/outstanding_lease.rb | 36 ++++++ spec/models/cells/outstanding_lease_spec.rb | 127 ++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 spec/models/cells/outstanding_lease_spec.rb diff --git a/app/models/cells/outstanding_lease.rb b/app/models/cells/outstanding_lease.rb index f74763e6b828ae..07d35c9f2226d2 100644 --- a/app/models/cells/outstanding_lease.rb +++ b/app/models/cells/outstanding_lease.rb @@ -3,5 +3,41 @@ module Cells class OutstandingLease < ApplicationRecord self.primary_key = :uuid + + def self.claim_service + ::Gitlab::TopologyServiceClient::ClaimService.instance # rubocop:disable CodeReuse/ServiceClass -- this is a gRPC client + end + + def self.create_from_request!(create_records:, destroy_records:, deadline: nil) + req = Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest.new( + create_records: create_records, + destroy_records: destroy_records, + cell_id: claim_service.cell_id + ) + + res = claim_service.begin_update(req, deadline: deadline) + + create!(uuid: res.lease_uuid.value) + end + + def send_commit_update!(deadline: nil) + req = Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid), + cell_id: self.class.claim_service.cell_id + ) + + self.class.claim_service.commit_update(req, deadline: deadline) + end + + def send_rollback_update!(deadline: nil) + return unless uuid + + req = Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid), + cell_id: self.class.claim_service.cell_id + ) + + self.class.claim_service.rollback_update(req, deadline: deadline) + end end end diff --git a/spec/models/cells/outstanding_lease_spec.rb b/spec/models/cells/outstanding_lease_spec.rb new file mode 100644 index 00000000000000..ac7b139a36596b --- /dev/null +++ b/spec/models/cells/outstanding_lease_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Cells::OutstandingLease, feature_category: :cell do + let(:cell_id) { 1 } + let(:uuid_value) { SecureRandom.uuid } + let(:mock_service) { instance_double(::Gitlab::TopologyServiceClient::ClaimService) } + + before do + allow(described_class).to receive(:claim_service).and_return(mock_service) + allow(mock_service).to receive(:cell_id).and_return(cell_id) + end + + describe '.create_from_request!' do + let(:create_records) { [{}] } + let(:destroy_records) { [{}] } + + let(:mock_response) do + Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateResponse.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid_value) + ) + end + + it 'calls begin_update and creates an OutstandingLease' do + expect(mock_service).to receive(:begin_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest), + deadline: nil + ).and_return(mock_response) + + lease = described_class.create_from_request!(create_records: create_records, destroy_records: destroy_records) + + expect(lease).to be_persisted + expect(lease.uuid).to eq(uuid_value) + end + + context 'with deadline' do + let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } + + it 'calls begin_update with deadline and creates an OutstandingLease' do + expect(mock_service).to receive(:begin_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest), + deadline: deadline + ).and_return(mock_response) + + lease = described_class.create_from_request!( + create_records: create_records, + destroy_records: destroy_records, + deadline: deadline + ) + + expect(lease).to be_persisted + expect(lease.uuid).to eq(uuid_value) + end + end + end + + describe '#send_commit_update!' do + let(:lease) { described_class.create!(uuid: uuid_value) } + + it 'sends a commit_update request with the correct parameters' do + expect(mock_service).to receive(:commit_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest), + deadline: nil + ) + + lease.send_commit_update! + end + + context 'with deadline' do + let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } + + it 'sends a commit_update request with the correct parameters' do + expect(mock_service).to receive(:commit_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest), + deadline: deadline + ) + + lease.send_commit_update!(deadline: deadline) + end + end + end + + describe '#send_rollback_update!' do + context 'when uuid is present' do + let(:lease) { described_class.create!(uuid: uuid_value) } + + it 'sends a rollback_update request with the correct parameters' do + expect(mock_service).to receive(:rollback_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest), + deadline: nil + ) + + lease.send_rollback_update! + end + + context 'with deadline' do + let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } + + it 'sends a rollback_update request with the correct parameters' do + expect(mock_service).to receive(:rollback_update).with( + an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest), + deadline: deadline + ) + + lease.send_rollback_update!(deadline: deadline) + end + end + end + + context 'when uuid is nil' do + let(:lease) { described_class.new(uuid: nil) } + + it 'does not send a rollback_update request' do + expect(mock_service).not_to receive(:rollback_update) + + lease.send_rollback_update! + end + end + end + + describe '.claim_service' do + it 'returns the ClaimService instance' do + expect(described_class.claim_service).to eq(mock_service) + end + end +end -- GitLab From c470ba27dbc944f70c77f72e001b419d9acdb1ac Mon Sep 17 00:00:00 2001 From: Bojan Marjanovic Date: Thu, 23 Oct 2025 16:24:57 +0200 Subject: [PATCH 2/2] Match expected requests --- spec/models/cells/outstanding_lease_spec.rb | 56 +++++++++++++-------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/spec/models/cells/outstanding_lease_spec.rb b/spec/models/cells/outstanding_lease_spec.rb index ac7b139a36596b..175c37217dc152 100644 --- a/spec/models/cells/outstanding_lease_spec.rb +++ b/spec/models/cells/outstanding_lease_spec.rb @@ -23,10 +23,14 @@ end it 'calls begin_update and creates an OutstandingLease' do - expect(mock_service).to receive(:begin_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest), - deadline: nil - ).and_return(mock_response) + expected_request = Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest.new( + create_records: create_records, + destroy_records: destroy_records, + cell_id: cell_id + ) + + expect(mock_service) + .to receive(:begin_update).with(expected_request, deadline: nil).and_return(mock_response) lease = described_class.create_from_request!(create_records: create_records, destroy_records: destroy_records) @@ -38,10 +42,14 @@ let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } it 'calls begin_update with deadline and creates an OutstandingLease' do - expect(mock_service).to receive(:begin_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest), - deadline: deadline - ).and_return(mock_response) + expected_request = Gitlab::Cells::TopologyService::Claims::V1::BeginUpdateRequest.new( + create_records: create_records, + destroy_records: destroy_records, + cell_id: cell_id + ) + + expect(mock_service) + .to receive(:begin_update).with(expected_request, deadline: deadline).and_return(mock_response) lease = described_class.create_from_request!( create_records: create_records, @@ -59,11 +67,13 @@ let(:lease) { described_class.create!(uuid: uuid_value) } it 'sends a commit_update request with the correct parameters' do - expect(mock_service).to receive(:commit_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest), - deadline: nil + expected_request = Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid_value), + cell_id: cell_id ) + expect(mock_service).to receive(:commit_update).with(expected_request, deadline: nil) + lease.send_commit_update! end @@ -71,11 +81,13 @@ let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } it 'sends a commit_update request with the correct parameters' do - expect(mock_service).to receive(:commit_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest), - deadline: deadline + expected_request = Gitlab::Cells::TopologyService::Claims::V1::CommitUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid_value), + cell_id: cell_id ) + expect(mock_service).to receive(:commit_update).with(expected_request, deadline: deadline) + lease.send_commit_update!(deadline: deadline) end end @@ -86,11 +98,13 @@ let(:lease) { described_class.create!(uuid: uuid_value) } it 'sends a rollback_update request with the correct parameters' do - expect(mock_service).to receive(:rollback_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest), - deadline: nil + expected_request = Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid_value), + cell_id: cell_id ) + expect(mock_service).to receive(:rollback_update).with(expected_request, deadline: nil) + lease.send_rollback_update! end @@ -98,11 +112,13 @@ let(:deadline) { GRPC::Core::TimeConsts.from_relative_time(5.0) } it 'sends a rollback_update request with the correct parameters' do - expect(mock_service).to receive(:rollback_update).with( - an_instance_of(Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest), - deadline: deadline + expected_request = Gitlab::Cells::TopologyService::Claims::V1::RollbackUpdateRequest.new( + lease_uuid: Gitlab::Cells::TopologyService::Types::V1::UUID.new(value: uuid_value), + cell_id: cell_id ) + expect(mock_service).to receive(:rollback_update).with(expected_request, deadline: deadline) + lease.send_rollback_update!(deadline: deadline) end end -- GitLab