Commit 116158c9 authored by Tyler Amos's avatar Tyler Amos

Save last_synced_at on licenses table

Add a column for last_synced_at to the licenses table.
Use this new column for the "Last sync" value shown in the details
section of the Subscription page.
Modify the activate and sync services to save last_synced_at when
creating a cloud license record.

Changelog: added
parent 336e847d
# frozen_string_literal: true
class AddLastSyncedAtToLicenses < ActiveRecord::Migration[6.1]
def change
add_column :licenses, :last_synced_at, :datetime_with_timezone
end
end
705c4cf981f1929f8e8e4d8a8a3c12613516d65e59c71ac79048224cd97c47cc
\ No newline at end of file
...@@ -14461,7 +14461,8 @@ CREATE TABLE licenses ( ...@@ -14461,7 +14461,8 @@ CREATE TABLE licenses (
data text NOT NULL, data text NOT NULL,
created_at timestamp without time zone, created_at timestamp without time zone,
updated_at timestamp without time zone, updated_at timestamp without time zone,
cloud boolean DEFAULT false cloud boolean DEFAULT false,
last_synced_at timestamp with time zone
); );
CREATE SEQUENCE licenses_id_seq CREATE SEQUENCE licenses_id_seq
...@@ -17,7 +17,7 @@ module GitlabSubscriptions ...@@ -17,7 +17,7 @@ module GitlabSubscriptions
return response unless response[:success] return response unless response[:success]
license = License.new(data: response[:license_key], cloud: true) license = License.new(data: response[:license_key], cloud: true, last_synced_at: Time.current)
if license.save if license.save
License.cloud.id_not_in(license.id).delete_all License.cloud.id_not_in(license.id).delete_all
......
...@@ -37,7 +37,7 @@ class SyncSeatLinkRequestWorker ...@@ -37,7 +37,7 @@ class SyncSeatLinkRequestWorker
def reset_license!(license_data) def reset_license!(license_data)
License.transaction do License.transaction do
License.cloud.delete_all License.cloud.delete_all
License.create!(data: license_data, cloud: true) License.create!(data: license_data, cloud: true, last_synced_at: Time.current)
end end
rescue StandardError => e rescue StandardError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e) Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
......
...@@ -6,7 +6,6 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do ...@@ -6,7 +6,6 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:admin) { create(:admin) } let_it_be(:admin) { create(:admin) }
let_it_be(:last_synced_at) { DateTime.current - 1.day }
let_it_be(:licensee) do let_it_be(:licensee) do
{ {
'Name' => 'User Example', 'Name' => 'User Example',
...@@ -17,10 +16,8 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do ...@@ -17,10 +16,8 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do
let_it_be(:license) do let_it_be(:license) do
create_current_license( create_current_license(
licensee: licensee, { licensee: licensee, cloud_licensing_enabled: true },
cloud_licensing_enabled: true, { cloud: true, last_synced_at: Time.current }
last_synced_at: last_synced_at,
next_sync_at: last_synced_at + 1.day
) )
end end
...@@ -28,20 +25,6 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do ...@@ -28,20 +25,6 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do
%w[last_sync billable_users_count maximum_user_count users_over_license_count] %w[last_sync billable_users_count maximum_user_count users_over_license_count]
end end
def query(field_name)
%(
{
currentLicense {
#{field_name}
}
}
)
end
def query_field(field_name)
GitlabSchema.execute(query(field_name), context: { current_user: admin }).as_json
end
before do before do
stub_application_setting(cloud_license_enabled: true) stub_application_setting(cloud_license_enabled: true)
end end
...@@ -52,6 +35,20 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do ...@@ -52,6 +35,20 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do
include_examples 'license type fields', %w[data currentLicense] include_examples 'license type fields', %w[data currentLicense]
describe "#users_over_license_count" do describe "#users_over_license_count" do
def query(field_name)
%(
{
currentLicense {
#{field_name}
}
}
)
end
def query_field(field_name)
GitlabSchema.execute(query(field_name), context: { current_user: admin }).as_json
end
context 'when license is for a trial' do context 'when license is for a trial' do
it 'returns 0' do it 'returns 0' do
create_current_license(licensee: licensee, restrictions: { trial: true }) create_current_license(licensee: licensee, restrictions: { trial: true })
...@@ -78,7 +75,7 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do ...@@ -78,7 +75,7 @@ RSpec.describe GitlabSchema.types['CurrentLicense'], :enable_admin_mode do
describe 'last_sync' do describe 'last_sync' do
let(:field_name) { :last_sync } let(:field_name) { :last_sync }
it { is_expected.to eq(last_synced_at.change(usec: 0)) } it { is_expected.to eq(license.last_synced_at) }
end end
describe 'billable_users_count' do describe 'billable_users_count' do
......
...@@ -62,7 +62,7 @@ RSpec.describe 'Activate a subscription' do ...@@ -62,7 +62,7 @@ RSpec.describe 'Activate a subscription' do
'expiresAt' => created_license.expires_at.to_s, 'expiresAt' => created_license.expires_at.to_s,
'blockChangesAt' => created_license.block_changes_at.to_s, 'blockChangesAt' => created_license.block_changes_at.to_s,
'activatedAt' => created_license.created_at.to_date.to_s, 'activatedAt' => created_license.created_at.to_date.to_s,
'lastSync' => nil, 'lastSync' => created_license.last_synced_at.iso8601,
'usersInLicenseCount' => nil, 'usersInLicenseCount' => nil,
'billableUsersCount' => 1, 'billableUsersCount' => 1,
'maximumUserCount' => 1, 'maximumUserCount' => 1,
......
...@@ -32,13 +32,18 @@ RSpec.describe GitlabSubscriptions::ActivateService do ...@@ -32,13 +32,18 @@ RSpec.describe GitlabSubscriptions::ActivateService do
end end
it 'persists license' do it 'persists license' do
result = execute_service freeze_time do
created_license = License.last result = execute_service
created_license = License.last
expect(result).to eq({ success: true, license: created_license }) expect(result).to eq({ success: true, license: created_license })
expect(created_license.data).to eq(license_key) expect(created_license).to have_attributes(
expect(created_license.cloud).to eq(true) data: license_key,
cloud: true,
last_synced_at: Time.current
)
end
end end
it 'deletes any existing cloud licenses' do it 'deletes any existing cloud licenses' do
......
...@@ -43,11 +43,12 @@ module EE ...@@ -43,11 +43,12 @@ module EE
::Gitlab::CurrentSettings.update!(check_namespace_plan: true) ::Gitlab::CurrentSettings.update!(check_namespace_plan: true)
end end
def create_current_license(options = {}) def create_current_license(gitlab_license_options = {}, license_options = {})
License.current.destroy! License.current.destroy!
gl_license = create(:gitlab_license, options) gl_license = create(:gitlab_license, gitlab_license_options)
create(:license, data: gl_license.export)
create(:license, license_options.merge(data: gl_license.export))
end end
::Project.prepend ClearLicensedFeatureAvailableCache ::Project.prepend ClearLicensedFeatureAvailableCache
......
...@@ -46,11 +46,14 @@ RSpec.describe SyncSeatLinkRequestWorker, type: :worker do ...@@ -46,11 +46,14 @@ RSpec.describe SyncSeatLinkRequestWorker, type: :worker do
shared_examples 'successful license creation' do shared_examples 'successful license creation' do
it 'persists the new license' do it 'persists the new license' do
expect { sync_seat_link }.to change(License, :count).by(1) freeze_time do
expect(License.last).to have_attributes( expect { sync_seat_link }.to change(License, :count).by(1)
data: license_key, expect(License.last).to have_attributes(
cloud: true data: license_key,
) cloud: true,
last_synced_at: Time.current
)
end
end 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