Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
61501a07
Commit
61501a07
authored
Nov 06, 2017
by
Alessio Caiazza
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Clusters::Applications services tests
parent
317c3cdd
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
184 additions
and
57 deletions
+184
-57
app/models/clusters/concerns/application_status.rb
app/models/clusters/concerns/application_status.rb
+1
-1
app/services/clusters/applications/check_installation_progress_service.rb
...sters/applications/check_installation_progress_service.rb
+2
-9
app/services/clusters/applications/finalize_installation_service.rb
...es/clusters/applications/finalize_installation_service.rb
+1
-7
app/services/clusters/applications/install_service.rb
app/services/clusters/applications/install_service.rb
+3
-6
app/services/clusters/applications/schedule_installation_service.rb
...es/clusters/applications/schedule_installation_service.rb
+4
-9
spec/services/clusters/applications/check_installation_progress_service_spec.rb
.../applications/check_installation_progress_service_spec.rb
+32
-25
spec/services/clusters/applications/finalize_installation_service_spec.rb
...usters/applications/finalize_installation_service_spec.rb
+32
-0
spec/services/clusters/applications/install_service_spec.rb
spec/services/clusters/applications/install_service_spec.rb
+54
-0
spec/services/clusters/applications/schedule_installation_service_spec.rb
...usters/applications/schedule_installation_service_spec.rb
+55
-0
No files found.
app/models/clusters/concerns/application_status.rb
View file @
61501a07
...
@@ -24,7 +24,7 @@ module Clusters
...
@@ -24,7 +24,7 @@ module Clusters
end
end
event
:make_scheduled
do
event
:make_scheduled
do
transition
any
-
[
:scheduled
]
=>
:scheduled
transition
%i(installable errored)
=>
:scheduled
end
end
before_transition
any
=>
[
:scheduled
]
do
|
app_status
,
_
|
before_transition
any
=>
[
:scheduled
]
do
|
app_status
,
_
|
...
...
app/services/clusters/applications/check_installation_progress_service.rb
View file @
61501a07
...
@@ -6,7 +6,7 @@ module Clusters
...
@@ -6,7 +6,7 @@ module Clusters
case
installation_phase
case
installation_phase
when
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
when
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
on_succeeded
finalize_installation
when
Gitlab
::
Kubernetes
::
Pod
::
FAILED
when
Gitlab
::
Kubernetes
::
Pod
::
FAILED
on_failed
on_failed
else
else
...
@@ -18,14 +18,6 @@ module Clusters
...
@@ -18,14 +18,6 @@ module Clusters
private
private
def
on_succeeded
if
app
.
make_installed
finalize_installation
else
app
.
make_errored!
(
"Failed to update app record;
#{
app
.
errors
}
"
)
end
end
def
on_failed
def
on_failed
app
.
make_errored!
(
installation_errors
||
'Installation silently failed'
)
app
.
make_errored!
(
installation_errors
||
'Installation silently failed'
)
finalize_installation
finalize_installation
...
@@ -34,6 +26,7 @@ module Clusters
...
@@ -34,6 +26,7 @@ module Clusters
def
check_timeout
def
check_timeout
if
Time
.
now
.
utc
-
app
.
updated_at
.
to_time
.
utc
>
ClusterWaitForAppInstallationWorker
::
TIMEOUT
if
Time
.
now
.
utc
-
app
.
updated_at
.
to_time
.
utc
>
ClusterWaitForAppInstallationWorker
::
TIMEOUT
app
.
make_errored!
(
'Installation timeouted'
)
app
.
make_errored!
(
'Installation timeouted'
)
finalize_installation
else
else
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
::
INTERVAL
,
app
.
name
,
app
.
id
)
ClusterWaitForAppInstallationWorker
::
INTERVAL
,
app
.
name
,
app
.
id
)
...
...
app/services/clusters/applications/finalize_installation_service.rb
View file @
61501a07
...
@@ -4,13 +4,7 @@ module Clusters
...
@@ -4,13 +4,7 @@ module Clusters
def
execute
def
execute
helm_api
.
delete_installation_pod!
(
app
)
helm_api
.
delete_installation_pod!
(
app
)
app
.
make_errored!
(
'Installation aborted'
)
if
aborted?
app
.
make_installed!
if
app
.
installing?
end
private
def
aborted?
app
.
installing?
||
app
.
scheduled?
end
end
end
end
end
end
...
...
app/services/clusters/applications/install_service.rb
View file @
61501a07
...
@@ -5,14 +5,11 @@ module Clusters
...
@@ -5,14 +5,11 @@ module Clusters
return
unless
app
.
scheduled?
return
unless
app
.
scheduled?
begin
begin
app
.
make_installing!
helm_api
.
install
(
app
)
helm_api
.
install
(
app
)
if
app
.
make_installing
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
::
INTERVAL
,
app
.
name
,
app
.
id
)
ClusterWaitForAppInstallationWorker
::
INTERVAL
,
app
.
name
,
app
.
id
)
else
app
.
make_errored!
(
"Failed to update app record;
#{
app
.
errors
}
"
)
end
rescue
KubeException
=>
ke
rescue
KubeException
=>
ke
app
.
make_errored!
(
"Kubernetes error:
#{
ke
.
message
}
"
)
app
.
make_errored!
(
"Kubernetes error:
#{
ke
.
message
}
"
)
rescue
StandardError
rescue
StandardError
...
...
app/services/clusters/applications/schedule_installation_service.rb
View file @
61501a07
...
@@ -2,15 +2,10 @@ module Clusters
...
@@ -2,15 +2,10 @@ module Clusters
module
Applications
module
Applications
class
ScheduleInstallationService
<
::
BaseService
class
ScheduleInstallationService
<
::
BaseService
def
execute
def
execute
application
=
application_class
.
find_or_create_by!
(
cluster:
cluster
)
application_class
.
find_or_create_by!
(
cluster:
cluster
).
try
do
|
application
|
application
.
make_scheduled!
application
.
make_scheduled!
ClusterInstallAppWorker
.
perform_async
(
application
.
name
,
application
.
id
)
ClusterInstallAppWorker
.
perform_async
(
application
.
name
,
application
.
id
)
true
end
rescue
ActiveRecord
::
RecordInvalid
false
rescue
StateMachines
::
InvalidTransition
false
end
end
private
private
...
...
spec/services/clusters/applications/check_installation_progress_service_spec.rb
View file @
61501a07
...
@@ -3,20 +3,27 @@ require 'spec_helper'
...
@@ -3,20 +3,27 @@ require 'spec_helper'
describe
Clusters
::
Applications
::
CheckInstallationProgressService
do
describe
Clusters
::
Applications
::
CheckInstallationProgressService
do
RESCHEDULE_PHASES
=
Gitlab
::
Kubernetes
::
Pod
::
PHASES
-
[
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
,
Gitlab
::
Kubernetes
::
Pod
::
FAILED
].
freeze
RESCHEDULE_PHASES
=
Gitlab
::
Kubernetes
::
Pod
::
PHASES
-
[
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
,
Gitlab
::
Kubernetes
::
Pod
::
FAILED
].
freeze
def
mock_helm_api
(
phase
,
errors:
nil
)
let
(
:application
)
{
create
(
:applications_helm
,
:installing
)
}
expect
(
service
).
to
receive
(
:installation_phase
).
once
.
and_return
(
phase
)
let
(
:service
)
{
described_class
.
new
(
application
)
}
expect
(
service
).
to
receive
(
:installation_errors
).
once
.
and_return
(
errors
)
if
errors
.
present?
let
(
:phase
)
{
Gitlab
::
Kubernetes
::
Pod
::
UNKNOWN
}
end
let
(
:errors
)
{
nil
}
shared_examples
'not yet completed phase'
do
|
phase
|
shared_examples
'a terminated installation'
do
context
"when the installation POD phase is
#{
phase
}
"
do
it
'finalize the installation'
do
before
do
expect
(
service
).
to
receive
(
:finalize_installation
).
once
mock_helm_api
(
phase
)
service
.
execute
end
end
end
shared_examples
'a not yet terminated installation'
do
|
a_phase
|
let
(
:phase
)
{
a_phase
}
context
"when phase is
#{
a_phase
}
"
do
context
'when not timeouted'
do
context
'when not timeouted'
do
it
'reschedule a new check'
do
it
'reschedule a new check'
do
expect
(
ClusterWaitForAppInstallationWorker
).
to
receive
(
:perform_in
).
once
expect
(
ClusterWaitForAppInstallationWorker
).
to
receive
(
:perform_in
).
once
expect
(
service
).
not_to
receive
(
:finalize_installation
)
service
.
execute
service
.
execute
...
@@ -28,6 +35,8 @@ describe Clusters::Applications::CheckInstallationProgressService do
...
@@ -28,6 +35,8 @@ describe Clusters::Applications::CheckInstallationProgressService do
context
'when timeouted'
do
context
'when timeouted'
do
let
(
:application
)
{
create
(
:applications_helm
,
:timeouted
)
}
let
(
:application
)
{
create
(
:applications_helm
,
:timeouted
)
}
it_behaves_like
'a terminated installation'
it
'make the application errored'
do
it
'make the application errored'
do
expect
(
ClusterWaitForAppInstallationWorker
).
not_to
receive
(
:perform_in
)
expect
(
ClusterWaitForAppInstallationWorker
).
not_to
receive
(
:perform_in
)
...
@@ -40,36 +49,34 @@ describe Clusters::Applications::CheckInstallationProgressService do
...
@@ -40,36 +49,34 @@ describe Clusters::Applications::CheckInstallationProgressService do
end
end
end
end
describe
'#execute'
do
before
do
let
(
:application
)
{
create
(
:applications_helm
,
:installing
)
}
expect
(
service
).
to
receive
(
:installation_phase
).
once
.
and_return
(
phase
)
let
(
:service
)
{
described_class
.
new
(
application
)
}
context
'when installation POD succeeded'
do
allow
(
service
).
to
receive
(
:installation_errors
).
and_return
(
errors
)
it
'make the application installed'
do
allow
(
service
).
to
receive
(
:finalize_installation
).
and_return
(
nil
)
mock_helm_api
(
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
)
end
expect
(
service
).
to
receive
(
:finalize_installation
).
once
service
.
execute
describe
'#execute'
do
context
'when installation POD succeeded'
do
let
(
:phase
)
{
Gitlab
::
Kubernetes
::
Pod
::
SUCCEEDED
}
expect
(
application
).
to
be_installed
it_behaves_like
'a terminated installation'
expect
(
application
.
status_reason
).
to
be_nil
end
end
end
context
'when installation POD failed'
do
context
'when installation POD failed'
do
let
(
:error_message
)
{
'test installation failed'
}
let
(
:phase
)
{
Gitlab
::
Kubernetes
::
Pod
::
FAILED
}
let
(
:errors
)
{
'test installation failed'
}
it
'make the application errored'
do
it_behaves_like
'a terminated installation'
mock_helm_api
(
Gitlab
::
Kubernetes
::
Pod
::
FAILED
,
errors:
error_message
)
expect
(
service
).
to
receive
(
:finalize_installation
).
once
it
'make the application errored'
do
service
.
execute
service
.
execute
expect
(
application
).
to
be_errored
expect
(
application
).
to
be_errored
expect
(
application
.
status_reason
).
to
eq
(
error
_message
)
expect
(
application
.
status_reason
).
to
eq
(
error
s
)
end
end
end
end
RESCHEDULE_PHASES
.
each
{
|
phase
|
it_behaves_like
'
not yet completed phase
'
,
phase
}
RESCHEDULE_PHASES
.
each
{
|
phase
|
it_behaves_like
'
a not yet terminated installation
'
,
phase
}
end
end
end
end
spec/services/clusters/applications/finalize_installation_service_spec.rb
0 → 100644
View file @
61501a07
require
'spec_helper'
describe
Clusters
::
Applications
::
FinalizeInstallationService
do
describe
'#execute'
do
let
(
:application
)
{
create
(
:applications_helm
,
:installing
)
}
let
(
:service
)
{
described_class
.
new
(
application
)
}
before
do
expect_any_instance_of
(
Gitlab
::
Kubernetes
::
Helm
).
to
receive
(
:delete_installation_pod!
).
with
(
application
)
end
context
'when installation POD succeeded'
do
it
'make the application installed'
do
service
.
execute
expect
(
application
).
to
be_installed
expect
(
application
.
status_reason
).
to
be_nil
end
end
context
'when installation POD failed'
do
let
(
:application
)
{
create
(
:applications_helm
,
:errored
)
}
it
'make the application errored'
do
service
.
execute
expect
(
application
).
to
be_errored
expect
(
application
.
status_reason
).
not_to
be_nil
end
end
end
end
spec/services/clusters/applications/install_service_spec.rb
0 → 100644
View file @
61501a07
require
'spec_helper'
describe
Clusters
::
Applications
::
InstallService
do
describe
'#execute'
do
let
(
:application
)
{
create
(
:applications_helm
,
:scheduled
)
}
let
(
:service
)
{
described_class
.
new
(
application
)
}
context
'when there are no errors'
do
before
do
expect_any_instance_of
(
Gitlab
::
Kubernetes
::
Helm
).
to
receive
(
:install
).
with
(
application
)
allow
(
ClusterWaitForAppInstallationWorker
).
to
receive
(
:perform_in
).
and_return
(
nil
)
end
it
'make the application installing'
do
service
.
execute
expect
(
application
).
to
be_installing
end
it
'schedule async installation status check'
do
expect
(
ClusterWaitForAppInstallationWorker
).
to
receive
(
:perform_in
).
once
service
.
execute
end
end
context
'when k8s cluster communication fails'
do
before
do
error
=
KubeException
.
new
(
500
,
'system failure'
,
nil
)
expect_any_instance_of
(
Gitlab
::
Kubernetes
::
Helm
).
to
receive
(
:install
).
with
(
application
).
and_raise
(
error
)
end
it
'make the application errored'
do
service
.
execute
expect
(
application
).
to
be_errored
expect
(
application
.
status_reason
).
to
match
(
/kubernetes error:/i
)
end
end
context
'when application cannot be persisted'
do
let
(
:application
)
{
build
(
:applications_helm
,
:scheduled
)
}
it
'make the application errored'
do
expect
(
application
).
to
receive
(
:make_installing!
).
once
.
and_raise
(
ActiveRecord
::
RecordInvalid
)
expect_any_instance_of
(
Gitlab
::
Kubernetes
::
Helm
).
not_to
receive
(
:install
)
service
.
execute
expect
(
application
).
to
be_errored
end
end
end
end
spec/services/clusters/applications/schedule_installation_service_spec.rb
0 → 100644
View file @
61501a07
require
'spec_helper'
describe
Clusters
::
Applications
::
ScheduleInstallationService
do
def
count_scheduled
application_class
&
.
with_status
(
:scheduled
)
&
.
count
||
0
end
shared_examples
'a failing service'
do
it
'raise an exception'
do
expect
(
ClusterInstallAppWorker
).
not_to
receive
(
:perform_async
)
count_before
=
count_scheduled
expect
{
service
.
execute
}.
to
raise_error
(
StandardError
)
expect
(
count_scheduled
).
to
eq
(
count_before
)
end
end
describe
'#execute'
do
let
(
:application_class
)
{
Clusters
::
Applications
::
Helm
}
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:project
)
{
cluster
.
project
}
let
(
:service
)
{
described_class
.
new
(
project
,
nil
,
cluster:
cluster
,
application_class:
application_class
)
}
it
'creates a new application'
do
expect
{
service
.
execute
}.
to
change
{
application_class
.
count
}.
by
(
1
)
end
it
'make the application scheduled'
do
expect
(
ClusterInstallAppWorker
).
to
receive
(
:perform_async
).
with
(
application_class
.
application_name
,
kind_of
(
Numeric
)).
once
expect
{
service
.
execute
}.
to
change
{
application_class
.
with_status
(
:scheduled
).
count
}.
by
(
1
)
end
context
'when installation is already in progress'
do
let
(
:application
)
{
create
(
:applications_helm
,
:installing
)
}
let
(
:cluster
)
{
application
.
cluster
}
it_behaves_like
'a failing service'
end
context
'when application_class is nil'
do
let
(
:application_class
)
{
nil
}
it_behaves_like
'a failing service'
end
context
'when application cannot be persisted'
do
before
do
expect_any_instance_of
(
application_class
).
to
receive
(
:make_scheduled!
).
once
.
and_raise
(
ActiveRecord
::
RecordInvalid
)
end
it_behaves_like
'a failing service'
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