Commit 5255296f authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'extract-ci-minutes-quota' into 'master'

Extract Ci::Minutes::Quota class

See merge request gitlab-org/gitlab!29230
parents aa9ee169 8d0594a8
...@@ -3,28 +3,18 @@ ...@@ -3,28 +3,18 @@
module EE module EE
module NamespacesHelper module NamespacesHelper
def namespace_extra_shared_runner_limits_quota(namespace) def namespace_extra_shared_runner_limits_quota(namespace)
limit = namespace.extra_shared_runners_minutes_limit.to_i report = ::Ci::Minutes::Quota.new(namespace).purchased_minutes_report
used = namespace.extra_shared_runners_minutes.to_i
status = namespace.extra_shared_runners_minutes_used? ? 'over_quota' : 'under_quota'
content_tag(:span, class: "shared_runners_limit_#{status}") do content_tag(:span, class: "shared_runners_limit_#{report.status}") do
"#{used} / #{limit}" "#{report.used} / #{report.limit}"
end end
end end
def namespace_shared_runner_limits_quota(namespace) def namespace_shared_runner_limits_quota(namespace)
used = namespace.shared_runners_minutes(include_extra: false).to_i report = ::Ci::Minutes::Quota.new(namespace).monthly_minutes_report
if namespace.shared_runners_minutes_limit_enabled?
limit = namespace.actual_shared_runners_minutes_limit(include_extra: false)
status = namespace.shared_runners_minutes_used? ? 'over_quota' : 'under_quota'
else
limit = 'Unlimited'
status = 'disabled'
end
content_tag(:span, class: "shared_runners_limit_#{status}") do content_tag(:span, class: "shared_runners_limit_#{report.status}") do
"#{used} / #{limit}" "#{report.used} / #{report.limit}"
end end
end end
......
# frozen_string_literal: true
# This class provides current status of Shared Runners minutes usage for a namespace
# taking in consideration the monthly minutes allowance that Gitlab.com provides and
# any possible purchased minutes.
module Ci
module Minutes
class Quota
Report = Struct.new(:used, :limit, :status)
def initialize(namespace)
@namespace = namespace
end
# Status of the monthly allowance being used.
def monthly_minutes_report
if namespace.shared_runners_minutes_limit_enabled? # TODO: try to refactor this
status = monthly_minutes_used_up? ? :over_quota : :under_quota
Report.new(monthly_minutes_used, monthly_minutes, status)
else
Report.new(monthly_minutes_used, 'Unlimited', :disabled)
end
end
# Status of any purchased minutes used.
def purchased_minutes_report
status = purchased_minutes_used_up? ? :over_quota : :under_quota
Report.new(purchased_minutes_used, purchased_minutes, status)
end
private
# TODO: maps to NamespacesHelper#namespace_shared_runner_limits_percent_used
# TODO: consider including this into monthly_minutes_report
def monthly_percent_used
return 0 unless namespace.shared_runners_minutes_limit_enabled?
100 * monthly_minutes_used.to_i / monthly_minutes
end
# TODO: maps to NamespacesHelper#namespace_extra_shared_runner_limits_percent_used
# TODO: consider including this into purchased_minutes_report
def purchased_percent_used
return 0 if purchased_minutes.zero?
100 * purchased_minutes_used.to_i / purchased_minutes
end
# TODO: maps to Namespace#shared_runners_minutes_used?
def monthly_minutes_used_up?
namespace.shared_runners_minutes_limit_enabled? &&
monthly_minutes_used >= monthly_minutes
end
# TODO: maps to Namespace#extra_shared_runners_minutes_used?
def purchased_minutes_used_up?
namespace.shared_runners_minutes_limit_enabled? &&
any_minutes_purchased? &&
purchased_minutes_used >= purchased_minutes
end
# TODO: maps to NamespaceStatistics#shared_runners_minutes(include_extra: false)
def monthly_minutes_used
minutes_used - purchased_minutes_used
end
def monthly_minutes_available?
minutes_used <= monthly_minutes
end
# TODO: maps to NamespaceStatistics#extra_shared_runners_minutes
def purchased_minutes_used
return 0 if no_minutes_purchased? || monthly_minutes_available?
minutes_used - monthly_minutes
end
def no_minutes_purchased?
purchased_minutes.zero?
end
def any_minutes_purchased?
purchased_minutes.positive?
end
# TODO: maps to NamespaceStatistics#shared_runners_minutes(include_extra: true)
def minutes_used
@minutes_used ||= namespace.shared_runners_seconds.to_i / 60
end
# TODO: maps to Namespace#actual_shared_runners_minuts_limit(include_extra: false)
def monthly_minutes
@monthly_minutes ||= (namespace.shared_runners_minutes_limit || ::Gitlab::CurrentSettings.shared_runners_minutes).to_i
end
def purchased_minutes
@purchased_minutes ||= namespace.extra_shared_runners_minutes_limit.to_i
end
attr_reader :namespace
end
end
end
...@@ -33,7 +33,7 @@ describe EE::NamespacesHelper do ...@@ -33,7 +33,7 @@ describe EE::NamespacesHelper do
end end
it 'returns the proper value for the used section' do it 'returns the proper value for the used section' do
allow(user_group).to receive(:shared_runners_minutes).and_return(100) allow(user_group).to receive(:shared_runners_seconds).and_return(100 * 60)
expect(helper.namespace_shared_runner_limits_quota(user_group)).to match(%r{100 / Unlimited}) expect(helper.namespace_shared_runner_limits_quota(user_group)).to match(%r{100 / Unlimited})
end end
...@@ -42,7 +42,7 @@ describe EE::NamespacesHelper do ...@@ -42,7 +42,7 @@ describe EE::NamespacesHelper do
context "when it's limited" do context "when it's limited" do
before do before do
allow(user_group).to receive(:shared_runners_minutes_limit_enabled?).and_return(true) allow(user_group).to receive(:shared_runners_minutes_limit_enabled?).and_return(true)
allow(user_group).to receive(:shared_runners_minutes).and_return(100) allow(user_group).to receive(:shared_runners_seconds).and_return(100 * 60)
user_group.update!(shared_runners_minutes_limit: 500) user_group.update!(shared_runners_minutes_limit: 500)
end end
...@@ -56,7 +56,7 @@ describe EE::NamespacesHelper do ...@@ -56,7 +56,7 @@ describe EE::NamespacesHelper do
describe '#namespace_extra_shared_runner_limits_quota' do describe '#namespace_extra_shared_runner_limits_quota' do
context 'when extra minutes are assigned' do context 'when extra minutes are assigned' do
it 'returns the proper values for used and limit sections' do it 'returns the proper values for used and limit sections' do
allow(user_group).to receive(:extra_shared_runners_minutes).and_return(50) allow(user_group).to receive(:shared_runners_seconds).and_return(50 * 60)
user_group.update!(extra_shared_runners_minutes_limit: 100) user_group.update!(extra_shared_runners_minutes_limit: 100)
expect(helper.namespace_extra_shared_runner_limits_quota(user_group)).to match(%r{50 / 100}) expect(helper.namespace_extra_shared_runner_limits_quota(user_group)).to match(%r{50 / 100})
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::Minutes::Quota do
let_it_be(:namespace) do
create(:namespace, namespace_statistics: create(:namespace_statistics))
end
let(:quota) { described_class.new(namespace) }
describe '#monthly_minutes_report' do
context 'when unlimited' do
before do
allow(namespace).to receive(:shared_runners_minutes_limit_enabled?).and_return(false)
end
context 'when minutes are not used' do
it 'returns unlimited report with no usage' do
report = quota.monthly_minutes_report
expect(report.limit).to eq 'Unlimited'
expect(report.used).to eq 0
expect(report.status).to eq :disabled
end
end
context 'when minutes are used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 20.minutes
end
it 'returns unlimited report with usage' do
report = quota.monthly_minutes_report
expect(report.limit).to eq 'Unlimited'
expect(report.used).to eq 20
expect(report.status).to eq :disabled
end
end
end
context 'when limited' do
before do
allow(namespace).to receive(:shared_runners_minutes_limit_enabled?).and_return(true)
namespace.shared_runners_minutes_limit = 100
end
context 'when minutes are not all used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 30.minutes
end
it 'returns report with under quota' do
report = quota.monthly_minutes_report
expect(report.limit).to eq 100
expect(report.used).to eq 30
expect(report.status).to eq :under_quota
end
end
context 'when minutes are all used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 101.minutes
end
it 'returns report with over quota' do
report = quota.monthly_minutes_report
expect(report.limit).to eq 100
expect(report.used).to eq 101
expect(report.status).to eq :over_quota
end
end
end
end
describe '#purchased_minutes_report' do
context 'when limit enabled' do
before do
allow(namespace).to receive(:shared_runners_minutes_limit_enabled?).and_return(true)
namespace.shared_runners_minutes_limit = 200
end
context 'when extra minutes have been purchased' do
before do
namespace.extra_shared_runners_minutes_limit = 100
end
context 'when all monthly minutes are used and some puarchased minutes are used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 250.minutes
end
it 'returns report with under quota' do
report = quota.purchased_minutes_report
expect(report.limit).to eq 100
expect(report.used).to eq 50
expect(report.status).to eq :under_quota
end
end
context 'when all monthly and all puarchased minutes have been used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 301.minutes
end
it 'returns report with over quota' do
report = quota.purchased_minutes_report
expect(report.limit).to eq 100
expect(report.used).to eq 101
expect(report.status).to eq :over_quota
end
end
context 'when not all monthly minutes have been used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 190.minutes
end
it 'returns report with no usage' do
report = quota.purchased_minutes_report
expect(report.limit).to eq 100
expect(report.used).to eq 0
expect(report.status).to eq :under_quota
end
end
end
context 'when no extra minutes have been purchased' do
before do
namespace.extra_shared_runners_minutes_limit = nil
end
context 'when all monthly minutes have been used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 201.minutes
end
it 'returns report without usage' do
report = quota.purchased_minutes_report
expect(report.limit).to eq 0
expect(report.used).to eq 0
expect(report.status).to eq :under_quota
end
end
context 'when not all monthly minutes have been used' do
before do
namespace.namespace_statistics.shared_runners_seconds = 190.minutes
end
it 'returns report with no usage' do
report = quota.purchased_minutes_report
expect(report.limit).to eq 0
expect(report.used).to eq 0
expect(report.status).to eq :under_quota
end
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