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
1ca9950d
Commit
1ca9950d
authored
Feb 11, 2020
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/gitlab@master
parent
bcc77054
Changes
66
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
66 changed files
with
1007 additions
and
806 deletions
+1007
-806
app/controllers/admin/services_controller.rb
app/controllers/admin/services_controller.rb
+6
-6
app/controllers/projects/serverless/functions_controller.rb
app/controllers/projects/serverless/functions_controller.rb
+11
-4
app/finders/projects/serverless/functions_finder.rb
app/finders/projects/serverless/functions_finder.rb
+12
-4
app/graphql/types/snippets/blob_type.rb
app/graphql/types/snippets/blob_type.rb
+4
-0
app/models/clusters/cluster.rb
app/models/clusters/cluster.rb
+6
-0
app/models/pages_domain.rb
app/models/pages_domain.rb
+4
-0
app/models/project.rb
app/models/project.rb
+7
-7
app/models/project_services/issue_tracker_service.rb
app/models/project_services/issue_tracker_service.rb
+1
-1
app/models/project_services/prometheus_service.rb
app/models/project_services/prometheus_service.rb
+1
-1
app/models/service.rb
app/models/service.rb
+12
-8
app/presenters/snippet_blob_presenter.rb
app/presenters/snippet_blob_presenter.rb
+7
-5
app/serializers/projects/serverless/service_entity.rb
app/serializers/projects/serverless/service_entity.rb
+14
-74
app/services/projects/create_service.rb
app/services/projects/create_service.rb
+4
-4
app/services/projects/propagate_service_template.rb
app/services/projects/propagate_service_template.rb
+14
-14
app/views/projects/services/mattermost_slash_commands/_help.html.haml
...ojects/services/mattermost_slash_commands/_help.html.haml
+2
-2
app/views/projects/services/slack_slash_commands/_help.html.haml
...ws/projects/services/slack_slash_commands/_help.html.haml
+1
-1
app/workers/all_queues.yml
app/workers/all_queues.yml
+1
-1
app/workers/pages_domain_removal_cron_worker.rb
app/workers/pages_domain_removal_cron_worker.rb
+3
-3
app/workers/pages_domain_ssl_renewal_cron_worker.rb
app/workers/pages_domain_ssl_renewal_cron_worker.rb
+5
-3
app/workers/pages_domain_verification_cron_worker.rb
app/workers/pages_domain_verification_cron_worker.rb
+5
-3
app/workers/propagate_service_template_worker.rb
app/workers/propagate_service_template_worker.rb
+26
-0
changelogs/unreleased/fj-add-plain-data-field-to-snippet-blob-type-endpoint.yml
...fj-add-plain-data-field-to-snippet-blob-type-endpoint.yml
+5
-0
changelogs/unreleased/rename_services_template_to_instance.yml
...elogs/unreleased/rename_services_template_to_instance.yml
+0
-5
config/sidekiq_queues.yml
config/sidekiq_queues.yml
+1
-1
db/migrate/20200123092602_rename_services_template_to_instance.rb
...te/20200123092602_rename_services_template_to_instance.rb
+0
-17
db/post_migrate/20191021101942_remove_empty_github_service_templates.rb
...e/20191021101942_remove_empty_github_service_templates.rb
+0
-4
db/post_migrate/20200123101859_cleanup_rename_services_template_to_instance.rb
...123101859_cleanup_rename_services_template_to_instance.rb
+0
-17
db/post_migrate/20200206111847_migrate_propagate_service_template_sidekiq_queue.rb
...11847_migrate_propagate_service_template_sidekiq_queue.rb
+0
-15
db/schema.rb
db/schema.rb
+2
-2
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+5
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+14
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+1
-0
lib/api/services.rb
lib/api/services.rb
+1
-1
lib/gitlab/import_export/import_export.yml
lib/gitlab/import_export/import_export.yml
+1
-1
lib/gitlab/serverless/service.rb
lib/gitlab/serverless/service.rb
+98
-0
lib/gitlab/usage_data.rb
lib/gitlab/usage_data.rb
+1
-1
qa/qa.rb
qa/qa.rb
+1
-0
qa/qa/vendor/jenkins/page/job.rb
qa/qa/vendor/jenkins/page/job.rb
+23
-0
spec/controllers/admin/services_controller_spec.rb
spec/controllers/admin/services_controller_spec.rb
+6
-6
spec/controllers/projects/serverless/functions_controller_spec.rb
...trollers/projects/serverless/functions_controller_spec.rb
+91
-14
spec/controllers/projects/services_controller_spec.rb
spec/controllers/projects/services_controller_spec.rb
+3
-3
spec/factories/pages_domains.rb
spec/factories/pages_domains.rb
+4
-0
spec/finders/projects/serverless/functions_finder_spec.rb
spec/finders/projects/serverless/functions_finder_spec.rb
+2
-2
spec/fixtures/trace/sample_trace
spec/fixtures/trace/sample_trace
+1
-1
spec/frontend/environments/environments_app_spec.js
spec/frontend/environments/environments_app_spec.js
+168
-0
spec/frontend/monitoring/components/dashboard_spec.js
spec/frontend/monitoring/components/dashboard_spec.js
+77
-123
spec/frontend/monitoring/components/dashboards_dropdown_spec.js
...rontend/monitoring/components/dashboards_dropdown_spec.js
+25
-38
spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
...nd/monitoring/components/duplicate_dashboard_form_spec.js
+14
-21
spec/frontend/monitoring/components/graph_group_spec.js
spec/frontend/monitoring/components/graph_group_spec.js
+6
-9
spec/frontend/monitoring/components/panel_type_spec.js
spec/frontend/monitoring/components/panel_type_spec.js
+7
-7
spec/graphql/types/snippets/blob_type_spec.rb
spec/graphql/types/snippets/blob_type_spec.rb
+3
-4
spec/javascripts/environments/environments_app_spec.js
spec/javascripts/environments/environments_app_spec.js
+0
-279
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+2
-2
spec/lib/gitlab/import_export/safe_model_attributes.yml
spec/lib/gitlab/import_export/safe_model_attributes.yml
+1
-1
spec/lib/gitlab/serverless/service_spec.rb
spec/lib/gitlab/serverless/service_spec.rb
+134
-0
spec/lib/gitlab/usage_data_spec.rb
spec/lib/gitlab/usage_data_spec.rb
+1
-1
spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb
.../migrate_propagate_service_template_sidekiq_queue_spec.rb
+0
-29
spec/models/service_spec.rb
spec/models/service_spec.rb
+30
-22
spec/presenters/snippet_blob_presenter_spec.rb
spec/presenters/snippet_blob_presenter_spec.rb
+36
-2
spec/services/projects/create_service_spec.rb
spec/services/projects/create_service_spec.rb
+7
-7
spec/services/projects/propagate_service_template_spec.rb
spec/services/projects/propagate_service_template_spec.rb
+18
-18
spec/support/helpers/kubernetes_helpers.rb
spec/support/helpers/kubernetes_helpers.rb
+8
-8
spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb
...mples/workers/pages_domain_cron_worker_shared_examples.rb
+21
-0
spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
+6
-2
spec/workers/pages_domain_verification_cron_worker_spec.rb
spec/workers/pages_domain_verification_cron_worker_spec.rb
+6
-2
spec/workers/propagate_service_template_worker_spec.rb
spec/workers/propagate_service_template_worker_spec.rb
+31
-0
No files found.
app/controllers/admin/services_controller.rb
View file @
1ca9950d
...
@@ -7,7 +7,7 @@ class Admin::ServicesController < Admin::ApplicationController
...
@@ -7,7 +7,7 @@ class Admin::ServicesController < Admin::ApplicationController
before_action
:service
,
only:
[
:edit
,
:update
]
before_action
:service
,
only:
[
:edit
,
:update
]
def
index
def
index
@services
=
instance_level_servic
es
@services
=
services_templat
es
end
end
def
edit
def
edit
...
@@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController
...
@@ -19,7 +19,7 @@ class Admin::ServicesController < Admin::ApplicationController
def
update
def
update
if
service
.
update
(
service_params
[
:service
])
if
service
.
update
(
service_params
[
:service
])
Propagate
InstanceLevelServic
eWorker
.
perform_async
(
service
.
id
)
if
service
.
active?
Propagate
ServiceTemplat
eWorker
.
perform_async
(
service
.
id
)
if
service
.
active?
redirect_to
admin_application_settings_services_path
,
redirect_to
admin_application_settings_services_path
,
notice:
'Application settings saved successfully'
notice:
'Application settings saved successfully'
...
@@ -31,17 +31,17 @@ class Admin::ServicesController < Admin::ApplicationController
...
@@ -31,17 +31,17 @@ class Admin::ServicesController < Admin::ApplicationController
private
private
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
instance_level_servic
es
def
services_templat
es
Service
.
available_services_names
.
map
do
|
service_name
|
Service
.
available_services_names
.
map
do
|
service_name
|
service
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service
_template
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service
.
where
(
instanc
e:
true
).
first_or_create
service
_template
.
where
(
templat
e:
true
).
first_or_create
end
end
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
service
def
service
@service
||=
Service
.
where
(
id:
params
[
:id
],
instanc
e:
true
).
first
@service
||=
Service
.
where
(
id:
params
[
:id
],
templat
e:
true
).
first
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
...
app/controllers/projects/serverless/functions_controller.rb
View file @
1ca9950d
...
@@ -8,11 +8,15 @@ module Projects
...
@@ -8,11 +8,15 @@ module Projects
def
index
def
index
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
json
do
format
.
json
do
functions
=
finder
.
execute
functions
=
finder
.
execute
.
select
do
|
function
|
can?
(
@current_user
,
:read_cluster
,
function
.
cluster
)
end
serialized_functions
=
serialize_function
(
functions
)
render
json:
{
render
json:
{
knative_installed:
finder
.
knative_installed
,
knative_installed:
finder
.
knative_installed
,
functions:
serialize
_function
(
functions
)
functions:
serialize
d_functions
}.
to_json
}.
to_json
end
end
...
@@ -23,11 +27,14 @@ module Projects
...
@@ -23,11 +27,14 @@ module Projects
end
end
def
show
def
show
@service
=
serialize_function
(
finder
.
service
(
params
[
:environment_id
],
params
[
:id
])
)
function
=
finder
.
service
(
params
[
:environment_id
],
params
[
:id
]
)
@prometheus
=
finder
.
has_prometheus?
(
params
[
:environment_id
]
)
return
not_found
unless
function
&&
can?
(
@current_user
,
:read_cluster
,
function
.
cluster
)
@service
=
serialize_function
(
function
)
return
not_found
if
@service
.
nil?
return
not_found
if
@service
.
nil?
@prometheus
=
finder
.
has_prometheus?
(
params
[
:environment_id
])
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
json
do
format
.
json
do
render
json:
@service
render
json:
@service
...
...
app/finders/projects/serverless/functions_finder.rb
View file @
1ca9950d
...
@@ -93,24 +93,32 @@ module Projects
...
@@ -93,24 +93,32 @@ module Projects
.
services
.
services
.
select
{
|
svc
|
svc
[
"metadata"
][
"name"
]
==
name
}
.
select
{
|
svc
|
svc
[
"metadata"
][
"name"
]
==
name
}
add_metadata
(
finder
,
services
).
first
unless
services
.
nil?
attributes
=
add_metadata
(
finder
,
services
).
first
next
unless
attributes
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
end
end
end
end
def
knative_services
def
knative_services
services_finders
.
map
do
|
finder
|
services_finders
.
map
do
|
finder
|
services
=
finder
.
services
attributes
=
add_metadata
(
finder
,
finder
.
services
)
add_metadata
(
finder
,
services
)
unless
services
.
nil?
attributes
&
.
map
do
|
attributes
|
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
end
end
end
end
end
def
add_metadata
(
finder
,
services
)
def
add_metadata
(
finder
,
services
)
return
if
services
.
nil?
add_pod_count
=
services
.
one?
add_pod_count
=
services
.
one?
services
.
each
do
|
s
|
services
.
each
do
|
s
|
s
[
"environment_scope"
]
=
finder
.
cluster
.
environment_scope
s
[
"environment_scope"
]
=
finder
.
cluster
.
environment_scope
s
[
"cluster_id"
]
=
finder
.
cluster
.
id
s
[
"environment"
]
=
finder
.
environment
s
[
"cluster"
]
=
finder
.
cluster
if
add_pod_count
if
add_pod_count
s
[
"podcount"
]
=
finder
s
[
"podcount"
]
=
finder
...
...
app/graphql/types/snippets/blob_type.rb
View file @
1ca9950d
...
@@ -12,6 +12,10 @@ module Types
...
@@ -12,6 +12,10 @@ module Types
description:
'Blob highlighted data'
,
description:
'Blob highlighted data'
,
null:
true
null:
true
field
:plain_highlighted_data
,
GraphQL
::
STRING_TYPE
,
description:
'Blob plain highlighted data'
,
null:
true
field
:raw_path
,
GraphQL
::
STRING_TYPE
,
field
:raw_path
,
GraphQL
::
STRING_TYPE
,
description:
'Blob raw content endpoint path'
,
description:
'Blob raw content endpoint path'
,
null:
false
null:
false
...
...
app/models/clusters/cluster.rb
View file @
1ca9950d
...
@@ -290,6 +290,12 @@ module Clusters
...
@@ -290,6 +290,12 @@ module Clusters
end
end
end
end
def
serverless_domain
strong_memoize
(
:serverless_domain
)
do
self
.
application_knative
&
.
serverless_domain_cluster
end
end
private
private
def
unique_management_project_environment_scope
def
unique_management_project_environment_scope
...
...
app/models/pages_domain.rb
View file @
1ca9950d
...
@@ -62,6 +62,8 @@ class PagesDomain < ApplicationRecord
...
@@ -62,6 +62,8 @@ class PagesDomain < ApplicationRecord
scope
:for_removal
,
->
{
where
(
"remove_at < ?"
,
Time
.
now
)
}
scope
:for_removal
,
->
{
where
(
"remove_at < ?"
,
Time
.
now
)
}
scope
:with_logging_info
,
->
{
includes
(
project:
[
:namespace
,
:route
])
}
def
verified?
def
verified?
!!
verified_at
!!
verified_at
end
end
...
@@ -285,3 +287,5 @@ class PagesDomain < ApplicationRecord
...
@@ -285,3 +287,5 @@ class PagesDomain < ApplicationRecord
!
auto_ssl_enabled?
&&
project
&
.
pages_https_only?
!
auto_ssl_enabled?
&&
project
&
.
pages_https_only?
end
end
end
end
PagesDomain
.
prepend_if_ee
(
'::EE::PagesDomain'
)
app/models/project.rb
View file @
1ca9950d
...
@@ -1224,13 +1224,13 @@ class Project < ApplicationRecord
...
@@ -1224,13 +1224,13 @@ class Project < ApplicationRecord
service
=
find_service
(
services
,
name
)
service
=
find_service
(
services
,
name
)
return
service
if
service
return
service
if
service
# We should check if
an instance-level
service exists
# We should check if
template for the
service exists
instance_level_service
=
find_service
(
instance_level_servic
es
,
name
)
template
=
find_service
(
services_templat
es
,
name
)
if
instance_level_servic
e
if
templat
e
Service
.
build_from_
instance
(
id
,
instance_level_servic
e
)
Service
.
build_from_
template
(
id
,
templat
e
)
else
else
# If no
instance-level service exists, we should create a new servi
ce. Ex `build_gitlab_ci_service`
# If no
template, we should create an instan
ce. Ex `build_gitlab_ci_service`
public_send
(
"build_
#{
name
}
_service"
)
# rubocop:disable GitlabSecurity/PublicSend
public_send
(
"build_
#{
name
}
_service"
)
# rubocop:disable GitlabSecurity/PublicSend
end
end
end
end
...
@@ -2460,8 +2460,8 @@ class Project < ApplicationRecord
...
@@ -2460,8 +2460,8 @@ class Project < ApplicationRecord
end
end
end
end
def
instance_level_servic
es
def
services_templat
es
@
instance_level_services
||=
Service
.
where
(
instanc
e:
true
)
@
services_templates
||=
Service
.
where
(
templat
e:
true
)
end
end
def
ensure_pages_metadatum
def
ensure_pages_metadatum
...
...
app/models/project_services/issue_tracker_service.rb
View file @
1ca9950d
...
@@ -164,7 +164,7 @@ class IssueTrackerService < Service
...
@@ -164,7 +164,7 @@ class IssueTrackerService < Service
end
end
def
one_issue_tracker
def
one_issue_tracker
return
if
instanc
e?
return
if
templat
e?
return
if
project
.
blank?
return
if
project
.
blank?
if
project
.
services
.
external_issue_trackers
.
where
.
not
(
id:
id
).
any?
if
project
.
services
.
external_issue_trackers
.
where
.
not
(
id:
id
).
any?
...
...
app/models/project_services/prometheus_service.rb
View file @
1ca9950d
...
@@ -85,7 +85,7 @@ class PrometheusService < MonitoringService
...
@@ -85,7 +85,7 @@ class PrometheusService < MonitoringService
end
end
def
prometheus_available?
def
prometheus_available?
return
false
if
instanc
e?
return
false
if
templat
e?
return
false
unless
project
return
false
unless
project
project
.
all_clusters
.
enabled
.
any?
{
|
cluster
|
cluster
.
application_prometheus_available?
}
project
.
all_clusters
.
enabled
.
any?
{
|
cluster
|
cluster
.
application_prometheus_available?
}
...
...
app/models/service.rb
View file @
1ca9950d
...
@@ -32,7 +32,7 @@ class Service < ApplicationRecord
...
@@ -32,7 +32,7 @@ class Service < ApplicationRecord
belongs_to
:project
,
inverse_of: :services
belongs_to
:project
,
inverse_of: :services
has_one
:service_hook
has_one
:service_hook
validates
:project_id
,
presence:
true
,
unless:
proc
{
|
service
|
service
.
instanc
e?
}
validates
:project_id
,
presence:
true
,
unless:
proc
{
|
service
|
service
.
templat
e?
}
validates
:type
,
presence:
true
validates
:type
,
presence:
true
scope
:visible
,
->
{
where
.
not
(
type:
'GitlabIssueTrackerService'
)
}
scope
:visible
,
->
{
where
.
not
(
type:
'GitlabIssueTrackerService'
)
}
...
@@ -70,8 +70,8 @@ class Service < ApplicationRecord
...
@@ -70,8 +70,8 @@ class Service < ApplicationRecord
true
true
end
end
def
instanc
e?
def
templat
e?
instanc
e
templat
e
end
end
def
category
def
category
...
@@ -299,15 +299,15 @@ class Service < ApplicationRecord
...
@@ -299,15 +299,15 @@ class Service < ApplicationRecord
service_names
.
sort_by
(
&
:downcase
)
service_names
.
sort_by
(
&
:downcase
)
end
end
def
self
.
build_from_
instance
(
project_id
,
instance_level_servic
e
)
def
self
.
build_from_
template
(
project_id
,
templat
e
)
service
=
instance_level_servic
e
.
dup
service
=
templat
e
.
dup
if
instance_level_servic
e
.
supports_data_fields?
if
templat
e
.
supports_data_fields?
data_fields
=
instance_level_servic
e
.
data_fields
.
dup
data_fields
=
templat
e
.
data_fields
.
dup
data_fields
.
service
=
service
data_fields
.
service
=
service
end
end
service
.
instanc
e
=
false
service
.
templat
e
=
false
service
.
project_id
=
project_id
service
.
project_id
=
project_id
service
.
active
=
false
if
service
.
active?
&&
!
service
.
valid?
service
.
active
=
false
if
service
.
active?
&&
!
service
.
valid?
service
service
...
@@ -321,6 +321,10 @@ class Service < ApplicationRecord
...
@@ -321,6 +321,10 @@ class Service < ApplicationRecord
nil
nil
end
end
def
self
.
find_by_template
find_by
(
template:
true
)
end
# override if needed
# override if needed
def
supports_data_fields?
def
supports_data_fields?
false
false
...
...
app/presenters/snippet_blob_presenter.rb
View file @
1ca9950d
...
@@ -4,11 +4,13 @@ class SnippetBlobPresenter < BlobPresenter
...
@@ -4,11 +4,13 @@ class SnippetBlobPresenter < BlobPresenter
def
highlighted_data
def
highlighted_data
return
if
blob
.
binary?
return
if
blob
.
binary?
if
blob
.
rich_viewer
&
.
partial_name
==
'markup'
highlight
(
plain:
false
)
blob
.
rendered_markup
end
else
highlight
def
plain_highlighted_data
end
return
if
blob
.
binary?
highlight
(
plain:
true
)
end
end
def
raw_path
def
raw_path
...
...
app/serializers/projects/serverless/service_entity.rb
View file @
1ca9950d
...
@@ -5,91 +5,31 @@ module Projects
...
@@ -5,91 +5,31 @@ module Projects
class
ServiceEntity
<
Grape
::
Entity
class
ServiceEntity
<
Grape
::
Entity
include
RequestAwareEntity
include
RequestAwareEntity
expose
:name
do
|
service
|
expose
:name
service
.
dig
(
'metadata'
,
'name'
)
expose
:namespace
end
expose
:environment_scope
expose
:podcount
expose
:namespace
do
|
service
|
expose
:created_at
service
.
dig
(
'metadata'
,
'namespace'
)
expose
:image
end
expose
:description
expose
:url
expose
:environment_scope
do
|
service
|
service
.
dig
(
'environment_scope'
)
end
expose
:cluster_id
do
|
service
|
service
.
dig
(
'cluster_id'
)
end
expose
:detail_url
do
|
service
|
expose
:detail_url
do
|
service
|
project_serverless_path
(
project_serverless_path
(
request
.
project
,
request
.
project
,
service
.
dig
(
'environment_scope'
),
service
.
environment_scope
,
service
.
dig
(
'metadata'
,
'name'
))
service
.
name
)
end
expose
:podcount
do
|
service
|
service
.
dig
(
'podcount'
)
end
end
expose
:metrics_url
do
|
service
|
expose
:metrics_url
do
|
service
|
project_serverless_metrics_path
(
project_serverless_metrics_path
(
request
.
project
,
request
.
project
,
service
.
dig
(
'environment_scope'
),
service
.
environment_scope
,
service
.
dig
(
'metadata'
,
'name'
))
+
".json"
service
.
name
,
format: :json
)
end
expose
:created_at
do
|
service
|
service
.
dig
(
'metadata'
,
'creationTimestamp'
)
end
expose
:url
do
|
service
|
knative_06_07_url
(
service
)
||
knative_05_url
(
service
)
end
expose
:description
do
|
service
|
knative_07_description
(
service
)
||
knative_05_06_description
(
service
)
end
end
expose
:image
do
|
service
|
expose
:cluster_id
do
|
service
|
service
.
dig
(
service
.
cluster
&
.
id
'spec'
,
'runLatest'
,
'configuration'
,
'build'
,
'template'
,
'name'
)
end
private
def
knative_07_description
(
service
)
service
.
dig
(
'spec'
,
'template'
,
'metadata'
,
'annotations'
,
'Description'
)
end
def
knative_05_url
(
service
)
"http://
#{
service
.
dig
(
'status'
,
'domain'
)
}
"
end
def
knative_06_07_url
(
service
)
service
.
dig
(
'status'
,
'url'
)
end
def
knative_05_06_description
(
service
)
service
.
dig
(
'spec'
,
'runLatest'
,
'configuration'
,
'revisionTemplate'
,
'metadata'
,
'annotations'
,
'Description'
)
end
end
end
end
end
end
...
...
app/services/projects/create_service.rb
View file @
1ca9950d
...
@@ -135,7 +135,7 @@ module Projects
...
@@ -135,7 +135,7 @@ module Projects
if
@project
.
save
if
@project
.
save
unless
@project
.
gitlab_project_import?
unless
@project
.
gitlab_project_import?
create_services_from_active_
instance_level_servic
es
(
@project
)
create_services_from_active_
templat
es
(
@project
)
@project
.
create_labels
@project
.
create_labels
end
end
...
@@ -161,9 +161,9 @@ module Projects
...
@@ -161,9 +161,9 @@ module Projects
end
end
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
create_services_from_active_
instance_level_servic
es
(
project
)
def
create_services_from_active_
templat
es
(
project
)
Service
.
where
(
instanc
e:
true
,
active:
true
).
each
do
|
template
|
Service
.
where
(
templat
e:
true
,
active:
true
).
each
do
|
template
|
service
=
Service
.
build_from_
instanc
e
(
project
.
id
,
template
)
service
=
Service
.
build_from_
templat
e
(
project
.
id
,
template
)
service
.
save!
service
.
save!
end
end
end
end
...
...
app/services/projects/propagate_
instance_level_servic
e.rb
→
app/services/projects/propagate_
service_templat
e.rb
View file @
1ca9950d
# frozen_string_literal: true
# frozen_string_literal: true
module
Projects
module
Projects
class
Propagate
InstanceLevelServic
e
class
Propagate
ServiceTemplat
e
BATCH_SIZE
=
100
BATCH_SIZE
=
100
def
self
.
propagate
(
*
args
)
def
self
.
propagate
(
*
args
)
new
(
*
args
).
propagate
new
(
*
args
).
propagate
end
end
def
initialize
(
instance_level_servic
e
)
def
initialize
(
templat
e
)
@
instance_level_service
=
instance_level_servic
e
@
template
=
templat
e
end
end
def
propagate
def
propagate
return
unless
@
instance_level_servic
e
.
active?
return
unless
@
templat
e
.
active?
Rails
.
logger
.
info
(
"Propagating services for
instance_level_service
#{
@instance_level_servic
e
.
id
}
"
)
# rubocop:disable Gitlab/RailsLogger
Rails
.
logger
.
info
(
"Propagating services for
template
#{
@templat
e
.
id
}
"
)
# rubocop:disable Gitlab/RailsLogger
propagate_projects_with_
instance_level_servic
e
propagate_projects_with_
templat
e
end
end
private
private
def
propagate_projects_with_
instance_level_servic
e
def
propagate_projects_with_
templat
e
loop
do
loop
do
batch
=
Project
.
uncached
{
project_ids_batch
}
batch
=
Project
.
uncached
{
project_ids_batch
}
bulk_create_from_
instance_level_servic
e
(
batch
)
unless
batch
.
empty?
bulk_create_from_
templat
e
(
batch
)
unless
batch
.
empty?
break
if
batch
.
size
<
BATCH_SIZE
break
if
batch
.
size
<
BATCH_SIZE
end
end
end
end
def
bulk_create_from_
instance_level_servic
e
(
batch
)
def
bulk_create_from_
templat
e
(
batch
)
service_list
=
batch
.
map
do
|
project_id
|
service_list
=
batch
.
map
do
|
project_id
|
service_hash
.
values
<<
project_id
service_hash
.
values
<<
project_id
end
end
...
@@ -52,7 +52,7 @@ module Projects
...
@@ -52,7 +52,7 @@ module Projects
SELECT true
SELECT true
FROM services
FROM services
WHERE services.project_id = projects.id
WHERE services.project_id = projects.id
AND services.type = '
#{
@
instance_level_servic
e
.
type
}
'
AND services.type = '
#{
@
templat
e
.
type
}
'
)
)
AND projects.pending_delete = false
AND projects.pending_delete = false
AND projects.archived = false
AND projects.archived = false
...
@@ -73,9 +73,9 @@ module Projects
...
@@ -73,9 +73,9 @@ module Projects
def
service_hash
def
service_hash
@service_hash
||=
@service_hash
||=
begin
begin
instance_hash
=
@instance_level_service
.
as_json
(
methods: :type
).
except
(
'id'
,
'instanc
e'
,
'project_id'
)
template_hash
=
@template
.
as_json
(
methods: :type
).
except
(
'id'
,
'templat
e'
,
'project_id'
)
instanc
e_hash
.
each_with_object
({})
do
|
(
key
,
value
),
service_hash
|
templat
e_hash
.
each_with_object
({})
do
|
(
key
,
value
),
service_hash
|
value
=
value
.
is_a?
(
Hash
)
?
value
.
to_json
:
value
value
=
value
.
is_a?
(
Hash
)
?
value
.
to_json
:
value
service_hash
[
ActiveRecord
::
Base
.
connection
.
quote_column_name
(
key
)]
=
service_hash
[
ActiveRecord
::
Base
.
connection
.
quote_column_name
(
key
)]
=
...
@@ -97,11 +97,11 @@ module Projects
...
@@ -97,11 +97,11 @@ module Projects
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
def
active_external_issue_tracker?
def
active_external_issue_tracker?
@
instance_level_service
.
issue_tracker?
&&
!
@instance_level_servic
e
.
default
@
template
.
issue_tracker?
&&
!
@templat
e
.
default
end
end
def
active_external_wiki?
def
active_external_wiki?
@
instance_level_servic
e
.
type
==
'ExternalWikiService'
@
templat
e
.
type
==
'ExternalWikiService'
end
end
end
end
end
end
app/views/projects/services/mattermost_slash_commands/_help.html.haml
View file @
1ca9950d
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
%p
.inline
%p
.inline
=
s_
(
"MattermostService|See list of available commands in Mattermost after setting up this service, by entering"
)
=
s_
(
"MattermostService|See list of available commands in Mattermost after setting up this service, by entering"
)
%kbd
.inline
/
<
trigger
>
help
%kbd
.inline
/
<
trigger
>
help
-
unless
enabled
||
@service
.
instanc
e?
-
unless
enabled
||
@service
.
templat
e?
=
render
'projects/services/mattermost_slash_commands/detailed_help'
,
subject:
@service
=
render
'projects/services/mattermost_slash_commands/detailed_help'
,
subject:
@service
-
if
enabled
&&
!
@service
.
instanc
e?
-
if
enabled
&&
!
@service
.
templat
e?
=
render
'projects/services/mattermost_slash_commands/installation_info'
,
subject:
@service
=
render
'projects/services/mattermost_slash_commands/installation_info'
,
subject:
@service
app/views/projects/services/slack_slash_commands/_help.html.haml
View file @
1ca9950d
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
%p
.inline
%p
.inline
=
s_
(
"SlackService|See list of available commands in Slack after setting up this service, by entering"
)
=
s_
(
"SlackService|See list of available commands in Slack after setting up this service, by entering"
)
%kbd
.inline
/
<
command
>
help
%kbd
.inline
/
<
command
>
help
-
unless
@service
.
instanc
e?
-
unless
@service
.
templat
e?
%p
=
_
(
"To set up this service:"
)
%p
=
_
(
"To set up this service:"
)
%ul
.list-unstyled.indent-list
%ul
.list-unstyled.indent-list
%li
%li
...
...
app/workers/all_queues.yml
View file @
1ca9950d
...
@@ -969,7 +969,7 @@
...
@@ -969,7 +969,7 @@
:latency_sensitive:
:latency_sensitive:
:resource_boundary: :unknown
:resource_boundary: :unknown
:weight:
1
:weight:
1
-
:name: propagate_
instance_level_servic
e
-
:name: propagate_
service_templat
e
:feature_category: :source_code_management
:feature_category: :source_code_management
:has_external_dependencies:
:has_external_dependencies:
:latency_sensitive:
:latency_sensitive:
...
...
app/workers/pages_domain_removal_cron_worker.rb
View file @
1ca9950d
...
@@ -2,14 +2,14 @@
...
@@ -2,14 +2,14 @@
class
PagesDomainRemovalCronWorker
class
PagesDomainRemovalCronWorker
include
ApplicationWorker
include
ApplicationWorker
include
CronjobQueue
# rubocop:disable Scalability/CronWorkerContext
include
CronjobQueue
feature_category
:pages
feature_category
:pages
worker_resource_boundary
:cpu
worker_resource_boundary
:cpu
def
perform
def
perform
PagesDomain
.
for_removal
.
find_each
do
|
domain
|
PagesDomain
.
for_removal
.
with_logging_info
.
find_each
do
|
domain
|
domain
.
destroy!
with_context
(
project:
domain
.
project
)
{
domain
.
destroy!
}
rescue
=>
e
rescue
=>
e
Gitlab
::
ErrorTracking
.
track_exception
(
e
)
Gitlab
::
ErrorTracking
.
track_exception
(
e
)
end
end
...
...
app/workers/pages_domain_ssl_renewal_cron_worker.rb
View file @
1ca9950d
...
@@ -2,15 +2,17 @@
...
@@ -2,15 +2,17 @@
class
PagesDomainSslRenewalCronWorker
class
PagesDomainSslRenewalCronWorker
include
ApplicationWorker
include
ApplicationWorker
include
CronjobQueue
# rubocop:disable Scalability/CronWorkerContext
include
CronjobQueue
feature_category
:pages
feature_category
:pages
def
perform
def
perform
return
unless
::
Gitlab
::
LetsEncrypt
.
enabled?
return
unless
::
Gitlab
::
LetsEncrypt
.
enabled?
PagesDomain
.
need_auto_ssl_renewal
.
find_each
do
|
domain
|
PagesDomain
.
need_auto_ssl_renewal
.
with_logging_info
.
find_each
do
|
domain
|
PagesDomainSslRenewalWorker
.
perform_async
(
domain
.
id
)
with_context
(
project:
domain
.
project
)
do
PagesDomainSslRenewalWorker
.
perform_async
(
domain
.
id
)
end
end
end
end
end
end
end
app/workers/pages_domain_verification_cron_worker.rb
View file @
1ca9950d
...
@@ -2,15 +2,17 @@
...
@@ -2,15 +2,17 @@
class
PagesDomainVerificationCronWorker
class
PagesDomainVerificationCronWorker
include
ApplicationWorker
include
ApplicationWorker
include
CronjobQueue
# rubocop:disable Scalability/CronWorkerContext
include
CronjobQueue
feature_category
:pages
feature_category
:pages
def
perform
def
perform
return
if
Gitlab
::
Database
.
read_only?
return
if
Gitlab
::
Database
.
read_only?
PagesDomain
.
needs_verification
.
find_each
do
|
domain
|
PagesDomain
.
needs_verification
.
with_logging_info
.
find_each
do
|
domain
|
PagesDomainVerificationWorker
.
perform_async
(
domain
.
id
)
with_context
(
project:
domain
.
project
)
do
PagesDomainVerificationWorker
.
perform_async
(
domain
.
id
)
end
end
end
end
end
end
end
app/workers/propagate_
instance_level_servic
e_worker.rb
→
app/workers/propagate_
service_templat
e_worker.rb
View file @
1ca9950d
# frozen_string_literal: true
# frozen_string_literal: true
# Worker for updating any project specific caches.
# Worker for updating any project specific caches.
class
Propagate
InstanceLevelServic
eWorker
class
Propagate
ServiceTemplat
eWorker
include
ApplicationWorker
include
ApplicationWorker
feature_category
:source_code_management
feature_category
:source_code_management
...
@@ -9,18 +9,18 @@ class PropagateInstanceLevelServiceWorker
...
@@ -9,18 +9,18 @@ class PropagateInstanceLevelServiceWorker
LEASE_TIMEOUT
=
4
.
hours
.
to_i
LEASE_TIMEOUT
=
4
.
hours
.
to_i
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
perform
(
instance_level_servic
e_id
)
def
perform
(
templat
e_id
)
return
unless
try_obtain_lease_for
(
instance_level_servic
e_id
)
return
unless
try_obtain_lease_for
(
templat
e_id
)
Projects
::
Propagate
InstanceLevelService
.
propagate
(
Service
.
find_by
(
id:
instance_level_servic
e_id
))
Projects
::
Propagate
ServiceTemplate
.
propagate
(
Service
.
find_by
(
id:
templat
e_id
))
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
private
private
def
try_obtain_lease_for
(
instance_level_servic
e_id
)
def
try_obtain_lease_for
(
templat
e_id
)
Gitlab
::
ExclusiveLease
Gitlab
::
ExclusiveLease
.
new
(
"propagate_
instance_level_service_worker:
#{
instance_level_servic
e_id
}
"
,
timeout:
LEASE_TIMEOUT
)
.
new
(
"propagate_
service_template_worker:
#{
templat
e_id
}
"
,
timeout:
LEASE_TIMEOUT
)
.
try_obtain
.
try_obtain
end
end
end
end
changelogs/unreleased/fj-add-plain-data-field-to-snippet-blob-type-endpoint.yml
0 → 100644
View file @
1ca9950d
---
title
:
Add plain_highlighted_data field to SnippetBlobType
merge_request
:
24856
author
:
type
:
changed
changelogs/unreleased/rename_services_template_to_instance.yml
deleted
100644 → 0
View file @
bcc77054
---
title
:
'
Service
model:
Rename
template
attribute
to
instance'
merge_request
:
23595
author
:
type
:
other
config/sidekiq_queues.yml
View file @
1ca9950d
...
@@ -194,7 +194,7 @@
...
@@ -194,7 +194,7 @@
-
1
-
1
-
-
project_update_repository_storage
-
-
project_update_repository_storage
-
1
-
1
-
-
propagate_
instance_level_servic
e
-
-
propagate_
service_templat
e
-
1
-
1
-
-
reactive_caching
-
-
reactive_caching
-
1
-
1
...
...
db/migrate/20200123092602_rename_services_template_to_instance.rb
deleted
100644 → 0
View file @
bcc77054
# frozen_string_literal: true
class
RenameServicesTemplateToInstance
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
rename_column_concurrently
:services
,
:template
,
:instance
end
def
down
undo_rename_column_concurrently
:services
,
:template
,
:instance
end
end
db/post_migrate/20191021101942_remove_empty_github_service_templates.rb
View file @
1ca9950d
...
@@ -23,10 +23,6 @@ class RemoveEmptyGithubServiceTemplates < ActiveRecord::Migration[5.2]
...
@@ -23,10 +23,6 @@ class RemoveEmptyGithubServiceTemplates < ActiveRecord::Migration[5.2]
private
private
def
relationship
def
relationship
# The column `template` was renamed to `instance`. Column information needs
# to be resetted to avoid cache problems after migrating down.
RemoveEmptyGithubServiceTemplates
::
Service
.
reset_column_information
RemoveEmptyGithubServiceTemplates
::
Service
.
where
(
template:
true
,
type:
'GithubService'
)
RemoveEmptyGithubServiceTemplates
::
Service
.
where
(
template:
true
,
type:
'GithubService'
)
end
end
end
end
db/post_migrate/20200123101859_cleanup_rename_services_template_to_instance.rb
deleted
100644 → 0
View file @
bcc77054
# frozen_string_literal: true
class
CleanupRenameServicesTemplateToInstance
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
cleanup_concurrent_column_rename
:services
,
:template
,
:instance
end
def
down
undo_cleanup_concurrent_column_rename
:services
,
:template
,
:instance
end
end
db/post_migrate/20200206111847_migrate_propagate_service_template_sidekiq_queue.rb
deleted
100644 → 0
View file @
bcc77054
# frozen_string_literal: true
class
MigratePropagateServiceTemplateSidekiqQueue
<
ActiveRecord
::
Migration
[
6.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
up
sidekiq_queue_migrate
'propagate_service_template'
,
to:
'propagate_instance_level_service'
end
def
down
sidekiq_queue_migrate
'propagate_instance_level_service'
,
to:
'propagate_service_template'
end
end
db/schema.rb
View file @
1ca9950d
...
@@ -3858,9 +3858,9 @@ ActiveRecord::Schema.define(version: 2020_02_07_151640) do
...
@@ -3858,9 +3858,9 @@ ActiveRecord::Schema.define(version: 2020_02_07_151640) do
t
.
boolean
"deployment_events"
,
default:
false
,
null:
false
t
.
boolean
"deployment_events"
,
default:
false
,
null:
false
t
.
string
"description"
,
limit:
500
t
.
string
"description"
,
limit:
500
t
.
boolean
"comment_on_event_enabled"
,
default:
true
,
null:
false
t
.
boolean
"comment_on_event_enabled"
,
default:
true
,
null:
false
t
.
boolean
"instance"
,
default:
false
t
.
boolean
"template"
,
default:
false
t
.
index
[
"instance"
],
name:
"index_services_on_instance"
t
.
index
[
"project_id"
],
name:
"index_services_on_project_id"
t
.
index
[
"project_id"
],
name:
"index_services_on_project_id"
t
.
index
[
"template"
],
name:
"index_services_on_template"
t
.
index
[
"type"
],
name:
"index_services_on_type"
t
.
index
[
"type"
],
name:
"index_services_on_type"
end
end
...
...
doc/api/graphql/reference/gitlab_schema.graphql
View file @
1ca9950d
...
@@ -6777,6 +6777,11 @@ type SnippetBlob {
...
@@ -6777,6 +6777,11 @@ type SnippetBlob {
"""
"""
path
:
String
path
:
String
"""
Blob
plain
highlighted
data
"""
plainHighlightedData
:
String
"""
"""
Blob
raw
content
endpoint
path
Blob
raw
content
endpoint
path
"""
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
1ca9950d
...
@@ -7612,6 +7612,20 @@
...
@@ -7612,6 +7612,20 @@
"isDeprecated"
:
false
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
"deprecationReason"
:
null
},
},
{
"name"
:
"plainHighlightedData"
,
"description"
:
"Blob plain highlighted data"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
{
"name"
:
"rawPath"
,
"name"
:
"rawPath"
,
"description"
:
"Blob raw content endpoint path"
,
"description"
:
"Blob raw content endpoint path"
,
...
...
doc/api/graphql/reference/index.md
View file @
1ca9950d
...
@@ -1071,6 +1071,7 @@ Represents the snippet blob
...
@@ -1071,6 +1071,7 @@ Represents the snippet blob
|
`mode`
| String | Blob mode |
|
`mode`
| String | Blob mode |
|
`name`
| String | Blob name |
|
`name`
| String | Blob name |
|
`path`
| String | Blob path |
|
`path`
| String | Blob path |
|
`plainHighlightedData`
| String | Blob plain highlighted data |
|
`rawPath`
| String! | Blob raw content endpoint path |
|
`rawPath`
| String! | Blob raw content endpoint path |
|
`richViewer`
| SnippetBlobViewer | Blob content rich viewer |
|
`richViewer`
| SnippetBlobViewer | Blob content rich viewer |
|
`simpleViewer`
| SnippetBlobViewer! | Blob content simple viewer |
|
`simpleViewer`
| SnippetBlobViewer! | Blob content simple viewer |
...
...
lib/api/services.rb
View file @
1ca9950d
...
@@ -132,7 +132,7 @@ module API
...
@@ -132,7 +132,7 @@ module API
helpers
do
helpers
do
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
slash_command_service
(
project
,
service_slug
,
params
)
def
slash_command_service
(
project
,
service_slug
,
params
)
project
.
services
.
active
.
where
(
instanc
e:
false
).
find
do
|
service
|
project
.
services
.
active
.
where
(
templat
e:
false
).
find
do
|
service
|
service
.
try
(
:token
)
==
params
[
:token
]
&&
service
.
to_param
==
service_slug
.
underscore
service
.
try
(
:token
)
==
params
[
:token
]
&&
service
.
to_param
==
service_slug
.
underscore
end
end
end
end
...
...
lib/gitlab/import_export/import_export.yml
View file @
1ca9950d
...
@@ -257,7 +257,7 @@ excluded_attributes:
...
@@ -257,7 +257,7 @@ excluded_attributes:
-
:token
-
:token
-
:token_encrypted
-
:token_encrypted
services
:
services
:
-
:
instanc
e
-
:
templat
e
error_tracking_setting
:
error_tracking_setting
:
-
:encrypted_token
-
:encrypted_token
-
:encrypted_token_iv
-
:encrypted_token_iv
...
...
lib/gitlab/serverless/service.rb
0 → 100644
View file @
1ca9950d
# frozen_string_literal: true
class
Gitlab::Serverless::Service
include
Gitlab
::
Utils
::
StrongMemoize
def
initialize
(
attributes
)
@attributes
=
attributes
end
def
name
@attributes
.
dig
(
'metadata'
,
'name'
)
end
def
namespace
@attributes
.
dig
(
'metadata'
,
'namespace'
)
end
def
environment_scope
@attributes
.
dig
(
'environment_scope'
)
end
def
environment
@attributes
.
dig
(
'environment'
)
end
def
podcount
@attributes
.
dig
(
'podcount'
)
end
def
created_at
strong_memoize
(
:created_at
)
do
timestamp
=
@attributes
.
dig
(
'metadata'
,
'creationTimestamp'
)
DateTime
.
parse
(
timestamp
)
if
timestamp
end
end
def
image
@attributes
.
dig
(
'spec'
,
'runLatest'
,
'configuration'
,
'build'
,
'template'
,
'name'
)
end
def
description
knative_07_description
||
knative_05_06_description
end
def
cluster
@attributes
.
dig
(
'cluster'
)
end
def
url
proxy_url
||
knative_06_07_url
||
knative_05_url
end
private
def
proxy_url
if
cluster
&
.
serverless_domain
Gitlab
::
Serverless
::
FunctionURI
.
new
(
function:
name
,
cluster:
cluster
.
serverless_domain
,
environment:
environment
)
end
end
def
knative_07_description
@attributes
.
dig
(
'spec'
,
'template'
,
'metadata'
,
'annotations'
,
'Description'
)
end
def
knative_05_06_description
@attributes
.
dig
(
'spec'
,
'runLatest'
,
'configuration'
,
'revisionTemplate'
,
'metadata'
,
'annotations'
,
'Description'
)
end
def
knative_05_url
domain
=
@attributes
.
dig
(
'status'
,
'domain'
)
return
unless
domain
"http://
#{
domain
}
"
end
def
knative_06_07_url
@attributes
.
dig
(
'status'
,
'url'
)
end
end
lib/gitlab/usage_data.rb
View file @
1ca9950d
...
@@ -179,7 +179,7 @@ module Gitlab
...
@@ -179,7 +179,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
services_usage
def
services_usage
service_counts
=
count
(
Service
.
active
.
where
(
instanc
e:
false
).
where
.
not
(
type:
'JiraService'
).
group
(
:type
),
fallback:
Hash
.
new
(
-
1
))
service_counts
=
count
(
Service
.
active
.
where
(
templat
e:
false
).
where
.
not
(
type:
'JiraService'
).
group
(
:type
),
fallback:
Hash
.
new
(
-
1
))
results
=
Service
.
available_services_names
.
each_with_object
({})
do
|
service_name
,
response
|
results
=
Service
.
available_services_names
.
each_with_object
({})
do
|
service_name
,
response
|
response
[
"projects_
#{
service_name
}
_active"
.
to_sym
]
=
service_counts
[
"
#{
service_name
}
_service"
.
camelize
]
||
0
response
[
"projects_
#{
service_name
}
_active"
.
to_sym
]
=
service_counts
[
"
#{
service_name
}
_service"
.
camelize
]
||
0
...
...
qa/qa.rb
View file @
1ca9950d
...
@@ -469,6 +469,7 @@ module QA
...
@@ -469,6 +469,7 @@ module QA
autoload
:Configure
,
'qa/vendor/jenkins/page/configure'
autoload
:Configure
,
'qa/vendor/jenkins/page/configure'
autoload
:NewCredentials
,
'qa/vendor/jenkins/page/new_credentials'
autoload
:NewCredentials
,
'qa/vendor/jenkins/page/new_credentials'
autoload
:NewJob
,
'qa/vendor/jenkins/page/new_job'
autoload
:NewJob
,
'qa/vendor/jenkins/page/new_job'
autoload
:Job
,
'qa/vendor/jenkins/page/job'
autoload
:ConfigureJob
,
'qa/vendor/jenkins/page/configure_job'
autoload
:ConfigureJob
,
'qa/vendor/jenkins/page/configure_job'
end
end
end
end
...
...
qa/qa/vendor/jenkins/page/job.rb
0 → 100644
View file @
1ca9950d
# frozen_string_literal: true
require
'capybara/dsl'
module
QA
module
Vendor
module
Jenkins
module
Page
class
Job
<
Page
::
Base
attr_accessor
:job_name
def
path
"/job/
#{
@job_name
}
"
end
def
has_successful_build?
page
.
has_text?
(
"Last successful build"
)
end
end
end
end
end
end
spec/controllers/admin/services_controller_spec.rb
View file @
1ca9950d
...
@@ -15,11 +15,11 @@ describe Admin::ServicesController do
...
@@ -15,11 +15,11 @@ describe Admin::ServicesController do
Service
.
available_services_names
.
each
do
|
service_name
|
Service
.
available_services_names
.
each
do
|
service_name
|
context
"
#{
service_name
}
"
do
context
"
#{
service_name
}
"
do
let!
(
:service
)
do
let!
(
:service
)
do
service_
instanc
e
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service_
templat
e
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service_
instance
.
where
(
instanc
e:
true
).
first_or_create
service_
template
.
where
(
templat
e:
true
).
first_or_create
end
end
it
'successfully displays the
servic
e'
do
it
'successfully displays the
templat
e'
do
get
:edit
,
params:
{
id:
service
.
id
}
get
:edit
,
params:
{
id:
service
.
id
}
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
...
@@ -34,7 +34,7 @@ describe Admin::ServicesController do
...
@@ -34,7 +34,7 @@ describe Admin::ServicesController do
RedmineService
.
create
(
RedmineService
.
create
(
project:
project
,
project:
project
,
active:
false
,
active:
false
,
instanc
e:
true
,
templat
e:
true
,
properties:
{
properties:
{
project_url:
'http://abc'
,
project_url:
'http://abc'
,
issues_url:
'http://abc'
,
issues_url:
'http://abc'
,
...
@@ -44,7 +44,7 @@ describe Admin::ServicesController do
...
@@ -44,7 +44,7 @@ describe Admin::ServicesController do
end
end
it
'calls the propagation worker when service is active'
do
it
'calls the propagation worker when service is active'
do
expect
(
Propagate
InstanceLevelServic
eWorker
).
to
receive
(
:perform_async
).
with
(
service
.
id
)
expect
(
Propagate
ServiceTemplat
eWorker
).
to
receive
(
:perform_async
).
with
(
service
.
id
)
put
:update
,
params:
{
id:
service
.
id
,
service:
{
active:
true
}
}
put
:update
,
params:
{
id:
service
.
id
,
service:
{
active:
true
}
}
...
@@ -52,7 +52,7 @@ describe Admin::ServicesController do
...
@@ -52,7 +52,7 @@ describe Admin::ServicesController do
end
end
it
'does not call the propagation worker when service is not active'
do
it
'does not call the propagation worker when service is not active'
do
expect
(
Propagate
InstanceLevelServic
eWorker
).
not_to
receive
(
:perform_async
)
expect
(
Propagate
ServiceTemplat
eWorker
).
not_to
receive
(
:perform_async
)
put
:update
,
params:
{
id:
service
.
id
,
service:
{
properties:
{}
}
}
put
:update
,
params:
{
id:
service
.
id
,
service:
{
properties:
{}
}
}
...
...
spec/controllers/projects/serverless/functions_controller_spec.rb
View file @
1ca9950d
...
@@ -14,9 +14,11 @@ describe Projects::Serverless::FunctionsController do
...
@@ -14,9 +14,11 @@ describe Projects::Serverless::FunctionsController do
let!
(
:deployment
)
{
create
(
:deployment
,
:success
,
environment:
environment
,
cluster:
cluster
)
}
let!
(
:deployment
)
{
create
(
:deployment
,
:success
,
environment:
environment
,
cluster:
cluster
)
}
let
(
:knative_services_finder
)
{
environment
.
knative_services_finder
}
let
(
:knative_services_finder
)
{
environment
.
knative_services_finder
}
let
(
:function_description
)
{
'A serverless function'
}
let
(
:function_description
)
{
'A serverless function'
}
let
(
:function_name
)
{
'some-function-name'
}
let
(
:knative_stub_options
)
do
let
(
:knative_stub_options
)
do
{
namespace:
namespace
.
namespace
,
name:
cluster
.
project
.
name
,
description:
function_description
}
{
namespace:
namespace
.
namespace
,
name:
function_
name
,
description:
function_description
}
end
end
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
let
(
:namespace
)
do
let
(
:namespace
)
do
create
(
:cluster_kubernetes_namespace
,
create
(
:cluster_kubernetes_namespace
,
...
@@ -87,25 +89,65 @@ describe Projects::Serverless::FunctionsController do
...
@@ -87,25 +89,65 @@ describe Projects::Serverless::FunctionsController do
end
end
context
'when functions were found'
do
context
'when functions were found'
do
let
(
:functions
)
{
[
"asdf"
]
}
let
(
:functions
)
{
[
{},
{}
]
}
before
do
before
do
stub_kubeclient_knative_services
(
namespace:
namespace
.
namespace
)
stub_kubeclient_knative_services
(
namespace:
namespace
.
namespace
,
cluster_id:
cluster
.
id
,
name:
function_name
)
get
:index
,
params:
params
({
format: :json
})
end
end
it
'returns functions'
do
it
'returns functions'
do
get
:index
,
params:
params
({
format: :json
})
expect
(
json_response
[
"functions"
]).
not_to
be_empty
expect
(
json_response
[
"functions"
]).
not_to
be_empty
end
end
it
{
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
}
it
'filters out the functions whose cluster the user does not have permission to read'
do
allow
(
controller
).
to
receive
(
:can?
).
and_return
(
true
)
expect
(
controller
).
to
receive
(
:can?
).
with
(
user
,
:read_cluster
,
cluster
).
and_return
(
false
)
get
:index
,
params:
params
({
format: :json
})
expect
(
json_response
[
"functions"
]).
to
be_empty
end
it
'returns a successful response status'
do
get
:index
,
params:
params
({
format: :json
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
end
context
'when there is serverless domain for a cluster'
do
let!
(
:serverless_domain_cluster
)
do
create
(
:serverless_domain_cluster
,
clusters_applications_knative_id:
knative
.
id
)
end
it
'returns JSON with function details with serverless domain URL'
do
get
:index
,
params:
params
({
format: :json
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
"functions"
]).
not_to
be_empty
expect
(
json_response
[
"functions"
]).
to
all
(
include
(
'url'
=>
"https://
#{
function_name
}
-
#{
serverless_domain_cluster
.
uuid
[
0
..
1
]
}
a1
#{
serverless_domain_cluster
.
uuid
[
2
..-
3
]
}
f2
#{
serverless_domain_cluster
.
uuid
[
-
2
..-
1
]
}#{
"%x"
%
environment
.
id
}
-
#{
environment
.
slug
}
.
#{
serverless_domain_cluster
.
domain
}
"
)
)
end
end
context
'when there is no serverless domain for a cluster'
do
it
'keeps function URL as it was'
do
expect
(
Gitlab
::
Serverless
::
Domain
).
not_to
receive
(
:new
)
get
:index
,
params:
params
({
format: :json
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
end
end
end
end
end
end
end
end
describe
'GET #show'
do
describe
'GET #show'
do
context
'
invalid data
'
do
context
'
with function that does not exist
'
do
it
'
has a bad function name
'
do
it
'
returns 404
'
do
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
"foo"
})
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
"foo"
})
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
...
@@ -113,15 +155,50 @@ describe Projects::Serverless::FunctionsController do
...
@@ -113,15 +155,50 @@ describe Projects::Serverless::FunctionsController do
context
'with valid data'
,
:use_clean_rails_memory_store_caching
do
context
'with valid data'
,
:use_clean_rails_memory_store_caching
do
shared_examples
'GET #show with valid data'
do
shared_examples
'GET #show with valid data'
do
it
'has a valid function name'
do
context
'when there is serverless domain for a cluster'
do
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
cluster
.
project
.
name
})
let!
(
:serverless_domain_cluster
)
do
create
(
:serverless_domain_cluster
,
clusters_applications_knative_id:
knative
.
id
)
end
it
'returns JSON with function details with serverless domain URL'
do
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
function_name
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
include
(
'url'
=>
"https://
#{
function_name
}
-
#{
serverless_domain_cluster
.
uuid
[
0
..
1
]
}
a1
#{
serverless_domain_cluster
.
uuid
[
2
..-
3
]
}
f2
#{
serverless_domain_cluster
.
uuid
[
-
2
..-
1
]
}#{
"%x"
%
environment
.
id
}
-
#{
environment
.
slug
}
.
#{
serverless_domain_cluster
.
domain
}
"
)
end
it
'returns 404 when user does not have permission to read the cluster'
do
allow
(
controller
).
to
receive
(
:can?
).
and_return
(
true
)
expect
(
controller
).
to
receive
(
:can?
).
with
(
user
,
:read_cluster
,
cluster
).
and_return
(
false
)
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
function_name
})
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when there is no serverless domain for a cluster'
do
it
'keeps function URL as it was'
do
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
function_name
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
include
(
'url'
=>
"http://
#{
function_name
}
.
#{
namespace
.
namespace
}
.example.com"
)
end
end
it
'return json with function details'
do
get
:show
,
params:
params
({
format: :json
,
environment_id:
"*"
,
id:
function_name
})
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
include
(
expect
(
json_response
).
to
include
(
'name'
=>
project
.
name
,
'name'
=>
function_
name
,
'url'
=>
"http://
#{
project
.
name
}
.
#{
namespace
.
namespace
}
.example.com"
,
'url'
=>
"http://
#{
function_
name
}
.
#{
namespace
.
namespace
}
.example.com"
,
'description'
=>
function_description
,
'description'
=>
function_description
,
'podcount'
=>
1
'podcount'
=>
0
)
)
end
end
end
end
...
@@ -180,8 +257,8 @@ describe Projects::Serverless::FunctionsController do
...
@@ -180,8 +257,8 @@ describe Projects::Serverless::FunctionsController do
'knative_installed'
=>
'checking'
,
'knative_installed'
=>
'checking'
,
'functions'
=>
[
'functions'
=>
[
a_hash_including
(
a_hash_including
(
'name'
=>
project
.
name
,
'name'
=>
function_
name
,
'url'
=>
"http://
#{
project
.
name
}
.
#{
namespace
.
namespace
}
.example.com"
,
'url'
=>
"http://
#{
function_
name
}
.
#{
namespace
.
namespace
}
.example.com"
,
'description'
=>
function_description
'description'
=>
function_description
)
)
]
]
...
...
spec/controllers/projects/services_controller_spec.rb
View file @
1ca9950d
...
@@ -154,12 +154,12 @@ describe Projects::ServicesController do
...
@@ -154,12 +154,12 @@ describe Projects::ServicesController do
end
end
end
end
context
'when activating Jira service from
instance level servic
e'
do
context
'when activating Jira service from
a templat
e'
do
let
(
:service
)
do
let
(
:service
)
do
create
(
:jira_service
,
project:
project
,
instanc
e:
true
)
create
(
:jira_service
,
project:
project
,
templat
e:
true
)
end
end
it
'activate Jira service from
instance level servic
e'
do
it
'activate Jira service from
templat
e'
do
expect
(
flash
[
:notice
]).
to
eq
'Jira activated.'
expect
(
flash
[
:notice
]).
to
eq
'Jira activated.'
end
end
end
end
...
...
spec/factories/pages_domains.rb
View file @
1ca9950d
...
@@ -380,5 +380,9 @@ x6zG6WoibsbsJMj70nwseUnPTBQNDP+j61RJjC/r
...
@@ -380,5 +380,9 @@ x6zG6WoibsbsJMj70nwseUnPTBQNDP+j61RJjC/r
scope
{
:instance
}
scope
{
:instance
}
usage
{
:serverless
}
usage
{
:serverless
}
end
end
trait
:with_project
do
association
:project
end
end
end
end
end
spec/finders/projects/serverless/functions_finder_spec.rb
View file @
1ca9950d
...
@@ -153,8 +153,8 @@ describe Projects::Serverless::FunctionsFinder do
...
@@ -153,8 +153,8 @@ describe Projects::Serverless::FunctionsFinder do
*
knative_services_finder
.
cache_args
)
*
knative_services_finder
.
cache_args
)
result
=
finder
.
service
(
cluster
.
environment_scope
,
cluster
.
project
.
name
)
result
=
finder
.
service
(
cluster
.
environment_scope
,
cluster
.
project
.
name
)
expect
(
result
).
not_to
be_empty
expect
(
result
).
to
be_present
expect
(
result
[
"metadata"
][
"name"
]
).
to
be_eql
(
cluster
.
project
.
name
)
expect
(
result
.
name
).
to
be_eql
(
cluster
.
project
.
name
)
end
end
it
'has metrics'
,
:use_clean_rails_memory_store_caching
do
it
'has metrics'
,
:use_clean_rails_memory_store_caching
do
...
...
spec/fixtures/trace/sample_trace
View file @
1ca9950d
...
@@ -2736,7 +2736,7 @@ Service
...
@@ -2736,7 +2736,7 @@ Service
when repository is empty
when repository is empty
test runs execute
test runs execute
Template
Template
.build_from_
instanc
e
.build_from_
templat
e
when template is invalid
when template is invalid
sets service template to inactive when template is invalid
sets service template to inactive when template is invalid
for pushover service
for pushover service
...
...
spec/frontend/environments/environments_app_spec.js
0 → 100644
View file @
1ca9950d
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Container
from
'
~/environments/components/container.vue
'
;
import
EmptyState
from
'
~/environments/components/empty_state.vue
'
;
import
EnvironmentsApp
from
'
~/environments/components/environments_app.vue
'
;
import
{
environment
,
folder
}
from
'
./mock_data
'
;
describe
(
'
Environment
'
,
()
=>
{
let
mock
;
let
wrapper
;
const
mockData
=
{
endpoint
:
'
environments.json
'
,
canCreateEnvironment
:
true
,
canReadEnvironment
:
true
,
newEnvironmentPath
:
'
environments/new
'
,
helpPagePath
:
'
help
'
,
canaryDeploymentFeatureId
:
'
canary_deployment
'
,
showCanaryDeploymentCallout
:
true
,
userCalloutsPath
:
'
/callouts
'
,
lockPromotionSvgPath
:
'
/assets/illustrations/lock-promotion.svg
'
,
helpCanaryDeploymentsPath
:
'
help/canary-deployments
'
,
};
const
mockRequest
=
(
response
,
body
)
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
response
,
body
,
{
'
X-nExt-pAge
'
:
'
2
'
,
'
x-page
'
:
'
1
'
,
'
X-Per-Page
'
:
'
1
'
,
'
X-Prev-Page
'
:
''
,
'
X-TOTAL
'
:
'
37
'
,
'
X-Total-Pages
'
:
'
2
'
,
});
};
const
createWrapper
=
(
shallow
=
false
)
=>
{
const
fn
=
shallow
?
shallowMount
:
mount
;
wrapper
=
fn
(
EnvironmentsApp
,
{
propsData
:
mockData
});
return
axios
.
waitForAll
();
};
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
wrapper
.
destroy
();
mock
.
restore
();
});
describe
(
'
successful request
'
,
()
=>
{
describe
(
'
without environments
'
,
()
=>
{
beforeEach
(()
=>
{
mockRequest
(
200
,
{
environments
:
[]
});
return
createWrapper
(
true
);
});
it
(
'
should render the empty state
'
,
()
=>
{
expect
(
wrapper
.
find
(
EmptyState
).
exists
()).
toBe
(
true
);
});
describe
(
'
when it is possible to enable a review app
'
,
()
=>
{
beforeEach
(()
=>
{
mockRequest
(
200
,
{
environments
:
[],
review_app
:
{
can_setup_review_app
:
true
}
});
return
createWrapper
();
});
it
(
'
should render the enable review app button
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.js-enable-review-app-button
'
).
text
()).
toContain
(
'
Enable review app
'
,
);
});
});
});
describe
(
'
with paginated environments
'
,
()
=>
{
const
environmentList
=
[
environment
];
beforeEach
(()
=>
{
mockRequest
(
200
,
{
environments
:
environmentList
,
stopped_count
:
1
,
available_count
:
0
,
});
return
createWrapper
();
});
it
(
'
should render a conatiner table with environments
'
,
()
=>
{
const
containerTable
=
wrapper
.
find
(
Container
);
expect
(
containerTable
.
exists
()).
toBe
(
true
);
expect
(
containerTable
.
props
(
'
environments
'
).
length
).
toEqual
(
environmentList
.
length
);
expect
(
containerTable
.
find
(
'
.environment-name
'
).
text
()).
toEqual
(
environmentList
[
0
].
name
);
});
describe
(
'
pagination
'
,
()
=>
{
it
(
'
should render pagination
'
,
()
=>
{
expect
(
wrapper
.
findAll
(
'
.gl-pagination li
'
).
length
).
toEqual
(
9
);
});
it
(
'
should make an API request when page is clicked
'
,
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
updateContent
'
).
mockImplementation
(()
=>
{});
wrapper
.
find
(
'
.gl-pagination li:nth-child(3) .page-link
'
).
trigger
(
'
click
'
);
expect
(
wrapper
.
vm
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
'
available
'
,
page
:
'
2
'
});
});
it
(
'
should make an API request when using tabs
'
,
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
updateContent
'
).
mockImplementation
(()
=>
{});
wrapper
.
find
(
'
.js-environments-tab-stopped
'
).
trigger
(
'
click
'
);
expect
(
wrapper
.
vm
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
'
stopped
'
,
page
:
'
1
'
});
});
});
});
});
describe
(
'
unsuccessful request
'
,
()
=>
{
beforeEach
(()
=>
{
mockRequest
(
500
,
{});
return
createWrapper
(
true
);
});
it
(
'
should render empty state
'
,
()
=>
{
expect
(
wrapper
.
find
(
EmptyState
).
exists
()).
toBe
(
true
);
});
});
describe
(
'
expandable folders
'
,
()
=>
{
beforeEach
(()
=>
{
mockRequest
(
200
,
{
environments
:
[
folder
],
stopped_count
:
1
,
available_count
:
0
,
});
mock
.
onGet
(
environment
.
folder_path
).
reply
(
200
,
{
environments
:
[
environment
]
});
return
createWrapper
().
then
(()
=>
{
// open folder
wrapper
.
find
(
'
.folder-name
'
).
trigger
(
'
click
'
);
return
axios
.
waitForAll
();
});
});
it
(
'
should open a closed folder
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.folder-icon.ic-chevron-right
'
).
exists
()).
toBe
(
false
);
});
it
(
'
should close an opened folder
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.folder-icon.ic-chevron-down
'
).
exists
()).
toBe
(
true
);
// close folder
wrapper
.
find
(
'
.folder-name
'
).
trigger
(
'
click
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
wrapper
.
find
(
'
.folder-icon.ic-chevron-down
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
should show children environments
'
,
()
=>
{
expect
(
wrapper
.
findAll
(
'
.js-child-row
'
).
length
).
toEqual
(
1
);
});
it
(
'
should show a button to show all environments
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
.text-center > a.btn
'
).
text
()).
toContain
(
'
Show all
'
);
});
});
});
spec/frontend/monitoring/components/dashboard_spec.js
View file @
1ca9950d
This diff is collapsed.
Click to expand it.
spec/frontend/monitoring/components/dashboards_dropdown_spec.js
View file @
1ca9950d
...
@@ -131,20 +131,17 @@ describe('DashboardsDropdown', () => {
...
@@ -131,20 +131,17 @@ describe('DashboardsDropdown', () => {
expect
(
findModal
().
contains
(
DuplicateDashboardForm
)).
toBe
(
true
);
expect
(
findModal
().
contains
(
DuplicateDashboardForm
)).
toBe
(
true
);
});
});
it
(
'
saves a new dashboard
'
,
done
=>
{
it
(
'
saves a new dashboard
'
,
()
=>
{
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
waitForPromises
()
return
waitForPromises
().
then
(()
=>
{
.
then
(()
=>
{
expect
(
okEvent
.
preventDefault
).
toHaveBeenCalled
();
expect
(
okEvent
.
preventDefault
).
toHaveBeenCalled
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
vm
.
$refs
.
duplicateDashboardModal
.
hide
).
toHaveBeenCalled
();
expect
(
wrapper
.
vm
.
$refs
.
duplicateDashboardModal
.
hide
).
toHaveBeenCalled
();
expect
(
wrapper
.
emitted
().
selectDashboard
).
toBeTruthy
();
expect
(
wrapper
.
emitted
().
selectDashboard
).
toBeTruthy
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
when a new dashboard is saved succesfully
'
,
()
=>
{
describe
(
'
when a new dashboard is saved succesfully
'
,
()
=>
{
...
@@ -167,52 +164,42 @@ describe('DashboardsDropdown', () => {
...
@@ -167,52 +164,42 @@ describe('DashboardsDropdown', () => {
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
};
};
it
(
'
to the default branch, redirects to the new dashboard
'
,
done
=>
{
it
(
'
to the default branch, redirects to the new dashboard
'
,
()
=>
{
submitForm
({
submitForm
({
branch
:
defaultBranch
,
branch
:
defaultBranch
,
});
});
waitForPromises
()
return
waitForPromises
().
then
(()
=>
{
.
then
(()
=>
{
expect
(
wrapper
.
emitted
().
selectDashboard
[
0
][
0
]).
toEqual
(
newDashboard
);
expect
(
wrapper
.
emitted
().
selectDashboard
[
0
][
0
]).
toEqual
(
newDashboard
);
});
done
();
})
.
catch
(
done
.
fail
);
});
});
it
(
'
to a new branch refreshes in the current dashboard
'
,
done
=>
{
it
(
'
to a new branch refreshes in the current dashboard
'
,
()
=>
{
submitForm
({
submitForm
({
branch
:
'
another-branch
'
,
branch
:
'
another-branch
'
,
});
});
waitForPromises
()
return
waitForPromises
().
then
(()
=>
{
.
then
(()
=>
{
expect
(
wrapper
.
emitted
().
selectDashboard
[
0
][
0
]).
toEqual
(
dashboardGitResponse
[
0
]);
expect
(
wrapper
.
emitted
().
selectDashboard
[
0
][
0
]).
toEqual
(
dashboardGitResponse
[
0
]);
});
done
();
})
.
catch
(
done
.
fail
);
});
});
});
});
it
(
'
handles error when a new dashboard is not saved
'
,
done
=>
{
it
(
'
handles error when a new dashboard is not saved
'
,
()
=>
{
const
errMsg
=
'
An error occurred
'
;
const
errMsg
=
'
An error occurred
'
;
duplicateDashboardAction
.
mockRejectedValueOnce
(
errMsg
);
duplicateDashboardAction
.
mockRejectedValueOnce
(
errMsg
);
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
findModal
().
vm
.
$emit
(
'
ok
'
,
okEvent
);
waitForPromises
()
return
waitForPromises
().
then
(()
=>
{
.
then
(()
=>
{
expect
(
okEvent
.
preventDefault
).
toHaveBeenCalled
();
expect
(
okEvent
.
preventDefault
).
toHaveBeenCalled
();
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
errMsg
);
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
fals
e
);
expect
(
findAlert
().
exists
()).
toBe
(
tru
e
);
expect
(
wrapper
.
vm
.
$refs
.
duplicateDashboardModal
.
hide
).
not
.
toHaveBeenCalled
(
);
expect
(
findAlert
().
text
()).
toBe
(
errMsg
);
done
(
);
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
})
expect
(
wrapper
.
vm
.
$refs
.
duplicateDashboardModal
.
hide
).
not
.
toHaveBeenCalled
();
.
catch
(
done
.
fail
);
}
);
});
});
it
(
'
id is correct, as the value of modal directive binding matches modal id
'
,
()
=>
{
it
(
'
id is correct, as the value of modal directive binding matches modal id
'
,
()
=>
{
...
...
spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
View file @
1ca9950d
...
@@ -44,30 +44,27 @@ describe('DuplicateDashboardForm', () => {
...
@@ -44,30 +44,27 @@ describe('DuplicateDashboardForm', () => {
describe
(
'
validates the file name
'
,
()
=>
{
describe
(
'
validates the file name
'
,
()
=>
{
const
findInvalidFeedback
=
()
=>
findByRef
(
'
fileNameFormGroup
'
).
find
(
'
.invalid-feedback
'
);
const
findInvalidFeedback
=
()
=>
findByRef
(
'
fileNameFormGroup
'
).
find
(
'
.invalid-feedback
'
);
it
(
'
when is empty
'
,
done
=>
{
it
(
'
when is empty
'
,
()
=>
{
setValue
(
'
fileName
'
,
''
);
setValue
(
'
fileName
'
,
''
);
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-valid
'
)).
toBe
(
true
);
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-valid
'
)).
toBe
(
true
);
expect
(
findInvalidFeedback
().
exists
()).
toBe
(
false
);
expect
(
findInvalidFeedback
().
exists
()).
toBe
(
false
);
done
();
});
});
});
});
it
(
'
when is valid
'
,
done
=>
{
it
(
'
when is valid
'
,
()
=>
{
setValue
(
'
fileName
'
,
'
my_dashboard.yml
'
);
setValue
(
'
fileName
'
,
'
my_dashboard.yml
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-valid
'
)).
toBe
(
true
);
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-valid
'
)).
toBe
(
true
);
expect
(
findInvalidFeedback
().
exists
()).
toBe
(
false
);
expect
(
findInvalidFeedback
().
exists
()).
toBe
(
false
);
done
();
});
});
});
});
it
(
'
when is not valid
'
,
done
=>
{
it
(
'
when is not valid
'
,
()
=>
{
setValue
(
'
fileName
'
,
'
my_dashboard.exe
'
);
setValue
(
'
fileName
'
,
'
my_dashboard.exe
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-invalid
'
)).
toBe
(
true
);
expect
(
findByRef
(
'
fileNameFormGroup
'
).
is
(
'
.is-invalid
'
)).
toBe
(
true
);
expect
(
findInvalidFeedback
().
text
()).
toBeTruthy
();
expect
(
findInvalidFeedback
().
text
()).
toBeTruthy
();
done
();
});
});
});
});
});
});
...
@@ -124,30 +121,26 @@ describe('DuplicateDashboardForm', () => {
...
@@ -124,30 +121,26 @@ describe('DuplicateDashboardForm', () => {
});
});
});
});
it
(
'
when a `default` branch option is set, branch input is invisible and ignored
'
,
done
=>
{
it
(
'
when a `default` branch option is set, branch input is invisible and ignored
'
,
()
=>
{
setChecked
(
wrapper
.
vm
.
$options
.
radioVals
.
DEFAULT
);
setChecked
(
wrapper
.
vm
.
$options
.
radioVals
.
DEFAULT
);
setValue
(
'
branchName
'
,
'
a-new-branch
'
);
setValue
(
'
branchName
'
,
'
a-new-branch
'
);
expect
(
lastChange
()).
resolves
.
toMatchObject
({
expect
(
lastChange
()).
resolves
.
toMatchObject
({
branch
:
defaultBranch
,
branch
:
defaultBranch
,
});
});
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findByRef
(
'
branchName
'
).
isVisible
()).
toBe
(
false
);
expect
(
findByRef
(
'
branchName
'
).
isVisible
()).
toBe
(
false
);
done
();
});
});
});
});
it
(
'
when `new` branch option is chosen, focuses on the branch name input
'
,
done
=>
{
it
(
'
when `new` branch option is chosen, focuses on the branch name input
'
,
()
=>
{
setChecked
(
wrapper
.
vm
.
$options
.
radioVals
.
NEW
);
setChecked
(
wrapper
.
vm
.
$options
.
radioVals
.
NEW
);
wrapper
.
vm
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
.
$nextTick
()
wrapper
.
find
(
'
form
'
).
trigger
(
'
change
'
);
.
then
(()
=>
{
expect
(
findByRef
(
'
branchName
'
).
is
(
'
:focus
'
)).
toBe
(
true
);
wrapper
.
find
(
'
form
'
).
trigger
(
'
change
'
);
});
expect
(
findByRef
(
'
branchName
'
).
is
(
'
:focus
'
)).
toBe
(
true
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
});
});
});
spec/frontend/monitoring/components/graph_group_spec.js
View file @
1ca9950d
...
@@ -32,25 +32,23 @@ describe('Graph group component', () => {
...
@@ -32,25 +32,23 @@ describe('Graph group component', () => {
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
});
});
it
(
'
should show the angle-right caret icon when the user collapses the group
'
,
done
=>
{
it
(
'
should show the angle-right caret icon when the user collapses the group
'
,
()
=>
{
wrapper
.
vm
.
collapse
();
wrapper
.
vm
.
collapse
();
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findContent
().
isVisible
()).
toBe
(
false
);
expect
(
findContent
().
isVisible
()).
toBe
(
false
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-right
'
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-right
'
);
done
();
});
});
});
});
it
(
'
should show the open the group when collapseGroup is set to true
'
,
done
=>
{
it
(
'
should show the open the group when collapseGroup is set to true
'
,
()
=>
{
wrapper
.
setProps
({
wrapper
.
setProps
({
collapseGroup
:
true
,
collapseGroup
:
true
,
});
});
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
done
();
});
});
});
});
...
@@ -102,13 +100,12 @@ describe('Graph group component', () => {
...
@@ -102,13 +100,12 @@ describe('Graph group component', () => {
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should show the panel content when clicked
'
,
done
=>
{
it
(
'
should show the panel content when clicked
'
,
()
=>
{
wrapper
.
vm
.
collapse
();
wrapper
.
vm
.
collapse
();
wrapper
.
vm
.
$nextTick
(()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
done
();
});
});
});
});
});
});
...
...
spec/frontend/monitoring/components/panel_type_spec.js
View file @
1ca9950d
...
@@ -28,6 +28,8 @@ describe('Panel Type component', () => {
...
@@ -28,6 +28,8 @@ describe('Panel Type component', () => {
const
exampleText
=
'
example_text
'
;
const
exampleText
=
'
example_text
'
;
const
findCopyLink
=
()
=>
wrapper
.
find
({
ref
:
'
copyChartLink
'
});
const
createWrapper
=
props
=>
{
const
createWrapper
=
props
=>
{
wrapper
=
shallowMount
(
PanelType
,
{
wrapper
=
shallowMount
(
PanelType
,
{
propsData
:
{
propsData
:
{
...
@@ -96,8 +98,7 @@ describe('Panel Type component', () => {
...
@@ -96,8 +98,7 @@ describe('Panel Type component', () => {
});
});
it
(
'
sets no clipboard copy link on dropdown by default
'
,
()
=>
{
it
(
'
sets no clipboard copy link on dropdown by default
'
,
()
=>
{
const
link
=
()
=>
wrapper
.
find
({
ref
:
'
copyChartLink
'
});
expect
(
findCopyLink
().
exists
()).
toBe
(
false
);
expect
(
link
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
Time Series Chart panel type
'
,
()
=>
{
describe
(
'
Time Series Chart panel type
'
,
()
=>
{
...
@@ -204,7 +205,6 @@ describe('Panel Type component', () => {
...
@@ -204,7 +205,6 @@ describe('Panel Type component', () => {
});
});
describe
(
'
when cliboard data is available
'
,
()
=>
{
describe
(
'
when cliboard data is available
'
,
()
=>
{
const
link
=
()
=>
wrapper
.
find
({
ref
:
'
copyChartLink
'
});
const
clipboardText
=
'
A value to copy.
'
;
const
clipboardText
=
'
A value to copy.
'
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
...
@@ -219,16 +219,16 @@ describe('Panel Type component', () => {
...
@@ -219,16 +219,16 @@ describe('Panel Type component', () => {
});
});
it
(
'
sets clipboard text on the dropdown
'
,
()
=>
{
it
(
'
sets clipboard text on the dropdown
'
,
()
=>
{
expect
(
l
ink
().
exists
()).
toBe
(
true
);
expect
(
findCopyL
ink
().
exists
()).
toBe
(
true
);
expect
(
l
ink
().
element
.
dataset
.
clipboardText
).
toBe
(
clipboardText
);
expect
(
findCopyL
ink
().
element
.
dataset
.
clipboardText
).
toBe
(
clipboardText
);
});
});
it
(
'
adds a copy button to the dropdown
'
,
()
=>
{
it
(
'
adds a copy button to the dropdown
'
,
()
=>
{
expect
(
l
ink
().
text
()).
toContain
(
'
Generate link to chart
'
);
expect
(
findCopyL
ink
().
text
()).
toContain
(
'
Generate link to chart
'
);
});
});
it
(
'
opens a toast on click
'
,
()
=>
{
it
(
'
opens a toast on click
'
,
()
=>
{
l
ink
().
vm
.
$emit
(
'
click
'
);
findCopyL
ink
().
vm
.
$emit
(
'
click
'
);
expect
(
wrapper
.
vm
.
$toast
.
show
).
toHaveBeenCalled
();
expect
(
wrapper
.
vm
.
$toast
.
show
).
toHaveBeenCalled
();
});
});
...
...
spec/graphql/types/snippets/blob_type_spec.rb
View file @
1ca9950d
...
@@ -4,10 +4,9 @@ require 'spec_helper'
...
@@ -4,10 +4,9 @@ require 'spec_helper'
describe
GitlabSchema
.
types
[
'SnippetBlob'
]
do
describe
GitlabSchema
.
types
[
'SnippetBlob'
]
do
it
'has the correct fields'
do
it
'has the correct fields'
do
expected_fields
=
[
:highlighted_data
,
:raw_path
,
expected_fields
=
[
:highlighted_data
,
:plain_highlighted_data
,
:size
,
:binary
,
:name
,
:path
,
:raw_path
,
:size
,
:binary
,
:name
,
:path
,
:simple_viewer
,
:rich_viewer
,
:simple_viewer
,
:rich_viewer
,
:mode
]
:mode
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
end
end
...
...
spec/javascripts/environments/environments_app_spec.js
deleted
100644 → 0
View file @
bcc77054
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
environmentsComponent
from
'
~/environments/components/environments_app.vue
'
;
import
{
environment
,
folder
}
from
'
./mock_data
'
;
describe
(
'
Environment
'
,
()
=>
{
const
mockData
=
{
endpoint
:
'
environments.json
'
,
canCreateEnvironment
:
true
,
canReadEnvironment
:
true
,
newEnvironmentPath
:
'
environments/new
'
,
helpPagePath
:
'
help
'
,
canaryDeploymentFeatureId
:
'
canary_deployment
'
,
showCanaryDeploymentCallout
:
true
,
userCalloutsPath
:
'
/callouts
'
,
lockPromotionSvgPath
:
'
/assets/illustrations/lock-promotion.svg
'
,
helpCanaryDeploymentsPath
:
'
help/canary-deployments
'
,
};
let
EnvironmentsComponent
;
let
component
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
EnvironmentsComponent
=
Vue
.
extend
(
environmentsComponent
);
});
afterEach
(()
=>
{
component
.
$destroy
();
mock
.
restore
();
});
describe
(
'
successful request
'
,
()
=>
{
describe
(
'
without environments
'
,
()
=>
{
beforeEach
(
done
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
200
,
{
environments
:
[]
});
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
setTimeout
(()
=>
{
done
();
},
0
);
});
it
(
'
should render the empty state
'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.js-new-environment-button
'
).
textContent
).
toContain
(
'
New environment
'
,
);
expect
(
component
.
$el
.
querySelector
(
'
.js-blank-state-title
'
).
textContent
).
toContain
(
"
You don't have any environments right now
"
,
);
});
describe
(
'
when it is possible to enable a review app
'
,
()
=>
{
beforeEach
(
done
=>
{
mock
.
onGet
(
mockData
.
endpoint
)
.
reply
(
200
,
{
environments
:
[],
review_app
:
{
can_setup_review_app
:
true
}
});
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
setTimeout
(()
=>
{
done
();
},
0
);
});
it
(
'
should render the enable review app button
'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.js-enable-review-app-button
'
).
textContent
).
toContain
(
'
Enable review app
'
,
);
});
});
});
describe
(
'
with paginated environments
'
,
()
=>
{
beforeEach
(
done
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
200
,
{
environments
:
[
environment
],
stopped_count
:
1
,
available_count
:
0
,
},
{
'
X-nExt-pAge
'
:
'
2
'
,
'
x-page
'
:
'
1
'
,
'
X-Per-Page
'
:
'
1
'
,
'
X-Prev-Page
'
:
''
,
'
X-TOTAL
'
:
'
37
'
,
'
X-Total-Pages
'
:
'
2
'
,
},
);
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
setTimeout
(()
=>
{
done
();
},
0
);
});
it
(
'
should render a table with environments
'
,
()
=>
{
expect
(
component
.
$el
.
querySelectorAll
(
'
table
'
)).
not
.
toBeNull
();
expect
(
component
.
$el
.
querySelector
(
'
.environment-name
'
).
textContent
.
trim
()).
toEqual
(
environment
.
name
,
);
});
describe
(
'
pagination
'
,
()
=>
{
it
(
'
should render pagination
'
,
()
=>
{
expect
(
component
.
$el
.
querySelectorAll
(
'
.gl-pagination li
'
).
length
).
toEqual
(
9
);
});
it
(
'
should make an API request when page is clicked
'
,
done
=>
{
spyOn
(
component
,
'
updateContent
'
);
setTimeout
(()
=>
{
component
.
$el
.
querySelector
(
'
.gl-pagination li:nth-child(3) .page-link
'
).
click
();
expect
(
component
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
'
available
'
,
page
:
'
2
'
});
done
();
},
0
);
});
it
(
'
should make an API request when using tabs
'
,
done
=>
{
setTimeout
(()
=>
{
spyOn
(
component
,
'
updateContent
'
);
component
.
$el
.
querySelector
(
'
.js-environments-tab-stopped
'
).
click
();
expect
(
component
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
'
stopped
'
,
page
:
'
1
'
});
done
();
},
0
);
});
});
});
});
describe
(
'
unsuccessfull request
'
,
()
=>
{
beforeEach
(
done
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
500
,
{});
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
setTimeout
(()
=>
{
done
();
},
0
);
});
it
(
'
should render empty state
'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.js-blank-state-title
'
).
textContent
).
toContain
(
"
You don't have any environments right now
"
,
);
});
});
describe
(
'
expandable folders
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
200
,
{
environments
:
[
folder
],
stopped_count
:
0
,
available_count
:
1
,
},
{
'
X-nExt-pAge
'
:
'
2
'
,
'
x-page
'
:
'
1
'
,
'
X-Per-Page
'
:
'
1
'
,
'
X-Prev-Page
'
:
''
,
'
X-TOTAL
'
:
'
37
'
,
'
X-Total-Pages
'
:
'
2
'
,
},
);
mock
.
onGet
(
environment
.
folder_path
).
reply
(
200
,
{
environments
:
[
environment
]
});
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
});
it
(
'
should open a closed folder
'
,
done
=>
{
setTimeout
(()
=>
{
component
.
$el
.
querySelector
(
'
.folder-name
'
).
click
();
Vue
.
nextTick
(()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.folder-icon.ic-chevron-right
'
)).
toBe
(
null
);
done
();
});
},
0
);
});
it
(
'
should close an opened folder
'
,
done
=>
{
setTimeout
(()
=>
{
// open folder
component
.
$el
.
querySelector
(
'
.folder-name
'
).
click
();
Vue
.
nextTick
(()
=>
{
// close folder
component
.
$el
.
querySelector
(
'
.folder-name
'
).
click
();
Vue
.
nextTick
(()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.folder-icon.ic-chevron-down
'
)).
toBe
(
null
);
done
();
});
});
},
0
);
});
it
(
'
should show children environments and a button to show all environments
'
,
done
=>
{
setTimeout
(()
=>
{
// open folder
component
.
$el
.
querySelector
(
'
.folder-name
'
).
click
();
Vue
.
nextTick
(()
=>
{
// wait for next async request
setTimeout
(()
=>
{
expect
(
component
.
$el
.
querySelectorAll
(
'
.js-child-row
'
).
length
).
toEqual
(
1
);
expect
(
component
.
$el
.
querySelector
(
'
.text-center > a.btn
'
).
textContent
).
toContain
(
'
Show all
'
,
);
done
();
});
});
},
0
);
});
});
describe
(
'
methods
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
mockData
.
endpoint
).
reply
(
200
,
{
environments
:
[],
stopped_count
:
0
,
available_count
:
1
,
},
{},
);
component
=
mountComponent
(
EnvironmentsComponent
,
mockData
);
spyOn
(
window
.
history
,
'
pushState
'
).
and
.
stub
();
});
describe
(
'
updateContent
'
,
()
=>
{
it
(
'
should set given parameters
'
,
done
=>
{
component
.
updateContent
({
scope
:
'
stopped
'
,
page
:
'
3
'
})
.
then
(()
=>
{
expect
(
component
.
page
).
toEqual
(
'
3
'
);
expect
(
component
.
scope
).
toEqual
(
'
stopped
'
);
expect
(
component
.
requestData
.
scope
).
toEqual
(
'
stopped
'
);
expect
(
component
.
requestData
.
page
).
toEqual
(
'
3
'
);
done
();
})
.
catch
(
done
.
fail
);
});
});
describe
(
'
onChangeTab
'
,
()
=>
{
it
(
'
should set page to 1
'
,
()
=>
{
spyOn
(
component
,
'
updateContent
'
);
component
.
onChangeTab
(
'
stopped
'
);
expect
(
component
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
'
stopped
'
,
page
:
'
1
'
});
});
});
describe
(
'
onChangePage
'
,
()
=>
{
it
(
'
should update page and keep scope
'
,
()
=>
{
spyOn
(
component
,
'
updateContent
'
);
component
.
onChangePage
(
4
);
expect
(
component
.
updateContent
).
toHaveBeenCalledWith
({
scope
:
component
.
scope
,
page
:
'
4
'
});
});
});
});
});
spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
View file @
1ca9950d
...
@@ -652,10 +652,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
...
@@ -652,10 +652,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
setup_import_export_config
(
'light'
)
setup_import_export_config
(
'light'
)
end
end
it
'does not import any
instance-level
services'
do
it
'does not import any
templated
services'
do
expect
(
restored_project_json
).
to
eq
(
true
)
expect
(
restored_project_json
).
to
eq
(
true
)
expect
(
project
.
services
.
where
(
instanc
e:
true
).
count
).
to
eq
(
0
)
expect
(
project
.
services
.
where
(
templat
e:
true
).
count
).
to
eq
(
0
)
end
end
it
'imports labels'
do
it
'imports labels'
do
...
...
spec/lib/gitlab/import_export/safe_model_attributes.yml
View file @
1ca9950d
...
@@ -453,7 +453,7 @@ Service:
...
@@ -453,7 +453,7 @@ Service:
-
updated_at
-
updated_at
-
active
-
active
-
properties
-
properties
-
instanc
e
-
templat
e
-
push_events
-
push_events
-
issues_events
-
issues_events
-
commit_events
-
commit_events
...
...
spec/lib/gitlab/serverless/service_spec.rb
0 → 100644
View file @
1ca9950d
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
Serverless
::
Service
do
let
(
:cluster
)
{
create
(
:cluster
)
}
let
(
:environment
)
{
create
(
:environment
)
}
let
(
:attributes
)
do
{
'apiVersion'
=>
'serving.knative.dev/v1alpha1'
,
'kind'
=>
'Service'
,
'metadata'
=>
{
'creationTimestamp'
=>
'2019-10-22T21:19:13Z'
,
'name'
=>
'kubetest'
,
'namespace'
=>
'project1-1-environment1'
},
'spec'
=>
{
'runLatest'
=>
{
'configuration'
=>
{
'build'
=>
{
'template'
=>
{
'name'
=>
'some-image'
}
}
}
}
},
'environment_scope'
=>
'*'
,
'cluster'
=>
cluster
,
'environment'
=>
environment
,
'podcount'
=>
0
}
end
it
'exposes methods extracting data from the attributes hash'
do
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
expect
(
service
.
name
).
to
eq
(
'kubetest'
)
expect
(
service
.
namespace
).
to
eq
(
'project1-1-environment1'
)
expect
(
service
.
environment_scope
).
to
eq
(
'*'
)
expect
(
service
.
podcount
).
to
eq
(
0
)
expect
(
service
.
created_at
).
to
eq
(
DateTime
.
parse
(
'2019-10-22T21:19:13Z'
))
expect
(
service
.
image
).
to
eq
(
'some-image'
)
expect
(
service
.
cluster
).
to
eq
(
cluster
)
expect
(
service
.
environment
).
to
eq
(
environment
)
end
it
'returns nil for missing attributes'
do
service
=
Gitlab
::
Serverless
::
Service
.
new
({})
[
:name
,
:namespace
,
:environment_scope
,
:cluster
,
:podcount
,
:created_at
,
:image
,
:description
,
:url
,
:environment
].
each
do
|
method
|
expect
(
service
.
send
(
method
)).
to
be_nil
end
end
describe
'#description'
do
it
'extracts the description in knative 7 format if available'
do
attributes
=
{
'spec'
=>
{
'template'
=>
{
'metadata'
=>
{
'annotations'
=>
{
'Description'
=>
'some description'
}
}
}
}
}
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
expect
(
service
.
description
).
to
eq
(
'some description'
)
end
it
'extracts the description in knative 5/6 format if 7 is not available'
do
attributes
=
{
'spec'
=>
{
'runLatest'
=>
{
'configuration'
=>
{
'revisionTemplate'
=>
{
'metadata'
=>
{
'annotations'
=>
{
'Description'
=>
'some description'
}
}
}
}
}
}
}
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
expect
(
service
.
description
).
to
eq
(
'some description'
)
end
end
describe
'#url'
do
it
'returns proxy URL if cluster has serverless domain'
do
# cluster = create(:cluster)
knative
=
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
create
(
:serverless_domain_cluster
,
clusters_applications_knative_id:
knative
.
id
)
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
.
merge
(
'cluster'
=>
cluster
))
expect
(
Gitlab
::
Serverless
::
FunctionURI
).
to
receive
(
:new
).
with
(
function:
service
.
name
,
cluster:
service
.
cluster
.
serverless_domain
,
environment:
service
.
environment
).
and_return
(
'https://proxy.example.com'
)
expect
(
service
.
url
).
to
eq
(
'https://proxy.example.com'
)
end
it
'returns the URL from the knative 6/7 format'
do
attributes
=
{
'status'
=>
{
'url'
=>
'https://example.com'
}
}
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
expect
(
service
.
url
).
to
eq
(
'https://example.com'
)
end
it
'returns the URL from the knative 5 format'
do
attributes
=
{
'status'
=>
{
'domain'
=>
'example.com'
}
}
service
=
Gitlab
::
Serverless
::
Service
.
new
(
attributes
)
expect
(
service
.
url
).
to
eq
(
'http://example.com'
)
end
end
end
spec/lib/gitlab/usage_data_spec.rb
View file @
1ca9950d
...
@@ -18,7 +18,7 @@ describe Gitlab::UsageData do
...
@@ -18,7 +18,7 @@ describe Gitlab::UsageData do
create
(
:service
,
project:
projects
[
1
],
type:
'SlackService'
,
active:
true
)
create
(
:service
,
project:
projects
[
1
],
type:
'SlackService'
,
active:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'SlackService'
,
active:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'SlackService'
,
active:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'MattermostService'
,
active:
false
)
create
(
:service
,
project:
projects
[
2
],
type:
'MattermostService'
,
active:
false
)
create
(
:service
,
project:
projects
[
2
],
type:
'MattermostService'
,
active:
true
,
instanc
e:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'MattermostService'
,
active:
true
,
templat
e:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'CustomIssueTrackerService'
,
active:
true
)
create
(
:service
,
project:
projects
[
2
],
type:
'CustomIssueTrackerService'
,
active:
true
)
create
(
:project_error_tracking_setting
,
project:
projects
[
0
])
create
(
:project_error_tracking_setting
,
project:
projects
[
0
])
create
(
:project_error_tracking_setting
,
project:
projects
[
1
],
enabled:
false
)
create
(
:project_error_tracking_setting
,
project:
projects
[
1
],
enabled:
false
)
...
...
spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb
deleted
100644 → 0
View file @
bcc77054
# frozen_string_literal: true
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'post_migrate'
,
'20200206111847_migrate_propagate_service_template_sidekiq_queue.rb'
)
describe
MigratePropagateServiceTemplateSidekiqQueue
,
:sidekiq
,
:redis
do
include
Gitlab
::
Database
::
MigrationHelpers
include
StubWorker
context
'when there are jobs in the queue'
do
it
'correctly migrates queue when migrating up'
do
Sidekiq
::
Testing
.
disable!
do
stub_worker
(
queue:
'propagate_service_template'
).
perform_async
(
'Something'
,
[
1
])
stub_worker
(
queue:
'propagate_instance_level_service'
).
perform_async
(
'Something'
,
[
1
])
described_class
.
new
.
up
expect
(
sidekiq_queue_length
(
'propagate_service_template'
)).
to
eq
0
expect
(
sidekiq_queue_length
(
'propagate_instance_level_service'
)).
to
eq
2
end
end
end
context
'when there are no jobs in the queues'
do
it
'does not raise error when migrating up'
do
expect
{
described_class
.
new
.
up
}.
not_to
raise_error
end
end
end
spec/models/service_spec.rb
View file @
1ca9950d
...
@@ -97,23 +97,23 @@ describe Service do
...
@@ -97,23 +97,23 @@ describe Service do
end
end
end
end
describe
"
Instanc
e"
do
describe
"
Templat
e"
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
describe
'.build_from_
instanc
e'
do
describe
'.build_from_
templat
e'
do
context
'when
instance level integration
is invalid'
do
context
'when
template
is invalid'
do
it
'sets
instance level integration to inactive when instanc
e is invalid'
do
it
'sets
service template to inactive when templat
e is invalid'
do
instance
=
build
(
:prometheus_service
,
instanc
e:
true
,
active:
true
,
properties:
{})
template
=
build
(
:prometheus_service
,
templat
e:
true
,
active:
true
,
properties:
{})
instanc
e
.
save
(
validate:
false
)
templat
e
.
save
(
validate:
false
)
service
=
described_class
.
build_from_
instance
(
project
.
id
,
instanc
e
)
service
=
described_class
.
build_from_
template
(
project
.
id
,
templat
e
)
expect
(
service
).
to
be_valid
expect
(
service
).
to
be_valid
expect
(
service
.
active
).
to
be
false
expect
(
service
.
active
).
to
be
false
end
end
end
end
describe
'build issue tracker from a
instance level integration
'
do
describe
'build issue tracker from a
template
'
do
let
(
:title
)
{
'custom title'
}
let
(
:title
)
{
'custom title'
}
let
(
:description
)
{
'custom description'
}
let
(
:description
)
{
'custom description'
}
let
(
:url
)
{
'http://jira.example.com'
}
let
(
:url
)
{
'http://jira.example.com'
}
...
@@ -127,9 +127,9 @@ describe Service do
...
@@ -127,9 +127,9 @@ describe Service do
}
}
end
end
shared_examples
'
integration creation from instance level
'
do
shared_examples
'
service creation from a template
'
do
it
'creates a correct service'
do
it
'creates a correct service'
do
service
=
described_class
.
build_from_
instance
(
project
.
id
,
instance_level_integration
)
service
=
described_class
.
build_from_
template
(
project
.
id
,
template
)
expect
(
service
).
to
be_active
expect
(
service
).
to
be_active
expect
(
service
.
title
).
to
eq
(
title
)
expect
(
service
.
title
).
to
eq
(
title
)
...
@@ -144,38 +144,38 @@ describe Service do
...
@@ -144,38 +144,38 @@ describe Service do
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
context
'when data are stored in properties'
do
context
'when data are stored in properties'
do
let
(
:properties
)
{
data_params
.
merge
(
title:
title
,
description:
description
)
}
let
(
:properties
)
{
data_params
.
merge
(
title:
title
,
description:
description
)
}
let!
(
:
instance_level_integration
)
do
let!
(
:
template
)
do
create
(
:jira_service
,
:without_properties_callback
,
instanc
e:
true
,
properties:
properties
.
merge
(
additional:
'something'
))
create
(
:jira_service
,
:without_properties_callback
,
templat
e:
true
,
properties:
properties
.
merge
(
additional:
'something'
))
end
end
it_behaves_like
'
integration creation from instance level
'
it_behaves_like
'
service creation from a template
'
end
end
context
'when data are stored in separated fields'
do
context
'when data are stored in separated fields'
do
let
(
:
instance_level_integration
)
do
let
(
:
template
)
do
create
(
:jira_service
,
data_params
.
merge
(
properties:
{},
title:
title
,
description:
description
,
instanc
e:
true
))
create
(
:jira_service
,
data_params
.
merge
(
properties:
{},
title:
title
,
description:
description
,
templat
e:
true
))
end
end
it_behaves_like
'
integration creation from instance level
'
it_behaves_like
'
service creation from a template
'
end
end
context
'when data are stored in both properties and separated fields'
do
context
'when data are stored in both properties and separated fields'
do
let
(
:properties
)
{
data_params
.
merge
(
title:
title
,
description:
description
)
}
let
(
:properties
)
{
data_params
.
merge
(
title:
title
,
description:
description
)
}
let
(
:
instance_level_integration
)
do
let
(
:
template
)
do
create
(
:jira_service
,
:without_properties_callback
,
active:
true
,
instanc
e:
true
,
properties:
properties
).
tap
do
|
service
|
create
(
:jira_service
,
:without_properties_callback
,
active:
true
,
templat
e:
true
,
properties:
properties
).
tap
do
|
service
|
create
(
:jira_tracker_data
,
data_params
.
merge
(
service:
service
))
create
(
:jira_tracker_data
,
data_params
.
merge
(
service:
service
))
end
end
end
end
it_behaves_like
'
integration creation from instance level
'
it_behaves_like
'
service creation from a template
'
end
end
end
end
end
end
describe
"for pushover service"
do
describe
"for pushover service"
do
let!
(
:
instance_level_integration
)
do
let!
(
:
service_template
)
do
PushoverService
.
create
(
PushoverService
.
create
(
instanc
e:
true
,
templat
e:
true
,
properties:
{
properties:
{
device:
'MyDevice'
,
device:
'MyDevice'
,
sound:
'mic'
,
sound:
'mic'
,
...
@@ -188,7 +188,7 @@ describe Service do
...
@@ -188,7 +188,7 @@ describe Service do
it
"has all fields prefilled"
do
it
"has all fields prefilled"
do
service
=
project
.
find_or_initialize_service
(
'pushover'
)
service
=
project
.
find_or_initialize_service
(
'pushover'
)
expect
(
service
.
instanc
e
).
to
eq
(
false
)
expect
(
service
.
templat
e
).
to
eq
(
false
)
expect
(
service
.
device
).
to
eq
(
'MyDevice'
)
expect
(
service
.
device
).
to
eq
(
'MyDevice'
)
expect
(
service
.
sound
).
to
eq
(
'mic'
)
expect
(
service
.
sound
).
to
eq
(
'mic'
)
expect
(
service
.
priority
).
to
eq
(
4
)
expect
(
service
.
priority
).
to
eq
(
4
)
...
@@ -391,6 +391,14 @@ describe Service do
...
@@ -391,6 +391,14 @@ describe Service do
end
end
end
end
describe
'.find_by_template'
do
let!
(
:service
)
{
create
(
:service
,
template:
true
)
}
it
'returns service template'
do
expect
(
described_class
.
find_by_template
).
to
eq
(
service
)
end
end
describe
'#api_field_names'
do
describe
'#api_field_names'
do
let
(
:fake_service
)
do
let
(
:fake_service
)
do
Class
.
new
(
Service
)
do
Class
.
new
(
Service
)
do
...
...
spec/presenters/snippet_blob_presenter_spec.rb
View file @
1ca9950d
...
@@ -18,7 +18,7 @@ describe SnippetBlobPresenter do
...
@@ -18,7 +18,7 @@ describe SnippetBlobPresenter do
snippet
.
file_name
=
'test.md'
snippet
.
file_name
=
'test.md'
snippet
.
content
=
'*foo*'
snippet
.
content
=
'*foo*'
expect
(
subject
).
to
eq
'<
p data-sourcepos="1:1-1:5" dir="auto"><em>foo</em></p
>'
expect
(
subject
).
to
eq
'<
span id="LC1" class="line" lang="markdown"><span class="ge">*foo*</span></span
>'
end
end
it
'returns syntax highlighted content'
do
it
'returns syntax highlighted content'
do
...
@@ -33,7 +33,41 @@ describe SnippetBlobPresenter do
...
@@ -33,7 +33,41 @@ describe SnippetBlobPresenter do
snippet
.
file_name
=
'test'
snippet
.
file_name
=
'test'
snippet
.
content
=
'foo'
snippet
.
content
=
'foo'
expect
(
described_class
.
new
(
snippet
.
blob
).
highlighted_data
).
to
eq
'<span id="LC1" class="line" lang="plaintext">foo</span>'
expect
(
subject
).
to
eq
'<span id="LC1" class="line" lang="plaintext">foo</span>'
end
end
describe
'#plain_highlighted_data'
do
let
(
:snippet
)
{
build
(
:personal_snippet
)
}
subject
{
described_class
.
new
(
snippet
.
blob
).
plain_highlighted_data
}
it
'returns nil when the snippet blob is binary'
do
allow
(
snippet
.
blob
).
to
receive
(
:binary?
).
and_return
(
true
)
expect
(
subject
).
to
be_nil
end
it
'returns plain content when snippet file is markup'
do
snippet
.
file_name
=
'test.md'
snippet
.
content
=
'*foo*'
expect
(
subject
).
to
eq
'<span id="LC1" class="line" lang="">*foo*</span>'
end
it
'returns plain syntax content'
do
snippet
.
file_name
=
'test.rb'
snippet
.
content
=
'class Foo;end'
expect
(
subject
)
.
to
eq
'<span id="LC1" class="line" lang="">class Foo;end</span>'
end
it
'returns plain text highlighted content'
do
snippet
.
file_name
=
'test'
snippet
.
content
=
'foo'
expect
(
subject
).
to
eq
'<span id="LC1" class="line" lang="">foo</span>'
end
end
end
end
...
...
spec/services/projects/create_service_spec.rb
View file @
1ca9950d
...
@@ -15,7 +15,7 @@ describe Projects::CreateService, '#execute' do
...
@@ -15,7 +15,7 @@ describe Projects::CreateService, '#execute' do
}
}
end
end
it
'creates labels on Project creation if there are
instance level servic
es'
do
it
'creates labels on Project creation if there are
templat
es'
do
Label
.
create
(
title:
"bug"
,
template:
true
)
Label
.
create
(
title:
"bug"
,
template:
true
)
project
=
create_project
(
user
,
opts
)
project
=
create_project
(
user
,
opts
)
...
@@ -96,7 +96,7 @@ describe Projects::CreateService, '#execute' do
...
@@ -96,7 +96,7 @@ describe Projects::CreateService, '#execute' do
end
end
it
'sets invalid service as inactive'
do
it
'sets invalid service as inactive'
do
create
(
:service
,
type:
'JiraService'
,
project:
nil
,
instanc
e:
true
,
active:
true
)
create
(
:service
,
type:
'JiraService'
,
project:
nil
,
templat
e:
true
,
active:
true
)
project
=
create_project
(
user
,
opts
)
project
=
create_project
(
user
,
opts
)
service
=
project
.
services
.
first
service
=
project
.
services
.
first
...
@@ -342,22 +342,22 @@ describe Projects::CreateService, '#execute' do
...
@@ -342,22 +342,22 @@ describe Projects::CreateService, '#execute' do
end
end
end
end
context
'when there is an active
instance level servic
e'
do
context
'when there is an active
service templat
e'
do
before
do
before
do
create
(
:service
,
project:
nil
,
instanc
e:
true
,
active:
true
)
create
(
:service
,
project:
nil
,
templat
e:
true
,
active:
true
)
end
end
it
'creates a service from
instance level servic
e'
do
it
'creates a service from
this templat
e'
do
project
=
create_project
(
user
,
opts
)
project
=
create_project
(
user
,
opts
)
expect
(
project
.
services
.
count
).
to
eq
1
expect
(
project
.
services
.
count
).
to
eq
1
end
end
end
end
context
'when a bad
instance level servic
e is created'
do
context
'when a bad
service templat
e is created'
do
it
'sets service to be inactive'
do
it
'sets service to be inactive'
do
opts
[
:import_url
]
=
'http://www.gitlab.com/gitlab-org/gitlab-foss'
opts
[
:import_url
]
=
'http://www.gitlab.com/gitlab-org/gitlab-foss'
create
(
:service
,
type:
'DroneCiService'
,
project:
nil
,
instanc
e:
true
,
active:
true
)
create
(
:service
,
type:
'DroneCiService'
,
project:
nil
,
templat
e:
true
,
active:
true
)
project
=
create_project
(
user
,
opts
)
project
=
create_project
(
user
,
opts
)
service
=
project
.
services
.
first
service
=
project
.
services
.
first
...
...
spec/services/projects/propagate_
instance_level_servic
e_spec.rb
→
spec/services/projects/propagate_
service_templat
e_spec.rb
View file @
1ca9950d
...
@@ -2,11 +2,11 @@
...
@@ -2,11 +2,11 @@
require
'spec_helper'
require
'spec_helper'
describe
Projects
::
Propagate
InstanceLevelServic
e
do
describe
Projects
::
Propagate
ServiceTemplat
e
do
describe
'.propagate'
do
describe
'.propagate'
do
let!
(
:
instance_level_integration
)
do
let!
(
:
service_template
)
do
PushoverService
.
create
(
PushoverService
.
create
(
instanc
e:
true
,
templat
e:
true
,
active:
true
,
active:
true
,
properties:
{
properties:
{
device:
'MyDevice'
,
device:
'MyDevice'
,
...
@@ -22,14 +22,14 @@ describe Projects::PropagateInstanceLevelService do
...
@@ -22,14 +22,14 @@ describe Projects::PropagateInstanceLevelService do
it
'creates services for projects'
do
it
'creates services for projects'
do
expect
(
project
.
pushover_service
).
to
be_nil
expect
(
project
.
pushover_service
).
to
be_nil
described_class
.
propagate
(
instance_level_integration
)
described_class
.
propagate
(
service_template
)
expect
(
project
.
reload
.
pushover_service
).
to
be_present
expect
(
project
.
reload
.
pushover_service
).
to
be_present
end
end
it
'creates services for a project that has another service'
do
it
'creates services for a project that has another service'
do
BambooService
.
create
(
BambooService
.
create
(
instanc
e:
true
,
templat
e:
true
,
active:
true
,
active:
true
,
project:
project
,
project:
project
,
properties:
{
properties:
{
...
@@ -42,14 +42,14 @@ describe Projects::PropagateInstanceLevelService do
...
@@ -42,14 +42,14 @@ describe Projects::PropagateInstanceLevelService do
expect
(
project
.
pushover_service
).
to
be_nil
expect
(
project
.
pushover_service
).
to
be_nil
described_class
.
propagate
(
instance_level_integration
)
described_class
.
propagate
(
service_template
)
expect
(
project
.
reload
.
pushover_service
).
to
be_present
expect
(
project
.
reload
.
pushover_service
).
to
be_present
end
end
it
'does not create the service if it exists already'
do
it
'does not create the service if it exists already'
do
other_service
=
BambooService
.
create
(
other_service
=
BambooService
.
create
(
instanc
e:
true
,
templat
e:
true
,
active:
true
,
active:
true
,
properties:
{
properties:
{
bamboo_url:
'http://gitlab.com'
,
bamboo_url:
'http://gitlab.com'
,
...
@@ -59,17 +59,17 @@ describe Projects::PropagateInstanceLevelService do
...
@@ -59,17 +59,17 @@ describe Projects::PropagateInstanceLevelService do
}
}
)
)
Service
.
build_from_
instance
(
project
.
id
,
instance_level_integration
).
save!
Service
.
build_from_
template
(
project
.
id
,
service_template
).
save!
Service
.
build_from_
instanc
e
(
project
.
id
,
other_service
).
save!
Service
.
build_from_
templat
e
(
project
.
id
,
other_service
).
save!
expect
{
described_class
.
propagate
(
instance_level_integration
)
}
expect
{
described_class
.
propagate
(
service_template
)
}
.
not_to
change
{
Service
.
count
}
.
not_to
change
{
Service
.
count
}
end
end
it
'creates the service containing the
instanc
e attributes'
do
it
'creates the service containing the
templat
e attributes'
do
described_class
.
propagate
(
instance_level_integration
)
described_class
.
propagate
(
service_template
)
expect
(
project
.
pushover_service
.
properties
).
to
eq
(
instance_level_integration
.
properties
)
expect
(
project
.
pushover_service
.
properties
).
to
eq
(
service_template
.
properties
)
end
end
describe
'bulk update'
,
:use_sql_query_cache
do
describe
'bulk update'
,
:use_sql_query_cache
do
...
@@ -80,7 +80,7 @@ describe Projects::PropagateInstanceLevelService do
...
@@ -80,7 +80,7 @@ describe Projects::PropagateInstanceLevelService do
project_total
.
times
{
create
(
:project
)
}
project_total
.
times
{
create
(
:project
)
}
described_class
.
propagate
(
instance_level_integration
)
described_class
.
propagate
(
service_template
)
end
end
it
'creates services for all projects'
do
it
'creates services for all projects'
do
...
@@ -90,18 +90,18 @@ describe Projects::PropagateInstanceLevelService do
...
@@ -90,18 +90,18 @@ describe Projects::PropagateInstanceLevelService do
describe
'external tracker'
do
describe
'external tracker'
do
it
'updates the project external tracker'
do
it
'updates the project external tracker'
do
instance_level_integration
.
update!
(
category:
'issue_tracker'
,
default:
false
)
service_template
.
update!
(
category:
'issue_tracker'
,
default:
false
)
expect
{
described_class
.
propagate
(
instance_level_integration
)
}
expect
{
described_class
.
propagate
(
service_template
)
}
.
to
change
{
project
.
reload
.
has_external_issue_tracker
}.
to
(
true
)
.
to
change
{
project
.
reload
.
has_external_issue_tracker
}.
to
(
true
)
end
end
end
end
describe
'external wiki'
do
describe
'external wiki'
do
it
'updates the project external tracker'
do
it
'updates the project external tracker'
do
instance_level_integration
.
update!
(
type:
'ExternalWikiService'
)
service_template
.
update!
(
type:
'ExternalWikiService'
)
expect
{
described_class
.
propagate
(
instance_level_integration
)
}
expect
{
described_class
.
propagate
(
service_template
)
}
.
to
change
{
project
.
reload
.
has_external_wiki
}.
to
(
true
)
.
to
change
{
project
.
reload
.
has_external_wiki
}.
to
(
true
)
end
end
end
end
...
...
spec/support/helpers/kubernetes_helpers.rb
View file @
1ca9950d
...
@@ -557,7 +557,7 @@ module KubernetesHelpers
...
@@ -557,7 +557,7 @@ module KubernetesHelpers
end
end
# noinspection RubyStringKeysInHashInspection
# noinspection RubyStringKeysInHashInspection
def
knative_06_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
)
def
knative_06_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
,
cluster_id:
9
)
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
"kind"
=>
"Service"
,
"kind"
=>
"Service"
,
"metadata"
=>
"metadata"
=>
...
@@ -612,12 +612,12 @@ module KubernetesHelpers
...
@@ -612,12 +612,12 @@ module KubernetesHelpers
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
},
},
"environment_scope"
=>
environment
,
"environment_scope"
=>
environment
,
"cluster_id"
=>
9
,
"cluster_id"
=>
cluster_id
,
"podcount"
=>
0
}
"podcount"
=>
0
}
end
end
# noinspection RubyStringKeysInHashInspection
# noinspection RubyStringKeysInHashInspection
def
knative_07_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
)
def
knative_07_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
,
cluster_id:
5
)
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
"kind"
=>
"Service"
,
"kind"
=>
"Service"
,
"metadata"
=>
"metadata"
=>
...
@@ -664,12 +664,12 @@ module KubernetesHelpers
...
@@ -664,12 +664,12 @@ module KubernetesHelpers
"traffic"
=>
[{
"latestRevision"
=>
true
,
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-92tsj"
}],
"traffic"
=>
[{
"latestRevision"
=>
true
,
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-92tsj"
}],
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
},
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
},
"environment_scope"
=>
environment
,
"environment_scope"
=>
environment
,
"cluster_id"
=>
5
,
"cluster_id"
=>
cluster_id
,
"podcount"
=>
0
}
"podcount"
=>
0
}
end
end
# noinspection RubyStringKeysInHashInspection
# noinspection RubyStringKeysInHashInspection
def
knative_09_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
)
def
knative_09_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
,
cluster_id:
5
)
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
"kind"
=>
"Service"
,
"kind"
=>
"Service"
,
"metadata"
=>
"metadata"
=>
...
@@ -716,12 +716,12 @@ module KubernetesHelpers
...
@@ -716,12 +716,12 @@ module KubernetesHelpers
"traffic"
=>
[{
"latestRevision"
=>
true
,
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-92tsj"
}],
"traffic"
=>
[{
"latestRevision"
=>
true
,
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-92tsj"
}],
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
},
"url"
=>
"http://
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
},
"environment_scope"
=>
environment
,
"environment_scope"
=>
environment
,
"cluster_id"
=>
5
,
"cluster_id"
=>
cluster_id
,
"podcount"
=>
0
}
"podcount"
=>
0
}
end
end
# noinspection RubyStringKeysInHashInspection
# noinspection RubyStringKeysInHashInspection
def
knative_05_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
)
def
knative_05_service
(
name:
'kubetest'
,
namespace:
'default'
,
domain:
'example.com'
,
description:
'a knative service'
,
environment:
'production'
,
cluster_id:
8
)
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
{
"apiVersion"
=>
"serving.knative.dev/v1alpha1"
,
"kind"
=>
"Service"
,
"kind"
=>
"Service"
,
"metadata"
=>
"metadata"
=>
...
@@ -771,7 +771,7 @@ module KubernetesHelpers
...
@@ -771,7 +771,7 @@ module KubernetesHelpers
"observedGeneration"
=>
1
,
"observedGeneration"
=>
1
,
"traffic"
=>
[{
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-58qgr"
}]
},
"traffic"
=>
[{
"percent"
=>
100
,
"revisionName"
=>
"
#{
name
}
-58qgr"
}]
},
"environment_scope"
=>
environment
,
"environment_scope"
=>
environment
,
"cluster_id"
=>
8
,
"cluster_id"
=>
cluster_id
,
"podcount"
=>
0
}
"podcount"
=>
0
}
end
end
...
...
spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb
0 → 100644
View file @
1ca9950d
# frozen_string_literal: true
RSpec
.
shared_examples
'a pages cronjob scheduling jobs with context'
do
|
scheduled_worker_class
|
let
(
:worker
)
{
described_class
.
new
}
it
'does not cause extra queries for multiple domains'
do
control
=
ActiveRecord
::
QueryRecorder
.
new
{
worker
.
perform
}
extra_domain
expect
{
worker
.
perform
}.
not_to
exceed_query_limit
(
control
)
end
it
'schedules the renewal with a context'
do
extra_domain
worker
.
perform
expect
(
scheduled_worker_class
.
jobs
.
last
).
to
include
(
"meta.project"
=>
extra_domain
.
project
.
full_path
)
end
end
spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
View file @
1ca9950d
...
@@ -12,7 +12,7 @@ describe PagesDomainSslRenewalCronWorker do
...
@@ -12,7 +12,7 @@ describe PagesDomainSslRenewalCronWorker do
end
end
describe
'#perform'
do
describe
'#perform'
do
let
(
:project
)
{
create
:project
}
let
_it_be
(
:project
)
{
create
:project
}
let!
(
:domain
)
{
create
(
:pages_domain
,
project:
project
,
auto_ssl_enabled:
false
)
}
let!
(
:domain
)
{
create
(
:pages_domain
,
project:
project
,
auto_ssl_enabled:
false
)
}
let!
(
:domain_with_enabled_auto_ssl
)
{
create
(
:pages_domain
,
project:
project
,
auto_ssl_enabled:
true
)
}
let!
(
:domain_with_enabled_auto_ssl
)
{
create
(
:pages_domain
,
project:
project
,
auto_ssl_enabled:
true
)
}
let!
(
:domain_with_obtained_letsencrypt
)
do
let!
(
:domain_with_obtained_letsencrypt
)
do
...
@@ -35,12 +35,16 @@ describe PagesDomainSslRenewalCronWorker do
...
@@ -35,12 +35,16 @@ describe PagesDomainSslRenewalCronWorker do
[
domain
,
[
domain
,
domain_with_obtained_letsencrypt
].
each
do
|
domain
|
domain_with_obtained_letsencrypt
].
each
do
|
domain
|
expect
(
PagesDomain
Verification
Worker
).
not_to
receive
(
:perform_async
).
with
(
domain
.
id
)
expect
(
PagesDomain
SslRenewal
Worker
).
not_to
receive
(
:perform_async
).
with
(
domain
.
id
)
end
end
worker
.
perform
worker
.
perform
end
end
it_behaves_like
'a pages cronjob scheduling jobs with context'
,
PagesDomainSslRenewalWorker
do
let
(
:extra_domain
)
{
create
(
:pages_domain
,
:with_project
,
auto_ssl_enabled:
true
)
}
end
shared_examples
'does nothing'
do
shared_examples
'does nothing'
do
it
'does nothing'
do
it
'does nothing'
do
expect
(
PagesDomainSslRenewalWorker
).
not_to
receive
(
:perform_async
)
expect
(
PagesDomainSslRenewalWorker
).
not_to
receive
(
:perform_async
)
...
...
spec/workers/pages_domain_verification_cron_worker_spec.rb
View file @
1ca9950d
...
@@ -5,9 +5,9 @@ require 'spec_helper'
...
@@ -5,9 +5,9 @@ require 'spec_helper'
describe
PagesDomainVerificationCronWorker
do
describe
PagesDomainVerificationCronWorker
do
subject
(
:worker
)
{
described_class
.
new
}
subject
(
:worker
)
{
described_class
.
new
}
describe
'#perform'
do
describe
'#perform'
,
:sidekiq
do
let!
(
:verified
)
{
create
(
:pages_domain
)
}
let!
(
:verified
)
{
create
(
:pages_domain
)
}
let!
(
:reverify
)
{
create
(
:pages_domain
,
:reverify
)
}
let!
(
:reverify
)
{
create
(
:pages_domain
,
:reverify
,
:with_project
)
}
let!
(
:disabled
)
{
create
(
:pages_domain
,
:disabled
)
}
let!
(
:disabled
)
{
create
(
:pages_domain
,
:disabled
)
}
it
'does nothing if the database is read-only'
do
it
'does nothing if the database is read-only'
do
...
@@ -26,5 +26,9 @@ describe PagesDomainVerificationCronWorker do
...
@@ -26,5 +26,9 @@ describe PagesDomainVerificationCronWorker do
worker
.
perform
worker
.
perform
end
end
it_behaves_like
'a pages cronjob scheduling jobs with context'
,
PagesDomainVerificationWorker
do
let
(
:extra_domain
)
{
create
(
:pages_domain
,
:reverify
,
:with_project
)
}
end
end
end
end
end
spec/workers/propagate_
instance_level_servic
e_worker_spec.rb
→
spec/workers/propagate_
service_templat
e_worker_spec.rb
View file @
1ca9950d
...
@@ -2,13 +2,13 @@
...
@@ -2,13 +2,13 @@
require
'spec_helper'
require
'spec_helper'
describe
Propagate
InstanceLevelServic
eWorker
do
describe
Propagate
ServiceTemplat
eWorker
do
include
ExclusiveLeaseHelpers
include
ExclusiveLeaseHelpers
describe
'#perform'
do
describe
'#perform'
do
it
'calls the propagate service with the
instance level servic
e'
do
it
'calls the propagate service with the
templat
e'
do
instance_level_servic
e
=
PushoverService
.
create
(
templat
e
=
PushoverService
.
create
(
instanc
e:
true
,
templat
e:
true
,
active:
true
,
active:
true
,
properties:
{
properties:
{
device:
'MyDevice'
,
device:
'MyDevice'
,
...
@@ -18,14 +18,14 @@ describe PropagateInstanceLevelServiceWorker do
...
@@ -18,14 +18,14 @@ describe PropagateInstanceLevelServiceWorker do
api_key:
'123456789'
api_key:
'123456789'
})
})
stub_exclusive_lease
(
"propagate_
instance_level_service_worker:
#{
instance_level_servic
e
.
id
}
"
,
stub_exclusive_lease
(
"propagate_
service_template_worker:
#{
templat
e
.
id
}
"
,
timeout:
Propagate
InstanceLevelServic
eWorker
::
LEASE_TIMEOUT
)
timeout:
Propagate
ServiceTemplat
eWorker
::
LEASE_TIMEOUT
)
expect
(
Projects
::
Propagate
InstanceLevelServic
e
)
expect
(
Projects
::
Propagate
ServiceTemplat
e
)
.
to
receive
(
:propagate
)
.
to
receive
(
:propagate
)
.
with
(
instance_level_servic
e
)
.
with
(
templat
e
)
subject
.
perform
(
instance_level_servic
e
.
id
)
subject
.
perform
(
templat
e
.
id
)
end
end
end
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