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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
ae72d71d
Commit
ae72d71d
authored
Nov 08, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/gitlab@master
parent
759bab05
Changes
71
Hide whitespace changes
Inline
Side-by-side
Showing
71 changed files
with
1270 additions
and
251 deletions
+1270
-251
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+5
-5
app/controllers/concerns/confirm_email_warning.rb
app/controllers/concerns/confirm_email_warning.rb
+5
-2
app/controllers/concerns/uploads_actions.rb
app/controllers/concerns/uploads_actions.rb
+17
-0
app/controllers/projects/environments_controller.rb
app/controllers/projects/environments_controller.rb
+1
-1
app/controllers/projects/error_tracking_controller.rb
app/controllers/projects/error_tracking_controller.rb
+63
-4
app/controllers/uploads_controller.rb
app/controllers/uploads_controller.rb
+1
-1
app/helpers/application_settings_helper.rb
app/helpers/application_settings_helper.rb
+1
-1
app/helpers/projects/error_tracking_helper.rb
app/helpers/projects/error_tracking_helper.rb
+9
-0
app/models/application_setting_implementation.rb
app/models/application_setting_implementation.rb
+3
-2
app/models/error_tracking/project_error_tracking_setting.rb
app/models/error_tracking/project_error_tracking_setting.rb
+20
-0
app/serializers/error_tracking/detailed_error_entity.rb
app/serializers/error_tracking/detailed_error_entity.rb
+27
-0
app/serializers/error_tracking/detailed_error_serializer.rb
app/serializers/error_tracking/detailed_error_serializer.rb
+7
-0
app/serializers/error_tracking/error_event_entity.rb
app/serializers/error_tracking/error_event_entity.rb
+7
-0
app/serializers/error_tracking/error_event_serializer.rb
app/serializers/error_tracking/error_event_serializer.rb
+7
-0
app/services/error_tracking/base_service.rb
app/services/error_tracking/base_service.rb
+66
-0
app/services/error_tracking/issue_details_service.rb
app/services/error_tracking/issue_details_service.rb
+15
-0
app/services/error_tracking/issue_latest_event_service.rb
app/services/error_tracking/issue_latest_event_service.rb
+15
-0
app/services/error_tracking/list_issues_service.rb
app/services/error_tracking/list_issues_service.rb
+7
-39
app/services/error_tracking/list_projects_service.rb
app/services/error_tracking/list_projects_service.rb
+23
-29
app/views/admin/application_settings/_snowplow.html.haml
app/views/admin/application_settings/_snowplow.html.haml
+2
-2
app/views/layouts/nav/sidebar/_project.html.haml
app/views/layouts/nav/sidebar/_project.html.haml
+2
-0
app/views/projects/environments/empty_logs.html.haml
app/views/projects/environments/empty_logs.html.haml
+14
-0
app/views/projects/environments/empty_metrics.html.haml
app/views/projects/environments/empty_metrics.html.haml
+2
-2
app/views/projects/error_tracking/details.html.haml
app/views/projects/error_tracking/details.html.haml
+3
-0
changelogs/unreleased/31222-follow-up-from-adjusts-snowplow-to-use-cookies-for-sessions.yml
...-up-from-adjusts-snowplow-to-use-cookies-for-sessions.yml
+5
-0
changelogs/unreleased/32052-add-pa-start-date-limit.yml
changelogs/unreleased/32052-add-pa-start-date-limit.yml
+5
-0
changelogs/unreleased/32464-backend-sentry-error-details.yml
changelogs/unreleased/32464-backend-sentry-error-details.yml
+5
-0
config/routes/project.rb
config/routes/project.rb
+10
-0
db/migrate/20191004080818_add_productivity_analytics_start_date.rb
...e/20191004080818_add_productivity_analytics_start_date.rb
+11
-0
db/migrate/20191004081520_fill_productivity_analytics_start_date.rb
.../20191004081520_fill_productivity_analytics_start_date.rb
+31
-0
db/migrate/20191028184740_rename_snowplow_site_id_to_snowplow_app_id.rb
...91028184740_rename_snowplow_site_id_to_snowplow_app_id.rb
+17
-0
db/post_migrate/20191029095537_cleanup_application_settings_snowplow_site_id_rename.rb
...7_cleanup_application_settings_snowplow_site_id_rename.rb
+17
-0
db/schema.rb
db/schema.rb
+2
-1
doc/api/settings.md
doc/api/settings.md
+1
-1
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+1
-0
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+5
-2
lib/api/settings.rb
lib/api/settings.rb
+1
-1
lib/gitlab/ci/config/entry/boolean.rb
lib/gitlab/ci/config/entry/boolean.rb
+20
-0
lib/gitlab/ci/config/entry/default.rb
lib/gitlab/ci/config/entry/default.rb
+6
-2
lib/gitlab/ci/config/entry/job.rb
lib/gitlab/ci/config/entry/job.rb
+4
-1
lib/gitlab/error_tracking/detailed_error.rb
lib/gitlab/error_tracking/detailed_error.rb
+31
-0
lib/gitlab/error_tracking/error_event.rb
lib/gitlab/error_tracking/error_event.rb
+11
-0
lib/gitlab/tracking.rb
lib/gitlab/tracking.rb
+2
-2
lib/sentry/client.rb
lib/sentry/client.rb
+97
-14
locale/gitlab.pot
locale/gitlab.pot
+18
-9
spec/controllers/application_controller_spec.rb
spec/controllers/application_controller_spec.rb
+6
-8
spec/controllers/projects/environments_controller_spec.rb
spec/controllers/projects/environments_controller_spec.rb
+2
-2
spec/controllers/projects/error_tracking_controller_spec.rb
spec/controllers/projects/error_tracking_controller_spec.rb
+191
-11
spec/controllers/uploads_controller_spec.rb
spec/controllers/uploads_controller_spec.rb
+12
-12
spec/db/schema_spec.rb
spec/db/schema_spec.rb
+1
-1
spec/factories/error_tracking/detailed_error.rb
spec/factories/error_tracking/detailed_error.rb
+29
-0
spec/factories/error_tracking/error_event.rb
spec/factories/error_tracking/error_event.rb
+18
-0
spec/features/projects/members/member_leaves_project_spec.rb
spec/features/projects/members/member_leaves_project_spec.rb
+1
-1
spec/fixtures/api/schemas/error_tracking/error.json
spec/fixtures/api/schemas/error_tracking/error.json
+17
-3
spec/fixtures/api/schemas/error_tracking/error_detailed.json
spec/fixtures/api/schemas/error_tracking/error_detailed.json
+45
-0
spec/fixtures/api/schemas/error_tracking/error_stack_trace.json
...ixtures/api/schemas/error_tracking/error_stack_trace.json
+14
-0
spec/fixtures/api/schemas/error_tracking/issue_detailed.json
spec/fixtures/api/schemas/error_tracking/issue_detailed.json
+11
-0
spec/fixtures/api/schemas/error_tracking/issue_stack_trace.json
...ixtures/api/schemas/error_tracking/issue_stack_trace.json
+11
-0
spec/helpers/application_settings_helper_spec.rb
spec/helpers/application_settings_helper_spec.rb
+1
-1
spec/lib/gitlab/ci/config/entry/default_spec.rb
spec/lib/gitlab/ci/config/entry/default_spec.rb
+1
-1
spec/lib/gitlab/ci/config/entry/job_spec.rb
spec/lib/gitlab/ci/config/entry/job_spec.rb
+1
-1
spec/lib/gitlab/ci/yaml_processor_spec.rb
spec/lib/gitlab/ci/yaml_processor_spec.rb
+19
-0
spec/lib/gitlab/tracking_spec.rb
spec/lib/gitlab/tracking_spec.rb
+1
-1
spec/migrations/fill_productivity_analytics_start_date_spec.rb
...migrations/fill_productivity_analytics_start_date_spec.rb
+39
-0
spec/requests/api/settings_spec.rb
spec/requests/api/settings_spec.rb
+1
-1
spec/requests/user_avatar_spec.rb
spec/requests/user_avatar_spec.rb
+36
-0
spec/services/error_tracking/issue_details_service_spec.rb
spec/services/error_tracking/issue_details_service_spec.rb
+48
-0
spec/services/error_tracking/issue_latest_event_service_spec.rb
...ervices/error_tracking/issue_latest_event_service_spec.rb
+48
-0
spec/services/error_tracking/list_issues_service_spec.rb
spec/services/error_tracking/list_issues_service_spec.rb
+5
-86
spec/services/error_tracking/list_projects_service_spec.rb
spec/services/error_tracking/list_projects_service_spec.rb
+1
-1
spec/support/shared_examples/services/error_tracking_service_shared_examples.rb
...amples/services/error_tracking_service_shared_examples.rb
+89
-0
No files found.
app/controllers/application_controller.rb
View file @
ae72d71d
...
@@ -20,11 +20,11 @@ class ApplicationController < ActionController::Base
...
@@ -20,11 +20,11 @@ class ApplicationController < ActionController::Base
before_action
:authenticate_user!
,
except:
[
:route_not_found
]
before_action
:authenticate_user!
,
except:
[
:route_not_found
]
before_action
:enforce_terms!
,
if: :should_enforce_terms?
before_action
:enforce_terms!
,
if: :should_enforce_terms?
before_action
:validate_user_service_ticket!
before_action
:validate_user_service_ticket!
before_action
:check_password_expiration
before_action
:check_password_expiration
,
if: :html_request?
before_action
:ldap_security_check
before_action
:ldap_security_check
before_action
:sentry_context
before_action
:sentry_context
before_action
:default_headers
before_action
:default_headers
before_action
:add_gon_variables
,
unless:
[
:peek_request?
,
:json_request?
]
before_action
:add_gon_variables
,
if: :html_request?
before_action
:configure_permitted_parameters
,
if: :devise_controller?
before_action
:configure_permitted_parameters
,
if: :devise_controller?
before_action
:require_email
,
unless: :devise_controller?
before_action
:require_email
,
unless: :devise_controller?
before_action
:active_user_check
,
unless: :devise_controller?
before_action
:active_user_check
,
unless: :devise_controller?
...
@@ -455,8 +455,8 @@ class ApplicationController < ActionController::Base
...
@@ -455,8 +455,8 @@ class ApplicationController < ActionController::Base
response
.
headers
[
'Page-Title'
]
=
URI
.
escape
(
page_title
(
'GitLab'
))
response
.
headers
[
'Page-Title'
]
=
URI
.
escape
(
page_title
(
'GitLab'
))
end
end
def
peek
_request?
def
html
_request?
request
.
path
.
start_with?
(
'/-/peek'
)
request
.
format
.
html?
end
end
def
json_request?
def
json_request?
...
@@ -466,7 +466,7 @@ class ApplicationController < ActionController::Base
...
@@ -466,7 +466,7 @@ class ApplicationController < ActionController::Base
def
should_enforce_terms?
def
should_enforce_terms?
return
false
unless
Gitlab
::
CurrentSettings
.
current_application_settings
.
enforce_terms
return
false
unless
Gitlab
::
CurrentSettings
.
current_application_settings
.
enforce_terms
!
(
peek_request?
||
devise_controller?
)
html_request?
&&
!
devise_controller?
end
end
def
set_usage_stats_consent_flag
def
set_usage_stats_consent_flag
...
...
app/controllers/concerns/confirm_email_warning.rb
View file @
ae72d71d
...
@@ -4,15 +4,18 @@ module ConfirmEmailWarning
...
@@ -4,15 +4,18 @@ module ConfirmEmailWarning
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
included
do
included
do
before_action
:set_confirm_warning
,
if:
->
{
Feature
.
enabled?
(
:soft_email_confirmation
)
}
before_action
:set_confirm_warning
,
if:
:show_confirm_warning?
end
end
protected
protected
def
show_confirm_warning?
html_request?
&&
request
.
get?
&&
Feature
.
enabled?
(
:soft_email_confirmation
)
end
def
set_confirm_warning
def
set_confirm_warning
return
unless
current_user
return
unless
current_user
return
if
current_user
.
confirmed?
return
if
current_user
.
confirmed?
return
if
peek_request?
||
json_request?
||
!
request
.
get?
email
=
current_user
.
unconfirmed_email
||
current_user
.
email
email
=
current_user
.
unconfirmed_email
||
current_user
.
email
...
...
app/controllers/concerns/uploads_actions.rb
View file @
ae72d71d
# frozen_string_literal: true
# frozen_string_literal: true
module
UploadsActions
module
UploadsActions
extend
ActiveSupport
::
Concern
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
include
SendFileUpload
include
SendFileUpload
UPLOAD_MOUNTS
=
%w(avatar attachment file logo header_logo favicon)
.
freeze
UPLOAD_MOUNTS
=
%w(avatar attachment file logo header_logo favicon)
.
freeze
included
do
prepend_before_action
:set_request_format_from_path_extension
end
def
create
def
create
uploader
=
UploadService
.
new
(
model
,
params
[
:file
],
uploader_class
).
execute
uploader
=
UploadService
.
new
(
model
,
params
[
:file
],
uploader_class
).
execute
...
@@ -64,6 +69,18 @@ module UploadsActions
...
@@ -64,6 +69,18 @@ module UploadsActions
private
private
# From ActionDispatch::Http::MimeNegotiation. We have an initializer that
# monkey-patches this method out (so that repository paths don't guess a
# format based on extension), but we do want this behaviour when serving
# uploads.
def
set_request_format_from_path_extension
path
=
request
.
headers
[
'action_dispatch.original_path'
]
||
request
.
headers
[
'PATH_INFO'
]
if
match
=
path
&
.
match
(
/\.(\w+)\z/
)
request
.
format
=
match
.
captures
.
first
end
end
def
uploader_class
def
uploader_class
raise
NotImplementedError
raise
NotImplementedError
end
end
...
...
app/controllers/projects/environments_controller.rb
View file @
ae72d71d
...
@@ -133,7 +133,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
...
@@ -133,7 +133,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
if
environment
if
environment
redirect_to
environment_metrics_path
(
environment
)
redirect_to
environment_metrics_path
(
environment
)
else
else
render
:empty
render
:empty
_metrics
end
end
end
end
...
...
app/controllers/projects/error_tracking_controller.rb
View file @
ae72d71d
...
@@ -15,6 +15,23 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
...
@@ -15,6 +15,23 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
end
end
end
end
def
details
respond_to
do
|
format
|
format
.
html
format
.
json
do
render_issue_detail_json
end
end
end
def
stack_trace
respond_to
do
|
format
|
format
.
json
do
render_issue_stack_trace_json
end
end
end
def
list_projects
def
list_projects
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
json
do
format
.
json
do
...
@@ -29,10 +46,7 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
...
@@ -29,10 +46,7 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
service
=
ErrorTracking
::
ListIssuesService
.
new
(
project
,
current_user
)
service
=
ErrorTracking
::
ListIssuesService
.
new
(
project
,
current_user
)
result
=
service
.
execute
result
=
service
.
execute
unless
result
[
:status
]
==
:success
return
if
handle_errors
(
result
)
return
render
json:
{
message:
result
[
:message
]
},
status:
result
[
:http_status
]
||
:bad_request
end
render
json:
{
render
json:
{
errors:
serialize_errors
(
result
[
:issues
]),
errors:
serialize_errors
(
result
[
:issues
]),
...
@@ -40,6 +54,28 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
...
@@ -40,6 +54,28 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
}
}
end
end
def
render_issue_detail_json
service
=
ErrorTracking
::
IssueDetailsService
.
new
(
project
,
current_user
,
issue_details_params
)
result
=
service
.
execute
return
if
handle_errors
(
result
)
render
json:
{
error:
serialize_detailed_error
(
result
[
:issue
])
}
end
def
render_issue_stack_trace_json
service
=
ErrorTracking
::
IssueLatestEventService
.
new
(
project
,
current_user
,
issue_details_params
)
result
=
service
.
execute
return
if
handle_errors
(
result
)
render
json:
{
error:
serialize_error_event
(
result
[
:latest_event
])
}
end
def
render_project_list_json
def
render_project_list_json
service
=
ErrorTracking
::
ListProjectsService
.
new
(
service
=
ErrorTracking
::
ListProjectsService
.
new
(
project
,
project
,
...
@@ -62,10 +98,21 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
...
@@ -62,10 +98,21 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
end
end
end
end
def
handle_errors
(
result
)
unless
result
[
:status
]
==
:success
render
json:
{
message:
result
[
:message
]
},
status:
result
[
:http_status
]
||
:bad_request
end
end
def
list_projects_params
def
list_projects_params
params
.
require
(
:error_tracking_setting
).
permit
([
:api_host
,
:token
])
params
.
require
(
:error_tracking_setting
).
permit
([
:api_host
,
:token
])
end
end
def
issue_details_params
params
.
permit
(
:issue_id
)
end
def
set_polling_interval
def
set_polling_interval
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
POLLING_INTERVAL
)
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
POLLING_INTERVAL
)
end
end
...
@@ -76,6 +123,18 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
...
@@ -76,6 +123,18 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
.
represent
(
errors
)
.
represent
(
errors
)
end
end
def
serialize_detailed_error
(
error
)
ErrorTracking
::
DetailedErrorSerializer
.
new
(
project:
project
,
user:
current_user
)
.
represent
(
error
)
end
def
serialize_error_event
(
event
)
ErrorTracking
::
ErrorEventSerializer
.
new
(
project:
project
,
user:
current_user
)
.
represent
(
event
)
end
def
serialize_projects
(
projects
)
def
serialize_projects
(
projects
)
ErrorTracking
::
ProjectSerializer
ErrorTracking
::
ProjectSerializer
.
new
(
project:
project
,
user:
current_user
)
.
new
(
project:
project
,
user:
current_user
)
...
...
app/controllers/uploads_controller.rb
View file @
ae72d71d
...
@@ -20,7 +20,7 @@ class UploadsController < ApplicationController
...
@@ -20,7 +20,7 @@ class UploadsController < ApplicationController
skip_before_action
:authenticate_user!
skip_before_action
:authenticate_user!
before_action
:upload_mount_satisfied?
before_action
:upload_mount_satisfied?
before_action
:
find_
model
before_action
:model
before_action
:authorize_access!
,
only:
[
:show
]
before_action
:authorize_access!
,
only:
[
:show
]
before_action
:authorize_create_access!
,
only:
[
:create
,
:authorize
]
before_action
:authorize_create_access!
,
only:
[
:create
,
:authorize
]
before_action
:verify_workhorse_api!
,
only:
[
:authorize
]
before_action
:verify_workhorse_api!
,
only:
[
:authorize
]
...
...
app/helpers/application_settings_helper.rb
View file @
ae72d71d
...
@@ -293,7 +293,7 @@ module ApplicationSettingsHelper
...
@@ -293,7 +293,7 @@ module ApplicationSettingsHelper
:snowplow_collector_hostname
,
:snowplow_collector_hostname
,
:snowplow_cookie_domain
,
:snowplow_cookie_domain
,
:snowplow_enabled
,
:snowplow_enabled
,
:snowplow_
site
_id
,
:snowplow_
app
_id
,
:snowplow_iglu_registry_url
,
:snowplow_iglu_registry_url
,
:push_event_hooks_limit
,
:push_event_hooks_limit
,
:push_event_activities_limit
,
:push_event_activities_limit
,
...
...
app/helpers/projects/error_tracking_helper.rb
View file @
ae72d71d
...
@@ -13,4 +13,13 @@ module Projects::ErrorTrackingHelper
...
@@ -13,4 +13,13 @@ module Projects::ErrorTrackingHelper
'illustration-path'
=>
image_path
(
'illustrations/cluster_popover.svg'
)
'illustration-path'
=>
image_path
(
'illustrations/cluster_popover.svg'
)
}
}
end
end
def
error_details_data
(
project
,
issue
)
opts
=
[
project
,
issue
,
{
format: :json
}]
{
'issue-details-path'
=>
details_namespace_project_error_tracking_index_path
(
*
opts
),
'issue-stack-trace-path'
=>
stack_trace_namespace_project_error_tracking_index_path
(
*
opts
)
}
end
end
end
app/models/application_setting_implementation.rb
View file @
ae72d71d
...
@@ -132,11 +132,12 @@ module ApplicationSettingImplementation
...
@@ -132,11 +132,12 @@ module ApplicationSettingImplementation
snowplow_collector_hostname:
nil
,
snowplow_collector_hostname:
nil
,
snowplow_cookie_domain:
nil
,
snowplow_cookie_domain:
nil
,
snowplow_enabled:
false
,
snowplow_enabled:
false
,
snowplow_
site
_id:
nil
,
snowplow_
app
_id:
nil
,
snowplow_iglu_registry_url:
nil
,
snowplow_iglu_registry_url:
nil
,
custom_http_clone_url_root:
nil
,
custom_http_clone_url_root:
nil
,
pendo_enabled:
false
,
pendo_enabled:
false
,
pendo_url:
nil
pendo_url:
nil
,
productivity_analytics_start_date:
Time
.
now
}
}
end
end
...
...
app/models/error_tracking/project_error_tracking_setting.rb
View file @
ae72d71d
...
@@ -87,10 +87,30 @@ module ErrorTracking
...
@@ -87,10 +87,30 @@ module ErrorTracking
{
projects:
sentry_client
.
list_projects
}
{
projects:
sentry_client
.
list_projects
}
end
end
def
issue_details
(
opts
=
{})
with_reactive_cache
(
'issue_details'
,
opts
.
stringify_keys
)
do
|
result
|
result
end
end
def
issue_latest_event
(
opts
=
{})
with_reactive_cache
(
'issue_latest_event'
,
opts
.
stringify_keys
)
do
|
result
|
result
end
end
def
calculate_reactive_cache
(
request
,
opts
)
def
calculate_reactive_cache
(
request
,
opts
)
case
request
case
request
when
'list_issues'
when
'list_issues'
{
issues:
sentry_client
.
list_issues
(
**
opts
.
symbolize_keys
)
}
{
issues:
sentry_client
.
list_issues
(
**
opts
.
symbolize_keys
)
}
when
'issue_details'
{
issue:
sentry_client
.
issue_details
(
**
opts
.
symbolize_keys
)
}
when
'issue_latest_event'
{
latest_event:
sentry_client
.
issue_latest_event
(
**
opts
.
symbolize_keys
)
}
end
end
rescue
Sentry
::
Client
::
Error
=>
e
rescue
Sentry
::
Client
::
Error
=>
e
{
error:
e
.
message
,
error_type:
SENTRY_API_ERROR_TYPE_NON_20X_RESPONSE
}
{
error:
e
.
message
,
error_type:
SENTRY_API_ERROR_TYPE_NON_20X_RESPONSE
}
...
...
app/serializers/error_tracking/detailed_error_entity.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
DetailedErrorEntity
<
Grape
::
Entity
expose
:count
,
:culprit
,
:external_base_url
,
:external_url
,
:first_release_last_commit
,
:first_release_short_version
,
:first_seen
,
:frequency
,
:id
,
:last_release_last_commit
,
:last_release_short_version
,
:last_seen
,
:message
,
:project_id
,
:project_name
,
:project_slug
,
:short_id
,
:status
,
:title
,
:type
,
:user_count
end
end
app/serializers/error_tracking/detailed_error_serializer.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
DetailedErrorSerializer
<
BaseSerializer
entity
DetailedErrorEntity
end
end
app/serializers/error_tracking/error_event_entity.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
ErrorEventEntity
<
Grape
::
Entity
expose
:issue_id
,
:date_received
,
:stack_trace_entries
end
end
app/serializers/error_tracking/error_event_serializer.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
ErrorEventSerializer
<
BaseSerializer
entity
ErrorEventEntity
end
end
app/services/error_tracking/base_service.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
BaseService
<
::
BaseService
def
execute
unauthorized
=
check_permissions
return
unauthorized
if
unauthorized
begin
response
=
fetch
rescue
Sentry
::
Client
::
Error
=>
e
return
error
(
e
.
message
,
:bad_request
)
rescue
Sentry
::
Client
::
MissingKeysError
=>
e
return
error
(
e
.
message
,
:internal_server_error
)
end
errors
=
parse_errors
(
response
)
return
errors
if
errors
success
(
parse_response
(
response
))
end
private
def
fetch
raise
NotImplementedError
,
"
#{
self
.
class
}
does not implement
#{
__method__
}
"
end
def
parse_response
(
response
)
raise
NotImplementedError
,
"
#{
self
.
class
}
does not implement
#{
__method__
}
"
end
def
check_permissions
return
error
(
'Error Tracking is not enabled'
)
unless
enabled?
return
error
(
'Access denied'
,
:unauthorized
)
unless
can_read?
end
def
parse_errors
(
response
)
return
error
(
'Not ready. Try again later'
,
:no_content
)
unless
response
return
error
(
response
[
:error
],
http_status_for
(
response
[
:error_type
]))
if
response
[
:error
].
present?
end
def
http_status_for
(
error_type
)
case
error_type
when
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_MISSING_KEYS
:internal_server_error
else
:bad_request
end
end
def
project_error_tracking_setting
project
.
error_tracking_setting
end
def
enabled?
project_error_tracking_setting
&
.
enabled?
end
def
can_read?
can?
(
current_user
,
:read_sentry_issue
,
project
)
end
end
end
app/services/error_tracking/issue_details_service.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
IssueDetailsService
<
ErrorTracking
::
BaseService
private
def
fetch
project_error_tracking_setting
.
issue_details
(
issue_id:
params
[
:issue_id
])
end
def
parse_response
(
response
)
{
issue:
response
[
:issue
]
}
end
end
end
app/services/error_tracking/issue_latest_event_service.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
ErrorTracking
class
IssueLatestEventService
<
ErrorTracking
::
BaseService
private
def
fetch
project_error_tracking_setting
.
issue_latest_event
(
issue_id:
params
[
:issue_id
])
end
def
parse_response
(
response
)
{
latest_event:
response
[
:latest_event
]
}
end
end
end
app/services/error_tracking/list_issues_service.rb
View file @
ae72d71d
# frozen_string_literal: true
# frozen_string_literal: true
module
ErrorTracking
module
ErrorTracking
class
ListIssuesService
<
::
BaseService
class
ListIssuesService
<
ErrorTracking
::
BaseService
DEFAULT_ISSUE_STATUS
=
'unresolved'
DEFAULT_ISSUE_STATUS
=
'unresolved'
DEFAULT_LIMIT
=
20
DEFAULT_LIMIT
=
20
def
execute
private
return
error
(
'Error Tracking is not enabled'
)
unless
enabled?
return
error
(
'Access denied'
,
:unauthorized
)
unless
can_read?
result
=
project_error_tracking_setting
.
list_sentry_issues
(
issue_status:
issue_status
,
limit:
limit
)
# our results are not yet ready
unless
result
return
error
(
'Not ready. Try again later'
,
:no_content
)
end
if
result
[
:error
].
present?
def
fetch
return
error
(
result
[
:error
],
http_status_from_error_type
(
result
[
:error_type
])
)
project_error_tracking_setting
.
list_sentry_issues
(
issue_status:
issue_status
,
limit:
limit
)
end
end
success
(
issues:
result
[
:issues
])
def
parse_response
(
response
)
{
issues:
response
[
:issues
]
}
end
end
def
external_url
def
external_url
project_error_tracking_setting
&
.
sentry_external_url
project_error_tracking_setting
&
.
sentry_external_url
end
end
private
def
http_status_from_error_type
(
error_type
)
case
error_type
when
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_MISSING_KEYS
:internal_server_error
else
:bad_request
end
end
def
project_error_tracking_setting
project
.
error_tracking_setting
end
def
issue_status
def
issue_status
params
[
:issue_status
]
||
DEFAULT_ISSUE_STATUS
params
[
:issue_status
]
||
DEFAULT_ISSUE_STATUS
end
end
...
@@ -50,13 +26,5 @@ module ErrorTracking
...
@@ -50,13 +26,5 @@ module ErrorTracking
def
limit
def
limit
params
[
:limit
]
||
DEFAULT_LIMIT
params
[
:limit
]
||
DEFAULT_LIMIT
end
end
def
enabled?
project_error_tracking_setting
&
.
enabled?
end
def
can_read?
can?
(
current_user
,
:read_sentry_issue
,
project
)
end
end
end
end
end
app/services/error_tracking/list_projects_service.rb
View file @
ae72d71d
# frozen_string_literal: true
# frozen_string_literal: true
module
ErrorTracking
module
ErrorTracking
class
ListProjectsService
<
::
BaseService
class
ListProjectsService
<
ErrorTracking
::
BaseService
def
execute
def
execute
return
error
(
'access denied'
)
unless
can_read?
unless
project_error_tracking_setting
.
valid?
return
error
(
project_error_tracking_setting
.
errors
.
full_messages
.
join
(
', '
),
:bad_request
)
setting
=
project_error_tracking_setting
unless
setting
.
valid?
return
error
(
setting
.
errors
.
full_messages
.
join
(
', '
),
:bad_request
)
end
end
begin
super
result
=
setting
.
list_sentry_projects
rescue
Sentry
::
Client
::
Error
=>
e
return
error
(
e
.
message
,
:bad_request
)
rescue
Sentry
::
Client
::
MissingKeysError
=>
e
return
error
(
e
.
message
,
:internal_server_error
)
end
success
(
projects:
result
[
:projects
])
end
end
private
private
def
project_error_tracking_setting
def
fetch
(
project
.
error_tracking_setting
||
project
.
build_error_tracking_setting
).
tap
do
|
setting
|
project_error_tracking_setting
.
list_sentry_projects
setting
.
api_url
=
ErrorTracking
::
ProjectErrorTrackingSetting
.
build_api_url_from
(
end
api_host:
params
[
:api_host
],
organization_slug:
'org'
,
def
parse_response
(
response
)
project_slug:
'proj'
{
projects:
response
[
:projects
]
}
)
setting
.
token
=
token
(
setting
)
setting
.
enabled
=
true
end
end
end
def
can_read?
def
project_error_tracking_setting
can?
(
current_user
,
:read_sentry_issue
,
project
)
@project_error_tracking_setting
||=
begin
(
super
||
project
.
build_error_tracking_setting
).
tap
do
|
setting
|
setting
.
api_url
=
ErrorTracking
::
ProjectErrorTrackingSetting
.
build_api_url_from
(
api_host:
params
[
:api_host
],
organization_slug:
'org'
,
project_slug:
'proj'
)
setting
.
token
=
token
(
setting
)
setting
.
enabled
=
true
end
end
end
end
def
token
(
setting
)
def
token
(
setting
)
...
...
app/views/admin/application_settings/_snowplow.html.haml
View file @
ae72d71d
...
@@ -21,8 +21,8 @@
...
@@ -21,8 +21,8 @@
=
f
.
label
:snowplow_collector_hostname
,
_
(
'Collector hostname'
),
class:
'label-light'
=
f
.
label
:snowplow_collector_hostname
,
_
(
'Collector hostname'
),
class:
'label-light'
=
f
.
text_field
:snowplow_collector_hostname
,
class:
'form-control'
,
placeholder:
'snowplow.example.com'
=
f
.
text_field
:snowplow_collector_hostname
,
class:
'form-control'
,
placeholder:
'snowplow.example.com'
.form-group
.form-group
=
f
.
label
:snowplow_
site_id
,
_
(
'Site
ID'
),
class:
'label-light'
=
f
.
label
:snowplow_
app_id
,
_
(
'App
ID'
),
class:
'label-light'
=
f
.
text_field
:snowplow_
site
_id
,
class:
'form-control'
=
f
.
text_field
:snowplow_
app
_id
,
class:
'form-control'
.form-group
.form-group
=
f
.
label
:snowplow_cookie_domain
,
_
(
'Cookie domain'
),
class:
'label-light'
=
f
.
label
:snowplow_cookie_domain
,
_
(
'Cookie domain'
),
class:
'label-light'
=
f
.
text_field
:snowplow_cookie_domain
,
class:
'form-control'
=
f
.
text_field
:snowplow_cookie_domain
,
class:
'form-control'
...
...
app/views/layouts/nav/sidebar/_project.html.haml
View file @
ae72d71d
...
@@ -247,6 +247,8 @@
...
@@ -247,6 +247,8 @@
%span
%span
=
_
(
'Serverless'
)
=
_
(
'Serverless'
)
=
render_if_exists
'layouts/nav/sidebar/pod_logs_link'
# EE-specific
-
if
project_nav_tab?
:clusters
-
if
project_nav_tab?
:clusters
-
show_cluster_hint
=
show_gke_cluster_integration_callout?
(
@project
)
-
show_cluster_hint
=
show_gke_cluster_integration_callout?
(
@project
)
=
nav_link
(
controller:
[
:clusters
,
:user
,
:gcp
])
do
=
nav_link
(
controller:
[
:clusters
,
:user
,
:gcp
])
do
...
...
app/views/projects/environments/empty_logs.html.haml
0 → 100644
View file @
ae72d71d
-
page_title
_
(
'Pod logs'
)
.row.empty-state
.col-sm-12
.svg-content
=
image_tag
'illustrations/operations_log_pods_empty.svg'
.col-12
.text-content
%h4
.text-center
=
s_
(
'Environments|No deployed environments'
)
%p
.state-description.text-center
=
s_
(
'Logs|To see the pod logs, deploy your code to an environment.'
)
.text-center
=
link_to
s_
(
'Environments|Learn about environments'
),
help_page_path
(
'ci/environments'
),
class:
'btn btn-success'
app/views/projects/environments/empty.html.haml
→
app/views/projects/environments/empty
_metrics
.html.haml
View file @
ae72d71d
...
@@ -7,8 +7,8 @@
...
@@ -7,8 +7,8 @@
.col-12
.col-12
.text-content
.text-content
%h4
.text-center
%h4
.text-center
=
s_
(
'
Metric
s|No deployed environments'
)
=
s_
(
'
Environment
s|No deployed environments'
)
%p
.state-description
%p
.state-description
=
s_
(
'Metrics|Check out the CI/CD documentation on deploying to an environment'
)
=
s_
(
'Metrics|Check out the CI/CD documentation on deploying to an environment'
)
.text-center
.text-center
=
link_to
s_
(
"
Metric
s|Learn about environments"
),
help_page_path
(
'ci/environments'
),
class:
'btn btn-success'
=
link_to
s_
(
"
Environment
s|Learn about environments"
),
help_page_path
(
'ci/environments'
),
class:
'btn btn-success'
app/views/projects/error_tracking/details.html.haml
0 → 100644
View file @
ae72d71d
-
page_title
_
(
'Error Details'
)
#js-error_tracking
{
data:
error_details_data
(
@current_user
,
@project
)
}
changelogs/unreleased/31222-follow-up-from-adjusts-snowplow-to-use-cookies-for-sessions.yml
0 → 100644
View file @
ae72d71d
---
title
:
Rename snowplow_site_id to snowplow_app_id in application_settings table
merge_request
:
19252
author
:
type
:
other
changelogs/unreleased/32052-add-pa-start-date-limit.yml
0 → 100644
View file @
ae72d71d
---
title
:
Add productivity analytics merge date filtering limit
merge_request
:
32052
author
:
type
:
fixed
changelogs/unreleased/32464-backend-sentry-error-details.yml
0 → 100644
View file @
ae72d71d
---
title
:
API for stack trace & detail view of Sentry error in GitLab
merge_request
:
19137
author
:
type
:
added
config/routes/project.rb
View file @
ae72d71d
...
@@ -441,6 +441,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
...
@@ -441,6 +441,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get
:metrics
,
action: :metrics_redirect
get
:metrics
,
action: :metrics_redirect
get
:folder
,
path:
'folders/*id'
,
constraints:
{
format:
/(html|json)/
}
get
:folder
,
path:
'folders/*id'
,
constraints:
{
format:
/(html|json)/
}
get
:search
get
:search
Gitlab
.
ee
do
get
:logs
,
action: :logs_redirect
end
end
end
resources
:deployments
,
only:
[
:index
]
do
resources
:deployments
,
only:
[
:index
]
do
...
@@ -613,6 +617,12 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
...
@@ -613,6 +617,12 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources
:error_tracking
,
only:
[
:index
],
controller: :error_tracking
do
resources
:error_tracking
,
only:
[
:index
],
controller: :error_tracking
do
collection
do
collection
do
get
':issue_id/details'
,
to:
'error_tracking#details'
,
as:
'details'
get
':issue_id/stack_trace'
,
to:
'error_tracking#stack_trace'
,
as:
'stack_trace'
post
:list_projects
post
:list_projects
end
end
end
end
...
...
db/migrate/20191004080818_add_productivity_analytics_start_date.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
class
AddProductivityAnalyticsStartDate
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:application_settings
,
:productivity_analytics_start_date
,
:datetime_with_timezone
end
end
db/migrate/20191004081520_fill_productivity_analytics_start_date.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
# Expected migration duration: 1 minute
class
FillProductivityAnalyticsStartDate
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
add_concurrent_index
:merge_request_metrics
,
:merged_at
,
where:
"merged_at > '2019-09-01' AND commits_count IS NOT NULL"
,
name:
'fill_productivity_analytics_start_date_tmp_index'
execute
(
<<
SQL
UPDATE application_settings
SET productivity_analytics_start_date = COALESCE((SELECT MIN(merged_at) FROM merge_request_metrics
WHERE merged_at > '2019-09-01' AND commits_count IS NOT NULL), NOW())
SQL
)
remove_concurrent_index
:merge_request_metrics
,
:merged_at
,
name:
'fill_productivity_analytics_start_date_tmp_index'
end
def
down
execute
(
'UPDATE application_settings SET productivity_analytics_start_date = NULL'
)
end
end
db/migrate/20191028184740_rename_snowplow_site_id_to_snowplow_app_id.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
class
RenameSnowplowSiteIdToSnowplowAppId
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
rename_column_concurrently
:application_settings
,
:snowplow_site_id
,
:snowplow_app_id
end
def
down
undo_rename_column_concurrently
:application_settings
,
:snowplow_site_id
,
:snowplow_app_id
end
end
db/post_migrate/20191029095537_cleanup_application_settings_snowplow_site_id_rename.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
class
CleanupApplicationSettingsSnowplowSiteIdRename
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
cleanup_concurrent_column_rename
:application_settings
,
:snowplow_site_id
,
:snowplow_app_id
end
def
down
undo_cleanup_concurrent_column_rename
:application_settings
,
:snowplow_site_id
,
:snowplow_app_id
end
end
db/schema.rb
View file @
ae72d71d
...
@@ -287,7 +287,6 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do
...
@@ -287,7 +287,6 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do
t
.
boolean
"hide_third_party_offers"
,
default:
false
,
null:
false
t
.
boolean
"hide_third_party_offers"
,
default:
false
,
null:
false
t
.
boolean
"snowplow_enabled"
,
default:
false
,
null:
false
t
.
boolean
"snowplow_enabled"
,
default:
false
,
null:
false
t
.
string
"snowplow_collector_hostname"
t
.
string
"snowplow_collector_hostname"
t
.
string
"snowplow_site_id"
t
.
string
"snowplow_cookie_domain"
t
.
string
"snowplow_cookie_domain"
t
.
boolean
"instance_statistics_visibility_private"
,
default:
false
,
null:
false
t
.
boolean
"instance_statistics_visibility_private"
,
default:
false
,
null:
false
t
.
boolean
"web_ide_clientside_preview_enabled"
,
default:
false
,
null:
false
t
.
boolean
"web_ide_clientside_preview_enabled"
,
default:
false
,
null:
false
...
@@ -350,6 +349,8 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do
...
@@ -350,6 +349,8 @@ ActiveRecord::Schema.define(version: 2019_11_05_094625) do
t
.
string
"eks_access_key_id"
,
limit:
128
t
.
string
"eks_access_key_id"
,
limit:
128
t
.
string
"encrypted_eks_secret_access_key_iv"
,
limit:
255
t
.
string
"encrypted_eks_secret_access_key_iv"
,
limit:
255
t
.
text
"encrypted_eks_secret_access_key"
t
.
text
"encrypted_eks_secret_access_key"
t
.
string
"snowplow_app_id"
t
.
datetime_with_timezone
"productivity_analytics_start_date"
t
.
index
[
"custom_project_templates_group_id"
],
name:
"index_application_settings_on_custom_project_templates_group_id"
t
.
index
[
"custom_project_templates_group_id"
],
name:
"index_application_settings_on_custom_project_templates_group_id"
t
.
index
[
"file_template_project_id"
],
name:
"index_application_settings_on_file_template_project_id"
t
.
index
[
"file_template_project_id"
],
name:
"index_application_settings_on_file_template_project_id"
t
.
index
[
"instance_administration_project_id"
],
name:
"index_applicationsettings_on_instance_administration_project_id"
t
.
index
[
"instance_administration_project_id"
],
name:
"index_applicationsettings_on_instance_administration_project_id"
...
...
doc/api/settings.md
View file @
ae72d71d
...
@@ -319,7 +319,7 @@ are listed in the descriptions of the relevant settings.
...
@@ -319,7 +319,7 @@ are listed in the descriptions of the relevant settings.
|
`snowplow_collector_hostname`
| string | required by:
`snowplow_enabled`
| The Snowplow collector hostname. (e.g.
`snowplow.trx.gitlab.net`
) |
|
`snowplow_collector_hostname`
| string | required by:
`snowplow_enabled`
| The Snowplow collector hostname. (e.g.
`snowplow.trx.gitlab.net`
) |
|
`snowplow_cookie_domain`
| string | no | The Snowplow cookie domain. (e.g.
`.gitlab.com`
) |
|
`snowplow_cookie_domain`
| string | no | The Snowplow cookie domain. (e.g.
`.gitlab.com`
) |
|
`snowplow_enabled`
| boolean | no | Enable snowplow tracking. |
|
`snowplow_enabled`
| boolean | no | Enable snowplow tracking. |
|
`snowplow_
site_id`
| string | no | The Snowplow site name / application id. (e.g.
`gitlab`
) |
|
`snowplow_
app_id`
| string | no | The Snowplow site name / application id. (e.g.
`gitlab`
) |
|
`snowplow_iglu_registry_url`
| string | no | The Snowplow base Iglu Schema Registry URL to use for custom context and self describing events'|
|
`snowplow_iglu_registry_url`
| string | no | The Snowplow base Iglu Schema Registry URL to use for custom context and self describing events'|
|
`pendo_url`
| string | required by:
`pendo_enabled`
| The Pendo endpoint url with js snippet. (e.g.
`https://cdn.pendo.io/agent/static/your-api-key/pendo.js`
) |
|
`pendo_url`
| string | required by:
`pendo_enabled`
| The Pendo endpoint url with js snippet. (e.g.
`https://cdn.pendo.io/agent/static/your-api-key/pendo.js`
) |
|
`pendo_enabled`
| boolean | no | Enable pendo tracking. |
|
`pendo_enabled`
| boolean | no | Enable pendo tracking. |
...
...
doc/ci/yaml/README.md
View file @
ae72d71d
...
@@ -135,6 +135,7 @@ The following job parameters can be defined inside a `default:` block:
...
@@ -135,6 +135,7 @@ The following job parameters can be defined inside a `default:` block:
-
[
`before_script`
](
#before_script-and-after_script
)
-
[
`before_script`
](
#before_script-and-after_script
)
-
[
`after_script`
](
#before_script-and-after_script
)
-
[
`after_script`
](
#before_script-and-after_script
)
-
[
`cache`
](
#cache
)
-
[
`cache`
](
#cache
)
-
[
`interruptible`
](
#interruptible
)
In the following example, the
`ruby:2.5`
image is set as the default for all
In the following example, the
`ruby:2.5`
image is set as the default for all
jobs except the
`rspec 2.6`
job, which uses the
`ruby:2.6`
image:
jobs except the
`rspec 2.6`
job, which uses the
`ruby:2.6`
image:
...
...
lib/api/merge_requests.rb
View file @
ae72d71d
...
@@ -296,9 +296,12 @@ module API
...
@@ -296,9 +296,12 @@ module API
end
end
get
':id/merge_requests/:merge_request_iid/commits'
do
get
':id/merge_requests/:merge_request_iid/commits'
do
merge_request
=
find_merge_request_with_access
(
params
[
:merge_request_iid
])
merge_request
=
find_merge_request_with_access
(
params
[
:merge_request_iid
])
commits
=
::
Kaminari
.
paginate_array
(
merge_request
.
commits
)
present
paginate
(
commits
),
with:
Entities
::
Commit
commits
=
paginate
(
merge_request
.
merge_request_diff
.
merge_request_diff_commits
)
.
map
{
|
commit
|
Commit
.
from_hash
(
commit
.
to_hash
,
merge_request
.
project
)
}
present
commits
,
with:
Entities
::
Commit
end
end
desc
'Show the merge request changes'
do
desc
'Show the merge request changes'
do
...
...
lib/api/settings.rb
View file @
ae72d71d
...
@@ -145,7 +145,7 @@ module API
...
@@ -145,7 +145,7 @@ module API
given
snowplow_enabled:
->
(
val
)
{
val
}
do
given
snowplow_enabled:
->
(
val
)
{
val
}
do
requires
:snowplow_collector_hostname
,
type:
String
,
desc:
'The Snowplow collector hostname'
requires
:snowplow_collector_hostname
,
type:
String
,
desc:
'The Snowplow collector hostname'
optional
:snowplow_cookie_domain
,
type:
String
,
desc:
'The Snowplow cookie domain'
optional
:snowplow_cookie_domain
,
type:
String
,
desc:
'The Snowplow cookie domain'
optional
:snowplow_
site_id
,
type:
String
,
desc:
'The Snowplow site name / application ic
'
optional
:snowplow_
app_id
,
type:
String
,
desc:
'The Snowplow site name / application id
'
end
end
optional
:pendo_enabled
,
type:
Grape
::
API
::
Boolean
,
desc:
'Enable Pendo tracking'
optional
:pendo_enabled
,
type:
Grape
::
API
::
Boolean
,
desc:
'Enable Pendo tracking'
given
pendo_enabled:
->
(
val
)
{
val
}
do
given
pendo_enabled:
->
(
val
)
{
val
}
do
...
...
lib/gitlab/ci/config/entry/boolean.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
Gitlab
module
Ci
class
Config
module
Entry
##
# Entry that represents the interrutible value.
#
class
Boolean
<
::
Gitlab
::
Config
::
Entry
::
Node
include
::
Gitlab
::
Config
::
Entry
::
Validatable
validations
do
validates
:config
,
boolean:
true
end
end
end
end
end
end
lib/gitlab/ci/config/entry/default.rb
View file @
ae72d71d
...
@@ -14,7 +14,7 @@ module Gitlab
...
@@ -14,7 +14,7 @@ module Gitlab
include
::
Gitlab
::
Config
::
Entry
::
Inheritable
include
::
Gitlab
::
Config
::
Entry
::
Inheritable
ALLOWED_KEYS
=
%i[before_script image services
ALLOWED_KEYS
=
%i[before_script image services
after_script cache]
.
freeze
after_script cache
interruptible
]
.
freeze
validations
do
validations
do
validates
:config
,
allowed_keys:
ALLOWED_KEYS
validates
:config
,
allowed_keys:
ALLOWED_KEYS
...
@@ -40,7 +40,11 @@ module Gitlab
...
@@ -40,7 +40,11 @@ module Gitlab
description:
'Configure caching between build jobs.'
,
description:
'Configure caching between build jobs.'
,
inherit:
true
inherit:
true
helpers
:before_script
,
:image
,
:services
,
:after_script
,
:cache
entry
:interruptible
,
Entry
::
Boolean
,
description:
'Set jobs interruptible default value.'
,
inherit:
false
helpers
:before_script
,
:image
,
:services
,
:after_script
,
:cache
,
:interruptible
private
private
...
...
lib/gitlab/ci/config/entry/job.rb
View file @
ae72d71d
...
@@ -38,7 +38,6 @@ module Gitlab
...
@@ -38,7 +38,6 @@ module Gitlab
with_options
allow_nil:
true
do
with_options
allow_nil:
true
do
validates
:tags
,
array_of_strings:
true
validates
:tags
,
array_of_strings:
true
validates
:allow_failure
,
boolean:
true
validates
:allow_failure
,
boolean:
true
validates
:interruptible
,
boolean:
true
validates
:parallel
,
numericality:
{
only_integer:
true
,
validates
:parallel
,
numericality:
{
only_integer:
true
,
greater_than_or_equal_to:
2
,
greater_than_or_equal_to:
2
,
less_than_or_equal_to:
50
}
less_than_or_equal_to:
50
}
...
@@ -100,6 +99,10 @@ module Gitlab
...
@@ -100,6 +99,10 @@ module Gitlab
description:
'Services that will be used to execute this job.'
,
description:
'Services that will be used to execute this job.'
,
inherit:
true
inherit:
true
entry
:interruptible
,
Entry
::
Boolean
,
description:
'Set jobs interruptible value.'
,
inherit:
true
entry
:only
,
Entry
::
Policy
,
entry
:only
,
Entry
::
Policy
,
description:
'Refs policy this job will be executed for.'
,
description:
'Refs policy this job will be executed for.'
,
default:
Entry
::
Policy
::
DEFAULT_ONLY
,
default:
Entry
::
Policy
::
DEFAULT_ONLY
,
...
...
lib/gitlab/error_tracking/detailed_error.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
Gitlab
module
ErrorTracking
class
DetailedError
include
ActiveModel
::
Model
attr_accessor
:count
,
:culprit
,
:external_base_url
,
:external_url
,
:first_release_last_commit
,
:first_release_short_version
,
:first_seen
,
:frequency
,
:id
,
:last_release_last_commit
,
:last_release_short_version
,
:last_seen
,
:message
,
:project_id
,
:project_name
,
:project_slug
,
:short_id
,
:status
,
:title
,
:type
,
:user_count
end
end
end
lib/gitlab/error_tracking/error_event.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
module
Gitlab
module
ErrorTracking
class
ErrorEvent
include
ActiveModel
::
Model
attr_accessor
:issue_id
,
:date_received
,
:stack_trace_entries
end
end
end
lib/gitlab/tracking.rb
View file @
ae72d71d
...
@@ -45,7 +45,7 @@ module Gitlab
...
@@ -45,7 +45,7 @@ module Gitlab
namespace:
SNOWPLOW_NAMESPACE
,
namespace:
SNOWPLOW_NAMESPACE
,
hostname:
Gitlab
::
CurrentSettings
.
snowplow_collector_hostname
,
hostname:
Gitlab
::
CurrentSettings
.
snowplow_collector_hostname
,
cookie_domain:
Gitlab
::
CurrentSettings
.
snowplow_cookie_domain
,
cookie_domain:
Gitlab
::
CurrentSettings
.
snowplow_cookie_domain
,
app_id:
Gitlab
::
CurrentSettings
.
snowplow_
site
_id
,
app_id:
Gitlab
::
CurrentSettings
.
snowplow_
app
_id
,
form_tracking:
additional_features
,
form_tracking:
additional_features
,
link_click_tracking:
additional_features
,
link_click_tracking:
additional_features
,
iglu_registry_url:
Gitlab
::
CurrentSettings
.
snowplow_iglu_registry_url
iglu_registry_url:
Gitlab
::
CurrentSettings
.
snowplow_iglu_registry_url
...
@@ -59,7 +59,7 @@ module Gitlab
...
@@ -59,7 +59,7 @@ module Gitlab
SnowplowTracker
::
AsyncEmitter
.
new
(
Gitlab
::
CurrentSettings
.
snowplow_collector_hostname
,
protocol:
'https'
),
SnowplowTracker
::
AsyncEmitter
.
new
(
Gitlab
::
CurrentSettings
.
snowplow_collector_hostname
,
protocol:
'https'
),
SnowplowTracker
::
Subject
.
new
,
SnowplowTracker
::
Subject
.
new
,
SNOWPLOW_NAMESPACE
,
SNOWPLOW_NAMESPACE
,
Gitlab
::
CurrentSettings
.
snowplow_
site
_id
Gitlab
::
CurrentSettings
.
snowplow_
app
_id
)
)
end
end
end
end
...
...
lib/sentry/client.rb
View file @
ae72d71d
...
@@ -12,6 +12,18 @@ module Sentry
...
@@ -12,6 +12,18 @@ module Sentry
@token
=
token
@token
=
token
end
end
def
issue_details
(
issue_id
:)
issue
=
get_issue
(
issue_id:
issue_id
)
map_to_detailed_error
(
issue
)
end
def
issue_latest_event
(
issue_id
:)
latest_event
=
get_issue_latest_event
(
issue_id:
issue_id
)
map_to_event
(
latest_event
)
end
def
list_issues
(
issue_status
:,
limit
:)
def
list_issues
(
issue_status
:,
limit
:)
issues
=
get_issues
(
issue_status:
issue_status
,
limit:
limit
)
issues
=
get_issues
(
issue_status:
issue_status
,
limit:
limit
)
...
@@ -61,6 +73,14 @@ module Sentry
...
@@ -61,6 +73,14 @@ module Sentry
})
})
end
end
def
get_issue
(
issue_id
:)
http_get
(
issue_api_url
(
issue_id
))
end
def
get_issue_latest_event
(
issue_id
:)
http_get
(
issue_latest_event_api_url
(
issue_id
))
end
def
get_projects
def
get_projects
http_get
(
projects_api_url
)
http_get
(
projects_api_url
)
end
end
...
@@ -102,6 +122,20 @@ module Sentry
...
@@ -102,6 +122,20 @@ module Sentry
projects_url
projects_url
end
end
def
issue_api_url
(
issue_id
)
issue_url
=
URI
(
@url
)
issue_url
.
path
=
"/api/0/issues/
#{
issue_id
}
/"
issue_url
end
def
issue_latest_event_api_url
(
issue_id
)
latest_event_url
=
URI
(
@url
)
latest_event_url
.
path
=
"/api/0/issues/
#{
issue_id
}
/events/latest/"
latest_event_url
end
def
issues_api_url
def
issues_api_url
issues_url
=
URI
(
@url
+
'/issues/'
)
issues_url
=
URI
(
@url
+
'/issues/'
)
issues_url
.
path
.
squeeze!
(
'/'
)
issues_url
.
path
.
squeeze!
(
'/'
)
...
@@ -119,38 +153,87 @@ module Sentry
...
@@ -119,38 +153,87 @@ module Sentry
def
issue_url
(
id
)
def
issue_url
(
id
)
issues_url
=
@url
+
"/issues/
#{
id
}
"
issues_url
=
@url
+
"/issues/
#{
id
}
"
issues_url
=
ErrorTracking
::
ProjectErrorTrackingSetting
.
extract_sentry_external_url
(
issues_url
)
uri
=
URI
(
issues_url
)
parse_sentry_url
(
issues_url
)
end
def
project_url
parse_sentry_url
(
@url
)
end
def
parse_sentry_url
(
api_url
)
url
=
ErrorTracking
::
ProjectErrorTrackingSetting
.
extract_sentry_external_url
(
api_url
)
uri
=
URI
(
url
)
uri
.
path
.
squeeze!
(
'/'
)
uri
.
path
.
squeeze!
(
'/'
)
# Remove trailing spaces
uri
=
uri
.
to_s
.
gsub
(
/\/\z/
,
''
)
uri
.
to_s
uri
end
end
def
map_to_error
(
issue
)
def
map_to_event
(
event
)
id
=
issue
.
fetch
(
'id'
)
stack_trace
=
parse_stack_trace
(
event
)
Gitlab
::
ErrorTracking
::
ErrorEvent
.
new
(
issue_id:
event
.
dig
(
'groupID'
),
date_received:
event
.
dig
(
'dateReceived'
),
stack_trace_entries:
stack_trace
)
end
count
=
issue
.
fetch
(
'count'
,
nil
)
def
parse_stack_trace
(
event
)
exception_entry
=
event
.
dig
(
'entries'
)
&
.
detect
{
|
h
|
h
[
'type'
]
==
'exception'
}
return
unless
exception_entry
frequency
=
issue
.
dig
(
'stats'
,
'24h'
)
exception_values
=
exception_entry
.
dig
(
'data'
,
'values'
)
message
=
issue
.
dig
(
'metadata'
,
'value'
)
stack_trace_entry
=
exception_values
&
.
detect
{
|
h
|
h
[
'stacktrace'
].
present?
}
return
unless
stack_trace_entry
external_url
=
issue_url
(
id
)
stack_trace_entry
.
dig
(
'stacktrace'
,
'frames'
)
end
def
map_to_detailed_error
(
issue
)
Gitlab
::
ErrorTracking
::
DetailedError
.
new
(
id:
issue
.
fetch
(
'id'
),
first_seen:
issue
.
fetch
(
'firstSeen'
,
nil
),
last_seen:
issue
.
fetch
(
'lastSeen'
,
nil
),
title:
issue
.
fetch
(
'title'
,
nil
),
type:
issue
.
fetch
(
'type'
,
nil
),
user_count:
issue
.
fetch
(
'userCount'
,
nil
),
count:
issue
.
fetch
(
'count'
,
nil
),
message:
issue
.
dig
(
'metadata'
,
'value'
),
culprit:
issue
.
fetch
(
'culprit'
,
nil
),
external_url:
issue_url
(
issue
.
fetch
(
'id'
)),
external_base_url:
project_url
,
short_id:
issue
.
fetch
(
'shortId'
,
nil
),
status:
issue
.
fetch
(
'status'
,
nil
),
frequency:
issue
.
dig
(
'stats'
,
'24h'
),
project_id:
issue
.
dig
(
'project'
,
'id'
),
project_name:
issue
.
dig
(
'project'
,
'name'
),
project_slug:
issue
.
dig
(
'project'
,
'slug'
),
first_release_last_commit:
issue
.
dig
(
'firstRelease'
,
'lastCommit'
),
last_release_last_commit:
issue
.
dig
(
'lastRelease'
,
'lastCommit'
),
first_release_short_version:
issue
.
dig
(
'firstRelease'
,
'shortVersion'
),
last_release_short_version:
issue
.
dig
(
'lastRelease'
,
'shortVersion'
)
)
end
def
map_to_error
(
issue
)
Gitlab
::
ErrorTracking
::
Error
.
new
(
Gitlab
::
ErrorTracking
::
Error
.
new
(
id:
i
d
,
id:
i
ssue
.
fetch
(
'id'
)
,
first_seen:
issue
.
fetch
(
'firstSeen'
,
nil
),
first_seen:
issue
.
fetch
(
'firstSeen'
,
nil
),
last_seen:
issue
.
fetch
(
'lastSeen'
,
nil
),
last_seen:
issue
.
fetch
(
'lastSeen'
,
nil
),
title:
issue
.
fetch
(
'title'
,
nil
),
title:
issue
.
fetch
(
'title'
,
nil
),
type:
issue
.
fetch
(
'type'
,
nil
),
type:
issue
.
fetch
(
'type'
,
nil
),
user_count:
issue
.
fetch
(
'userCount'
,
nil
),
user_count:
issue
.
fetch
(
'userCount'
,
nil
),
count:
count
,
count:
issue
.
fetch
(
'count'
,
nil
)
,
message:
message
,
message:
issue
.
dig
(
'metadata'
,
'value'
)
,
culprit:
issue
.
fetch
(
'culprit'
,
nil
),
culprit:
issue
.
fetch
(
'culprit'
,
nil
),
external_url:
external_url
,
external_url:
issue_url
(
issue
.
fetch
(
'id'
))
,
short_id:
issue
.
fetch
(
'shortId'
,
nil
),
short_id:
issue
.
fetch
(
'shortId'
,
nil
),
status:
issue
.
fetch
(
'status'
,
nil
),
status:
issue
.
fetch
(
'status'
,
nil
),
frequency:
frequency
,
frequency:
issue
.
dig
(
'stats'
,
'24h'
)
,
project_id:
issue
.
dig
(
'project'
,
'id'
),
project_id:
issue
.
dig
(
'project'
,
'id'
),
project_name:
issue
.
dig
(
'project'
,
'name'
),
project_name:
issue
.
dig
(
'project'
,
'name'
),
project_slug:
issue
.
dig
(
'project'
,
'slug'
)
project_slug:
issue
.
dig
(
'project'
,
'slug'
)
...
...
locale/gitlab.pot
View file @
ae72d71d
...
@@ -1798,6 +1798,9 @@ msgstr ""
...
@@ -1798,6 +1798,9 @@ msgstr ""
msgid "Any user"
msgid "Any user"
msgstr ""
msgstr ""
msgid "App ID"
msgstr ""
msgid "Appearance"
msgid "Appearance"
msgstr ""
msgstr ""
...
@@ -6406,12 +6409,18 @@ msgstr ""
...
@@ -6406,12 +6409,18 @@ msgstr ""
msgid "Environments|Job"
msgid "Environments|Job"
msgstr ""
msgstr ""
msgid "Environments|Learn about environments"
msgstr ""
msgid "Environments|Learn more about stopping environments"
msgid "Environments|Learn more about stopping environments"
msgstr ""
msgstr ""
msgid "Environments|New environment"
msgid "Environments|New environment"
msgstr ""
msgstr ""
msgid "Environments|No deployed environments"
msgstr ""
msgid "Environments|No deployments yet"
msgid "Environments|No deployments yet"
msgstr ""
msgstr ""
...
@@ -6580,6 +6589,9 @@ msgstr ""
...
@@ -6580,6 +6589,9 @@ msgstr ""
msgid "Error"
msgid "Error"
msgstr ""
msgstr ""
msgid "Error Details"
msgstr ""
msgid "Error Tracking"
msgid "Error Tracking"
msgstr ""
msgstr ""
...
@@ -10177,6 +10189,9 @@ msgstr ""
...
@@ -10177,6 +10189,9 @@ msgstr ""
msgid "Logs"
msgid "Logs"
msgstr ""
msgstr ""
msgid "Logs|To see the pod logs, deploy your code to an environment."
msgstr ""
msgid "MD5"
msgid "MD5"
msgstr ""
msgstr ""
...
@@ -10678,9 +10693,6 @@ msgstr ""
...
@@ -10678,9 +10693,6 @@ msgstr ""
msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
msgid "Metrics|Label of the y-axis (usually the unit). The x-axis always represents time."
msgstr ""
msgstr ""
msgid "Metrics|Learn about environments"
msgstr ""
msgid "Metrics|Legend label (optional)"
msgid "Metrics|Legend label (optional)"
msgstr ""
msgstr ""
...
@@ -10696,9 +10708,6 @@ msgstr ""
...
@@ -10696,9 +10708,6 @@ msgstr ""
msgid "Metrics|New metric"
msgid "Metrics|New metric"
msgstr ""
msgstr ""
msgid "Metrics|No deployed environments"
msgstr ""
msgid "Metrics|PromQL query is valid"
msgid "Metrics|PromQL query is valid"
msgstr ""
msgstr ""
...
@@ -12355,6 +12364,9 @@ msgstr ""
...
@@ -12355,6 +12364,9 @@ msgstr ""
msgid "Please wait while we import the repository for you. Refresh at will."
msgid "Please wait while we import the repository for you. Refresh at will."
msgstr ""
msgstr ""
msgid "Pod logs"
msgstr ""
msgid "Pod not found"
msgid "Pod not found"
msgstr ""
msgstr ""
...
@@ -15599,9 +15611,6 @@ msgstr ""
...
@@ -15599,9 +15611,6 @@ msgstr ""
msgid "Single or combined queries"
msgid "Single or combined queries"
msgstr ""
msgstr ""
msgid "Site ID"
msgstr ""
msgid "Size"
msgid "Size"
msgstr ""
msgstr ""
...
...
spec/controllers/application_controller_spec.rb
View file @
ae72d71d
...
@@ -90,14 +90,6 @@ describe ApplicationController do
...
@@ -90,14 +90,6 @@ describe ApplicationController do
let
(
:format
)
{
:html
}
let
(
:format
)
{
:html
}
it_behaves_like
'setting gon variables'
it_behaves_like
'setting gon variables'
context
'for peek requests'
do
before
do
request
.
path
=
'/-/peek'
end
it_behaves_like
'not setting gon variables'
end
end
end
context
'with json format'
do
context
'with json format'
do
...
@@ -105,6 +97,12 @@ describe ApplicationController do
...
@@ -105,6 +97,12 @@ describe ApplicationController do
it_behaves_like
'not setting gon variables'
it_behaves_like
'not setting gon variables'
end
end
context
'with atom format'
do
let
(
:format
)
{
:atom
}
it_behaves_like
'not setting gon variables'
end
end
end
describe
'session expiration'
do
describe
'session expiration'
do
...
...
spec/controllers/projects/environments_controller_spec.rb
View file @
ae72d71d
...
@@ -330,11 +330,11 @@ describe Projects::EnvironmentsController do
...
@@ -330,11 +330,11 @@ describe Projects::EnvironmentsController do
expect
(
response
).
to
redirect_to
(
environment_metrics_path
(
environment
))
expect
(
response
).
to
redirect_to
(
environment_metrics_path
(
environment
))
end
end
it
'redirects to empty page if no environment exists'
do
it
'redirects to empty
metrics
page if no environment exists'
do
get
:metrics_redirect
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
get
:metrics_redirect
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
expect
(
response
).
to
be_ok
expect
(
response
).
to
be_ok
expect
(
response
).
to
render_template
'empty'
expect
(
response
).
to
render_template
'empty
_metrics
'
end
end
end
end
...
...
spec/controllers/projects/error_tracking_controller_spec.rb
View file @
ae72d71d
...
@@ -46,17 +46,6 @@ describe Projects::ErrorTrackingController do
...
@@ -46,17 +46,6 @@ describe Projects::ErrorTrackingController do
end
end
describe
'format json'
do
describe
'format json'
do
shared_examples
'no data'
do
it
'returns no data'
do
get
:index
,
params:
project_params
(
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'error_tracking/index'
)
expect
(
json_response
[
'external_url'
]).
to
be_nil
expect
(
json_response
[
'errors'
]).
to
eq
([])
end
end
let
(
:list_issues_service
)
{
spy
(
:list_issues_service
)
}
let
(
:list_issues_service
)
{
spy
(
:list_issues_service
)
}
let
(
:external_url
)
{
'http://example.com'
}
let
(
:external_url
)
{
'http://example.com'
}
...
@@ -66,6 +55,19 @@ describe Projects::ErrorTrackingController do
...
@@ -66,6 +55,19 @@ describe Projects::ErrorTrackingController do
.
and_return
(
list_issues_service
)
.
and_return
(
list_issues_service
)
end
end
context
'no data'
do
before
do
expect
(
list_issues_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
,
http_status: :no_content
)
end
it
'returns no data'
do
get
:index
,
params:
project_params
(
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
end
context
'service result is successful'
do
context
'service result is successful'
do
before
do
before
do
expect
(
list_issues_service
).
to
receive
(
:execute
)
expect
(
list_issues_service
).
to
receive
(
:execute
)
...
@@ -232,8 +234,186 @@ describe Projects::ErrorTrackingController do
...
@@ -232,8 +234,186 @@ describe Projects::ErrorTrackingController do
end
end
end
end
describe
'GET #issue_details'
do
let_it_be
(
:issue_id
)
{
1234
}
let
(
:issue_details_service
)
{
spy
(
:issue_details_service
)
}
let
(
:permitted_params
)
do
ActionController
::
Parameters
.
new
(
{
issue_id:
issue_id
.
to_s
}
).
permit!
end
before
do
expect
(
ErrorTracking
::
IssueDetailsService
)
.
to
receive
(
:new
).
with
(
project
,
user
,
permitted_params
)
.
and_return
(
issue_details_service
)
end
describe
'format json'
do
context
'no data'
do
before
do
expect
(
issue_details_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
,
http_status: :no_content
)
end
it
'returns no data'
do
get
:details
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
end
context
'service result is successful'
do
before
do
expect
(
issue_details_service
).
to
receive
(
:execute
)
.
and_return
(
status: :success
,
issue:
error
)
end
let
(
:error
)
{
build
(
:detailed_error_tracking_error
)
}
it
'returns an error'
do
get
:details
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'error_tracking/issue_detailed'
)
expect
(
json_response
[
'error'
]).
to
eq
(
error
.
as_json
)
end
end
context
'service result is erroneous'
do
let
(
:error_message
)
{
'error message'
}
context
'without http_status'
do
before
do
expect
(
issue_details_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
,
message:
error_message
)
end
it
'returns 400 with message'
do
get
:details
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'message'
]).
to
eq
(
error_message
)
end
end
context
'with explicit http_status'
do
let
(
:http_status
)
{
:no_content
}
before
do
expect
(
issue_details_service
).
to
receive
(
:execute
).
and_return
(
status: :error
,
message:
error_message
,
http_status:
http_status
)
end
it
'returns http_status with message'
do
get
:details
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
http_status
)
expect
(
json_response
[
'message'
]).
to
eq
(
error_message
)
end
end
end
end
end
describe
'GET #stack_trace'
do
let_it_be
(
:issue_id
)
{
1234
}
let
(
:issue_stack_trace_service
)
{
spy
(
:issue_stack_trace_service
)
}
let
(
:permitted_params
)
do
ActionController
::
Parameters
.
new
(
{
issue_id:
issue_id
.
to_s
}
).
permit!
end
before
do
expect
(
ErrorTracking
::
IssueLatestEventService
)
.
to
receive
(
:new
).
with
(
project
,
user
,
permitted_params
)
.
and_return
(
issue_stack_trace_service
)
end
describe
'format json'
do
context
'awaiting data'
do
before
do
expect
(
issue_stack_trace_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
,
http_status: :no_content
)
end
it
'returns no data'
do
get
:stack_trace
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
end
context
'service result is successful'
do
before
do
expect
(
issue_stack_trace_service
).
to
receive
(
:execute
)
.
and_return
(
status: :success
,
latest_event:
error_event
)
end
let
(
:error_event
)
{
build
(
:error_tracking_error_event
)
}
it
'returns an error'
do
get
:stack_trace
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
match_response_schema
(
'error_tracking/issue_stack_trace'
)
expect
(
json_response
[
'error'
]).
to
eq
(
error_event
.
as_json
)
end
end
context
'service result is erroneous'
do
let
(
:error_message
)
{
'error message'
}
context
'without http_status'
do
before
do
expect
(
issue_stack_trace_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
,
message:
error_message
)
end
it
'returns 400 with message'
do
get
:stack_trace
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'message'
]).
to
eq
(
error_message
)
end
end
context
'with explicit http_status'
do
let
(
:http_status
)
{
:no_content
}
before
do
expect
(
issue_stack_trace_service
).
to
receive
(
:execute
).
and_return
(
status: :error
,
message:
error_message
,
http_status:
http_status
)
end
it
'returns http_status with message'
do
get
:stack_trace
,
params:
issue_params
(
issue_id:
issue_id
,
format: :json
)
expect
(
response
).
to
have_gitlab_http_status
(
http_status
)
expect
(
json_response
[
'message'
]).
to
eq
(
error_message
)
end
end
end
end
end
private
private
def
issue_params
(
opts
=
{})
project_params
.
reverse_merge
(
opts
)
end
def
project_params
(
opts
=
{})
def
project_params
(
opts
=
{})
opts
.
reverse_merge
(
namespace_id:
project
.
namespace
,
project_id:
project
)
opts
.
reverse_merge
(
namespace_id:
project
.
namespace
,
project_id:
project
)
end
end
...
...
spec/controllers/uploads_controller_spec.rb
View file @
ae72d71d
...
@@ -228,10 +228,10 @@ describe UploadsController do
...
@@ -228,10 +228,10 @@ describe UploadsController do
user
.
block
user
.
block
end
end
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"user"
,
mounted_as:
"avatar"
,
id:
user
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"user"
,
mounted_as:
"avatar"
,
id:
user
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
@@ -320,10 +320,10 @@ describe UploadsController do
...
@@ -320,10 +320,10 @@ describe UploadsController do
end
end
context
"when not signed in"
do
context
"when not signed in"
do
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"project"
,
mounted_as:
"avatar"
,
id:
project
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"project"
,
mounted_as:
"avatar"
,
id:
project
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
@@ -343,10 +343,10 @@ describe UploadsController do
...
@@ -343,10 +343,10 @@ describe UploadsController do
project
.
add_maintainer
(
user
)
project
.
add_maintainer
(
user
)
end
end
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"project"
,
mounted_as:
"avatar"
,
id:
project
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"project"
,
mounted_as:
"avatar"
,
id:
project
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
@@ -439,10 +439,10 @@ describe UploadsController do
...
@@ -439,10 +439,10 @@ describe UploadsController do
user
.
block
user
.
block
end
end
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"group"
,
mounted_as:
"avatar"
,
id:
group
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"group"
,
mounted_as:
"avatar"
,
id:
group
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
@@ -526,10 +526,10 @@ describe UploadsController do
...
@@ -526,10 +526,10 @@ describe UploadsController do
end
end
context
"when not signed in"
do
context
"when not signed in"
do
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"note"
,
mounted_as:
"attachment"
,
id:
note
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"note"
,
mounted_as:
"attachment"
,
id:
note
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
@@ -549,10 +549,10 @@ describe UploadsController do
...
@@ -549,10 +549,10 @@ describe UploadsController do
project
.
add_maintainer
(
user
)
project
.
add_maintainer
(
user
)
end
end
it
"re
directs to the sign in page
"
do
it
"re
sponds with status 401
"
do
get
:show
,
params:
{
model:
"note"
,
mounted_as:
"attachment"
,
id:
note
.
id
,
filename:
"dk.png"
}
get
:show
,
params:
{
model:
"note"
,
mounted_as:
"attachment"
,
id:
note
.
id
,
filename:
"dk.png"
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
have_gitlab_http_status
(
401
)
end
end
end
end
...
...
spec/db/schema_spec.rb
View file @
ae72d71d
...
@@ -13,7 +13,7 @@ describe 'Database schema' do
...
@@ -13,7 +13,7 @@ describe 'Database schema' do
# EE: edit the ee/spec/db/schema_support.rb
# EE: edit the ee/spec/db/schema_support.rb
IGNORED_FK_COLUMNS
=
{
IGNORED_FK_COLUMNS
=
{
abuse_reports:
%w[reporter_id user_id]
,
abuse_reports:
%w[reporter_id user_id]
,
application_settings:
%w[performance_bar_allowed_group_id slack_app_id snowplow_
site
_id eks_account_id eks_access_key_id]
,
application_settings:
%w[performance_bar_allowed_group_id slack_app_id snowplow_
app
_id eks_account_id eks_access_key_id]
,
approvers:
%w[target_id user_id]
,
approvers:
%w[target_id user_id]
,
approvals:
%w[user_id]
,
approvals:
%w[user_id]
,
approver_groups:
%w[target_id]
,
approver_groups:
%w[target_id]
,
...
...
spec/factories/error_tracking/detailed_error.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:detailed_error_tracking_error
,
class:
Gitlab
::
ErrorTracking
::
DetailedError
do
id
{
'id'
}
title
{
'title'
}
type
{
'error'
}
user_count
{
1
}
count
{
2
}
first_seen
{
Time
.
now
}
last_seen
{
Time
.
now
}
message
{
'message'
}
culprit
{
'culprit'
}
external_url
{
'http://example.com/id'
}
external_base_url
{
'http://example.com'
}
project_id
{
'project1'
}
project_name
{
'project name'
}
project_slug
{
'project_name'
}
short_id
{
'ID'
}
status
{
'unresolved'
}
frequency
{
[]
}
first_release_last_commit
{
'68c914da9'
}
last_release_last_commit
{
'9ad419c86'
}
first_release_short_version
{
'abc123'
}
last_release_short_version
{
'abc123'
}
skip_create
end
end
spec/factories/error_tracking/error_event.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:error_tracking_error_event
,
class:
Gitlab
::
ErrorTracking
::
ErrorEvent
do
issue_id
{
'id'
}
date_received
{
Time
.
now
.
iso8601
}
stack_trace_entries
do
{
'stacktrace'
=>
{
'frames'
=>
[{
'file'
=>
'test.rb'
}]
}
}
end
skip_create
end
end
spec/features/projects/members/member_leaves_project_spec.rb
View file @
ae72d71d
...
@@ -20,7 +20,7 @@ describe 'Projects > Members > Member leaves project' do
...
@@ -20,7 +20,7 @@ describe 'Projects > Members > Member leaves project' do
expect
(
project
.
users
.
exists?
(
user
.
id
)).
to
be_falsey
expect
(
project
.
users
.
exists?
(
user
.
id
)).
to
be_falsey
end
end
it
'user leaves project by url param'
,
:js
do
it
'user leaves project by url param'
,
:js
,
:quarantine
do
visit
project_path
(
project
,
leave:
1
)
visit
project_path
(
project
,
leave:
1
)
page
.
accept_confirm
page
.
accept_confirm
...
...
spec/fixtures/api/schemas/error_tracking/error.json
View file @
ae72d71d
...
@@ -4,7 +4,14 @@
...
@@ -4,7 +4,14 @@
"external_url"
,
"external_url"
,
"last_seen"
,
"last_seen"
,
"message"
,
"message"
,
"type"
"type"
,
"title"
,
"project_id"
,
"project_name"
,
"project_slug"
,
"short_id"
,
"status"
,
"frequency"
],
],
"properties"
:
{
"properties"
:
{
"id"
:
{
"type"
:
"string"
},
"id"
:
{
"type"
:
"string"
},
...
@@ -15,7 +22,14 @@
...
@@ -15,7 +22,14 @@
"culprit"
:
{
"type"
:
"string"
},
"culprit"
:
{
"type"
:
"string"
},
"count"
:
{
"type"
:
"integer"
},
"count"
:
{
"type"
:
"integer"
},
"external_url"
:
{
"type"
:
"string"
},
"external_url"
:
{
"type"
:
"string"
},
"user_count"
:
{
"type"
:
"integer"
}
"user_count"
:
{
"type"
:
"integer"
},
"title"
:
{
"type"
:
"string"
},
"project_id"
:
{
"type"
:
"string"
},
"project_name"
:
{
"type"
:
"string"
},
"project_slug"
:
{
"type"
:
"string"
},
"short_id"
:
{
"type"
:
"string"
},
"status"
:
{
"type"
:
"string"
},
"frequency"
:
{
"type"
:
"array"
}
},
},
"additionalProperties"
:
tru
e
"additionalProperties"
:
fals
e
}
}
spec/fixtures/api/schemas/error_tracking/error_detailed.json
0 → 100644
View file @
ae72d71d
{
"type"
:
"object"
,
"required"
:
[
"external_url"
,
"external_base_url"
,
"last_seen"
,
"message"
,
"type"
,
"title"
,
"project_id"
,
"project_name"
,
"project_slug"
,
"short_id"
,
"status"
,
"frequency"
,
"first_release_last_commit"
,
"last_release_last_commit"
,
"first_release_short_version"
,
"last_release_short_version"
],
"properties"
:
{
"id"
:
{
"type"
:
"string"
},
"first_seen"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
},
"last_seen"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
},
"type"
:
{
"type"
:
"string"
},
"message"
:
{
"type"
:
"string"
},
"culprit"
:
{
"type"
:
"string"
},
"count"
:
{
"type"
:
"integer"
},
"external_url"
:
{
"type"
:
"string"
},
"external_base_url"
:
{
"type"
:
"string"
},
"user_count"
:
{
"type"
:
"integer"
},
"title"
:
{
"type"
:
"string"
},
"project_id"
:
{
"type"
:
"string"
},
"project_name"
:
{
"type"
:
"string"
},
"project_slug"
:
{
"type"
:
"string"
},
"short_id"
:
{
"type"
:
"string"
},
"status"
:
{
"type"
:
"string"
},
"frequency"
:
{
"type"
:
"array"
},
"first_release_last_commit"
:
{
"type"
:
[
"string"
,
"null"
]
},
"last_release_last_commit"
:
{
"type"
:
[
"string"
,
"null"
]
},
"first_release_short_version"
:
{
"type"
:
[
"string"
,
"null"
]
},
"last_release_short_version"
:
{
"type"
:
[
"string"
,
"null"
]
}
},
"additionalProperties"
:
false
}
spec/fixtures/api/schemas/error_tracking/error_stack_trace.json
0 → 100644
View file @
ae72d71d
{
"type"
:
"object"
,
"required"
:
[
"issue_id"
,
"stack_trace_entries"
,
"date_received"
],
"properties"
:
{
"issue_id"
:
{
"type"
:
[
"string"
,
"integer"
]
},
"stack_trace_entries"
:
{
"type"
:
"object"
},
"date_received"
:
{
"type"
:
"string"
}
},
"additionalProperties"
:
false
}
spec/fixtures/api/schemas/error_tracking/issue_detailed.json
0 → 100644
View file @
ae72d71d
{
"type"
:
"object"
,
"required"
:
[
"error"
],
"properties"
:
{
"error"
:
{
"$ref"
:
"error_detailed.json"
}
},
"additionalProperties"
:
false
}
spec/fixtures/api/schemas/error_tracking/issue_stack_trace.json
0 → 100644
View file @
ae72d71d
{
"type"
:
"object"
,
"required"
:
[
"error"
],
"properties"
:
{
"error"
:
{
"$ref"
:
"error_stack_trace.json"
}
},
"additionalProperties"
:
false
}
spec/helpers/application_settings_helper_spec.rb
View file @
ae72d71d
...
@@ -38,7 +38,7 @@ describe ApplicationSettingsHelper do
...
@@ -38,7 +38,7 @@ describe ApplicationSettingsHelper do
it_behaves_like
'when HTTP protocol is in use'
,
'http'
it_behaves_like
'when HTTP protocol is in use'
,
'http'
context
'with tracking parameters'
do
context
'with tracking parameters'
do
it
{
expect
(
visible_attributes
).
to
include
(
*
%i(snowplow_collector_hostname snowplow_cookie_domain snowplow_enabled snowplow_
site
_id)
)
}
it
{
expect
(
visible_attributes
).
to
include
(
*
%i(snowplow_collector_hostname snowplow_cookie_domain snowplow_enabled snowplow_
app
_id)
)
}
it
{
expect
(
visible_attributes
).
to
include
(
*
%i(pendo_enabled pendo_url)
)
}
it
{
expect
(
visible_attributes
).
to
include
(
*
%i(pendo_enabled pendo_url)
)
}
end
end
...
...
spec/lib/gitlab/ci/config/entry/default_spec.rb
View file @
ae72d71d
...
@@ -26,7 +26,7 @@ describe Gitlab::Ci::Config::Entry::Default do
...
@@ -26,7 +26,7 @@ describe Gitlab::Ci::Config::Entry::Default do
it
'contains the expected node names'
do
it
'contains the expected node names'
do
expect
(
described_class
.
nodes
.
keys
)
expect
(
described_class
.
nodes
.
keys
)
.
to
match_array
(
%i[before_script image services
.
to
match_array
(
%i[before_script image services
after_script cache]
)
after_script cache
interruptible
]
)
end
end
end
end
end
end
...
...
spec/lib/gitlab/ci/config/entry/job_spec.rb
View file @
ae72d71d
...
@@ -24,7 +24,7 @@ describe Gitlab::Ci::Config::Entry::Job do
...
@@ -24,7 +24,7 @@ describe Gitlab::Ci::Config::Entry::Job do
let
(
:result
)
do
let
(
:result
)
do
%i[before_script script stage type after_script cache
%i[before_script script stage type after_script cache
image services only except rules needs variables artifacts
image services only except rules needs variables artifacts
environment coverage retry]
environment coverage retry
interruptible
]
end
end
it
{
is_expected
.
to
match_array
result
}
it
{
is_expected
.
to
match_array
result
}
...
...
spec/lib/gitlab/ci/yaml_processor_spec.rb
View file @
ae72d71d
...
@@ -108,6 +108,25 @@ module Gitlab
...
@@ -108,6 +108,25 @@ module Gitlab
it
{
expect
(
subject
[
:interruptible
]).
to
be_falsy
}
it
{
expect
(
subject
[
:interruptible
]).
to
be_falsy
}
end
end
it
"returns interruptible when overridden for job"
do
config
=
YAML
.
dump
({
default:
{
interruptible:
true
},
rspec:
{
script:
"rspec"
}
})
config_processor
=
Gitlab
::
Ci
::
YamlProcessor
.
new
(
config
)
expect
(
config_processor
.
stage_builds_attributes
(
"test"
).
size
).
to
eq
(
1
)
expect
(
config_processor
.
stage_builds_attributes
(
"test"
).
first
).
to
eq
({
stage:
"test"
,
stage_idx:
2
,
name:
"rspec"
,
options:
{
script:
[
"rspec"
]
},
interruptible:
true
,
allow_failure:
false
,
when:
"on_success"
,
yaml_variables:
[]
})
end
end
end
describe
'retry entry'
do
describe
'retry entry'
do
...
...
spec/lib/gitlab/tracking_spec.rb
View file @
ae72d71d
...
@@ -8,7 +8,7 @@ describe Gitlab::Tracking do
...
@@ -8,7 +8,7 @@ describe Gitlab::Tracking do
stub_application_setting
(
snowplow_enabled:
true
)
stub_application_setting
(
snowplow_enabled:
true
)
stub_application_setting
(
snowplow_collector_hostname:
'gitfoo.com'
)
stub_application_setting
(
snowplow_collector_hostname:
'gitfoo.com'
)
stub_application_setting
(
snowplow_cookie_domain:
'.gitfoo.com'
)
stub_application_setting
(
snowplow_cookie_domain:
'.gitfoo.com'
)
stub_application_setting
(
snowplow_
site
_id:
'_abc123_'
)
stub_application_setting
(
snowplow_
app
_id:
'_abc123_'
)
stub_application_setting
(
snowplow_iglu_registry_url:
'https://example.org'
)
stub_application_setting
(
snowplow_iglu_registry_url:
'https://example.org'
)
end
end
...
...
spec/migrations/fill_productivity_analytics_start_date_spec.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'migrate'
,
'20191004081520_fill_productivity_analytics_start_date.rb'
)
describe
FillProductivityAnalyticsStartDate
,
:migration
do
let
(
:settings_table
)
{
table
(
'application_settings'
)
}
let
(
:metrics_table
)
{
table
(
'merge_request_metrics'
)
}
before
do
settings_table
.
create!
end
context
'with NO productivity analytics data available'
do
it
'sets start_date to NOW'
do
expect
{
migrate!
}.
to
change
{
settings_table
.
first
&
.
productivity_analytics_start_date
}.
to
(
be_like_time
(
Time
.
now
))
end
end
context
'with productivity analytics data available'
do
before
do
ActiveRecord
::
Base
.
transaction
do
ActiveRecord
::
Base
.
connection
.
execute
(
'ALTER TABLE merge_request_metrics DISABLE TRIGGER ALL'
)
metrics_table
.
create!
(
merged_at:
Time
.
parse
(
'2019-09-09'
),
commits_count:
nil
,
merge_request_id:
3
)
metrics_table
.
create!
(
merged_at:
Time
.
parse
(
'2019-10-10'
),
commits_count:
5
,
merge_request_id:
1
)
metrics_table
.
create!
(
merged_at:
Time
.
parse
(
'2019-11-11'
),
commits_count:
10
,
merge_request_id:
2
)
ActiveRecord
::
Base
.
connection
.
execute
(
'ALTER TABLE merge_request_metrics ENABLE TRIGGER ALL'
)
end
end
it
'set start_date to earliest merged_at value with PA data available'
do
expect
{
migrate!
}.
to
change
{
settings_table
.
first
&
.
productivity_analytics_start_date
}.
to
(
be_like_time
(
Time
.
parse
(
'2019-10-10'
)))
end
end
end
spec/requests/api/settings_spec.rb
View file @
ae72d71d
...
@@ -178,7 +178,7 @@ describe API::Settings, 'Settings' do
...
@@ -178,7 +178,7 @@ describe API::Settings, 'Settings' do
snowplow_collector_hostname:
"snowplow.example.com"
,
snowplow_collector_hostname:
"snowplow.example.com"
,
snowplow_cookie_domain:
".example.com"
,
snowplow_cookie_domain:
".example.com"
,
snowplow_enabled:
true
,
snowplow_enabled:
true
,
snowplow_
site_id:
"site
_id"
,
snowplow_
app_id:
"app
_id"
,
snowplow_iglu_registry_url:
'https://example.com'
snowplow_iglu_registry_url:
'https://example.com'
}
}
end
end
...
...
spec/requests/user_avatar_spec.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
require
'spec_helper'
describe
'Loading a user avatar'
do
let
(
:user
)
{
create
(
:user
,
:with_avatar
)
}
context
'when logged in'
do
# The exact query count will vary depending on the 2FA settings of the
# instance, group, and user. Removing those extra 2FA queries in this case
# may not be a good idea, so we just set up the ideal case.
before
do
stub_application_setting
(
require_two_factor_authentication:
true
)
login_as
(
create
(
:user
,
:two_factor
))
end
# One each for: current user, avatar user, and upload record
it
'only performs three SQL queries'
do
get
user
.
avatar_url
# Skip queries on first application load
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
{
get
user
.
avatar_url
}.
not_to
exceed_query_limit
(
3
)
end
end
context
'when logged out'
do
# One each for avatar user and upload record
it
'only performs two SQL queries'
do
get
user
.
avatar_url
# Skip queries on first application load
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
{
get
user
.
avatar_url
}.
not_to
exceed_query_limit
(
2
)
end
end
end
spec/services/error_tracking/issue_details_service_spec.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
require
'spec_helper'
describe
ErrorTracking
::
IssueDetailsService
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let
(
:sentry_url
)
{
'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project'
}
let
(
:token
)
{
'test-token'
}
let
(
:result
)
{
subject
.
execute
}
let
(
:error_tracking_setting
)
do
create
(
:project_error_tracking_setting
,
api_url:
sentry_url
,
token:
token
,
project:
project
)
end
subject
{
described_class
.
new
(
project
,
user
)
}
before
do
expect
(
project
).
to
receive
(
:error_tracking_setting
).
at_least
(
:once
).
and_return
(
error_tracking_setting
)
project
.
add_reporter
(
user
)
end
describe
'#execute'
do
context
'with authorized user'
do
context
'when issue_details returns a detailed error'
do
let
(
:detailed_error
)
{
build
(
:detailed_error_tracking_error
)
}
before
do
expect
(
error_tracking_setting
)
.
to
receive
(
:issue_details
).
and_return
(
issue:
detailed_error
)
end
it
'returns the detailed error'
do
expect
(
result
).
to
eq
(
status: :success
,
issue:
detailed_error
)
end
end
include_examples
'error tracking service data not ready'
,
:issue_details
include_examples
'error tracking service sentry error handling'
,
:issue_details
include_examples
'error tracking service http status handling'
,
:issue_details
end
include_examples
'error tracking service unauthorized user'
include_examples
'error tracking service disabled'
end
end
spec/services/error_tracking/issue_latest_event_service_spec.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
require
'spec_helper'
describe
ErrorTracking
::
IssueLatestEventService
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let
(
:sentry_url
)
{
'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project'
}
let
(
:token
)
{
'test-token'
}
let
(
:result
)
{
subject
.
execute
}
let
(
:error_tracking_setting
)
do
create
(
:project_error_tracking_setting
,
api_url:
sentry_url
,
token:
token
,
project:
project
)
end
subject
{
described_class
.
new
(
project
,
user
)
}
before
do
expect
(
project
).
to
receive
(
:error_tracking_setting
).
at_least
(
:once
).
and_return
(
error_tracking_setting
)
project
.
add_reporter
(
user
)
end
describe
'#execute'
do
context
'with authorized user'
do
context
'when issue_latest_event returns an error event'
do
let
(
:error_event
)
{
build
(
:error_tracking_error_event
)
}
before
do
expect
(
error_tracking_setting
)
.
to
receive
(
:issue_latest_event
).
and_return
(
latest_event:
error_event
)
end
it
'returns the error event'
do
expect
(
result
).
to
eq
(
status: :success
,
latest_event:
error_event
)
end
end
include_examples
'error tracking service data not ready'
,
:issue_latest_event
include_examples
'error tracking service sentry error handling'
,
:issue_latest_event
include_examples
'error tracking service http status handling'
,
:issue_latest_event
end
include_examples
'error tracking service unauthorized user'
include_examples
'error tracking service disabled'
end
end
spec/services/error_tracking/list_issues_service_spec.rb
View file @
ae72d71d
...
@@ -37,93 +37,12 @@ describe ErrorTracking::ListIssuesService do
...
@@ -37,93 +37,12 @@ describe ErrorTracking::ListIssuesService do
end
end
end
end
context
'when list_sentry_issues returns nil'
do
include_examples
'error tracking service data not ready'
,
:list_sentry_issues
before
do
include_examples
'error tracking service sentry error handling'
,
:list_sentry_issues
expect
(
error_tracking_setting
)
include_examples
'error tracking service http status handling'
,
:list_sentry_issues
.
to
receive
(
:list_sentry_issues
).
and_return
(
nil
)
end
it
'result is not ready'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :no_content
,
message:
'Not ready. Try again later'
)
end
end
context
'when list_sentry_issues returns error'
do
before
do
allow
(
error_tracking_setting
)
.
to
receive
(
:list_sentry_issues
)
.
and_return
(
error:
'Sentry response status code: 401'
,
error_type:
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_NON_20X_RESPONSE
)
end
it
'returns the error'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :bad_request
,
message:
'Sentry response status code: 401'
)
end
end
context
'when list_sentry_issues returns error with http_status'
do
before
do
allow
(
error_tracking_setting
)
.
to
receive
(
:list_sentry_issues
)
.
and_return
(
error:
'Sentry API response is missing keys. key not found: "id"'
,
error_type:
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_MISSING_KEYS
)
end
it
'returns the error with correct http_status'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :internal_server_error
,
message:
'Sentry API response is missing keys. key not found: "id"'
)
end
end
end
end
context
'with unauthorized user'
do
include_examples
'error tracking service unauthorized user'
let
(
:unauthorized_user
)
{
create
(
:user
)
}
include_examples
'error tracking service disabled'
subject
{
described_class
.
new
(
project
,
unauthorized_user
)
}
it
'returns error'
do
result
=
subject
.
execute
expect
(
result
).
to
include
(
status: :error
,
message:
'Access denied'
,
http_status: :unauthorized
)
end
end
context
'with error tracking disabled'
do
before
do
error_tracking_setting
.
enabled
=
false
end
it
'raises error'
do
result
=
subject
.
execute
expect
(
result
).
to
include
(
status: :error
,
message:
'Error Tracking is not enabled'
)
end
end
end
describe
'#sentry_external_url'
do
let
(
:external_url
)
{
'https://sentrytest.gitlab.com/sentry-org/sentry-project'
}
it
'calls ErrorTracking::ProjectErrorTrackingSetting'
do
expect
(
error_tracking_setting
).
to
receive
(
:sentry_external_url
).
and_call_original
subject
.
external_url
end
end
end
end
end
spec/services/error_tracking/list_projects_service_spec.rb
View file @
ae72d71d
...
@@ -127,7 +127,7 @@ describe ErrorTracking::ListProjectsService do
...
@@ -127,7 +127,7 @@ describe ErrorTracking::ListProjectsService do
end
end
it
'returns error'
do
it
'returns error'
do
expect
(
result
).
to
include
(
status: :error
,
message:
'
access denied'
)
expect
(
result
).
to
include
(
status: :error
,
message:
'
Access denied'
,
http_status: :unauthorized
)
end
end
end
end
...
...
spec/support/shared_examples/services/error_tracking_service_shared_examples.rb
0 → 100644
View file @
ae72d71d
# frozen_string_literal: true
shared_examples
'error tracking service data not ready'
do
|
service_call
|
context
"when
#{
service_call
}
returns nil"
do
before
do
expect
(
error_tracking_setting
)
.
to
receive
(
service_call
).
and_return
(
nil
)
end
it
'result is not ready'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :no_content
,
message:
'Not ready. Try again later'
)
end
end
end
shared_examples
'error tracking service sentry error handling'
do
|
service_call
|
context
"when
#{
service_call
}
returns error"
do
before
do
allow
(
error_tracking_setting
)
.
to
receive
(
service_call
)
.
and_return
(
error:
'Sentry response status code: 401'
,
error_type:
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_NON_20X_RESPONSE
)
end
it
'returns the error'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :bad_request
,
message:
'Sentry response status code: 401'
)
end
end
end
shared_examples
'error tracking service http status handling'
do
|
service_call
|
context
"when
#{
service_call
}
returns error with http_status"
do
before
do
allow
(
error_tracking_setting
)
.
to
receive
(
service_call
)
.
and_return
(
error:
'Sentry API response is missing keys. key not found: "id"'
,
error_type:
ErrorTracking
::
ProjectErrorTrackingSetting
::
SENTRY_API_ERROR_TYPE_MISSING_KEYS
)
end
it
'returns the error with correct http_status'
do
expect
(
result
).
to
eq
(
status: :error
,
http_status: :internal_server_error
,
message:
'Sentry API response is missing keys. key not found: "id"'
)
end
end
end
shared_examples
'error tracking service unauthorized user'
do
context
'with unauthorized user'
do
let
(
:unauthorized_user
)
{
create
(
:user
)
}
subject
{
described_class
.
new
(
project
,
unauthorized_user
)
}
it
'returns error'
do
result
=
subject
.
execute
expect
(
result
).
to
include
(
status: :error
,
message:
'Access denied'
,
http_status: :unauthorized
)
end
end
end
shared_examples
'error tracking service disabled'
do
context
'with error tracking disabled'
do
before
do
error_tracking_setting
.
enabled
=
false
end
it
'raises error'
do
result
=
subject
.
execute
expect
(
result
).
to
include
(
status: :error
,
message:
'Error Tracking is not enabled'
)
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