Commit 14065e89 authored by Stan Hu's avatar Stan Hu

Merge branch '12241-current-active-users-historic-max' into 'master'

Resolve "Current active users > historic max"

Closes #12241

See merge request gitlab-org/gitlab-ee!15107
parents d2e8d26c b65c6773
...@@ -21,10 +21,13 @@ class HistoricalData < ApplicationRecord ...@@ -21,10 +21,13 @@ class HistoricalData < ApplicationRecord
find_by(date: date) find_by(date: date)
end end
def max_historical_user_count def max_historical_user_count(license: nil, from: nil, to: nil)
exp_date = License.current&.expires_at || Date.today license ||= License.current
expires_at = license&.expires_at || Date.today
from ||= expires_at - 1.year
to ||= expires_at
HistoricalData.during(exp_date.ago(1.year)..exp_date).maximum(:active_user_count) || 0 HistoricalData.during(from..to).maximum(:active_user_count) || 0
end end
end end
end end
...@@ -406,10 +406,7 @@ class License < ApplicationRecord ...@@ -406,10 +406,7 @@ class License < ApplicationRecord
end end
def historical_max(from = nil, to = nil) def historical_max(from = nil, to = nil)
from ||= starts_at - 1.year HistoricalData.max_historical_user_count(license: self, from: from, to: to)
to ||= starts_at
HistoricalData.during(from..to).maximum(:active_user_count) || 0
end end
def historical_max_with_default_period def historical_max_with_default_period
...@@ -439,22 +436,27 @@ class License < ApplicationRecord ...@@ -439,22 +436,27 @@ class License < ApplicationRecord
self.errors.add(:base, "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc.") self.errors.add(:base, "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc.")
end end
def empty_historical_max? def prior_historical_max
historical_max == 0 @prior_historical_max ||= begin
from = starts_at - 1.year
to = starts_at
historical_max(from, to)
end
end end
def check_users_limit def check_users_limit
return unless restricted_user_count return unless restricted_user_count
if previous_user_count && (historical_max <= previous_user_count) if previous_user_count && (prior_historical_max <= previous_user_count)
return if restricted_user_count >= current_active_users_count return if restricted_user_count >= current_active_users_count
else else
return if restricted_user_count >= historical_max return if restricted_user_count >= prior_historical_max
end end
user_count = empty_historical_max? ? current_active_users_count : historical_max user_count = prior_historical_max.zero? ? current_active_users_count : prior_historical_max
add_limit_error(current_period: empty_historical_max?, user_count: user_count) add_limit_error(current_period: prior_historical_max.zero?, user_count: user_count)
end end
def check_trueup def check_trueup
......
---
title: Show correct historic max user count for a license
merge_request: 15107
author:
type: fixed
...@@ -39,75 +39,98 @@ describe HistoricalData do ...@@ -39,75 +39,98 @@ describe HistoricalData do
end end
end end
describe ".max_historical_user_count" do describe '.max_historical_user_count' do
before do context 'with multiple historical data points for the current license' do
(1..3).each do |i| before do
described_class.create!(date: Time.now - i.days, active_user_count: i * 100) (1..3).each do |i|
described_class.create!(date: Time.now - i.days, active_user_count: i * 100)
end
end end
end
it "returns max user count for the past year" do it 'returns max user count for the past year' do
expect(described_class.max_historical_user_count).to eq(300) expect(described_class.max_historical_user_count).to eq(300)
end
end end
end
describe '.max_historical_user_count with different plans' do
using RSpec::Parameterized::TableSyntax
before do context 'using parameters' do
create(:group_member, :guest) let!(:license) do
create(:group_member, :reporter) create(
create(:license, plan: plan) :license,
starts_at: Date.new(2014, 1, 1),
described_class.track! expires_at: Date.new(2014, 12, 1)
end )
end
where(:gl_plan, :expected_count) do it 'returns max user count for the given license' do
::License::STARTER_PLAN | 2 expect(described_class.max_historical_user_count(license: license)).to eq(1200)
::License::PREMIUM_PLAN | 2 end
::License::ULTIMATE_PLAN | 1
end
with_them do it 'returns max user count for the time range' do
let(:plan) { gl_plan } from = Date.new(2014, 6, 1)
to = Date.new(2014, 9, 1)
it 'does not count guest users' do expect(described_class.max_historical_user_count(from: from, to: to)).to eq(900)
expect(described_class.max_historical_user_count).to eq(expected_count)
end end
end end
end
describe '.max_historical_user_count with data outside of the license period' do context 'with different plans' do
let!(:license) { create(:license) } using RSpec::Parameterized::TableSyntax
context 'with stats before the license period' do
before do before do
described_class.create!(date: license.starts_at.ago(2.days), active_user_count: 10) create(:group_member, :guest)
end create(:group_member, :reporter)
create(:license, plan: plan)
it 'ignore those records' do described_class.track!
expect(described_class.max_historical_user_count).to eq(0)
end end
end
context 'with stats after the license period' do where(:gl_plan, :expected_count) do
before do ::License::STARTER_PLAN | 2
described_class.create!(date: license.expires_at.in(2.days), active_user_count: 10) ::License::PREMIUM_PLAN | 2
::License::ULTIMATE_PLAN | 1
end end
it 'ignore those records' do with_them do
expect(described_class.max_historical_user_count).to eq(0) let(:plan) { gl_plan }
it 'does not count guest users' do
expect(described_class.max_historical_user_count).to eq(expected_count)
end
end end
end end
context 'with stats inside license period' do context 'with data outside of the license period' do
before do let!(:license) { create(:license) }
described_class.create!(date: license.starts_at.in(2.days), active_user_count: 10)
described_class.create!(date: license.starts_at.in(5.days), active_user_count: 15) context 'with stats before the license period' do
before do
described_class.create!(date: license.starts_at.ago(2.days), active_user_count: 10)
end
it 'ignore those records' do
expect(described_class.max_historical_user_count).to eq(0)
end
end
context 'with stats after the license period' do
before do
described_class.create!(date: license.expires_at.in(2.days), active_user_count: 10)
end
it 'ignore those records' do
expect(described_class.max_historical_user_count).to eq(0)
end
end end
it 'returns max value for active_user_count' do context 'with stats inside license period' do
expect(described_class.max_historical_user_count).to eq(15) before do
described_class.create!(date: license.starts_at.in(2.days), active_user_count: 10)
described_class.create!(date: license.starts_at.in(5.days), active_user_count: 15)
end
it 'returns max value for active_user_count' do
expect(described_class.max_historical_user_count).to eq(15)
end
end end
end end
end end
......
...@@ -83,7 +83,7 @@ describe License do ...@@ -83,7 +83,7 @@ describe License do
active_user_count: User.active.count - 1 active_user_count: User.active.count - 1
} }
allow(license).to receive(:historical_max).and_return(0) HistoricalData.delete_all
end end
context 'with previous_user_count and active users above of license limit' do context 'with previous_user_count and active users above of license limit' do
......
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