Commit bb9ef246 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'move-shared-runners-remaining-minutes-to-quota' into 'master'

Move shared_runners_remaining_minutes to Ci::Minutes::Quota

See merge request gitlab-org/gitlab!48939
parents babf17e2 20e1817a
...@@ -5,7 +5,6 @@ module Ci ...@@ -5,7 +5,6 @@ module Ci
class Context class Context
delegate :shared_runners_minutes_limit_enabled?, to: :level delegate :shared_runners_minutes_limit_enabled?, to: :level
delegate :name, to: :namespace, prefix: true delegate :name, to: :namespace, prefix: true
delegate :shared_runners_remaining_minutes_percent, to: :namespace
attr_reader :level attr_reader :level
...@@ -15,9 +14,17 @@ module Ci ...@@ -15,9 +14,17 @@ module Ci
@level = project || namespace @level = project || namespace
end end
def percent_total_minutes_remaining
quota.percent_total_minutes_remaining
end
private private
attr_reader :project, :namespace attr_reader :project, :namespace
def quota
@quota ||= ::Ci::Minutes::Quota.new(namespace)
end
end end
end end
end end
...@@ -50,7 +50,7 @@ module Ci ...@@ -50,7 +50,7 @@ module Ci
end end
def calculate_notification_stage def calculate_notification_stage
percentage = context.shared_runners_remaining_minutes_percent.to_i percentage = context.percent_total_minutes_remaining.to_i
if percentage <= PERCENTAGES[:exceeded] if percentage <= PERCENTAGES[:exceeded]
:exceeded :exceeded
......
...@@ -52,8 +52,18 @@ module Ci ...@@ -52,8 +52,18 @@ module Ci
@total_minutes_used ||= namespace.shared_runners_seconds.to_i / 60 @total_minutes_used ||= namespace.shared_runners_seconds.to_i / 60
end end
def percent_total_minutes_remaining
return 0 if total_minutes == 0
100 * total_minutes_remaining.to_i / total_minutes
end
private private
def total_minutes_remaining
[total_minutes.to_i - total_minutes_used, 0].max
end
def monthly_minutes_used_up? def monthly_minutes_used_up?
namespace.shared_runners_minutes_limit_enabled? && namespace.shared_runners_minutes_limit_enabled? &&
monthly_minutes_used >= monthly_minutes monthly_minutes_used >= monthly_minutes
......
...@@ -265,17 +265,6 @@ module EE ...@@ -265,17 +265,6 @@ module EE
actual_shared_runners_minutes_limit.nonzero? actual_shared_runners_minutes_limit.nonzero?
end end
def shared_runners_remaining_minutes_percent
return 0 if shared_runners_remaining_minutes.to_f <= 0
return 0 if actual_shared_runners_minutes_limit.to_f == 0
(shared_runners_remaining_minutes.to_f * 100) / actual_shared_runners_minutes_limit.to_f
end
def shared_runners_remaining_minutes_below_threshold?
shared_runners_remaining_minutes_percent.to_i <= last_ci_minutes_usage_notification_level.to_i
end
def any_project_with_shared_runners_enabled? def any_project_with_shared_runners_enabled?
all_projects.with_shared_runners.any? all_projects.with_shared_runners.any?
end end
...@@ -445,10 +434,6 @@ module EE ...@@ -445,10 +434,6 @@ module EE
) )
end end
def shared_runners_remaining_minutes
[actual_shared_runners_minutes_limit.to_f - ci_minutes_quota.total_minutes_used.to_f, 0].max
end
def total_repository_size_excess_calculation(repository_size_limit, project_level: true) def total_repository_size_excess_calculation(repository_size_limit, project_level: true)
total_excess = (total_repository_size_arel - repository_size_limit).sum total_excess = (total_repository_size_arel - repository_size_limit).sum
relation = projects_for_repository_size_excess((repository_size_limit unless project_level)) relation = projects_for_repository_size_excess((repository_size_limit unless project_level))
......
...@@ -182,8 +182,7 @@ module EE ...@@ -182,8 +182,7 @@ module EE
delegate :shared_runners_minutes, :shared_runners_seconds, :shared_runners_seconds_last_reset, delegate :shared_runners_minutes, :shared_runners_seconds, :shared_runners_seconds_last_reset,
to: :statistics, allow_nil: true to: :statistics, allow_nil: true
delegate :actual_shared_runners_minutes_limit, delegate :actual_shared_runners_minutes_limit, to: :shared_runners_limit_namespace
:shared_runners_remaining_minutes_below_threshold?, to: :shared_runners_limit_namespace
delegate :last_update_succeeded?, :last_update_failed?, delegate :last_update_succeeded?, :last_update_failed?,
:ever_updated_successfully?, :hard_failed?, :ever_updated_successfully?, :hard_failed?,
......
...@@ -20,21 +20,21 @@ RSpec.describe 'CI shared runner limits' do ...@@ -20,21 +20,21 @@ RSpec.describe 'CI shared runner limits' do
group.add_developer(user) group.add_developer(user)
end end
where(:case_name, :percent, :remaining_minutes) do where(:case_name, :percent_threshold, :minutes_limit, :minutes_used) do
'warning level' | 30 | 4 'warning level' | 30 | 1000 | 800
'danger level' | 5 | 1 'danger level' | 5 | 1000 | 980
end end
with_them do with_them do
context "when there is a notification and minutes still exist", :js do context "when there is a notification and minutes still exist", :js do
let(:message) do let(:message) do
"Group #{group.name} has #{percent}% or less Shared Runner Pipeline minutes remaining. " \ "Group #{group.name} has #{percent_threshold}% or less Shared Runner Pipeline minutes remaining. " \
"Once it runs out, no new jobs or pipelines in its projects will run." "Once it runs out, no new jobs or pipelines in its projects will run."
end end
before do before do
group.update!(shared_runners_minutes_limit: 20) group.update!(shared_runners_minutes_limit: minutes_limit)
allow_any_instance_of(EE::Namespace).to receive(:shared_runners_remaining_minutes).and_return(remaining_minutes) allow_any_instance_of(EE::Namespace).to receive(:shared_runners_seconds).and_return(minutes_used.minutes)
end end
it 'displays a warning message on pipelines page' do it 'displays a warning message on pipelines page' do
...@@ -111,21 +111,21 @@ RSpec.describe 'CI shared runner limits' do ...@@ -111,21 +111,21 @@ RSpec.describe 'CI shared runner limits' do
group.add_owner(user) group.add_owner(user)
end end
where(:case_name, :percent, :remaining_minutes) do where(:case_name, :percent_threshold, :minutes_limit, :minutes_used) do
'warning level' | 30 | 4 'warning level' | 30 | 1000 | 800
'danger level' | 5 | 1 'danger level' | 5 | 1000 | 980
end end
with_them do with_them do
context "when there is a notification and minutes still exist", :js do context "when there is a notification and minutes still exist", :js do
let(:message) do let(:message) do
"Group #{group.name} has #{percent}% or less Shared Runner Pipeline minutes remaining. " \ "Group #{group.name} has #{percent_threshold}% or less Shared Runner Pipeline minutes remaining. " \
"Once it runs out, no new jobs or pipelines in its projects will run." "Once it runs out, no new jobs or pipelines in its projects will run."
end end
before do before do
group.update!(shared_runners_minutes_limit: 20) group.update!(shared_runners_minutes_limit: minutes_limit)
allow_any_instance_of(EE::Namespace).to receive(:shared_runners_remaining_minutes).and_return(remaining_minutes) allow_any_instance_of(EE::Namespace).to receive(:shared_runners_seconds).and_return(minutes_used.minutes)
end end
it 'displays a warning message on group overview page' do it 'displays a warning message on group overview page' do
......
...@@ -38,7 +38,7 @@ RSpec.describe Ci::Minutes::Notification do ...@@ -38,7 +38,7 @@ RSpec.describe Ci::Minutes::Notification do
context 'when at the warning level' do context 'when at the warning level' do
before do before do
allow(group).to receive(:shared_runners_remaining_minutes).and_return(4) allow(group).to receive(:shared_runners_seconds).and_return(16.minutes)
end end
describe '#show?' do describe '#show?' do
...@@ -70,7 +70,7 @@ RSpec.describe Ci::Minutes::Notification do ...@@ -70,7 +70,7 @@ RSpec.describe Ci::Minutes::Notification do
context 'when at the danger level' do context 'when at the danger level' do
before do before do
allow(group).to receive(:shared_runners_remaining_minutes).and_return(1) allow(group).to receive(:shared_runners_seconds).and_return(19.minutes)
end end
describe '#show?' do describe '#show?' do
...@@ -102,7 +102,7 @@ RSpec.describe Ci::Minutes::Notification do ...@@ -102,7 +102,7 @@ RSpec.describe Ci::Minutes::Notification do
context 'when right at the limit for notification' do context 'when right at the limit for notification' do
before do before do
allow(group).to receive(:shared_runners_remaining_minutes).and_return(6) allow(group).to receive(:shared_runners_seconds).and_return(14.minutes)
end end
describe '#show?' do describe '#show?' do
...@@ -167,7 +167,7 @@ RSpec.describe Ci::Minutes::Notification do ...@@ -167,7 +167,7 @@ RSpec.describe Ci::Minutes::Notification do
shared_examples 'not eligible to see notifications' do shared_examples 'not eligible to see notifications' do
before do before do
group.shared_runners_minutes_limit = 10 group.shared_runners_minutes_limit = 10
allow(group).to receive(:shared_runners_remaining_minutes).and_return(2) allow(group).to receive(:shared_runners_seconds).and_return(8.minutes)
end end
context 'when not permitted to see notifications' do context 'when not permitted to see notifications' do
......
...@@ -275,4 +275,27 @@ RSpec.describe Ci::Minutes::Quota do ...@@ -275,4 +275,27 @@ RSpec.describe Ci::Minutes::Quota do
it { is_expected.to eq(expected_minutes) } it { is_expected.to eq(expected_minutes) }
end end
end end
describe '#percent_total_minutes_remaining' do
subject { quota.percent_total_minutes_remaining }
where(:total_minutes_used, :monthly_minutes, :purchased_minutes, :result) do
0 | 0 | 0 | 0
10 | 0 | 0 | 0
0 | 70 | 30 | 100
60 | 70 | 30 | 40
100 | 70 | 30 | 0
120 | 70 | 30 | 0
end
with_them do
before do
allow(namespace).to receive(:shared_runners_seconds).and_return(total_minutes_used * 60)
allow(namespace).to receive(:shared_runners_minutes_limit).and_return(monthly_minutes)
allow(namespace).to receive(:extra_shared_runners_minutes_limit).and_return(purchased_minutes)
end
it { is_expected.to eq(result) }
end
end
end end
...@@ -770,73 +770,6 @@ RSpec.describe Namespace do ...@@ -770,73 +770,6 @@ RSpec.describe Namespace do
end end
end end
describe '#shared_runners_remaining_minutes_percent' do
let(:namespace) { build(:namespace) }
subject { namespace.shared_runners_remaining_minutes_percent }
it 'returns the minutes left as a percent of the limit' do
stub_minutes_used_and_limit(8, 10)
expect(subject).to eq(20)
end
it 'returns 100 when minutes used are 0' do
stub_minutes_used_and_limit(0, 10)
expect(subject).to eq(100)
end
it 'returns 0 when the limit is 0' do
stub_minutes_used_and_limit(0, 0)
expect(subject).to eq(0)
end
it 'returns 0 when the limit is nil' do
stub_minutes_used_and_limit(nil, nil)
expect(subject).to eq(0)
end
it 'returns 0 when minutes used are over the limit' do
stub_minutes_used_and_limit(11, 10)
expect(subject).to eq(0)
end
it 'returns 0 when minutes used are equal to the limit' do
stub_minutes_used_and_limit(10, 10)
expect(subject).to eq(0)
end
def stub_minutes_used_and_limit(minutes_used, limit)
seconds_used = minutes_used.present? ? minutes_used * 60 : minutes_used
allow(namespace).to receive(:shared_runners_seconds).and_return(seconds_used)
allow(namespace).to receive(:actual_shared_runners_minutes_limit).and_return(limit)
end
end
describe '#shared_runners_remaining_minutes_below_threshold?' do
let(:namespace) { build(:namespace, last_ci_minutes_usage_notification_level: 30) }
subject { namespace.shared_runners_remaining_minutes_below_threshold? }
it 'is true when minutes left is below the notification level' do
allow(namespace).to receive(:shared_runners_remaining_minutes_percent).and_return(10)
expect(subject).to be_truthy
end
it 'is false when minutes left is not below the notification level' do
allow(namespace).to receive(:shared_runners_remaining_minutes_percent).and_return(80)
expect(subject).to be_falsey
end
end
describe '#actual_plan' do describe '#actual_plan' do
context 'when namespace does not have a subscription associated' do context 'when namespace does not have a subscription associated' do
it 'generates a subscription and returns default plan' do it 'generates a subscription and returns default plan' do
......
...@@ -16,7 +16,6 @@ RSpec.describe Project do ...@@ -16,7 +16,6 @@ RSpec.describe Project do
it { is_expected.to delegate_method(:actual_shared_runners_minutes_limit).to(:shared_runners_limit_namespace) } it { is_expected.to delegate_method(:actual_shared_runners_minutes_limit).to(:shared_runners_limit_namespace) }
it { is_expected.to delegate_method(:shared_runners_minutes_limit_enabled?).to(:shared_runners_limit_namespace) } it { is_expected.to delegate_method(:shared_runners_minutes_limit_enabled?).to(:shared_runners_limit_namespace) }
it { is_expected.to delegate_method(:shared_runners_remaining_minutes_below_threshold?).to(:shared_runners_limit_namespace) }
it { is_expected.to delegate_method(:closest_gitlab_subscription).to(:namespace) } it { is_expected.to delegate_method(:closest_gitlab_subscription).to(:namespace) }
......
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