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
096c2166
Commit
096c2166
authored
Jul 06, 2017
by
Rémy Coutable
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[EE] Allow to enable the performance bar per user or Feature group
Signed-off-by:
Rémy Coutable
<
remy@rymai.me
>
parent
0115f8f0
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
522 additions
and
48 deletions
+522
-48
app/controllers/admin/application_settings_controller.rb
app/controllers/admin/application_settings_controller.rb
+2
-0
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+1
-16
app/controllers/concerns/with_performance_bar.rb
app/controllers/concerns/with_performance_bar.rb
+17
-0
app/helpers/nav_helper.rb
app/helpers/nav_helper.rb
+1
-1
app/helpers/performance_bar_helper.rb
app/helpers/performance_bar_helper.rb
+7
-0
app/models/application_setting.rb
app/models/application_setting.rb
+37
-0
app/views/admin/application_settings/_form.html.haml
app/views/admin/application_settings/_form.html.haml
+16
-0
app/views/layouts/_head.html.haml
app/views/layouts/_head.html.haml
+2
-2
changelogs/unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml
...unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml
+4
-0
config/initializers/flipper.rb
config/initializers/flipper.rb
+6
-2
db/migrate/20170706151212_add_performance_bar_allowed_group_id_to_application_settings.rb
...rformance_bar_allowed_group_id_to_application_settings.rb
+9
-0
db/schema.rb
db/schema.rb
+2
-1
doc/README.md
doc/README.md
+1
-0
doc/administration/monitoring/performance/img/performance_bar.png
...nistration/monitoring/performance/img/performance_bar.png
+0
-0
doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
...erformance/img/performance_bar_configuration_settings.png
+0
-0
doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
...toring/performance/img/performance_bar_line_profiling.png
+0
-0
doc/administration/monitoring/performance/img/performance_bar_sql_queries.png
...onitoring/performance/img/performance_bar_sql_queries.png
+0
-0
doc/administration/monitoring/performance/performance_bar.md
doc/administration/monitoring/performance/performance_bar.md
+63
-0
doc/api/README.md
doc/api/README.md
+1
-0
doc/api/features.md
doc/api/features.md
+3
-2
doc/development/feature_flags.md
doc/development/feature_flags.md
+17
-2
lib/api/features.rb
lib/api/features.rb
+17
-12
lib/feature.rb
lib/feature.rb
+8
-0
lib/gitlab/performance_bar.rb
lib/gitlab/performance_bar.rb
+35
-2
spec/features/user_can_display_performance_bar_spec.rb
spec/features/user_can_display_performance_bar_spec.rb
+8
-8
spec/lib/gitlab/performance_bar_spec.rb
spec/lib/gitlab/performance_bar_spec.rb
+102
-0
spec/models/application_setting_spec.rb
spec/models/application_setting_spec.rb
+145
-0
spec/requests/api/features_spec.rb
spec/requests/api/features_spec.rb
+14
-0
spec/support/stub_configuration.rb
spec/support/stub_configuration.rb
+4
-0
No files found.
app/controllers/admin/application_settings_controller.rb
View file @
096c2166
...
@@ -125,6 +125,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
...
@@ -125,6 +125,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_port
,
:metrics_port
,
:metrics_sample_interval
,
:metrics_sample_interval
,
:metrics_timeout
,
:metrics_timeout
,
:performance_bar_allowed_group_id
,
:performance_bar_enabled
,
:recaptcha_enabled
,
:recaptcha_enabled
,
:recaptcha_private_key
,
:recaptcha_private_key
,
:recaptcha_site_key
,
:recaptcha_site_key
,
...
...
app/controllers/application_controller.rb
View file @
096c2166
...
@@ -9,7 +9,7 @@ class ApplicationController < ActionController::Base
...
@@ -9,7 +9,7 @@ class ApplicationController < ActionController::Base
include
SentryHelper
include
SentryHelper
include
WorkhorseHelper
include
WorkhorseHelper
include
EnforcesTwoFactorAuthentication
include
EnforcesTwoFactorAuthentication
include
Peek
::
Rblineprof
::
CustomControllerHelpers
include
WithPerformanceBar
before_action
:authenticate_user_from_private_token!
before_action
:authenticate_user_from_private_token!
before_action
:authenticate_user_from_rss_token!
before_action
:authenticate_user_from_rss_token!
...
@@ -68,21 +68,6 @@ class ApplicationController < ActionController::Base
...
@@ -68,21 +68,6 @@ class ApplicationController < ActionController::Base
end
end
end
end
def
peek_enabled?
return
false
unless
Gitlab
::
PerformanceBar
.
enabled?
return
false
unless
current_user
if
RequestStore
.
active?
if
RequestStore
.
store
.
key?
(
:peek_enabled
)
RequestStore
.
store
[
:peek_enabled
]
else
RequestStore
.
store
[
:peek_enabled
]
=
cookies
[
:perf_bar_enabled
].
present?
end
else
cookies
[
:perf_bar_enabled
].
present?
end
end
protected
protected
# This filter handles both private tokens and personal access tokens
# This filter handles both private tokens and personal access tokens
...
...
app/controllers/concerns/with_performance_bar.rb
0 → 100644
View file @
096c2166
module
WithPerformanceBar
extend
ActiveSupport
::
Concern
included
do
include
Peek
::
Rblineprof
::
CustomControllerHelpers
end
def
peek_enabled?
return
false
unless
Gitlab
::
PerformanceBar
.
enabled?
(
current_user
)
if
RequestStore
.
active?
RequestStore
.
fetch
(
:peek_enabled
)
{
cookies
[
:perf_bar_enabled
].
present?
}
else
cookies
[
:perf_bar_enabled
].
present?
end
end
end
app/helpers/nav_helper.rb
View file @
096c2166
...
@@ -23,7 +23,7 @@ module NavHelper
...
@@ -23,7 +23,7 @@ module NavHelper
def
nav_header_class
def
nav_header_class
class_name
=
''
class_name
=
''
class_name
<<
" with-horizontal-nav"
if
defined?
(
nav
)
&&
nav
class_name
<<
" with-horizontal-nav"
if
defined?
(
nav
)
&&
nav
class_name
<<
" with-peek"
if
pe
ek
_enabled?
class_name
<<
" with-peek"
if
pe
rformance_bar
_enabled?
class_name
class_name
end
end
...
...
app/helpers/performance_bar_helper.rb
0 → 100644
View file @
096c2166
module
PerformanceBarHelper
# This is a hack since using `alias_method :performance_bar_enabled?, :peek_enabled?`
# in WithPerformanceBar breaks tests (but works in the browser).
def
performance_bar_enabled?
peek_enabled?
end
end
app/models/application_setting.rb
View file @
096c2166
...
@@ -247,6 +247,7 @@ class ApplicationSetting < ActiveRecord::Base
...
@@ -247,6 +247,7 @@ class ApplicationSetting < ActiveRecord::Base
koding_url:
nil
,
koding_url:
nil
,
max_artifacts_size:
Settings
.
artifacts
[
'max_size'
],
max_artifacts_size:
Settings
.
artifacts
[
'max_size'
],
max_attachment_size:
Settings
.
gitlab
[
'max_attachment_size'
],
max_attachment_size:
Settings
.
gitlab
[
'max_attachment_size'
],
performance_bar_allowed_group_id:
nil
,
plantuml_enabled:
false
,
plantuml_enabled:
false
,
plantuml_url:
nil
,
plantuml_url:
nil
,
recaptcha_enabled:
false
,
recaptcha_enabled:
false
,
...
@@ -379,6 +380,42 @@ class ApplicationSetting < ActiveRecord::Base
...
@@ -379,6 +380,42 @@ class ApplicationSetting < ActiveRecord::Base
super
(
levels
.
map
{
|
level
|
Gitlab
::
VisibilityLevel
.
level_value
(
level
)
})
super
(
levels
.
map
{
|
level
|
Gitlab
::
VisibilityLevel
.
level_value
(
level
)
})
end
end
def
performance_bar_allowed_group_id
=
(
group_full_path
)
group
=
Group
.
find_by_full_path
(
group_full_path
)
return
unless
group
&&
group
.
id
!=
performance_bar_allowed_group_id
super
(
group
.
id
)
Gitlab
::
PerformanceBar
.
expire_allowed_user_ids_cache
end
def
performance_bar_allowed_group
Group
.
find_by_id
(
performance_bar_allowed_group_id
)
end
# Return true is the Performance Bar is available globally or for the
# `performance_team` feature group
def
performance_bar_enabled?
feature
=
Feature
.
get
(
:performance_bar
)
feature
.
on?
||
feature
.
groups_value
.
include?
(
'performance_team'
)
end
# - If `enable` is true, enable the `performance_bar` feature for the
# `performance_team` feature group
# - If `enable` is false, disable the `performance_bar` feature globally
def
performance_bar_enabled
=
(
enable
)
feature
=
Feature
.
get
(
:performance_bar
)
performance_bar_on
=
performance_bar_enabled?
if
enable
&&
!
performance_bar_on
feature
.
enable_group
(
:performance_team
)
Gitlab
::
PerformanceBar
.
expire_allowed_user_ids_cache
elsif
!
enable
&&
performance_bar_on
feature
.
disable
Gitlab
::
PerformanceBar
.
expire_allowed_user_ids_cache
end
end
# Choose one of the available repository storage options. Currently all have
# Choose one of the available repository storage options. Currently all have
# equal weighting.
# equal weighting.
def
pick_repository_storage
def
pick_repository_storage
...
...
app/views/admin/application_settings/_form.html.haml
View file @
096c2166
...
@@ -358,6 +358,22 @@
...
@@ -358,6 +358,22 @@
%strong
.cred
WARNING:
%strong
.cred
WARNING:
Environment variable `prometheus_multiproc_dir` does not exist or is not pointing to a valid directory.
Environment variable `prometheus_multiproc_dir` does not exist or is not pointing to a valid directory.
%fieldset
%legend
Profiling - Performance Bar
%p
Enable the Performance Bar for a given group.
=
link_to
icon
(
'question-circle'
),
help_page_path
(
'administration/monitoring/performance/performance_bar'
)
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
=
f
.
label
:performance_bar_enabled
do
=
f
.
check_box
:performance_bar_enabled
Enable the Performance Bar
.form-group
=
f
.
label
:performance_bar_allowed_group_id
,
'Allowed group'
,
class:
'control-label col-sm-2'
.col-sm-10
=
f
.
text_field
:performance_bar_allowed_group_id
,
class:
'form-control'
,
placeholder:
'my-org/my-group'
,
value:
@application_setting
.
performance_bar_allowed_group
&
.
full_path
%fieldset
%fieldset
%legend
Background Jobs
%legend
Background Jobs
%p
%p
...
...
app/views/layouts/_head.html.haml
View file @
096c2166
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
=
stylesheet_link_tag
"application"
,
media:
"all"
=
stylesheet_link_tag
"application"
,
media:
"all"
=
stylesheet_link_tag
"print"
,
media:
"print"
=
stylesheet_link_tag
"print"
,
media:
"print"
=
stylesheet_link_tag
"test"
,
media:
"all"
if
Rails
.
env
.
test?
=
stylesheet_link_tag
"test"
,
media:
"all"
if
Rails
.
env
.
test?
=
stylesheet_link_tag
'peek'
if
pe
ek
_enabled?
=
stylesheet_link_tag
'peek'
if
pe
rformance_bar
_enabled?
-
if
show_new_nav?
-
if
show_new_nav?
=
stylesheet_link_tag
"new_nav"
,
media:
"all"
=
stylesheet_link_tag
"new_nav"
,
media:
"all"
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
=
webpack_bundle_tag
"main"
=
webpack_bundle_tag
"main"
=
webpack_bundle_tag
"raven"
if
current_application_settings
.
clientside_sentry_enabled
=
webpack_bundle_tag
"raven"
if
current_application_settings
.
clientside_sentry_enabled
=
webpack_bundle_tag
"test"
if
Rails
.
env
.
test?
=
webpack_bundle_tag
"test"
if
Rails
.
env
.
test?
=
webpack_bundle_tag
'peek'
if
pe
ek
_enabled?
=
webpack_bundle_tag
'peek'
if
pe
rformance_bar
_enabled?
-
if
content_for?
(
:page_specific_javascripts
)
-
if
content_for?
(
:page_specific_javascripts
)
=
yield
:page_specific_javascripts
=
yield
:page_specific_javascripts
...
...
changelogs/unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml
0 → 100644
View file @
096c2166
---
title
:
Allow to enable the performance bar per user or Feature group
merge_request
:
12362
author
:
config/initializers/flipper.rb
View file @
096c2166
require
'flipper/middleware/memoizer'
require
'flipper/middleware/memoizer'
Rails
.
application
.
config
.
middleware
.
use
Flipper
::
Middleware
::
Memoizer
,
unless
Rails
.
env
.
test?
Rails
.
application
.
config
.
middleware
.
use
Flipper
::
Middleware
::
Memoizer
,
lambda
{
Feature
.
flipper
}
lambda
{
Feature
.
flipper
}
Feature
.
register_feature_groups
end
db/migrate/20170706151212_add_performance_bar_allowed_group_id_to_application_settings.rb
0 → 100644
View file @
096c2166
class
AddPerformanceBarAllowedGroupIdToApplicationSettings
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:application_settings
,
:performance_bar_allowed_group_id
,
:integer
end
end
db/schema.rb
View file @
096c2166
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#
#
# It's strongly recommended that you check this file into your version control system.
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
20170
627211700
)
do
ActiveRecord
::
Schema
.
define
(
version:
20170
706151212
)
do
# These are extensions that must be enabled in order to support this database
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
enable_extension
"plpgsql"
...
@@ -144,6 +144,7 @@ ActiveRecord::Schema.define(version: 20170627211700) do
...
@@ -144,6 +144,7 @@ ActiveRecord::Schema.define(version: 20170627211700) do
t
.
boolean
"authorized_keys_enabled"
,
default:
true
,
null:
false
t
.
boolean
"authorized_keys_enabled"
,
default:
true
,
null:
false
t
.
boolean
"help_page_hide_commercial_content"
,
default:
false
t
.
boolean
"help_page_hide_commercial_content"
,
default:
false
t
.
string
"help_page_support_url"
t
.
string
"help_page_support_url"
t
.
integer
"performance_bar_allowed_group_id"
end
end
create_table
"approvals"
,
force: :cascade
do
|
t
|
create_table
"approvals"
,
force: :cascade
do
|
t
|
...
...
doc/README.md
View file @
096c2166
...
@@ -193,6 +193,7 @@ have access to GitLab administration tools and settings.
...
@@ -193,6 +193,7 @@ have access to GitLab administration tools and settings.
-
[
Operations
](
administration/operations.md
)
: Keeping GitLab up and running.
-
[
Operations
](
administration/operations.md
)
: Keeping GitLab up and running.
-
[
Polling
](
administration/polling.md
)
: Configure how often the GitLab UI polls for updates.
-
[
Polling
](
administration/polling.md
)
: Configure how often the GitLab UI polls for updates.
-
[
Request Profiling
](
administration/monitoring/performance/request_profiling.md
)
: Get a detailed profile on slow requests.
-
[
Request Profiling
](
administration/monitoring/performance/request_profiling.md
)
: Get a detailed profile on slow requests.
-
[
Performance Bar
](
administration/monitoring/performance/performance_bar.md
)
: Get performance information for the current page.
### Customization
### Customization
...
...
doc/administration/monitoring/performance/img/performance_bar.png
0 → 100644
View file @
096c2166
182 KB
doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
0 → 100644
View file @
096c2166
19.9 KB
doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
0 → 100644
View file @
096c2166
158 KB
doc/administration/monitoring/performance/img/performance_bar_sql_queries.png
0 → 100644
View file @
096c2166
161 KB
doc/administration/monitoring/performance/performance_bar.md
0 → 100644
View file @
096c2166
# Performance Bar
A Performance Bar can be displayed, to dig into the performance of a page. When
activated, it looks as follows:
![
Performance Bar
](
img/performance_bar.png
)
It allows you to:
-
see the current host serving the page
-
see the timing of the page (backend, frontend)
-
the number of DB queries, the time it took, and the detail of these queries
![
SQL profiling using the Performance Bar
](
img/performance_bar_sql_queries.png
)
-
the number of calls to Redis, and the time it took
-
the number of background jobs created by Sidekiq, and the time it took
-
the number of Ruby GC calls, and the time it took
-
profile the code used to generate the page, line by line
![
Line profiling using the Performance Bar
](
img/performance_bar_line_profiling.png
)
## Enable the Performance Bar via the Admin panel
GitLab Performance Bar is disabled by default. To enable it for a given group,
navigate to the Admin area in
**Settings > Profiling - Performance Bar**
(
`/admin/application_settings`
).
The only required setting you need to set is the full path of the group that
will be allowed to display the Performance Bar.
Make sure _Enable the Performance Bar_ is checked and hit
**Save**
to save the changes.
---
![
GitLab Performance Bar Admin Settings
](
img/performance_bar_configuration_settings.png
)
---
## Enable the Performance Bar via the API
Under the hood, the Performance Bar activation is done via the
`performance_bar`
[
Feature Flag
](
../../../development/features_flags.md
)
.
That means you can also enable or disable it via the
[
Features API
](
../../../api/features.md#set-or-create-a-feature
)
.
### For the `performance_team` feature group
The
`performance_team`
feature group maps to the group specified in your
[
Admin
area
](
#enable-the-performance-bar-via-the-admin-panel
)
.
```
curl --data "feature_group=performance_team" --data "value=true" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/features/performance_bar
```
### For specific users
It's also possible to enable the Performance Bar for specific users in addition
to a group, or even instead of a group:
```
curl --data "user=my_username" --data "value=true" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/features/performance_bar
```
[
reconfigure
]:
../../restart_gitlab.md#omnibus-gitlab-reconfigure
doc/api/README.md
View file @
096c2166
...
@@ -17,6 +17,7 @@ following locations:
...
@@ -17,6 +17,7 @@ following locations:
-
[
Deploy Keys
](
deploy_keys.md
)
-
[
Deploy Keys
](
deploy_keys.md
)
-
[
Environments
](
environments.md
)
-
[
Environments
](
environments.md
)
-
[
Events
](
events.md
)
-
[
Events
](
events.md
)
-
[
Feature flags
](
features.md
)
-
[
Gitignores templates
](
templates/gitignores.md
)
-
[
Gitignores templates
](
templates/gitignores.md
)
-
[
GitLab CI Config templates
](
templates/gitlab_ci_ymls.md
)
-
[
GitLab CI Config templates
](
templates/gitlab_ci_ymls.md
)
-
[
Groups
](
groups.md
)
-
[
Groups
](
groups.md
)
...
...
doc/api/features.md
View file @
096c2166
# Features API
# Features
flags
API
All methods require administrator authorization.
All methods require administrator authorization.
...
@@ -61,7 +61,8 @@ POST /features/:name
...
@@ -61,7 +61,8 @@ POST /features/:name
|
`feature_group`
| string | no | A Feature group name |
|
`feature_group`
| string | no | A Feature group name |
|
`user`
| string | no | A GitLab username |
|
`user`
| string | no | A GitLab username |
Note that
`feature_group`
and
`user`
are mutually exclusive.
Note that you can enable or disable a feature for both a
`feature_group`
and a
`user`
with a single API call.
```
bash
```
bash
curl
--data
"value=30"
--header
"PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK"
https://gitlab.example.com/api/v4/features/new_library
curl
--data
"value=30"
--header
"PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK"
https://gitlab.example.com/api/v4/features/new_library
...
...
doc/development/feature_flags.md
View file @
096c2166
...
@@ -3,5 +3,20 @@
...
@@ -3,5 +3,20 @@
Starting from GitLab 9.3 we support feature flags via
Starting from GitLab 9.3 we support feature flags via
[
Flipper
](
https://github.com/jnunemaker/flipper/
)
. You should use the
`Feature`
[
Flipper
](
https://github.com/jnunemaker/flipper/
)
. You should use the
`Feature`
class (defined in
`lib/feature.rb`
) in your code to get, set and list feature
class (defined in
`lib/feature.rb`
) in your code to get, set and list feature
flags. During runtime you can set the values for the gates via the
flags.
[
admin API
](
../api/features.md
)
.
During runtime you can set the values for the gates via the
[
features API
](
../api/features.md
)
(
accessible
to admins only).
## Feature groups
Starting from GitLab 9.4 we support feature groups via
[
Flipper groups
](
https://github.com/jnunemaker/flipper/blob/v0.10.2/docs/Gates.md#2-group
)
.
Feature groups must be defined statically in
`lib/feature.rb`
(in the
`.register_feature_groups`
method), but their implementation can obviously be
dynamic (querying the DB etc.). You can see how the
`performance_team`
feature
group for a concrete example.
Once defined in
`lib/feature.rb`
, you will be able to activate a
feature for a given feature group via the
[
`feature_group` param of the features API
](
../api/features.md#set-or-create-a-feature
)
lib/api/features.rb
View file @
096c2166
...
@@ -14,14 +14,12 @@ module API
...
@@ -14,14 +14,12 @@ module API
end
end
end
end
def
gate_target
(
params
)
def
gate_targets
(
params
)
if
params
[
:feature_group
]
targets
=
[]
Feature
.
group
(
params
[
:feature_group
])
targets
<<
Feature
.
group
(
params
[
:feature_group
])
if
params
[
:feature_group
]
elsif
params
[
:user
]
targets
<<
User
.
find_by_username
(
params
[
:user
])
if
params
[
:user
]
User
.
find_by_username
(
params
[
:user
])
else
targets
gate_value
(
params
)
end
end
end
end
end
...
@@ -42,18 +40,25 @@ module API
...
@@ -42,18 +40,25 @@ module API
requires
:value
,
type:
String
,
desc:
'`true` or `false` to enable/disable, an integer for percentage of time'
requires
:value
,
type:
String
,
desc:
'`true` or `false` to enable/disable, an integer for percentage of time'
optional
:feature_group
,
type:
String
,
desc:
'A Feature group name'
optional
:feature_group
,
type:
String
,
desc:
'A Feature group name'
optional
:user
,
type:
String
,
desc:
'A GitLab username'
optional
:user
,
type:
String
,
desc:
'A GitLab username'
mutually_exclusive
:feature_group
,
:user
end
end
post
':name'
do
post
':name'
do
feature
=
Feature
.
get
(
params
[
:name
])
feature
=
Feature
.
get
(
params
[
:name
])
target
=
gate_target
(
params
)
target
s
=
gate_targets
(
params
)
value
=
gate_value
(
params
)
value
=
gate_value
(
params
)
case
value
case
value
when
true
when
true
feature
.
enable
(
target
)
if
targets
.
present?
targets
.
each
{
|
target
|
feature
.
enable
(
target
)
}
else
feature
.
enable
end
when
false
when
false
feature
.
disable
(
target
)
if
targets
.
present?
targets
.
each
{
|
target
|
feature
.
disable
(
target
)
}
else
feature
.
disable
end
else
else
feature
.
enable_percentage_of_time
(
value
)
feature
.
enable_percentage_of_time
(
value
)
end
end
...
...
lib/feature.rb
View file @
096c2166
...
@@ -57,5 +57,13 @@ class Feature
...
@@ -57,5 +57,13 @@ class Feature
Flipper
.
new
(
adapter
)
Flipper
.
new
(
adapter
)
end
end
end
end
def
register_feature_groups
Flipper
.
register
(
:performance_team
)
do
|
actor
|
user
=
actor
.
thing
user
&
.
is_a?
(
User
)
&&
Gitlab
::
PerformanceBar
.
allowed_user?
(
user
)
end
end
end
end
end
end
lib/gitlab/performance_bar.rb
View file @
096c2166
module
Gitlab
module
Gitlab
module
PerformanceBar
module
PerformanceBar
def
self
.
enabled?
include
Gitlab
::
CurrentSettings
Feature
.
enabled?
(
'gitlab_performance_bar'
)
ALLOWED_USER_IDS_KEY
=
'performance_bar_allowed_user_ids'
.
freeze
# The time (in seconds) after which a set of allowed user IDs is expired
# automatically.
ALLOWED_USER_IDS_TIME_TO_LIVE
=
10
.
minutes
def
self
.
enabled?
(
current_user
=
nil
)
Feature
.
enabled?
(
:performance_bar
,
current_user
)
end
def
self
.
allowed_user?
(
user
)
return
false
unless
allowed_group_id
allowed_user_ids
.
include?
(
user
.
id
)
end
def
self
.
allowed_group_id
current_application_settings
.
performance_bar_allowed_group_id
end
def
self
.
allowed_user_ids
Rails
.
cache
.
fetch
(
ALLOWED_USER_IDS_KEY
,
expires_in:
ALLOWED_USER_IDS_TIME_TO_LIVE
)
do
group
=
Group
.
find_by_id
(
allowed_group_id
)
if
group
GroupMembersFinder
.
new
(
group
).
execute
.
pluck
(
:user_id
)
else
[]
end
end
end
def
self
.
expire_allowed_user_ids_cache
Rails
.
cache
.
delete
(
ALLOWED_USER_IDS_KEY
)
end
end
end
end
end
end
spec/features/user_can_display_performance_bar_spec.rb
View file @
096c2166
...
@@ -38,17 +38,17 @@ describe 'User can display performance bar', :js do
...
@@ -38,17 +38,17 @@ describe 'User can display performance bar', :js do
visit
root_path
visit
root_path
end
end
context
'when the
gitlab_
performance_bar feature is disabled'
do
context
'when the performance_bar feature is disabled'
do
before
do
before
do
Feature
.
disable
(
'gitlab_performance_bar'
)
Feature
.
disable
(
:performance_bar
)
end
end
it_behaves_like
'performance bar is disabled'
it_behaves_like
'performance bar is disabled'
end
end
context
'when the
gitlab_
performance_bar feature is enabled'
do
context
'when the performance_bar feature is enabled'
do
before
do
before
do
Feature
.
enable
(
'gitlab_performance_bar'
)
Feature
.
enable
(
:performance_bar
)
end
end
it_behaves_like
'performance bar is disabled'
it_behaves_like
'performance bar is disabled'
...
@@ -62,17 +62,17 @@ describe 'User can display performance bar', :js do
...
@@ -62,17 +62,17 @@ describe 'User can display performance bar', :js do
visit
root_path
visit
root_path
end
end
context
'when the
gitlab_
performance_bar feature is disabled'
do
context
'when the performance_bar feature is disabled'
do
before
do
before
do
Feature
.
disable
(
'gitlab_performance_bar'
)
Feature
.
disable
(
:performance_bar
)
end
end
it_behaves_like
'performance bar is disabled'
it_behaves_like
'performance bar is disabled'
end
end
context
'when the
gitlab_
performance_bar feature is enabled'
do
context
'when the performance_bar feature is enabled'
do
before
do
before
do
Feature
.
enable
(
'gitlab_performance_bar'
)
Feature
.
enable
(
:performance_bar
)
end
end
it_behaves_like
'performance bar is enabled'
it_behaves_like
'performance bar is enabled'
...
...
spec/lib/gitlab/performance_bar_spec.rb
0 → 100644
View file @
096c2166
require
'spec_helper'
describe
Gitlab
::
PerformanceBar
do
describe
'.enabled?'
do
it
'returns false when given actor is nil'
do
expect
(
described_class
.
enabled?
(
nil
)).
to
be_falsy
end
it
'returns false when feature is disabled'
do
actor
=
double
(
'actor'
)
expect
(
Feature
).
to
receive
(
:enabled?
)
.
with
(
:performance_bar
,
actor
).
and_return
(
false
)
expect
(
described_class
.
enabled?
(
actor
)).
to
be_falsy
end
it
'returns true when feature is enabled'
do
actor
=
double
(
'actor'
)
expect
(
Feature
).
to
receive
(
:enabled?
)
.
with
(
:performance_bar
,
actor
).
and_return
(
true
)
expect
(
described_class
.
enabled?
(
actor
)).
to
be_truthy
end
end
shared_examples
'allowed user IDs are cached in Redis for 10 minutes'
do
before
do
# Warm the Redis cache
described_class
.
allowed_user?
(
user
)
end
it
'caches the allowed user IDs in cache'
,
:caching
do
expect
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_truthy
end
.
not_to
exceed_query_limit
(
0
)
end
end
describe
'.allowed_user?'
do
let
(
:user
)
{
create
(
:user
)
}
before
do
stub_performance_bar_setting
(
allowed_group:
'my-group'
)
end
context
'when allowed group does not exist'
do
it
'returns false'
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_falsy
end
end
context
'when allowed group exists'
do
let!
(
:my_group
)
{
create
(
:group
,
path:
'my-group'
)
}
context
'when user is not a member of the allowed group'
do
it
'returns false'
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_falsy
end
it_behaves_like
'allowed user IDs are cached in Redis for 10 minutes'
end
context
'when user is a member of the allowed group'
do
before
do
my_group
.
add_developer
(
user
)
end
it
'returns true'
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_truthy
end
it_behaves_like
'allowed user IDs are cached in Redis for 10 minutes'
end
end
context
'when allowed group is nested'
,
:nested_groups
do
let!
(
:nested_my_group
)
{
create
(
:group
,
parent:
create
(
:group
,
path:
'my-org'
),
path:
'my-group'
)
}
before
do
create
(
:group
,
path:
'my-group'
)
nested_my_group
.
add_developer
(
user
)
stub_performance_bar_setting
(
allowed_group:
'my-org/my-group'
)
end
it
'returns the nested group'
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_truthy
end
end
context
'when a nested group has the same path'
,
:nested_groups
do
before
do
create
(
:group
,
:nested
,
path:
'my-group'
).
add_developer
(
user
)
end
it
'returns false'
do
expect
(
described_class
.
allowed_user?
(
user
)).
to
be_falsy
end
end
end
end
spec/models/application_setting_spec.rb
View file @
096c2166
...
@@ -233,6 +233,151 @@ describe ApplicationSetting, models: true do
...
@@ -233,6 +233,151 @@ describe ApplicationSetting, models: true do
end
end
end
end
describe
'performance bar settings'
do
before
do
Flipper
.
unregister_groups
Flipper
.
register
(
:performance_team
)
end
after
do
Flipper
.
unregister_groups
end
describe
'performance_bar_allowed_group_id='
do
it
'does not persist an invalid group path'
do
setting
.
performance_bar_allowed_group_id
=
'foo'
expect
(
setting
.
performance_bar_allowed_group_id
).
to
be_nil
end
context
'with a path to an existing group'
do
let
(
:group
)
{
create
(
:group
)
}
it
'persists a valid group path and clears allowed user IDs cache'
do
expect
(
Gitlab
::
PerformanceBar
).
to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_allowed_group_id
=
group
.
full_path
expect
(
setting
.
performance_bar_allowed_group_id
).
to
eq
(
group
.
id
)
end
context
'when the given path is the same'
do
before
do
setting
.
performance_bar_allowed_group_id
=
group
.
full_path
end
it
'clears the cached allowed user IDs'
do
expect
(
Gitlab
::
PerformanceBar
).
not_to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_allowed_group_id
=
group
.
full_path
end
end
end
end
describe
'performance_bar_allowed_group'
do
context
'with no performance_bar_allowed_group_id saved'
do
it
'returns nil'
do
expect
(
setting
.
performance_bar_allowed_group
).
to
be_nil
end
end
context
'with a performance_bar_allowed_group_id saved'
do
let
(
:group
)
{
create
(
:group
)
}
before
do
setting
.
performance_bar_allowed_group_id
=
group
.
full_path
end
it
'returns the group'
do
expect
(
setting
.
performance_bar_allowed_group
).
to
eq
(
group
)
end
end
end
describe
'performance_bar_enabled?'
do
context
'with the Performance Bar is enabled globally'
do
before
do
Feature
.
enable
(
:performance_bar
)
end
it
'returns true'
do
expect
(
setting
).
to
be_performance_bar_enabled
end
end
context
'with the Performance Bar is enabled for the performance_team group'
do
before
do
Feature
.
enable_group
(
:performance_bar
,
:performance_team
)
end
it
'returns true'
do
expect
(
setting
).
to
be_performance_bar_enabled
end
end
context
'with the Performance Bar is enabled for a specific user'
do
before
do
Feature
.
enable
(
:performance_team
,
create
(
:user
))
end
it
'returns false'
do
expect
(
setting
).
not_to
be_performance_bar_enabled
end
end
end
describe
'performance_bar_enabled='
do
context
'when the performance bar is enabled'
do
before
do
Feature
.
enable
(
:performance_bar
)
end
context
'when passing true'
do
it
'does not clear allowed user IDs cache'
do
expect
(
Gitlab
::
PerformanceBar
).
not_to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_enabled
=
true
expect
(
setting
).
to
be_performance_bar_enabled
end
end
context
'when passing false'
do
it
'disables the performance bar and clears allowed user IDs cache'
do
expect
(
Gitlab
::
PerformanceBar
).
to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_enabled
=
false
expect
(
setting
).
not_to
be_performance_bar_enabled
end
end
end
context
'when the performance bar is disabled'
do
before
do
Feature
.
disable
(
:performance_bar
)
end
context
'when passing true'
do
it
'enables the performance bar and clears allowed user IDs cache'
do
expect
(
Gitlab
::
PerformanceBar
).
to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_enabled
=
true
expect
(
setting
).
to
be_performance_bar_enabled
end
end
context
'when passing false'
do
it
'does not clear allowed user IDs cache'
do
expect
(
Gitlab
::
PerformanceBar
).
not_to
receive
(
:expire_allowed_user_ids_cache
)
setting
.
performance_bar_enabled
=
false
expect
(
setting
).
not_to
be_performance_bar_enabled
end
end
end
end
end
describe
'usage ping settings'
do
describe
'usage ping settings'
do
context
'when the usage ping is disabled in gitlab.yml'
do
context
'when the usage ping is disabled in gitlab.yml'
do
before
do
before
do
...
...
spec/requests/api/features_spec.rb
View file @
096c2166
...
@@ -113,6 +113,20 @@ describe API::Features do
...
@@ -113,6 +113,20 @@ describe API::Features do
{
'key'
=>
'actors'
,
'value'
=>
[
"User:
#{
user
.
id
}
"
]
}
{
'key'
=>
'actors'
,
'value'
=>
[
"User:
#{
user
.
id
}
"
]
}
])
])
end
end
it
'creates an enabled feature for the given user and feature group when passed user=username and feature_group=perf_team'
do
post
api
(
"/features/
#{
feature_name
}
"
,
admin
),
value:
'true'
,
user:
user
.
username
,
feature_group:
'perf_team'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
).
to
eq
(
'name'
=>
'my_feature'
,
'state'
=>
'conditional'
,
'gates'
=>
[
{
'key'
=>
'boolean'
,
'value'
=>
false
},
{
'key'
=>
'groups'
,
'value'
=>
[
'perf_team'
]
},
{
'key'
=>
'actors'
,
'value'
=>
[
"User:
#{
user
.
id
}
"
]
}
])
end
end
end
it
'creates a feature with the given percentage if passed an integer'
do
it
'creates a feature with the given percentage if passed an integer'
do
...
...
spec/support/stub_configuration.rb
View file @
096c2166
...
@@ -39,6 +39,10 @@ module StubConfiguration
...
@@ -39,6 +39,10 @@ module StubConfiguration
allow
(
Gitlab
.
config
.
omniauth
).
to
receive_messages
(
messages
)
allow
(
Gitlab
.
config
.
omniauth
).
to
receive_messages
(
messages
)
end
end
def
stub_performance_bar_setting
(
messages
)
allow
(
Gitlab
.
config
.
performance_bar
).
to
receive_messages
(
messages
)
end
private
private
# Modifies stubbed messages to also stub possible predicate versions
# Modifies stubbed messages to also stub possible predicate versions
...
...
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