Commit 2eb416e6 authored by Tyler Amos's avatar Tyler Amos Committed by Jan Provaznik

Use excess storage size logic for storage banners

Implement a toggle between using the first version of storage banners
and the new version.
parent 81527d40
...@@ -43,7 +43,7 @@ module EE ...@@ -43,7 +43,7 @@ module EE
GraphQL::FLOAT_TYPE, GraphQL::FLOAT_TYPE,
null: true, null: true,
description: 'Total storage limit of the root namespace in bytes', description: 'Total storage limit of the root namespace in bytes',
resolve: -> (obj, _args, _ctx) { EE::Namespace::RootStorageSize.new(obj).limit } resolve: -> (obj, _args, _ctx) { obj.root_storage_size.limit }
field :is_temporary_storage_increase_enabled, field :is_temporary_storage_increase_enabled,
GraphQL::BOOLEAN_TYPE, GraphQL::BOOLEAN_TYPE,
......
...@@ -16,7 +16,7 @@ module EE ...@@ -16,7 +16,7 @@ module EE
def namespace_storage_alert(namespace) def namespace_storage_alert(namespace)
return {} if current_user.nil? return {} if current_user.nil?
payload = Namespaces::CheckStorageSizeService.new(namespace, current_user).execute.payload payload = check_storage_size_service(namespace).execute.payload
return {} if payload.empty? return {} if payload.empty?
...@@ -70,5 +70,15 @@ module EE ...@@ -70,5 +70,15 @@ module EE
EE::SUBSCRIPTIONS_MORE_STORAGE_URL EE::SUBSCRIPTIONS_MORE_STORAGE_URL
end end
private
def check_storage_size_service(namespace)
if namespace.additional_repo_storage_by_namespace_enabled?
::Namespaces::CheckExcessStorageSizeService.new(namespace, current_user)
else
::Namespaces::CheckStorageSizeService.new(namespace, current_user)
end
end
end end
end end
...@@ -194,7 +194,7 @@ module EE ...@@ -194,7 +194,7 @@ module EE
def over_storage_limit? def over_storage_limit?
::Gitlab::CurrentSettings.enforce_namespace_storage_limit? && ::Gitlab::CurrentSettings.enforce_namespace_storage_limit? &&
::Feature.enabled?(:namespace_storage_limit, root_ancestor) && ::Feature.enabled?(:namespace_storage_limit, root_ancestor) &&
RootStorageSize.new(root_ancestor).above_size_limit? root_ancestor.root_storage_size.above_size_limit?
end end
def total_repository_size_excess def total_repository_size_excess
...@@ -386,6 +386,15 @@ module EE ...@@ -386,6 +386,15 @@ module EE
update(temporary_storage_increase_ends_on: TEMPORARY_STORAGE_INCREASE_DAYS.days.from_now) update(temporary_storage_increase_ends_on: TEMPORARY_STORAGE_INCREASE_DAYS.days.from_now)
end end
def additional_repo_storage_by_namespace_enabled?
!::Feature.enabled?(:namespace_storage_limit, self) && ::Feature.enabled?(:additional_repo_storage_by_namespace, self)
end
def root_storage_size
klass = additional_repo_storage_by_namespace_enabled? ? RootExcessStorageSize : RootStorageSize
klass.new(self)
end
private private
def fallback_plan def fallback_plan
......
...@@ -23,7 +23,7 @@ class NamespaceLimit < ApplicationRecord ...@@ -23,7 +23,7 @@ class NamespaceLimit < ApplicationRecord
def eligible_for_temporary_storage_increase? def eligible_for_temporary_storage_increase?
return false unless ::Feature.enabled?(:temporary_storage_increase, namespace) return false unless ::Feature.enabled?(:temporary_storage_increase, namespace)
EE::Namespace::RootStorageSize.new(namespace).usage_ratio >= MIN_REQURIED_STORAGE_USAGE_RATIO namespace.root_storage_size.usage_ratio >= MIN_REQURIED_STORAGE_USAGE_RATIO
end end
private private
......
...@@ -56,12 +56,20 @@ module EE ...@@ -56,12 +56,20 @@ module EE
def storage_size_limit_alert def storage_size_limit_alert
return unless repository&.repo_type&.project? return unless repository&.repo_type&.project?
payload = Namespaces::CheckStorageSizeService.new(project.namespace, user).execute.payload payload = check_storage_size_service(project.namespace).execute.payload
return unless payload.present? return unless payload.present?
alert_level = "##### #{payload[:alert_level].to_s.upcase} #####" alert_level = "##### #{payload[:alert_level].to_s.upcase} #####"
[alert_level, payload[:usage_message], payload[:explanation_message]].join("\n") [alert_level, payload[:usage_message], payload[:explanation_message]].join("\n")
end end
def check_storage_size_service(namespace)
if namespace.additional_repo_storage_by_namespace_enabled?
::Namespaces::CheckExcessStorageSizeService.new(namespace, user)
else
::Namespaces::CheckStorageSizeService.new(namespace, user)
end
end
end end
end end
...@@ -71,10 +71,21 @@ RSpec.describe EE::NamespaceStorageLimitAlertHelper do ...@@ -71,10 +71,21 @@ RSpec.describe EE::NamespaceStorageLimitAlertHelper do
} }
end end
where(:namespace_storage_limit_enabled, :additional_repo_storage_by_namespace_enabled, :service_class_name) do
true | false | Namespaces::CheckStorageSizeService
true | true | Namespaces::CheckStorageSizeService
false | true | Namespaces::CheckExcessStorageSizeService
false | false | Namespaces::CheckStorageSizeService
end
with_them do
before do before do
stub_feature_flags(namespace_storage_limit: namespace_storage_limit_enabled)
stub_feature_flags(additional_repo_storage_by_namespace: additional_repo_storage_by_namespace_enabled)
allow(helper).to receive(:current_user).and_return(admin) allow(helper).to receive(:current_user).and_return(admin)
allow_next_instance_of(Namespaces::CheckStorageSizeService, namespace, admin) do |check_storage_size_service| allow_next_instance_of(service_class_name, namespace, admin) do |service|
expect(check_storage_size_service).to receive(:execute).and_return(ServiceResponse.success(payload: payload)) expect(service).to receive(:execute).and_return(ServiceResponse.success(payload: payload))
end end
end end
...@@ -114,6 +125,7 @@ RSpec.describe EE::NamespaceStorageLimitAlertHelper do ...@@ -114,6 +125,7 @@ RSpec.describe EE::NamespaceStorageLimitAlertHelper do
it { is_expected.to eq({}) } it { is_expected.to eq({}) }
end end
end end
end
describe '#namespace_storage_alert_style' do describe '#namespace_storage_alert_style' do
subject { helper.namespace_storage_alert_style(alert_level) } subject { helper.namespace_storage_alert_style(alert_level) }
......
...@@ -5,14 +5,19 @@ require 'spec_helper' ...@@ -5,14 +5,19 @@ require 'spec_helper'
RSpec.describe NamespaceLimit do RSpec.describe NamespaceLimit do
let(:namespace_limit) { build(:namespace_limit) } let(:namespace_limit) { build(:namespace_limit) }
let(:usage_ratio) { 0.5 } let(:usage_ratio) { 0.5 }
let(:namespace_storage_limit_enabled) { true }
subject { namespace_limit } subject { namespace_limit }
before do before do
allow_next_instance_of(EE::Namespace::RootStorageSize, namespace_limit.namespace) do |root_storage| stub_feature_flags(namespace_storage_limit: namespace_storage_limit_enabled)
[EE::Namespace::RootStorageSize, EE::Namespace::RootExcessStorageSize].each do |class_name|
allow_next_instance_of(class_name, namespace_limit.namespace) do |root_storage|
allow(root_storage).to receive(:usage_ratio).and_return(usage_ratio) allow(root_storage).to receive(:usage_ratio).and_return(usage_ratio)
end end
end end
end
it { is_expected.to belong_to(:namespace) } it { is_expected.to belong_to(:namespace) }
...@@ -54,21 +59,39 @@ RSpec.describe NamespaceLimit do ...@@ -54,21 +59,39 @@ RSpec.describe NamespaceLimit do
context 'when usage ratio is above the threshold' do context 'when usage ratio is above the threshold' do
let(:usage_ratio) { 0.5 } let(:usage_ratio) { 0.5 }
it { is_expected.to be_truthy } it { is_expected.to eq(true) }
context 'when feature is disabled' do context 'when feature flag :temporary_storage_increase disabled' do
before do before do
stub_feature_flags(temporary_storage_increase: false) stub_feature_flags(temporary_storage_increase: false)
end end
context 'when feature flag :namespace_storage_limit disabled' do
let(:namespace_storage_limit_enabled) { false }
it { is_expected.to eq(false) }
end
it { is_expected.to eq(false) } it { is_expected.to eq(false) }
end end
context 'when feature flag :namespace_storage_limit disabled' do
let(:namespace_storage_limit_enabled) { false }
it { is_expected.to eq(true) }
end
end end
context 'when usage ratio is below the threshold' do context 'when usage ratio is below the threshold' do
let(:usage_ratio) { 0.49 } let(:usage_ratio) { 0.49 }
it { is_expected.to be_falsey } context 'when feature flag :namespace_storage_limit disabled' do
let(:namespace_storage_limit_enabled) { false }
it { is_expected.to eq(false) }
end
it { is_expected.to eq(false) }
end end
end end
...@@ -126,6 +149,12 @@ RSpec.describe NamespaceLimit do ...@@ -126,6 +149,12 @@ RSpec.describe NamespaceLimit do
let(:usage_ratio) { 0.5 } let(:usage_ratio) { 0.5 }
it { is_expected.to be_valid } it { is_expected.to be_valid }
context 'when feature flag :namespace_storage_limit disabled' do
let(:namespace_storage_limit_enabled) { false }
it { is_expected.to be_valid }
end
end end
context 'when storage usage is below threshold' do context 'when storage usage is below threshold' do
...@@ -135,6 +164,15 @@ RSpec.describe NamespaceLimit do ...@@ -135,6 +164,15 @@ RSpec.describe NamespaceLimit do
expect(namespace_limit).to be_invalid expect(namespace_limit).to be_invalid
expect(namespace_limit.errors[:temporary_storage_increase_ends_on]).to include("can only be set with more than 50% usage") expect(namespace_limit.errors[:temporary_storage_increase_ends_on]).to include("can only be set with more than 50% usage")
end end
context 'when feature flag :namespace_storage_limit disabled' do
let(:namespace_storage_limit_enabled) { false }
it 'is invalid' do
expect(namespace_limit).to be_invalid
expect(namespace_limit.errors[:temporary_storage_increase_ends_on]).to include("can only be set with more than 50% usage")
end
end
end end
end end
end end
......
...@@ -1770,6 +1770,32 @@ RSpec.describe Namespace do ...@@ -1770,6 +1770,32 @@ RSpec.describe Namespace do
end end
end end
describe '#root_storage_size' do
let_it_be(:namespace) { build(:namespace) }
subject { namespace.root_storage_size }
context 'with feature flag :namespace_storage_limit enabled' do
it 'initializes a new instance of EE::Namespace::RootStorageSize' do
expect(EE::Namespace::RootStorageSize).to receive(:new).with(namespace)
subject
end
end
context 'with feature flag :namespace_storage_limit disabled' do
before do
stub_feature_flags(namespace_storage_limit: false)
end
it 'initializes a new instance of EE::Namespace::RootExcessStorageSize' do
expect(EE::Namespace::RootExcessStorageSize).to receive(:new).with(namespace)
subject
end
end
end
def create_project(repository_size:, lfs_objects_size:, repository_size_limit:) def create_project(repository_size:, lfs_objects_size:, repository_size_limit:)
create(:project, namespace: namespace, repository_size_limit: repository_size_limit).tap do |project| create(:project, namespace: namespace, repository_size_limit: repository_size_limit).tap do |project|
create(:project_statistics, project: project, repository_size: repository_size, lfs_objects_size: lfs_objects_size) create(:project_statistics, project: project, repository_size: repository_size, lfs_objects_size: lfs_objects_size)
......
...@@ -104,17 +104,30 @@ RSpec.describe PostReceiveService, :geo do ...@@ -104,17 +104,30 @@ RSpec.describe PostReceiveService, :geo do
end end
describe 'storage size limit alerts' do describe 'storage size limit alerts' do
using RSpec::Parameterized::TableSyntax
let(:check_storage_size_response) { ServiceResponse.success } let(:check_storage_size_response) { ServiceResponse.success }
where(:namespace_storage_limit_enabled, :additional_repo_storage_by_namespace_enabled, :service_class_name) do
true | false | Namespaces::CheckStorageSizeService
true | true | Namespaces::CheckStorageSizeService
false | true | Namespaces::CheckExcessStorageSizeService
false | false | Namespaces::CheckStorageSizeService
end
with_them do
before do before do
expect_next_instance_of(Namespaces::CheckStorageSizeService, project.namespace, user) do |check_storage_size_service| stub_feature_flags(namespace_storage_limit: namespace_storage_limit_enabled)
expect(check_storage_size_service).to receive(:execute).and_return(check_storage_size_response) stub_feature_flags(additional_repo_storage_by_namespace: additional_repo_storage_by_namespace_enabled)
allow_next_instance_of(service_class_name, project.namespace, user) do |service|
expect(service).to receive(:execute).and_return(check_storage_size_response)
end end
end end
context 'when there is no payload' do context 'when there is no payload' do
it 'adds no alert' do it 'adds no alert' do
expect(subject.size).to eq(0) expect(subject).to be_empty
end end
end end
...@@ -132,9 +145,10 @@ RSpec.describe PostReceiveService, :geo do ...@@ -132,9 +145,10 @@ RSpec.describe PostReceiveService, :geo do
it 'adds an alert' do it 'adds an alert' do
response = subject response = subject
expect(response.size).to eq(1) expect(response).to be_present
expect(response).to include({ 'type' => 'alert', 'message' => "##### INFO #####\nUsage\nExplanation" }) expect(response).to include({ 'type' => 'alert', 'message' => "##### INFO #####\nUsage\nExplanation" })
end end
end 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