Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
1f3794ea
Commit
1f3794ea
authored
Sep 23, 2021
by
Allison Browne
Committed by
Fabio Pitino
Sep 23, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Quota Presenter to separate Quota related display logic
parent
7c2fbd9e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
481 additions
and
394 deletions
+481
-394
ee/app/models/ci/minutes/quota.rb
ee/app/models/ci/minutes/quota.rb
+28
-79
ee/app/presenters/ci/minutes/quota_presenter.rb
ee/app/presenters/ci/minutes/quota_presenter.rb
+70
-0
ee/app/views/namespaces/_additional_minutes_status.html.haml
ee/app/views/namespaces/_additional_minutes_status.html.haml
+3
-2
ee/app/views/namespaces/_shared_runner_status.html.haml
ee/app/views/namespaces/_shared_runner_status.html.haml
+3
-2
ee/app/views/namespaces/pipelines_quota/_extra_shared_runners_minutes_quota.html.haml
...lines_quota/_extra_shared_runners_minutes_quota.html.haml
+5
-4
ee/app/views/namespaces/pipelines_quota/_list.haml
ee/app/views/namespaces/pipelines_quota/_list.haml
+8
-6
ee/spec/helpers/ee/namespaces_helper_spec.rb
ee/spec/helpers/ee/namespaces_helper_spec.rb
+5
-4
ee/spec/models/ci/minutes/quota_spec.rb
ee/spec/models/ci/minutes/quota_spec.rb
+46
-297
ee/spec/presenters/ci/minutes/quota_presenter_spec.rb
ee/spec/presenters/ci/minutes/quota_presenter_spec.rb
+313
-0
No files found.
ee/app/models/ci/minutes/quota.rb
View file @
1f3794ea
...
@@ -9,39 +9,14 @@ module Ci
...
@@ -9,39 +9,14 @@ module Ci
class
Quota
class
Quota
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
Report
=
Struct
.
new
(
:used
,
:limit
,
:status
)
attr_reader
:namespace
def
initialize
(
namespace
)
def
initialize
(
namespace
)
@namespace
=
namespace
@namespace
=
namespace
end
end
def
enabled?
def
enabled?
namespace_root?
&&
total_minutes
.
nonzero?
namespace_root?
&&
!
namespace_unlimited_minutes?
end
# Status of the monthly allowance being used.
def
monthly_minutes_report
Report
.
new
(
monthly_minutes_used
,
minutes_limit
,
report_status
)
end
def
monthly_percent_used
return
0
unless
enabled?
return
0
if
monthly_minutes
==
0
100
*
monthly_minutes_used
.
to_i
/
monthly_minutes
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
def
purchased_percent_used
return
0
unless
enabled?
return
0
if
purchased_minutes
==
0
100
*
purchased_minutes_used
.
to_i
/
purchased_minutes
end
end
def
minutes_used_up?
def
minutes_used_up?
...
@@ -58,14 +33,6 @@ module Ci
...
@@ -58,14 +33,6 @@ module Ci
total_minutes
.
to_i
-
total_minutes_used
total_minutes
.
to_i
-
total_minutes_used
end
end
def
display_shared_runners_data?
namespace_root?
&&
any_project_enabled?
end
def
display_minutes_available_data?
display_shared_runners_data?
&&
total_minutes
.
nonzero?
end
def
total_minutes
def
total_minutes
strong_memoize
(
:total_minutes
)
do
strong_memoize
(
:total_minutes
)
do
monthly_minutes
+
purchased_minutes
monthly_minutes
+
purchased_minutes
...
@@ -78,54 +45,43 @@ module Ci
...
@@ -78,54 +45,43 @@ module Ci
end
end
end
end
def
any_project_enabled?
def
purchased_minutes
strong_memoize
(
:
any_project_enabled
)
do
strong_memoize
(
:
purchased_minutes
)
do
namespace
.
any_project_with_shared_runners_enabled?
namespace
.
extra_shared_runners_minutes_limit
.
to_i
end
end
end
end
private
def
namespace_root?
strong_memoize
(
:namespace_root
)
do
attr_reader
:namespace
namespace
.
root?
def
minutes_limit
return
_
(
'Not supported'
)
unless
display_shared_runners_data?
if
display_minutes_available_data?
monthly_minutes
else
_
(
'Unlimited'
)
end
end
end
end
def
report_status
def
namespace_unlimited_minutes?
return
:disabled
unless
enabled?
total_minutes
.
to_i
==
0
monthly_minutes_used_up?
?
:over_quota
:
:under_quota
end
end
def
total_minutes_remaining
def
monthly_minutes
[
current_balance
,
0
].
max
strong_memoize
(
:monthly_minutes
)
do
(
namespace
.
shared_runners_minutes_limit
||
::
Gitlab
::
CurrentSettings
.
shared_runners_minutes
).
to_i
end
end
end
# === private to view ===
def
monthly_minutes_used_up?
def
monthly_minutes_used_up?
return
false
unless
enabled?
return
false
unless
enabled?
monthly_minutes_used
>=
monthly_minutes
monthly_minutes_used
>=
monthly_minutes
end
end
def
purchased_minutes_used_up?
return
false
unless
enabled?
any_minutes_purchased?
&&
purchased_minutes_used
>=
purchased_minutes
end
def
monthly_minutes_used
def
monthly_minutes_used
total_minutes_used
-
purchased_minutes_used
total_minutes_used
-
purchased_minutes_used
end
end
def
monthly_minutes_available?
def
purchased_minutes_used_up?
total_minutes_used
<=
monthly_minutes
return
false
unless
enabled?
any_minutes_purchased?
&&
purchased_minutes_used
>=
purchased_minutes
end
end
def
purchased_minutes_used
def
purchased_minutes_used
...
@@ -134,6 +90,12 @@ module Ci
...
@@ -134,6 +90,12 @@ module Ci
total_minutes_used
-
monthly_minutes
total_minutes_used
-
monthly_minutes
end
end
private
def
monthly_minutes_available?
total_minutes_used
<=
monthly_minutes
end
def
no_minutes_purchased?
def
no_minutes_purchased?
purchased_minutes
==
0
purchased_minutes
==
0
end
end
...
@@ -142,22 +104,9 @@ module Ci
...
@@ -142,22 +104,9 @@ module Ci
purchased_minutes
>
0
purchased_minutes
>
0
end
end
def
monthly_minutes
# === private to model ===
strong_memoize
(
:monthly_minutes
)
do
def
total_minutes_remaining
(
namespace
.
shared_runners_minutes_limit
||
::
Gitlab
::
CurrentSettings
.
shared_runners_minutes
).
to_i
[
current_balance
,
0
].
max
end
end
def
purchased_minutes
strong_memoize
(
:purchased_minutes
)
do
namespace
.
extra_shared_runners_minutes_limit
.
to_i
end
end
def
namespace_root?
strong_memoize
(
:namespace_root
)
do
namespace
.
root?
end
end
end
end
end
end
end
...
...
ee/app/presenters/ci/minutes/quota_presenter.rb
0 → 100644
View file @
1f3794ea
# frozen_string_literal: true
module
Ci
module
Minutes
class
QuotaPresenter
<
Gitlab
::
View
::
Presenter
::
Simple
include
Gitlab
::
Utils
::
StrongMemoize
presents
Quota
,
as: :quota
Report
=
Struct
.
new
(
:used
,
:limit
,
:status
)
# Status of the monthly allowance being used.
def
monthly_minutes_report
Report
.
new
(
quota
.
monthly_minutes_used
,
minutes_limit
,
report_status
)
end
def
monthly_percent_used
return
0
unless
quota
.
enabled?
return
0
if
quota
.
monthly_minutes
==
0
100
*
quota
.
monthly_minutes_used
.
to_i
/
quota
.
monthly_minutes
end
# Status of any purchased minutes used.
def
purchased_minutes_report
status
=
quota
.
purchased_minutes_used_up?
?
:over_quota
:
:under_quota
Report
.
new
(
quota
.
purchased_minutes_used
,
quota
.
purchased_minutes
,
status
)
end
def
purchased_percent_used
return
0
unless
quota
.
enabled?
return
0
if
quota
.
purchased_minutes
==
0
100
*
quota
.
purchased_minutes_used
.
to_i
/
quota
.
purchased_minutes
end
def
display_minutes_available_data?
display_shared_runners_data?
&&
!
quota
.
namespace_unlimited_minutes?
end
def
display_shared_runners_data?
quota
.
namespace_root?
&&
any_project_enabled?
end
def
any_project_enabled?
strong_memoize
(
:any_project_enabled
)
do
quota
.
namespace
.
any_project_with_shared_runners_enabled?
end
end
private
def
report_status
return
:disabled
unless
quota
.
enabled?
quota
.
monthly_minutes_used_up?
?
:over_quota
:
:under_quota
end
def
minutes_limit
return
_
(
'Not supported'
)
unless
display_shared_runners_data?
if
display_minutes_available_data?
quota
.
monthly_minutes
else
_
(
'Unlimited'
)
end
end
end
end
end
ee/app/views/namespaces/_additional_minutes_status.html.haml
View file @
1f3794ea
...
@@ -2,11 +2,12 @@
...
@@ -2,11 +2,12 @@
-
namespace
=
local_assigns
.
fetch
(
:namespace
)
-
namespace
=
local_assigns
.
fetch
(
:namespace
)
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota_presenter
=
Ci
::
Minutes
::
QuotaPresenter
.
new
(
minutes_quota
)
-
return
unless
minutes_quota
.
enabled?
-
return
unless
minutes_quota
.
enabled?
-
if
minutes_quota
.
display_shared_runners_data?
-
if
minutes_quota
_presenter
.
display_shared_runners_data?
%li
%li
%span
.light
=
_
(
'Additional minutes:'
)
%span
.light
=
_
(
'Additional minutes:'
)
%strong
%strong
=
ci_minutes_report
(
minutes_quota
.
purchased_minutes_report
)
=
ci_minutes_report
(
minutes_quota
_presenter
.
purchased_minutes_report
)
ee/app/views/namespaces/_shared_runner_status.html.haml
View file @
1f3794ea
-
namespace
=
local_assigns
.
fetch
(
:namespace
)
-
namespace
=
local_assigns
.
fetch
(
:namespace
)
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota_presenter
=
Ci
::
Minutes
::
QuotaPresenter
.
new
(
minutes_quota
)
-
if
minutes_quota
.
display_shared_runners_data?
-
if
minutes_quota
_presenter
.
display_shared_runners_data?
%li
%li
%span
.light
=
_
(
'Pipeline minutes quota:'
)
%span
.light
=
_
(
'Pipeline minutes quota:'
)
%strong
%strong
=
ci_minutes_report
(
minutes_quota
.
monthly_minutes_report
)
=
ci_minutes_report
(
minutes_quota
_presenter
.
monthly_minutes_report
)
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'user/admin_area/settings/continuous_integration'
,
anchor:
'shared-runners-pipeline-minutes-quota'
),
target:
'_blank'
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'user/admin_area/settings/continuous_integration'
,
anchor:
'shared-runners-pipeline-minutes-quota'
),
target:
'_blank'
ee/app/views/namespaces/pipelines_quota/_extra_shared_runners_minutes_quota.html.haml
View file @
1f3794ea
-
return
unless
Gitlab
.
com?
-
return
unless
Gitlab
.
com?
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
return
unless
minutes_quota
.
display_minutes_available_data?
&&
minutes_quota
.
purchased_minutes_report
.
limit
>
0
-
minutes_quota_presenter
=
Ci
::
Minutes
::
QuotaPresenter
.
new
(
minutes_quota
)
-
return
unless
minutes_quota_presenter
.
display_minutes_available_data?
&&
minutes_quota_presenter
.
purchased_minutes_report
.
limit
>
0
.row
.row
.col-sm-6
.col-sm-6
%strong
%strong
=
_
(
"Additional minutes"
)
=
_
(
"Additional minutes"
)
%div
%div
=
ci_minutes_report
(
minutes_quota
.
purchased_minutes_report
)
=
ci_minutes_report
(
minutes_quota
_presenter
.
purchased_minutes_report
)
minutes
minutes
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'subscriptions/gitlab_com/index'
,
anchor:
'purchase-additional-ci-minutes'
),
target:
'_blank'
,
rel:
'noopener noreferrer'
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'subscriptions/gitlab_com/index'
,
anchor:
'purchase-additional-ci-minutes'
),
target:
'_blank'
,
rel:
'noopener noreferrer'
.col-sm-6.right
.col-sm-6.right
#{
minutes_quota
.
purchased_percent_used
}
% used
#{
minutes_quota
_presenter
.
purchased_percent_used
}
% used
=
ci_minutes_progress_bar
(
minutes_quota
.
purchased_percent_used
)
=
ci_minutes_progress_bar
(
minutes_quota
_presenter
.
purchased_percent_used
)
ee/app/views/namespaces/pipelines_quota/_list.haml
View file @
1f3794ea
-
namespace
=
locals
.
fetch
(
:namespace
)
-
namespace
=
locals
.
fetch
(
:namespace
)
-
projects
=
locals
.
fetch
(
:projects
)
-
projects
=
locals
.
fetch
(
:projects
)
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota
=
namespace
.
ci_minutes_quota
-
minutes_quota_presenter
=
Ci
::
Minutes
::
QuotaPresenter
.
new
(
minutes_quota
)
.pipeline-quota.container-fluid
.pipeline-quota.container-fluid
.row
.row
...
@@ -21,19 +23,19 @@
...
@@ -21,19 +23,19 @@
-
else
-
else
=
s_
(
'UsageQuota|Current period usage'
)
=
s_
(
'UsageQuota|Current period usage'
)
%div
%div
=
ci_minutes_report
(
minutes_quota
.
monthly_minutes_report
)
=
ci_minutes_report
(
minutes_quota
_presenter
.
monthly_minutes_report
)
minutes
minutes
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'user/admin_area/settings/continuous_integration'
,
anchor:
'shared-runners-pipeline-minutes-quota'
),
target:
'_blank'
,
'aria-label'
:
_
(
'Shared runners help link'
)
=
link_to
sprite_icon
(
'question-o'
),
help_page_path
(
'user/admin_area/settings/continuous_integration'
,
anchor:
'shared-runners-pipeline-minutes-quota'
),
target:
'_blank'
,
'aria-label'
:
_
(
'Shared runners help link'
)
.col-sm-6.right
.col-sm-6.right
-
if
minutes_quota
.
display_minutes_available_data?
-
if
minutes_quota
_presenter
.
display_minutes_available_data?
#{
minutes_quota
.
monthly_percent_used
}
% used
#{
minutes_quota
_presenter
.
monthly_percent_used
}
% used
-
elsif
!
minutes_quota
.
any_project_enabled?
-
elsif
!
minutes_quota
_presenter
.
any_project_enabled?
0% used
0% used
-
else
-
else
=
s_
(
'UsageQuota|Unlimited'
)
=
s_
(
'UsageQuota|Unlimited'
)
=
ci_minutes_progress_bar
(
minutes_quota
.
monthly_percent_used
)
=
ci_minutes_progress_bar
(
minutes_quota
_presenter
.
monthly_percent_used
)
=
render
'namespaces/pipelines_quota/extra_shared_runners_minutes_quota'
,
namespace:
namespace
=
render
'namespaces/pipelines_quota/extra_shared_runners_minutes_quota'
,
namespace:
namespace
...
@@ -48,7 +50,7 @@
...
@@ -48,7 +50,7 @@
=
_
(
'Minutes'
)
=
_
(
'Minutes'
)
%tbody
%tbody
-
if
!
minutes_quota
.
any_project_enabled?
-
if
!
minutes_quota
_presenter
.
any_project_enabled?
%tr
%tr
%td
{
colspan:
2
}
%td
{
colspan:
2
}
.nothing-here-block
.nothing-here-block
...
...
ee/spec/helpers/ee/namespaces_helper_spec.rb
View file @
1f3794ea
...
@@ -51,9 +51,10 @@ RSpec.describe EE::NamespacesHelper do
...
@@ -51,9 +51,10 @@ RSpec.describe EE::NamespacesHelper do
describe
'#ci_minutes_report'
do
describe
'#ci_minutes_report'
do
let
(
:quota
)
{
Ci
::
Minutes
::
Quota
.
new
(
user_group
)
}
let
(
:quota
)
{
Ci
::
Minutes
::
Quota
.
new
(
user_group
)
}
let
(
:quota_presenter
)
{
Ci
::
Minutes
::
QuotaPresenter
.
new
(
quota
)
}
describe
'rendering monthly minutes report'
do
describe
'rendering monthly minutes report'
do
let
(
:report
)
{
quota
.
monthly_minutes_report
}
let
(
:report
)
{
quota
_presenter
.
monthly_minutes_report
}
context
"when ci minutes quota is not enabled"
do
context
"when ci minutes quota is not enabled"
do
before
do
before
do
...
@@ -62,7 +63,7 @@ RSpec.describe EE::NamespacesHelper do
...
@@ -62,7 +63,7 @@ RSpec.describe EE::NamespacesHelper do
context
'and the namespace is eligible for unlimited'
do
context
'and the namespace is eligible for unlimited'
do
before
do
before
do
allow
(
quota
).
to
receive
(
:namespace_
eligible
?
).
and_return
(
true
)
allow
(
quota
).
to
receive
(
:namespace_
root
?
).
and_return
(
true
)
allow
(
user_group
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
allow
(
user_group
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
end
end
...
@@ -79,7 +80,7 @@ RSpec.describe EE::NamespacesHelper do
...
@@ -79,7 +80,7 @@ RSpec.describe EE::NamespacesHelper do
context
'and the namespace is not eligible for unlimited'
do
context
'and the namespace is not eligible for unlimited'
do
before
do
before
do
allow
(
quota
).
to
receive
(
:namespace_
eligible
?
).
and_return
(
false
)
allow
(
quota
).
to
receive
(
:namespace_
root
?
).
and_return
(
false
)
end
end
it
'returns Not supported for the limit section'
do
it
'returns Not supported for the limit section'
do
...
@@ -103,7 +104,7 @@ RSpec.describe EE::NamespacesHelper do
...
@@ -103,7 +104,7 @@ RSpec.describe EE::NamespacesHelper do
end
end
describe
'rendering purchased minutes report'
do
describe
'rendering purchased minutes report'
do
let
(
:report
)
{
quota
.
purchased_minutes_report
}
let
(
:report
)
{
Ci
::
Minutes
::
QuotaPresenter
.
new
(
quota
)
.
purchased_minutes_report
}
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
...
...
ee/spec/models/ci/minutes/quota_spec.rb
View file @
1f3794ea
...
@@ -63,244 +63,6 @@ RSpec.describe Ci::Minutes::Quota do
...
@@ -63,244 +63,6 @@ RSpec.describe Ci::Minutes::Quota do
end
end
end
end
describe
'#monthly_minutes_report'
do
context
'when the quota is not enabled'
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
false
)
allow
(
namespace
).
to
receive
(
:root?
).
and_return
(
namespace_eligible
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
end
context
'when the namespace is not eligible'
do
let
(
:namespace_eligible
)
{
false
}
it
'returns not supported report with no usage'
do
report
=
quota
.
monthly_minutes_report
expect
(
report
.
limit
).
to
eq
'Not supported'
expect
(
report
.
used
).
to
eq
0
expect
(
report
.
status
).
to
eq
:disabled
end
end
context
'when the namespace is eligible'
do
let
(
:namespace_eligible
)
{
true
}
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
end
context
'when limited'
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
true
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_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
(
quota
).
to
receive
(
: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
describe
'#monthly_percent_used'
do
subject
{
quota
.
monthly_percent_used
}
where
(
:limit_enabled
,
:monthly_limit
,
:purchased_limit
,
:minutes_used
,
:result
,
:title
)
do
false
|
200
|
0
|
40
|
0
|
'limit not enabled'
true
|
200
|
0
|
0
|
0
|
'monthly limit set and no usage'
true
|
200
|
0
|
40
|
20
|
'monthly limit set and usage lower than 100%'
true
|
200
|
0
|
200
|
100
|
'monthly limit set and usage at 100%'
true
|
200
|
0
|
210
|
105
|
'monthly limit set and usage above 100%'
true
|
0
|
0
|
0
|
0
|
'monthly limit not set and no usage'
true
|
0
|
0
|
40
|
0
|
'monthly limit not set and some usage'
true
|
200
|
100
|
0
|
0
|
'monthly and purchased limits set and no usage'
true
|
200
|
100
|
40
|
20
|
'monthly and purchased limits set and low usage'
true
|
200
|
100
|
210
|
100
|
'usage capped to 100% and overflows into purchased minutes'
end
with_them
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
limit_enabled
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
namespace
.
shared_runners_minutes_limit
=
monthly_limit
namespace
.
extra_shared_runners_minutes_limit
=
purchased_limit
namespace
.
namespace_statistics
.
shared_runners_seconds
=
minutes_used
.
minutes
end
it
'returns the percentage'
do
is_expected
.
to
eq
result
end
end
end
describe
'#purchased_percent_used'
do
subject
{
quota
.
purchased_percent_used
}
where
(
:limit_enabled
,
:monthly_limit
,
:purchased_limit
,
:minutes_used
,
:result
,
:title
)
do
false
|
0
|
0
|
40
|
0
|
'limit not enabled'
true
|
0
|
200
|
40
|
20
|
'monthly limit not set and purchased limit set and low usage'
true
|
200
|
0
|
40
|
0
|
'monthly limit set and purchased limit not set and usage below monthly'
true
|
200
|
0
|
240
|
0
|
'monthly limit set and purchased limit not set and usage above monthly'
true
|
200
|
200
|
0
|
0
|
'monthly and purchased limits set and no usage'
true
|
200
|
200
|
40
|
0
|
'monthly and purchased limits set and usage below monthly'
true
|
200
|
200
|
200
|
0
|
'monthly and purchased limits set and monthly minutes maxed out'
true
|
200
|
200
|
300
|
50
|
'monthly and purchased limits set and some purchased minutes used'
true
|
200
|
200
|
400
|
100
|
'monthly and purchased limits set and all minutes used'
true
|
200
|
200
|
430
|
115
|
'monthly and purchased limits set and usage beyond all limits'
end
with_them
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
limit_enabled
)
namespace
.
shared_runners_minutes_limit
=
monthly_limit
namespace
.
extra_shared_runners_minutes_limit
=
purchased_limit
namespace
.
namespace_statistics
.
shared_runners_seconds
=
minutes_used
.
minutes
end
it
'returns the percentage'
do
is_expected
.
to
eq
result
end
end
end
describe
'#minutes_used_up?'
do
describe
'#minutes_used_up?'
do
subject
{
quota
.
minutes_used_up?
}
subject
{
quota
.
minutes_used_up?
}
...
@@ -394,98 +156,85 @@ RSpec.describe Ci::Minutes::Quota do
...
@@ -394,98 +156,85 @@ RSpec.describe Ci::Minutes::Quota do
end
end
end
end
describe
'#
any_project_enabled
?'
do
describe
'#
monthly_minutes_used_up
?'
do
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
)
}
subject
{
quota
.
monthly_minutes_used_up?
}
context
'when namespace has any project with shared runners enabled'
do
context
'when quota is enabled'
do
before
do
let
(
:total_minutes
)
{
1000
}
project
.
update!
(
shared_runners_enabled:
true
)
end
it
'returns true'
do
expect
(
quota
.
any_project_enabled?
).
to
be_truthy
end
end
context
'when namespace has no projects with shared runners enabled'
do
before
do
before
do
project
.
update!
(
shared_runners_enabled:
false
)
allow
(
namespace
).
to
receive
(
:shared_runners_minutes_limit
).
and_return
(
total_minutes
)
end
allow
(
namespace
).
to
receive
(
:shared_runners_seconds
).
and_return
(
total_minutes_used
*
60
)
it
'returns false'
do
expect
(
quota
.
any_project_enabled?
).
to
be_falsey
end
end
end
it
'does not trigger additional queries when called multiple times'
do
context
'when monthly minutes quota greater than monthly minutes used'
do
# memoizes the result
let
(
:total_minutes_used
)
{
total_minutes
-
1
}
quota
.
any_project_enabled?
# count
it
{
is_expected
.
to
be_falsey
}
actual
=
ActiveRecord
::
QueryRecorder
.
new
do
quota
.
any_project_enabled?
end
end
expect
(
actual
.
count
).
to
eq
(
0
)
context
'when monthly minutes quota less than monthly minutes used'
do
end
let
(
:total_minutes_used
)
{
total_minutes
+
1
}
end
describe
'#display_shared_runners_data?'
do
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
,
shared_runners_enabled:
true
)
}
subject
{
quota
.
display_shared_runners_data?
}
it
{
is_expected
.
to
be_truthy
}
end
context
'when the namespace is root and it has a project with shared runners enabled'
do
it
{
is_expected
.
to
be_truthy
}
end
context
'when the namespace is not root
'
do
context
'when monthly minutes quota equals monthly minutes used
'
do
let
(
:namespace
)
{
create
(
:group
,
:nested
)
}
let
(
:total_minutes_used
)
{
total_minutes
}
it
{
is_expected
.
to
be_falsey
}
it
{
is_expected
.
to
be_truthy
}
end
end
end
context
'when
the namespaces has no project with shared runners en
abled'
do
context
'when
quota is dis
abled'
do
before
do
before
do
project
.
update!
(
shared_runners_enabled:
false
)
allow
(
namespace
).
to
receive
(
:shared_runners_minutes_limit
).
and_return
(
0
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
{
is_expected
.
to
be_falsey
}
end
end
end
end
describe
'#display_minutes_available_data?'
do
describe
'purchased_minutes_used_up?'
do
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
,
shared_runners_enabled:
true
)
}
subject
{
quota
.
purchased_minutes_used_up?
}
subject
{
quota
.
display_minutes_available_data?
}
context
'when the namespace is root and it has a project with shared runners enabled'
do
context
'when there is a minutes limit'
do
before
do
namespace
.
update!
(
shared_runners_minutes_limit:
200
)
end
it
{
is_expected
.
to
be_truthy
}
context
'when quota is enabled'
do
before
do
allow
(
namespace
).
to
receive
(
:shared_runners_minutes_limit
).
and_return
(
1000
)
end
end
context
'when there is no minutes limit'
do
context
'when no minutes are purchased'
do
let
(
:purchased_minutes
)
{
0
}
before
do
before
do
namespace
.
update!
(
shared_runners_minutes_limit:
0
)
allow
(
namespace
).
to
receive
(
:extra_shared_runners_minutes_limit
).
and_return
(
purchased_minutes
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
{
is_expected
.
to
be_falsey
}
end
end
end
context
'when the namespace is not root'
do
context
'when minutes are purchased'
do
let
(
:namespace
)
{
create
(
:group
,
:nested
)
}
where
(
:purchased_minutes
,
:monthly_minutes
,
:total_minutes_used
,
:result
)
do
1000
|
1000
|
2001
|
true
1000
|
1000
|
2000
|
true
1000
|
1000
|
1999
|
false
end
it
{
is_expected
.
to
be_falsey
}
with_them
do
before
do
allow
(
namespace
).
to
receive
(
:shared_runners_seconds
).
and_return
(
total_minutes_used
*
60
)
allow
(
namespace
).
to
receive
(
:extra_shared_runners_minutes_limit
).
and_return
(
purchased_minutes
)
allow
(
namespace
).
to
receive
(
:shared_runners_minutes_limit
).
and_return
(
monthly_minutes
)
end
it
{
is_expected
.
to
eq
(
result
)
}
end
end
end
end
context
'when
the namespaces has no project with shared runners en
abled'
do
context
'when
quota is dis
abled'
do
before
do
before
do
project
.
update!
(
shared_runners_enabled:
false
)
allow
(
namespace
).
to
receive
(
:shared_runners_minutes_limit
).
and_return
(
0
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
{
is_expected
.
to
be_falsey
}
...
...
ee/spec/presenters/ci/minutes/quota_presenter_spec.rb
0 → 100644
View file @
1f3794ea
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Ci
::
Minutes
::
QuotaPresenter
do
using
RSpec
::
Parameterized
::
TableSyntax
let_it_be_with_reload
(
:namespace
)
do
create
(
:group
,
namespace_statistics:
create
(
:namespace_statistics
))
end
let
(
:quota
)
{
Ci
::
Minutes
::
Quota
.
new
(
namespace
)
}
subject
(
:presenter
)
{
described_class
.
new
(
quota
)
}
describe
'#monthly_minutes_report'
do
context
'when the quota is not enabled'
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
false
)
allow
(
namespace
).
to
receive
(
:root?
).
and_return
(
namespace_eligible
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
end
context
'when the namespace is not eligible'
do
let
(
:namespace_eligible
)
{
false
}
it
'returns not supported report with no usage'
do
report
=
presenter
.
monthly_minutes_report
expect
(
report
.
limit
).
to
eq
'Not supported'
expect
(
report
.
used
).
to
eq
0
expect
(
report
.
status
).
to
eq
:disabled
end
end
context
'when the namespace is eligible'
do
let
(
:namespace_eligible
)
{
true
}
context
'when minutes are not used'
do
it
'returns unlimited report with no usage'
do
report
=
presenter
.
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
=
presenter
.
monthly_minutes_report
expect
(
report
.
limit
).
to
eq
'Unlimited'
expect
(
report
.
used
).
to
eq
20
expect
(
report
.
status
).
to
eq
:disabled
end
end
end
end
context
'when limited'
do
before
do
allow
(
presenter
).
to
receive
(
:enabled?
).
and_return
(
true
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_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
=
presenter
.
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
=
presenter
.
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
(
quota
).
to
receive
(
: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
=
presenter
.
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
=
presenter
.
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
=
presenter
.
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
=
presenter
.
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
=
presenter
.
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
describe
'#monthly_percent_used'
do
subject
{
presenter
.
monthly_percent_used
}
where
(
:limit_enabled
,
:monthly_limit
,
:purchased_limit
,
:minutes_used
,
:result
,
:title
)
do
false
|
200
|
0
|
40
|
0
|
'limit not enabled'
true
|
200
|
0
|
0
|
0
|
'monthly limit set and no usage'
true
|
200
|
0
|
40
|
20
|
'monthly limit set and usage lower than 100%'
true
|
200
|
0
|
200
|
100
|
'monthly limit set and usage at 100%'
true
|
200
|
0
|
210
|
105
|
'monthly limit set and usage above 100%'
true
|
0
|
0
|
0
|
0
|
'monthly limit not set and no usage'
true
|
0
|
0
|
40
|
0
|
'monthly limit not set and some usage'
true
|
200
|
100
|
0
|
0
|
'monthly and purchased limits set and no usage'
true
|
200
|
100
|
40
|
20
|
'monthly and purchased limits set and low usage'
true
|
200
|
100
|
210
|
100
|
'usage capped to 100% and overflows into purchased minutes'
end
with_them
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
limit_enabled
)
allow
(
namespace
).
to
receive
(
:any_project_with_shared_runners_enabled?
).
and_return
(
true
)
namespace
.
shared_runners_minutes_limit
=
monthly_limit
namespace
.
extra_shared_runners_minutes_limit
=
purchased_limit
namespace
.
namespace_statistics
.
shared_runners_seconds
=
minutes_used
.
minutes
end
it
'returns the percentage'
do
is_expected
.
to
eq
result
end
end
end
describe
'#purchased_percent_used'
do
subject
{
presenter
.
purchased_percent_used
}
where
(
:limit_enabled
,
:monthly_limit
,
:purchased_limit
,
:minutes_used
,
:result
,
:title
)
do
false
|
0
|
0
|
40
|
0
|
'limit not enabled'
true
|
0
|
200
|
40
|
20
|
'monthly limit not set and purchased limit set and low usage'
true
|
200
|
0
|
40
|
0
|
'monthly limit set and purchased limit not set and usage below monthly'
true
|
200
|
0
|
240
|
0
|
'monthly limit set and purchased limit not set and usage above monthly'
true
|
200
|
200
|
0
|
0
|
'monthly and purchased limits set and no usage'
true
|
200
|
200
|
40
|
0
|
'monthly and purchased limits set and usage below monthly'
true
|
200
|
200
|
200
|
0
|
'monthly and purchased limits set and monthly minutes maxed out'
true
|
200
|
200
|
300
|
50
|
'monthly and purchased limits set and some purchased minutes used'
true
|
200
|
200
|
400
|
100
|
'monthly and purchased limits set and all minutes used'
true
|
200
|
200
|
430
|
115
|
'monthly and purchased limits set and usage beyond all limits'
end
with_them
do
before
do
allow
(
quota
).
to
receive
(
:enabled?
).
and_return
(
limit_enabled
)
namespace
.
shared_runners_minutes_limit
=
monthly_limit
namespace
.
extra_shared_runners_minutes_limit
=
purchased_limit
namespace
.
namespace_statistics
.
shared_runners_seconds
=
minutes_used
.
minutes
end
it
'returns the percentage'
do
is_expected
.
to
eq
result
end
end
end
describe
'#any_project_enabled?'
do
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
)
}
context
'when namespace has any project with shared runners enabled'
do
before
do
project
.
update!
(
shared_runners_enabled:
true
)
end
it
'returns true'
do
expect
(
presenter
.
any_project_enabled?
).
to
be_truthy
end
end
context
'when namespace has no projects with shared runners enabled'
do
before
do
project
.
update!
(
shared_runners_enabled:
false
)
end
it
'returns false'
do
expect
(
presenter
.
any_project_enabled?
).
to
be_falsey
end
end
it
'does not trigger additional queries when called multiple times'
do
# memoizes the result
presenter
.
any_project_enabled?
# count
actual
=
ActiveRecord
::
QueryRecorder
.
new
do
presenter
.
any_project_enabled?
end
expect
(
actual
.
count
).
to
eq
(
0
)
end
end
describe
'#display_shared_runners_data?'
do
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
,
shared_runners_enabled:
true
)
}
subject
{
presenter
.
send
(
'display_shared_runners_data?'
)
}
context
'when the namespace is root and it has a project with shared runners enabled'
do
it
{
is_expected
.
to
be_truthy
}
end
context
'when the namespace is not root'
do
let
(
:namespace
)
{
create
(
:group
,
:nested
)
}
it
{
is_expected
.
to
be_falsey
}
end
context
'when the namespaces has no project with shared runners enabled'
do
before
do
project
.
update!
(
shared_runners_enabled:
false
)
end
it
{
is_expected
.
to
be_falsey
}
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment