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
189565fa
Commit
189565fa
authored
Nov 12, 2019
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Persist and control auto stop date for environments
This commit persists and controls auto stop date for environments
parent
46f2255d
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
491 additions
and
34 deletions
+491
-34
app/controllers/projects/environments_controller.rb
app/controllers/projects/environments_controller.rb
+29
-5
app/models/concerns/ci/metadatable.rb
app/models/concerns/ci/metadatable.rb
+6
-2
app/models/environment.rb
app/models/environment.rb
+15
-0
app/policies/project_policy.rb
app/policies/project_policy.rb
+1
-2
app/serializers/environment_entity.rb
app/serializers/environment_entity.rb
+9
-0
app/services/deployments/after_create_service.rb
app/services/deployments/after_create_service.rb
+7
-0
app/services/environments/reset_auto_stop_service.rb
app/services/environments/reset_auto_stop_service.rb
+22
-0
app/views/projects/environments/show.html.haml
app/views/projects/environments/show.html.haml
+2
-2
config/routes/project.rb
config/routes/project.rb
+1
-0
db/migrate/20191004151428_add_auto_stop_in_to_environments.rb
...igrate/20191004151428_add_auto_stop_in_to_environments.rb
+9
-0
db/migrate/20191202181924_add_environment_auto_stop_in_to_ci_builds_metadata.rb
...924_add_environment_auto_stop_in_to_ci_builds_metadata.rb
+13
-0
db/schema.rb
db/schema.rb
+2
-0
ee/app/policies/ee/environment_policy.rb
ee/app/policies/ee/environment_policy.rb
+1
-0
ee/spec/controllers/projects/environments_controller_spec.rb
ee/spec/controllers/projects/environments_controller_spec.rb
+25
-0
ee/spec/fixtures/api/schemas/environment.json
ee/spec/fixtures/api/schemas/environment.json
+3
-1
lib/gitlab/ci/config/entry/environment.rb
lib/gitlab/ci/config/entry/environment.rb
+6
-1
locale/gitlab.pot
locale/gitlab.pot
+12
-0
spec/controllers/projects/environments_controller_spec.rb
spec/controllers/projects/environments_controller_spec.rb
+46
-14
spec/factories/environments.rb
spec/factories/environments.rb
+8
-0
spec/features/projects/environments/environments_spec.rb
spec/features/projects/environments/environments_spec.rb
+3
-3
spec/fixtures/api/schemas/environment.json
spec/fixtures/api/schemas/environment.json
+2
-0
spec/lib/gitlab/ci/config/entry/environment_spec.rb
spec/lib/gitlab/ci/config/entry/environment_spec.rb
+29
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+16
-0
spec/models/environment_spec.rb
spec/models/environment_spec.rb
+56
-0
spec/policies/environment_policy_spec.rb
spec/policies/environment_policy_spec.rb
+1
-1
spec/policies/project_policy_spec.rb
spec/policies/project_policy_spec.rb
+2
-2
spec/serializers/environment_entity_spec.rb
spec/serializers/environment_entity_spec.rb
+8
-0
spec/services/ci/create_pipeline_service_spec.rb
spec/services/ci/create_pipeline_service_spec.rb
+19
-0
spec/services/deployments/after_create_service_spec.rb
spec/services/deployments/after_create_service_spec.rb
+15
-0
spec/services/environments/reset_auto_stop_service_spec.rb
spec/services/environments/reset_auto_stop_service_spec.rb
+54
-0
spec/support/shared_contexts/policies/project_policy_shared_context.rb
...shared_contexts/policies/project_policy_shared_context.rb
+2
-1
spec/support/shared_examples/controllers/environments_controller_shared_examples.rb
...es/controllers/environments_controller_shared_examples.rb
+67
-0
No files found.
app/controllers/projects/environments_controller.rb
View file @
189565fa
...
...
@@ -7,14 +7,15 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action
:authorize_read_environment!
before_action
:authorize_create_environment!
,
only:
[
:new
,
:create
]
before_action
:authorize_stop_environment!
,
only:
[
:stop
]
before_action
:authorize_update_environment!
,
only:
[
:edit
,
:update
]
before_action
:authorize_update_environment!
,
only:
[
:edit
,
:update
,
:cancel_auto_stop
]
before_action
:authorize_admin_environment!
,
only:
[
:terminal
,
:terminal_websocket_authorize
]
before_action
:environment
,
only:
[
:show
,
:edit
,
:update
,
:stop
,
:terminal
,
:terminal_websocket_authorize
,
:metrics
]
before_action
:environment
,
only:
[
:show
,
:edit
,
:update
,
:stop
,
:terminal
,
:terminal_websocket_authorize
,
:metrics
,
:cancel_auto_stop
]
before_action
:verify_api_request!
,
only: :terminal_websocket_authorize
before_action
:expire_etag_cache
,
only:
[
:index
]
before_action
:expire_etag_cache
,
only:
[
:index
]
,
unless:
->
{
request
.
format
.
json?
}
before_action
only:
[
:metrics
,
:additional_metrics
,
:metrics_dashboard
]
do
push_frontend_feature_flag
(
:prometheus_computed_alerts
)
end
after_action
:expire_etag_cache
,
only:
[
:cancel_auto_stop
]
def
index
@environments
=
project
.
environments
...
...
@@ -104,6 +105,27 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
end
def
cancel_auto_stop
result
=
Environments
::
ResetAutoStopService
.
new
(
project
,
current_user
)
.
execute
(
environment
)
if
result
[
:status
]
==
:success
respond_to
do
|
format
|
message
=
_
(
'Auto stop successfully canceled.'
)
format
.
html
{
redirect_back_or_default
(
default:
{
action:
'show'
},
options:
{
notice:
message
})
}
format
.
json
{
render
json:
{
message:
message
},
status: :ok
}
end
else
respond_to
do
|
format
|
message
=
result
[
:message
]
format
.
html
{
redirect_back_or_default
(
default:
{
action:
'show'
},
options:
{
alert:
message
})
}
format
.
json
{
render
json:
{
message:
message
},
status: :unprocessable_entity
}
end
end
end
def
terminal
# Currently, this acts as a hint to load the terminal details into the cache
# if they aren't there already. In the future, users will need these details
...
...
@@ -175,8 +197,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
end
def
expire_etag_cache
return
if
request
.
format
.
json?
# this forces to reload json content
Gitlab
::
EtagCaching
::
Store
.
new
.
tap
do
|
store
|
store
.
touch
(
project_environments_path
(
project
,
format: :json
))
...
...
@@ -222,6 +242,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController
def
authorize_stop_environment!
access_denied!
unless
can?
(
current_user
,
:stop_environment
,
environment
)
end
def
authorize_update_environment!
access_denied!
unless
can?
(
current_user
,
:update_environment
,
environment
)
end
end
Projects
::
EnvironmentsController
.
prepend_if_ee
(
'EE::Projects::EnvironmentsController'
)
app/models/concerns/ci/metadatable.rb
View file @
189565fa
...
...
@@ -17,6 +17,7 @@ module Ci
delegate
:timeout
,
to: :metadata
,
prefix:
true
,
allow_nil:
true
delegate
:interruptible
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
delegate
:has_exposed_artifacts?
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
delegate
:environment_auto_stop_in
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
before_create
:ensure_metadata
end
...
...
@@ -47,8 +48,11 @@ module Ci
def
options
=
(
value
)
write_metadata_attribute
(
:options
,
:config_options
,
value
)
# Store presence of exposed artifacts in build metadata to make it easier to query
ensure_metadata
.
has_exposed_artifacts
=
value
&
.
dig
(
:artifacts
,
:expose_as
).
present?
ensure_metadata
.
tap
do
|
metadata
|
# Store presence of exposed artifacts in build metadata to make it easier to query
metadata
.
has_exposed_artifacts
=
value
&
.
dig
(
:artifacts
,
:expose_as
).
present?
metadata
.
environment_auto_stop_in
=
value
&
.
dig
(
:environment
,
:auto_stop_in
)
end
end
def
yaml_variables
=
(
value
)
...
...
app/models/environment.rb
View file @
189565fa
...
...
@@ -162,6 +162,10 @@ class Environment < ApplicationRecord
stop_action
&
.
play
(
current_user
)
end
def
reset_auto_stop
update_column
(
:auto_stop_at
,
nil
)
end
def
actions_for
(
environment
)
return
[]
unless
manual_actions
...
...
@@ -261,6 +265,17 @@ class Environment < ApplicationRecord
end
end
def
auto_stop_in
auto_stop_at
-
Time
.
now
if
auto_stop_at
end
def
auto_stop_in
=
(
value
)
return
unless
value
return
unless
parsed_result
=
ChronicDuration
.
parse
(
value
)
self
.
auto_stop_at
=
parsed_result
.
seconds
.
from_now
end
private
def
generate_slug
...
...
app/policies/project_policy.rb
View file @
189565fa
...
...
@@ -262,6 +262,7 @@ class ProjectPolicy < BasePolicy
enable
:update_container_image
enable
:destroy_container_image
enable
:create_environment
enable
:update_environment
enable
:create_deployment
enable
:update_deployment
enable
:create_release
...
...
@@ -278,8 +279,6 @@ class ProjectPolicy < BasePolicy
enable
:admin_board
enable
:push_to_delete_protected_branch
enable
:update_project_snippet
enable
:update_environment
enable
:update_deployment
enable
:admin_project_snippet
enable
:admin_project_member
enable
:admin_note
...
...
app/serializers/environment_entity.rb
View file @
189565fa
...
...
@@ -24,6 +24,10 @@ class EnvironmentEntity < Grape::Entity
stop_project_environment_path
(
environment
.
project
,
environment
)
end
expose
:cancel_auto_stop_path
,
if:
->
(
*
)
{
can_update_environment?
}
do
|
environment
|
cancel_auto_stop_project_environment_path
(
environment
.
project
,
environment
)
end
expose
:cluster_type
,
if:
->
(
environment
,
_
)
{
cluster_platform_kubernetes?
}
do
|
environment
|
cluster
.
cluster_type
end
...
...
@@ -37,6 +41,7 @@ class EnvironmentEntity < Grape::Entity
end
expose
:created_at
,
:updated_at
expose
:auto_stop_at
,
expose_nil:
false
expose
:can_stop
do
|
environment
|
environment
.
available?
&&
can?
(
current_user
,
:stop_environment
,
environment
)
...
...
@@ -54,6 +59,10 @@ class EnvironmentEntity < Grape::Entity
can?
(
request
.
current_user
,
:create_environment_terminal
,
environment
)
end
def
can_update_environment?
can?
(
current_user
,
:update_environment
,
environment
)
end
def
cluster_platform_kubernetes?
deployment_platform
&&
deployment_platform
.
is_a?
(
Clusters
::
Platforms
::
Kubernetes
)
end
...
...
app/services/deployments/after_create_service.rb
View file @
189565fa
...
...
@@ -29,6 +29,7 @@ module Deployments
environment
.
external_url
=
url
end
renew_auto_stop_in
environment
.
fire_state_event
(
action
)
if
environment
.
save
&&
!
environment
.
stopped?
...
...
@@ -63,6 +64,12 @@ module Deployments
def
action
environment_options
[
:action
]
||
'start'
end
def
renew_auto_stop_in
return
unless
deployable
environment
.
auto_stop_in
=
deployable
.
environment_auto_stop_in
end
end
end
...
...
app/services/environments/reset_auto_stop_service.rb
0 → 100644
View file @
189565fa
# frozen_string_literal: true
module
Environments
class
ResetAutoStopService
<
::
BaseService
def
execute
(
environment
)
return
error
(
_
(
'Failed to cancel auto stop because you do not have permission to update the environment.'
))
unless
can_update_environment?
(
environment
)
return
error
(
_
(
'Failed to cancel auto stop because the environment is not set as auto stop.'
))
unless
environment
.
auto_stop_at?
if
environment
.
reset_auto_stop
success
else
error
(
_
(
'Failed to cancel auto stop because failed to update the environment.'
))
end
end
private
def
can_update_environment?
(
environment
)
can?
(
current_user
,
:update_environment
,
environment
)
end
end
end
app/views/projects/environments/show.html.haml
View file @
189565fa
...
...
@@ -5,7 +5,7 @@
-
content_for
:page_specific_javascripts
do
=
stylesheet_link_tag
'page_bundles/xterm'
-
if
can?
(
current_user
,
:stop_environment
,
@environment
)
-
if
@environment
.
available?
&&
can?
(
current_user
,
:stop_environment
,
@environment
)
#stop-environment-modal
.modal.fade
{
tabindex:
-
1
}
.modal-dialog
.modal-content
...
...
@@ -40,7 +40,7 @@
=
render
'projects/environments/metrics_button'
,
environment:
@environment
-
if
can?
(
current_user
,
:update_environment
,
@environment
)
=
link_to
_
(
'Edit'
),
edit_project_environment_path
(
@project
,
@environment
),
class:
'btn'
-
if
can?
(
current_user
,
:stop_environment
,
@environment
)
-
if
@environment
.
available?
&&
can?
(
current_user
,
:stop_environment
,
@environment
)
=
button_tag
class:
'btn btn-danger'
,
type:
'button'
,
data:
{
toggle:
'modal'
,
target:
'#stop-environment-modal'
}
do
=
sprite_icon
(
'stop'
)
...
...
config/routes/project.rb
View file @
189565fa
...
...
@@ -224,6 +224,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources
:environments
,
except:
[
:destroy
]
do
member
do
post
:stop
post
:cancel_auto_stop
get
:terminal
get
:metrics
get
:additional_metrics
...
...
db/migrate/20191004151428_add_auto_stop_in_to_environments.rb
0 → 100644
View file @
189565fa
# frozen_string_literal: true
class
AddAutoStopInToEnvironments
<
ActiveRecord
::
Migration
[
5.2
]
DOWNTIME
=
false
def
change
add_column
:environments
,
:auto_stop_at
,
:datetime_with_timezone
end
end
db/migrate/20191202181924_add_environment_auto_stop_in_to_ci_builds_metadata.rb
0 → 100644
View file @
189565fa
# frozen_string_literal: true
class
AddEnvironmentAutoStopInToCiBuildsMetadata
<
ActiveRecord
::
Migration
[
5.2
]
DOWNTIME
=
false
def
up
add_column
:ci_builds_metadata
,
:environment_auto_stop_in
,
:string
,
limit:
255
end
def
down
remove_column
:ci_builds_metadata
,
:environment_auto_stop_in
end
end
db/schema.rb
View file @
189565fa
...
...
@@ -717,6 +717,7 @@ ActiveRecord::Schema.define(version: 2019_12_04_093410) do
t
.
jsonb
"config_options"
t
.
jsonb
"config_variables"
t
.
boolean
"has_exposed_artifacts"
t
.
string
"environment_auto_stop_in"
,
limit:
255
t
.
index
[
"build_id"
],
name:
"index_ci_builds_metadata_on_build_id"
,
unique:
true
t
.
index
[
"build_id"
],
name:
"index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts"
,
where:
"(has_exposed_artifacts IS TRUE)"
t
.
index
[
"build_id"
],
name:
"index_ci_builds_metadata_on_build_id_and_interruptible"
,
where:
"(interruptible = true)"
...
...
@@ -1447,6 +1448,7 @@ ActiveRecord::Schema.define(version: 2019_12_04_093410) do
t
.
string
"environment_type"
t
.
string
"state"
,
default:
"available"
,
null:
false
t
.
string
"slug"
,
null:
false
t
.
datetime_with_timezone
"auto_stop_at"
t
.
index
[
"name"
],
name:
"index_environments_on_name_varchar_pattern_ops"
,
opclass: :varchar_pattern_ops
t
.
index
[
"project_id"
,
"name"
],
name:
"index_environments_on_project_id_and_name"
,
unique:
true
t
.
index
[
"project_id"
,
"slug"
],
name:
"index_environments_on_project_id_and_slug"
,
unique:
true
...
...
ee/app/policies/ee/environment_policy.rb
View file @
189565fa
...
...
@@ -11,6 +11,7 @@ module EE
prevent
:create_environment_terminal
prevent
:create_deployment
prevent
:update_deployment
prevent
:update_environment
end
private
...
...
ee/spec/controllers/projects/environments_controller_spec.rb
View file @
189565fa
...
...
@@ -282,6 +282,31 @@ describe Projects::EnvironmentsController do
end
end
describe
'POST #cancel_auto_stop'
do
subject
{
post
:cancel_auto_stop
,
params:
params
}
let
(
:params
)
{
environment_params
}
context
'when environment is set as auto-stop'
do
let
(
:environment
)
{
create
(
:environment
,
:will_auto_stop
,
name:
'staging'
,
project:
project
)
}
it_behaves_like
'successful response for #cancel_auto_stop'
context
'when the environment is protected'
do
before
do
stub_licensed_features
(
protected_environments:
true
)
create
(
:protected_environment
,
name:
'staging'
,
project:
project
)
end
it
'shows NOT Found'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
def
environment_params
(
opts
=
{})
opts
.
reverse_merge
(
namespace_id:
project
.
namespace
,
project_id:
project
,
...
...
ee/spec/fixtures/api/schemas/environment.json
View file @
189565fa
...
...
@@ -71,6 +71,8 @@
},
"can_stop"
:
{
"type"
:
"boolean"
}
},
"cancel_auto_stop_path"
:
{
"type"
:
"string"
},
"auto_stop_at"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
}
}
}
lib/gitlab/ci/config/entry/environment.rb
View file @
189565fa
...
...
@@ -10,7 +10,7 @@ module Gitlab
class
Environment
<
::
Gitlab
::
Config
::
Entry
::
Node
include
::
Gitlab
::
Config
::
Entry
::
Configurable
ALLOWED_KEYS
=
%i[name url action on_stop kubernetes]
.
freeze
ALLOWED_KEYS
=
%i[name url action on_stop
auto_stop_in
kubernetes]
.
freeze
entry
:kubernetes
,
Entry
::
Kubernetes
,
description:
'Kubernetes deployment configuration.'
...
...
@@ -49,6 +49,7 @@ module Gitlab
validates
:on_stop
,
type:
String
,
allow_nil:
true
validates
:kubernetes
,
type:
Hash
,
allow_nil:
true
validates
:auto_stop_in
,
duration:
true
,
allow_nil:
true
end
end
...
...
@@ -80,6 +81,10 @@ module Gitlab
value
[
:kubernetes
]
end
def
auto_stop_in
value
[
:auto_stop_in
]
end
def
value
case
@config
when
String
then
{
name:
@config
,
action:
'start'
}
...
...
locale/gitlab.pot
View file @
189565fa
...
...
@@ -2312,6 +2312,9 @@ msgstr ""
msgid "Auto License Compliance"
msgstr ""
msgid "Auto stop successfully canceled."
msgstr ""
msgid "Auto-cancel redundant, pending pipelines"
msgstr ""
...
...
@@ -7251,6 +7254,15 @@ msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr ""
msgid "Failed to cancel auto stop because failed to update the environment."
msgstr ""
msgid "Failed to cancel auto stop because the environment is not set as auto stop."
msgstr ""
msgid "Failed to cancel auto stop because you do not have permission to update the environment."
msgstr ""
msgid "Failed to change the owner"
msgstr ""
...
...
spec/controllers/projects/environments_controller_spec.rb
View file @
189565fa
...
...
@@ -5,16 +5,14 @@ require 'spec_helper'
describe
Projects
::
EnvironmentsController
do
include
MetricsDashboardHelpers
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:maintainer
)
{
create
(
:user
,
name:
'main-dos'
).
tap
{
|
u
|
project
.
add_maintainer
(
u
)
}
}
let_it_be
(
:reporter
)
{
create
(
:user
,
name:
'repo-dos'
).
tap
{
|
u
|
project
.
add_reporter
(
u
)
}
}
let
(
:user
)
{
maintainer
}
let_it_be
(
:environment
)
do
create
(
:environment
,
name:
'production'
,
project:
project
)
end
let!
(
:environment
)
{
create
(
:environment
,
name:
'production'
,
project:
project
)
}
before
do
project
.
add_maintainer
(
user
)
sign_in
(
user
)
end
...
...
@@ -245,6 +243,36 @@ describe Projects::EnvironmentsController do
end
end
describe
'POST #cancel_auto_stop'
do
subject
{
post
:cancel_auto_stop
,
params:
params
}
let
(
:params
)
{
environment_params
}
context
'when environment is set as auto-stop'
do
let
(
:environment
)
{
create
(
:environment
,
:will_auto_stop
,
name:
'staging'
,
project:
project
)
}
it_behaves_like
'successful response for #cancel_auto_stop'
context
'when user is reporter'
do
let
(
:user
)
{
reporter
}
it
'shows NOT Found'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'when environment is not set as auto-stop'
do
let
(
:environment
)
{
create
(
:environment
,
name:
'staging'
,
project:
project
)
}
it_behaves_like
'failed response for #cancel_auto_stop'
do
let
(
:message
)
{
'the environment is not set as auto stop'
}
end
end
end
describe
'GET #terminal'
do
context
'with valid id'
do
it
'responds with a status code 200'
do
...
...
@@ -320,21 +348,21 @@ describe Projects::EnvironmentsController do
end
describe
'GET #metrics_redirect'
do
let
(
:project
)
{
create
(
:project
)
}
it
'redirects to environment if it exists'
do
environment
=
create
(
:environment
,
name:
'production'
,
project:
project
)
get
:metrics_redirect
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
expect
(
response
).
to
redirect_to
(
environment_metrics_path
(
environment
))
end
it
'redirects to empty metrics page if no environment exis
ts'
do
get
:metrics_redirect
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
context
'when there are no environmen
ts'
do
let
(
:environment
)
{
}
expect
(
response
).
to
be_ok
expect
(
response
).
to
render_template
'empty_metrics'
it
'redirects to empty metrics page'
do
get
:metrics_redirect
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
}
expect
(
response
).
to
be_ok
expect
(
response
).
to
render_template
'empty_metrics'
end
end
end
...
...
@@ -549,6 +577,10 @@ describe Projects::EnvironmentsController do
let
(
:project
)
{
project_with_dashboard
(
dashboard_path
,
dashboard_yml
)
}
let
(
:environment
)
{
create
(
:environment
,
name:
'production'
,
project:
project
)
}
before
do
project
.
add_maintainer
(
user
)
end
it_behaves_like
'the specified dashboard'
,
'Test Dashboard'
end
...
...
spec/factories/environments.rb
View file @
189565fa
...
...
@@ -44,5 +44,13 @@ FactoryBot.define do
status
{
'created'
}
self
.
when
{
'manual'
}
end
trait
:auto_stopped
do
auto_stop_at
{
1
.
day
.
ago
}
end
trait
:will_auto_stop
do
auto_stop_at
{
1
.
day
.
from_now
}
end
end
end
spec/features/projects/environments/environments_spec.rb
View file @
189565fa
...
...
@@ -144,8 +144,8 @@ describe 'Environments page', :js do
expect
(
page
).
to
have_content
(
'No deployments yet'
)
end
it
'
does not show sti
p button when environment is not stoppable'
do
expect
(
page
).
not_
to
have_selector
(
stop_button_selector
)
it
'
shows sto
p button when environment is not stoppable'
do
expect
(
page
).
to
have_selector
(
stop_button_selector
)
end
end
...
...
@@ -205,7 +205,7 @@ describe 'Environments page', :js do
end
it
'shows a stop button'
do
expect
(
page
).
not_
to
have_selector
(
stop_button_selector
)
expect
(
page
).
to
have_selector
(
stop_button_selector
)
end
it
'does not show external link button'
do
...
...
spec/fixtures/api/schemas/environment.json
View file @
189565fa
...
...
@@ -24,9 +24,11 @@
"has_stop_action"
:
{
"type"
:
"boolean"
},
"environment_path"
:
{
"type"
:
"string"
},
"stop_path"
:
{
"type"
:
"string"
},
"cancel_auto_stop_path"
:
{
"type"
:
"string"
},
"folder_path"
:
{
"type"
:
"string"
},
"created_at"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
},
"updated_at"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
},
"auto_stop_at"
:
{
"type"
:
"string"
,
"format"
:
"date-time"
},
"can_stop"
:
{
"type"
:
"boolean"
},
"cluster_type"
:
{
"type"
:
"types/nullable_string.json"
},
"terminal_path"
:
{
"type"
:
"types/nullable_string.json"
},
...
...
spec/lib/gitlab/ci/config/entry/environment_spec.rb
View file @
189565fa
...
...
@@ -206,6 +206,35 @@ describe Gitlab::Ci::Config::Entry::Environment do
end
end
context
'when auto_stop_in is specified'
do
let
(
:config
)
do
{
name:
'review/$CI_COMMIT_REF_NAME'
,
url:
'https://$CI_COMMIT_REF_NAME.review.gitlab.com'
,
on_stop:
'stop_review'
,
auto_stop_in:
auto_stop_in
}
end
context
'when auto_stop_in is correct format'
do
let
(
:auto_stop_in
)
{
'2 days'
}
it
'becomes valid'
do
expect
(
entry
).
to
be_valid
expect
(
entry
.
auto_stop_in
).
to
eq
(
auto_stop_in
)
end
end
context
'when auto_stop_in is invalid format'
do
let
(
:auto_stop_in
)
{
'invalid'
}
it
'becomes invalid'
do
expect
(
entry
).
not_to
be_valid
expect
(
entry
.
errors
).
to
include
'environment auto stop in should be a duration'
end
end
end
context
'when configuration is invalid'
do
context
'when configuration is an array'
do
let
(
:config
)
{
[
'env'
]
}
...
...
spec/models/ci/build_spec.rb
View file @
189565fa
...
...
@@ -4113,4 +4113,20 @@ describe Ci::Build do
end
end
end
describe
'#environment_auto_stop_in'
do
subject
{
build
.
environment_auto_stop_in
}
context
'when build option has environment auto_stop_in'
do
let
(
:build
)
{
create
(
:ci_build
,
options:
{
environment:
{
name:
'test'
,
auto_stop_in:
'1 day'
}
})
}
it
{
is_expected
.
to
eq
(
'1 day'
)
}
end
context
'when build option does not have environment auto_stop_in'
do
let
(
:build
)
{
create
(
:ci_build
)
}
it
{
is_expected
.
to
be_nil
}
end
end
end
spec/models/environment_spec.rb
View file @
189565fa
...
...
@@ -441,6 +441,16 @@ describe Environment, :use_clean_rails_memory_store_caching do
end
end
describe
'#reset_auto_stop'
do
subject
{
environment
.
reset_auto_stop
}
let
(
:environment
)
{
create
(
:environment
,
:auto_stopped
)
}
it
'nullifies the auto_stop_at'
do
expect
{
subject
}.
to
change
(
environment
,
:auto_stop_at
).
from
(
Time
).
to
(
nil
)
end
end
describe
'#actions_for'
do
let
(
:deployment
)
{
create
(
:deployment
,
:success
,
environment:
environment
)
}
let
(
:pipeline
)
{
deployment
.
deployable
.
pipeline
}
...
...
@@ -1088,6 +1098,52 @@ describe Environment, :use_clean_rails_memory_store_caching do
end
end
describe
'#auto_stop_in'
do
subject
{
environment
.
auto_stop_in
}
context
'when environment will be expired'
do
let
(
:environment
)
{
build
(
:environment
,
:will_auto_stop
)
}
it
'returns when it will expire'
do
Timecop
.
freeze
{
is_expected
.
to
eq
(
1
.
day
.
to_i
)
}
end
end
context
'when environment is not expired'
do
let
(
:environment
)
{
build
(
:environment
)
}
it
{
is_expected
.
to
be_nil
}
end
end
describe
'#auto_stop_in='
do
subject
{
environment
.
auto_stop_in
=
value
}
let
(
:environment
)
{
build
(
:environment
)
}
where
(
:value
,
:expected_result
)
do
'2 days'
|
2
.
days
.
to_i
'1 week'
|
1
.
week
.
to_i
'2h20min'
|
2
.
hours
.
to_i
+
20
.
minutes
.
to_i
'abcdef'
|
ChronicDuration
::
DurationParseError
''
|
nil
nil
|
nil
end
with_them
do
it
'sets correct auto_stop_in'
do
Timecop
.
freeze
do
if
expected_result
.
is_a?
(
Integer
)
||
expected_result
.
nil?
subject
expect
(
environment
.
auto_stop_in
).
to
eq
(
expected_result
)
else
expect
{
subject
}.
to
raise_error
(
expected_result
)
end
end
end
end
end
describe
'.find_or_create_by_name'
do
it
'finds an existing environment if it exists'
do
env
=
create
(
:environment
)
...
...
spec/policies/environment_policy_spec.rb
View file @
189565fa
...
...
@@ -68,7 +68,7 @@ describe EnvironmentPolicy do
nil
|
false
:guest
|
false
:reporter
|
false
:developer
|
fals
e
:developer
|
tru
e
:maintainer
|
true
end
...
...
spec/policies/project_policy_spec.rb
View file @
189565fa
...
...
@@ -42,13 +42,13 @@ describe ProjectPolicy do
update_commit_status create_build update_build create_pipeline
update_pipeline create_merge_request_from create_wiki push_code
resolve_note create_container_image update_container_image destroy_container_image
create_environment create_deployment update_deployment create_release update_release
create_environment
update_environment
create_deployment update_deployment create_release update_release
]
end
let
(
:base_maintainer_permissions
)
do
%i[
push_to_delete_protected_branch update_project_snippet
update_environment
push_to_delete_protected_branch update_project_snippet
admin_project_snippet admin_project_member admin_note admin_wiki admin_project
admin_commit_status admin_build admin_container_image
admin_pipeline admin_environment admin_deployment destroy_release add_cluster
...
...
spec/serializers/environment_entity_spec.rb
View file @
189565fa
...
...
@@ -62,4 +62,12 @@ describe EnvironmentEntity do
end
end
end
context
'with auto_stop_in'
do
let
(
:environment
)
{
create
(
:environment
,
:will_auto_stop
)
}
it
'exposes auto stop related information'
do
expect
(
subject
).
to
include
(
:cancel_auto_stop_path
,
:auto_stop_at
)
end
end
end
spec/services/ci/create_pipeline_service_spec.rb
View file @
189565fa
...
...
@@ -781,6 +781,25 @@ describe Ci::CreatePipelineService do
end
end
context
'with environment with auto_stop_in'
do
before
do
config
=
YAML
.
dump
(
deploy:
{
environment:
{
name:
"review/$CI_COMMIT_REF_NAME"
,
auto_stop_in:
'1 day'
},
script:
'ls'
})
stub_ci_pipeline_yaml_file
(
config
)
end
it
'creates the environment with auto stop in'
do
result
=
execute_service
expect
(
result
).
to
be_persisted
expect
(
result
.
builds
.
first
.
options
[
:environment
][
:auto_stop_in
]).
to
eq
(
'1 day'
)
end
end
context
'with environment name including persisted variables'
do
before
do
config
=
YAML
.
dump
(
...
...
spec/services/deployments/after_create_service_spec.rb
View file @
189565fa
...
...
@@ -115,6 +115,21 @@ describe Deployments::AfterCreateService do
expect
(
subject
.
environment
.
external_url
).
to
eq
(
'http://master.review-apps.gitlab.com'
)
end
end
context
'when auto_stop_in are used'
do
let
(
:options
)
do
{
name:
'production'
,
auto_stop_in:
'1 day'
}
end
it
'renews auto stop at'
do
Timecop
.
freeze
do
environment
.
update!
(
auto_stop_at:
nil
)
expect
{
subject
.
execute
}
.
to
change
{
environment
.
reset
.
auto_stop_at
&
.
round
}.
from
(
nil
).
to
(
1
.
day
.
since
.
round
)
end
end
end
end
describe
'#expanded_environment_url'
do
...
...
spec/services/environments/reset_auto_stop_service_spec.rb
0 → 100644
View file @
189565fa
# frozen_string_literal: true
require
'spec_helper'
describe
Environments
::
ResetAutoStopService
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:developer
)
{
create
(
:user
).
tap
{
|
user
|
project
.
add_developer
(
user
)
}
}
let_it_be
(
:reporter
)
{
create
(
:user
).
tap
{
|
user
|
project
.
add_reporter
(
user
)
}
}
let
(
:user
)
{
developer
}
let
(
:service
)
{
described_class
.
new
(
project
,
user
)
}
describe
'#execute'
do
subject
{
service
.
execute
(
environment
)
}
context
'when environment will be stopped automatically'
do
let
(
:environment
)
{
create
(
:environment
,
:will_auto_stop
,
project:
project
)
}
it
'resets auto stop'
do
expect
(
environment
).
to
receive
(
:reset_auto_stop
).
and_call_original
expect
(
subject
[
:status
]).
to
eq
(
:success
)
end
context
'when failed to reset auto stop'
do
before
do
expect
(
environment
).
to
receive
(
:reset_auto_stop
)
{
false
}
end
it
'returns error'
do
expect
(
subject
[
:status
]).
to
eq
(
:error
)
expect
(
subject
[
:message
]).
to
eq
(
'Failed to cancel auto stop because failed to update the environment.'
)
end
end
context
'when user is reporter'
do
let
(
:user
)
{
reporter
}
it
'returns error'
do
expect
(
subject
[
:status
]).
to
eq
(
:error
)
expect
(
subject
[
:message
]).
to
eq
(
'Failed to cancel auto stop because you do not have permission to update the environment.'
)
end
end
end
context
'when environment will not be stopped automatically'
do
let
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
it
'returns error'
do
expect
(
subject
[
:status
]).
to
eq
(
:error
)
expect
(
subject
[
:message
]).
to
eq
(
'Failed to cancel auto stop because the environment is not set as auto stop.'
)
end
end
end
end
spec/support/shared_contexts/policies/project_policy_shared_context.rb
View file @
189565fa
...
...
@@ -39,12 +39,13 @@ RSpec.shared_context 'ProjectPolicy context' do
update_pipeline create_merge_request_from create_wiki push_code
resolve_note create_container_image update_container_image
create_environment create_deployment update_deployment create_release update_release
update_environment
]
end
let
(
:base_maintainer_permissions
)
do
%i[
push_to_delete_protected_branch update_project_snippet
update_environment
push_to_delete_protected_branch update_project_snippet
admin_project_snippet admin_project_member admin_note admin_wiki admin_project
admin_commit_status admin_build admin_container_image
admin_pipeline admin_environment admin_deployment destroy_release add_cluster
...
...
spec/support/shared_examples/controllers/environments_controller_shared_examples.rb
0 → 100644
View file @
189565fa
# frozen_string_literal: true
shared_examples_for
'successful response for #cancel_auto_stop'
do
include
GitlabRoutingHelper
context
'when request is html'
do
let
(
:params
)
{
environment_params
(
format: :html
)
}
it
'redirects to show page'
do
subject
expect
(
response
).
to
redirect_to
(
environment_path
(
environment
))
expect
(
flash
[
:notice
]).
to
eq
(
'Auto stop successfully canceled.'
)
end
it
'expires etag caching'
do
expect_next_instance_of
(
Gitlab
::
EtagCaching
::
Store
)
do
|
etag_caching
|
expect
(
etag_caching
).
to
receive
(
:touch
).
with
(
project_environments_path
(
project
,
format: :json
))
end
subject
end
end
context
'when request is js'
do
let
(
:params
)
{
environment_params
(
format: :json
)
}
it
'responds as ok'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
'message'
]).
to
eq
(
'Auto stop successfully canceled.'
)
end
it
'expires etag caching'
do
expect_next_instance_of
(
Gitlab
::
EtagCaching
::
Store
)
do
|
etag_caching
|
expect
(
etag_caching
).
to
receive
(
:touch
).
with
(
project_environments_path
(
project
,
format: :json
))
end
subject
end
end
end
shared_examples_for
'failed response for #cancel_auto_stop'
do
context
'when request is html'
do
let
(
:params
)
{
environment_params
(
format: :html
)
}
it
'redirects to show page'
do
subject
expect
(
response
).
to
redirect_to
(
environment_path
(
environment
))
expect
(
flash
[
:alert
]).
to
eq
(
"Failed to cancel auto stop because
#{
message
}
."
)
end
end
context
'when request is js'
do
let
(
:params
)
{
environment_params
(
format: :json
)
}
it
'responds as unprocessable entity'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
expect
(
json_response
[
'message'
]).
to
eq
(
"Failed to cancel auto stop because
#{
message
}
."
)
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