From 7ba65b48ab40a7a79c06d6d5088719ae070125e1 Mon Sep 17 00:00:00 2001 From: Mohamed Moustafa Date: Mon, 17 Mar 2025 15:44:10 +0100 Subject: [PATCH 1/2] Update billable user counts on license creation --- ee/app/models/license.rb | 6 ++++++ ee/spec/models/license_spec.rb | 12 ++++++++++++ ee/spec/requests/api/license_spec.rb | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ee/app/models/license.rb b/ee/app/models/license.rb index ebb3af11940086..bcba572ab94bc3 100644 --- a/ee/app/models/license.rb +++ b/ee/app/models/license.rb @@ -47,6 +47,7 @@ class License < ApplicationRecord after_create :update_trial_setting after_commit :reset_current after_commit :reset_future_dated, on: [:create, :destroy] + after_commit :update_billable_user_counts, on: :create scope :cloud, -> { where(cloud: true) } scope :recent, -> { reorder(id: :desc) } @@ -361,6 +362,11 @@ def update_trial_setting settings.update license_trial_ends_on: license.expires_at end + def update_billable_user_counts + identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users] + ::Analytics::UsageTrends::CounterJobWorker.perform_async(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now) + end + def paid? [License::STARTER_PLAN, License::PREMIUM_PLAN, License::ULTIMATE_PLAN].include?(plan) end diff --git a/ee/spec/models/license_spec.rb b/ee/spec/models/license_spec.rb index f395a55b5a48a1..ac92cee41eb082 100644 --- a/ee/spec/models/license_spec.rb +++ b/ee/spec/models/license_spec.rb @@ -18,6 +18,10 @@ def build_license_with_add_ons(add_ons, plan: nil) build(:license, data: gl_license.export) end + before do + allow(::Analytics::UsageTrends::CounterJobWorker).to receive(:perform_async) + end + describe 'validations' do describe '#valid_license' do subject(:license) { build(:license, data: gl_license.class.encryptor.encrypt(gl_license.to_json)) } @@ -626,6 +630,14 @@ def current_license_cached_value end end end + + describe '#update_billable_user_counts' do + subject!(:license) { create(:license, data: gl_license.export, starts_at: Date.current) } + + it 'updates billable user counts' do + expect(::Analytics::UsageTrends::CounterJobWorker).to have_received(:perform_async).once + end + end end describe 'Scopes' do diff --git a/ee/spec/requests/api/license_spec.rb b/ee/spec/requests/api/license_spec.rb index f8c12a0004c8c9..3dcec170b170c5 100644 --- a/ee/spec/requests/api/license_spec.rb +++ b/ee/spec/requests/api/license_spec.rb @@ -235,7 +235,7 @@ def license_json(license) end describe 'PUT /license/:id/refresh_billable_users' do - let(:license) { create(:license) } + let!(:license) { create(:license) } let(:endpoint) { "/license/#{license.id}/refresh_billable_users" } before do -- GitLab From db8f7edeb0c82c302a37d8e8bcedbee275c34501 Mon Sep 17 00:00:00 2001 From: Mohamed Moustafa Date: Mon, 28 Jul 2025 15:57:14 +0200 Subject: [PATCH 2/2] Get up-to-date license seat count for failing test --- qa/qa/ee/resource/license.rb | 17 +++++++++++++++++ qa/qa/resource/api_fabricator.rb | 2 +- .../user_registration_billing_spec.rb | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/qa/qa/ee/resource/license.rb b/qa/qa/ee/resource/license.rb index 818be1fc6c9f9b..6bee5da2a5b0cd 100644 --- a/qa/qa/ee/resource/license.rb +++ b/qa/qa/ee/resource/license.rb @@ -28,6 +28,10 @@ def delete_all(api_client = nil) instance(api_client).delete_all end + def current(api_client = nil) + instance(api_client).current + end + private def instance(api_client) @@ -132,6 +136,19 @@ def delete_all raise(ResourceNotDeletedError, "One or more licenses failed to delete: #{errors}") unless errors.empty? end + def current + current_license = parse_body(get(::QA::Runtime::API::Request.new(api_client, '/license').url)) + + License.init do |resource| + resource.id = current_license[:id] + resource.api_client = api_client + end + end + + def refresh_billable_users! + api_put_to("#{api_get_path}/refresh_billable_users", nil) + end + private # License key length diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb index da6ae0a9fefbb5..8f34da1f902883 100644 --- a/qa/qa/resource/api_fabricator.rb +++ b/qa/qa/resource/api_fabricator.rb @@ -150,7 +150,7 @@ def api_put def api_put_to(put_path, body) response = put(Runtime::API::Request.new(api_client, put_path).url, body) - unless response.code == HTTP_STATUS_OK + unless [HTTP_STATUS_OK, HTTP_STATUS_ACCEPTED].include? response.code raise(ResourceFabricationFailedError, <<~MSG.strip) Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`. #{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])} diff --git a/qa/qa/specs/features/ee/browser_ui/11_fulfillment/utilization/user_registration_billing_spec.rb b/qa/qa/specs/features/ee/browser_ui/11_fulfillment/utilization/user_registration_billing_spec.rb index 3a1572ff81378c..c58a35d6c67f01 100644 --- a/qa/qa/specs/features/ee/browser_ui/11_fulfillment/utilization/user_registration_billing_spec.rb +++ b/qa/qa/specs/features/ee/browser_ui/11_fulfillment/utilization/user_registration_billing_spec.rb @@ -15,6 +15,11 @@ module QA username: "qa-test-#{SecureRandom.hex(3)}") end + def refresh_billable_users_in_license + EE::Resource::License.current.refresh_billable_users! + sleep 5 # wait for billable users to be refreshed + end + before do # Enable sign-ups Runtime::ApplicationSettings.set_application_settings(signup_enabled: true) @@ -28,6 +33,7 @@ module QA end Flow::UserOnboarding.onboard_user + refresh_billable_users_in_license end after do @@ -60,6 +66,7 @@ module QA user.reload! && user.approve! # first reload the API resource to fetch the ID, then approve EE::Page::Admin::Dashboard.perform do |dashboard| + refresh_billable_users_in_license dashboard.refresh # Validate billable users has not changed after approval @@ -67,6 +74,7 @@ module QA group.add_member(user) # add the user to the group + refresh_billable_users_in_license dashboard.refresh # Validate billable users incremented by 1 @@ -74,6 +82,7 @@ module QA group.remove_member(user) # remove the user from the group + refresh_billable_users_in_license dashboard.refresh # Validate billable users equals the original amount -- GitLab