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
bd1857c7
Commit
bd1857c7
authored
Aug 05, 2021
by
Pedro Pombeiro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extract runner registration service from endpoint
parent
b4bfb098
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
330 additions
and
378 deletions
+330
-378
app/services/ci/register_runner_service.rb
app/services/ci/register_runner_service.rb
+36
-0
lib/api/ci/helpers/runner.rb
lib/api/ci/helpers/runner.rb
+0
-8
lib/api/ci/runner.rb
lib/api/ci/runner.rb
+2
-15
spec/requests/api/ci/runner/runners_post_spec.rb
spec/requests/api/ci/runner/runners_post_spec.rb
+66
-355
spec/services/ci/register_runner_service_spec.rb
spec/services/ci/register_runner_service_spec.rb
+226
-0
No files found.
app/services/ci/register_runner_service.rb
0 → 100644
View file @
bd1857c7
# frozen_string_literal: true
module
Ci
class
RegisterRunnerService
def
execute
(
registration_token
,
attributes
)
runner_type_attrs
=
check_token_and_extract_attrs
(
registration_token
)
return
unless
runner_type_attrs
::
Ci
::
Runner
.
create
(
attributes
.
merge
(
runner_type_attrs
))
end
private
def
check_token_and_extract_attrs
(
registration_token
)
if
runner_registration_token_valid?
(
registration_token
)
# Create shared runner. Requires admin access
{
runner_type: :instance_type
}
elsif
runner_registrar_valid?
(
'project'
)
&&
project
=
::
Project
.
find_by_runners_token
(
registration_token
)
# Create a specific runner for the project
{
runner_type: :project_type
,
projects:
[
project
]
}
elsif
runner_registrar_valid?
(
'group'
)
&&
group
=
::
Group
.
find_by_runners_token
(
registration_token
)
# Create a specific runner for the group
{
runner_type: :group_type
,
groups:
[
group
]
}
end
end
def
runner_registration_token_valid?
(
registration_token
)
ActiveSupport
::
SecurityUtils
.
secure_compare
(
registration_token
,
Gitlab
::
CurrentSettings
.
runners_registration_token
)
end
def
runner_registrar_valid?
(
type
)
Feature
.
disabled?
(
:runner_registration_control
)
||
Gitlab
::
CurrentSettings
.
valid_runner_registrars
.
include?
(
type
)
end
end
end
lib/api/ci/helpers/runner.rb
View file @
bd1857c7
...
...
@@ -11,14 +11,6 @@ module API
JOB_TOKEN_HEADER
=
'HTTP_JOB_TOKEN'
JOB_TOKEN_PARAM
=
:token
def
runner_registration_token_valid?
ActiveSupport
::
SecurityUtils
.
secure_compare
(
params
[
:token
],
Gitlab
::
CurrentSettings
.
runners_registration_token
)
end
def
runner_registrar_valid?
(
type
)
Feature
.
disabled?
(
:runner_registration_control
)
||
Gitlab
::
CurrentSettings
.
valid_runner_registrars
.
include?
(
type
)
end
def
authenticate_runner!
forbidden!
unless
current_runner
...
...
lib/api/ci/runner.rb
View file @
bd1857c7
...
...
@@ -28,21 +28,8 @@ module API
attributes
=
attributes_for_keys
([
:description
,
:active
,
:locked
,
:run_untagged
,
:tag_list
,
:access_level
,
:maximum_timeout
])
.
merge
(
get_runner_details_from_request
)
attributes
=
if
runner_registration_token_valid?
# Create shared runner. Requires admin access
attributes
.
merge
(
runner_type: :instance_type
)
elsif
runner_registrar_valid?
(
'project'
)
&&
@project
=
Project
.
find_by_runners_token
(
params
[
:token
])
# Create a specific runner for the project
attributes
.
merge
(
runner_type: :project_type
,
projects:
[
@project
])
elsif
runner_registrar_valid?
(
'group'
)
&&
@group
=
Group
.
find_by_runners_token
(
params
[
:token
])
# Create a specific runner for the group
attributes
.
merge
(
runner_type: :group_type
,
groups:
[
@group
])
else
forbidden!
end
@runner
=
::
Ci
::
Runner
.
create
(
attributes
)
@runner
=
::
Ci
::
RegisterRunnerService
.
new
.
execute
(
params
[
:token
],
attributes
)
forbidden!
unless
@runner
if
@runner
.
persisted?
present
@runner
,
with:
Entities
::
Ci
::
RunnerRegistrationDetails
...
...
spec/requests/api/ci/runner/runners_post_spec.rb
View file @
bd1857c7
...
...
@@ -3,21 +3,6 @@
require
'spec_helper'
RSpec
.
describe
API
::
Ci
::
Runner
,
:clean_gitlab_redis_shared_state
do
include
StubGitlabCalls
include
RedisHelpers
include
WorkhorseHelpers
let
(
:registration_token
)
{
'abcdefg123456'
}
before
do
stub_feature_flags
(
ci_enable_live_trace:
true
)
stub_feature_flags
(
runner_registration_control:
false
)
stub_gitlab_calls
stub_application_setting
(
runners_registration_token:
registration_token
)
stub_application_setting
(
valid_runner_registrars:
ApplicationSetting
::
VALID_RUNNER_REGISTRAR_TYPES
)
allow_any_instance_of
(
::
Ci
::
Runner
).
to
receive
(
:cache_attributes
)
end
describe
'/api/v4/runners'
do
describe
'POST /api/v4/runners'
do
context
'when no token is provided'
do
...
...
@@ -30,354 +15,79 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context
'when invalid token is provided'
do
it
'returns 403 error'
do
allow_next_instance_of
(
::
Ci
::
RegisterRunnerService
)
do
|
service
|
allow
(
service
).
to
receive
(
:execute
).
and_return
(
nil
)
end
post
api
(
'/runners'
),
params:
{
token:
'invalid'
}
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when valid
token is
provided'
do
context
'when valid
parameters are
provided'
do
def
request
post
api
(
'/runners'
),
params:
{
token:
token
}
end
context
'with a registration token'
do
let
(
:token
)
{
registration_token
}
it
'creates runner with default values'
do
request
runner
=
::
Ci
::
Runner
.
first
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
json_response
[
'id'
]).
to
eq
(
runner
.
id
)
expect
(
json_response
[
'token'
]).
to
eq
(
runner
.
token
)
expect
(
runner
.
run_untagged
).
to
be
true
expect
(
runner
.
active
).
to
be
true
expect
(
runner
.
token
).
not_to
eq
(
registration_token
)
expect
(
runner
).
to
be_instance_type
end
it_behaves_like
'storing arguments in the application context for the API'
do
subject
{
request
}
let
(
:expected_params
)
{
{
client_id:
"runner/
#{
::
Ci
::
Runner
.
first
.
id
}
"
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
do
let
(
:subject_proc
)
{
proc
{
request
}
}
end
end
context
'when project token is used'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:token
)
{
project
.
runners_token
}
it
'creates project runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
project
.
runners
.
size
).
to
eq
(
1
)
runner
=
::
Ci
::
Runner
.
first
expect
(
runner
.
token
).
not_to
eq
(
registration_token
)
expect
(
runner
.
token
).
not_to
eq
(
project
.
runners_token
)
expect
(
runner
).
to
be_project_type
post
api
(
'/runners'
),
params:
{
token:
'valid token'
,
description:
'server.hostname'
,
run_untagged:
false
,
tag_list:
'tag1, tag2'
,
locked:
true
,
active:
true
,
access_level:
'ref_protected'
,
maximum_timeout:
9000
}
end
it_behaves_like
'storing arguments in the application context for the API'
do
subject
{
request
}
let_it_be
(
:new_runner
)
{
create
(
:ci_runner
)
}
let
(
:expected_params
)
{
{
project:
project
.
full_path
,
client_id:
"runner/
#{
::
Ci
::
Runner
.
first
.
id
}
"
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
do
let
(
:subject_proc
)
{
proc
{
request
}
}
end
context
'when it exceeds the application limits'
do
before
do
create
(
:ci_runner
,
runner_type: :project_type
,
projects:
[
project
],
contacted_at:
1
.
second
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_project_runners:
1
)
end
it
'does not create runner'
do
request
allow_next_instance_of
(
::
Ci
::
RegisterRunnerService
)
do
|
service
|
expected_params
=
{
description:
'server.hostname'
,
run_untagged:
false
,
tag_list:
%w(tag1 tag2)
,
locked:
true
,
active:
true
,
access_level:
'ref_protected'
,
maximum_timeout:
9000
}.
stringify_keys
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'message'
]).
to
include
(
'runner_projects.base'
=>
[
'Maximum number of ci registered project runners (1) exceeded'
])
expect
(
project
.
runners
.
reload
.
size
).
to
eq
(
1
)
allow
(
service
).
to
receive
(
:execute
)
.
once
.
with
(
'valid token'
,
a_hash_including
(
expected_params
))
.
and_return
(
new_runner
)
end
end
context
'when abandoned runners cause application limits to not be exceeded'
do
before
do
create
(
:ci_runner
,
runner_type: :project_type
,
projects:
[
project
],
created_at:
14
.
months
.
ago
,
contacted_at:
13
.
months
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_project_runners:
1
)
end
it
'creates runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
json_response
[
'message'
]).
to
be_nil
expect
(
project
.
runners
.
reload
.
size
).
to
eq
(
2
)
expect
(
project
.
runners
.
recent
.
size
).
to
eq
(
1
)
end
end
context
'when valid runner registrars do not include project'
do
before
do
stub_application_setting
(
valid_runner_registrars:
[
'group'
])
end
context
'when feature flag is enabled'
do
before
do
stub_feature_flags
(
runner_registration_control:
true
)
end
it
'returns 403 error'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when feature flag is disabled'
do
it
'registers the runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
active
).
to
be
true
end
end
end
end
context
'when group token is used'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:token
)
{
group
.
runners_token
}
it
'creates a group runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
runner
=
::
Ci
::
Runner
.
first
expect
(
runner
.
token
).
not_to
eq
(
registration_token
)
expect
(
runner
.
token
).
not_to
eq
(
group
.
runners_token
)
expect
(
runner
).
to
be_group_type
expect
(
json_response
[
'id'
]).
to
eq
(
new_runner
.
id
)
expect
(
json_response
[
'token'
]).
to
eq
(
new_runner
.
token
)
end
it_behaves_like
'storing arguments in the application context for the API'
do
subject
{
request
}
let
(
:expected_params
)
{
{
root_namespace:
group
.
full_path_components
.
first
,
client_id:
"runner/
#{
::
Ci
::
Runner
.
first
.
id
}
"
}
}
let
(
:expected_params
)
{
{
client_id:
"runner/
#{
new_runner
.
id
}
"
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
do
let
(
:subject_proc
)
{
proc
{
request
}
}
end
context
'when it exceeds the application limits'
do
before
do
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
contacted_at:
nil
,
created_at:
1
.
month
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_group_runners:
1
)
end
it
'does not create runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'message'
]).
to
include
(
'runner_namespaces.base'
=>
[
'Maximum number of ci registered group runners (1) exceeded'
])
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
end
end
context
'when abandoned runners cause application limits to not be exceeded'
do
before
do
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
created_at:
4
.
months
.
ago
,
contacted_at:
3
.
months
.
ago
)
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
contacted_at:
nil
,
created_at:
4
.
months
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_group_runners:
1
)
end
it
'creates runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
json_response
[
'message'
]).
to
be_nil
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
3
)
expect
(
group
.
runners
.
recent
.
size
).
to
eq
(
1
)
end
end
context
'calling actual register service'
do
include
StubGitlabCalls
context
'when valid runner registrars do not include group'
do
before
do
stub_application_setting
(
valid_runner_registrars:
[
'project'
])
end
let
(
:registration_token
)
{
'abcdefg123456'
}
context
'when feature flag is enabled'
do
before
do
stub_feature_flags
(
runner_registration_control:
true
)
end
it
'returns 403 error'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'when feature flag is disabled'
do
it
'registers the runner'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
active
).
to
be
true
end
end
end
end
end
context
'when runner description is provided'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
description:
'server.hostname'
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
description
).
to
eq
(
'server.hostname'
)
end
end
context
'when runner tags are provided'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
tag_list:
'tag1, tag2'
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
tag_list
.
sort
).
to
eq
(
%w(tag1 tag2)
)
end
end
context
'when option for running untagged jobs is provided'
do
context
'when tags are provided'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
run_untagged:
false
,
tag_list:
[
'tag'
]
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
run_untagged
).
to
be
false
expect
(
::
Ci
::
Runner
.
first
.
tag_list
.
sort
).
to
eq
([
'tag'
])
end
end
context
'when tags are not provided'
do
it
'returns 400 error'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
run_untagged:
false
}
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'message'
]).
to
include
(
'tags_list'
=>
[
'can not be empty when runner is not allowed to pick untagged jobs'
])
end
end
end
context
'when option for locking Runner is provided'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
locked:
true
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
locked
).
to
be
true
end
end
context
'when option for activating a Runner is provided'
do
context
'when active is set to true'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
active:
true
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
active
).
to
be
true
end
end
context
'when active is set to false'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
active:
false
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
active
).
to
be
false
end
end
end
context
'when access_level is provided for Runner'
do
context
'when access_level is set to ref_protected'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
access_level:
'ref_protected'
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
ref_protected?
).
to
be
true
end
end
context
'when access_level is set to not_protected'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
access_level:
'not_protected'
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
ref_protected?
).
to
be
false
end
end
end
context
'when maximum job timeout is specified'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
maximum_timeout:
9000
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
maximum_timeout
).
to
eq
(
9000
)
end
context
'when maximum job timeout is empty'
do
it
'creates runner'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
,
maximum_timeout:
''
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
maximum_timeout
).
to
be_nil
end
end
stub_gitlab_calls
stub_application_setting
(
runners_registration_token:
registration_token
)
allow_any_instance_of
(
::
Ci
::
Runner
).
to
receive
(
:cache_attributes
)
end
%w(name version revision platform architecture)
.
each
do
|
param
|
...
...
@@ -391,7 +101,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
fir
st
.
read_attribute
(
param
.
to_sym
)).
to
eq
(
value
)
expect
(
::
Ci
::
Runner
.
la
st
.
read_attribute
(
param
.
to_sym
)).
to
eq
(
value
)
end
end
end
...
...
@@ -402,7 +112,8 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
headers:
{
'X-Forwarded-For'
=>
'123.111.123.111'
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
::
Ci
::
Runner
.
first
.
ip_address
).
to
eq
(
'123.111.123.111'
)
expect
(
::
Ci
::
Runner
.
last
.
ip_address
).
to
eq
(
'123.111.123.111'
)
end
end
end
end
...
...
spec/services/ci/register_runner_service_spec.rb
0 → 100644
View file @
bd1857c7
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
::
Ci
::
RegisterRunnerService
do
let
(
:registration_token
)
{
'abcdefg123456'
}
before
do
stub_feature_flags
(
runner_registration_control:
false
)
stub_application_setting
(
runners_registration_token:
registration_token
)
stub_application_setting
(
valid_runner_registrars:
ApplicationSetting
::
VALID_RUNNER_REGISTRAR_TYPES
)
end
describe
'#execute'
do
let
(
:token
)
{
}
let
(
:args
)
{
{}
}
subject
{
described_class
.
new
.
execute
(
token
,
args
)
}
context
'when no token is provided'
do
let
(
:token
)
{
''
}
it
'returns nil'
do
is_expected
.
to
be_nil
end
end
context
'when invalid token is provided'
do
let
(
:token
)
{
'invalid'
}
it
'returns nil'
do
is_expected
.
to
be_nil
end
end
context
'when valid token is provided'
do
context
'with a registration token'
do
let
(
:token
)
{
registration_token
}
it
'creates runner with default values'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
persisted?
).
to
be_truthy
expect
(
subject
.
run_untagged
).
to
be
true
expect
(
subject
.
active
).
to
be
true
expect
(
subject
.
token
).
not_to
eq
(
registration_token
)
expect
(
subject
).
to
be_instance_type
end
context
'with non-default arguments'
do
let
(
:args
)
do
{
description:
'some description'
,
active:
false
,
locked:
true
,
run_untagged:
false
,
tag_list:
%w(tag1 tag2)
,
access_level:
'ref_protected'
,
maximum_timeout:
600
,
name:
'some name'
,
version:
'some version'
,
revision:
'some revision'
,
platform:
'some platform'
,
architecture:
'some architecture'
,
ip_address:
'10.0.0.1'
,
config:
{
gpus:
'some gpu config'
}
}
end
it
'creates runner with specified values'
,
:aggregate_failures
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
active
).
to
eq
args
[
:active
]
expect
(
subject
.
locked
).
to
eq
args
[
:locked
]
expect
(
subject
.
run_untagged
).
to
eq
args
[
:run_untagged
]
expect
(
subject
.
tags
).
to
contain_exactly
(
an_object_having_attributes
(
name:
'tag1'
),
an_object_having_attributes
(
name:
'tag2'
)
)
expect
(
subject
.
access_level
).
to
eq
args
[
:access_level
]
expect
(
subject
.
maximum_timeout
).
to
eq
args
[
:maximum_timeout
]
expect
(
subject
.
name
).
to
eq
args
[
:name
]
expect
(
subject
.
version
).
to
eq
args
[
:version
]
expect
(
subject
.
revision
).
to
eq
args
[
:revision
]
expect
(
subject
.
platform
).
to
eq
args
[
:platform
]
expect
(
subject
.
architecture
).
to
eq
args
[
:architecture
]
expect
(
subject
.
ip_address
).
to
eq
args
[
:ip_address
]
end
end
end
context
'when project token is used'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:token
)
{
project
.
runners_token
}
it
'creates project runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
project
.
runners
.
size
).
to
eq
(
1
)
is_expected
.
to
eq
(
project
.
runners
.
first
)
expect
(
subject
.
token
).
not_to
eq
(
registration_token
)
expect
(
subject
.
token
).
not_to
eq
(
project
.
runners_token
)
expect
(
subject
).
to
be_project_type
end
context
'when it exceeds the application limits'
do
before
do
create
(
:ci_runner
,
runner_type: :project_type
,
projects:
[
project
],
contacted_at:
1
.
second
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_project_runners:
1
)
end
it
'does not create runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
persisted?
).
to
be_falsey
expect
(
subject
.
errors
.
messages
).
to
eq
(
'runner_projects.base'
:
[
'Maximum number of ci registered project runners (1) exceeded'
])
expect
(
project
.
runners
.
reload
.
size
).
to
eq
(
1
)
end
end
context
'when abandoned runners cause application limits to not be exceeded'
do
before
do
create
(
:ci_runner
,
runner_type: :project_type
,
projects:
[
project
],
created_at:
14
.
months
.
ago
,
contacted_at:
13
.
months
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_project_runners:
1
)
end
it
'creates runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
errors
).
to
be_empty
expect
(
project
.
runners
.
reload
.
size
).
to
eq
(
2
)
expect
(
project
.
runners
.
recent
.
size
).
to
eq
(
1
)
end
end
context
'when valid runner registrars do not include project'
do
before
do
stub_application_setting
(
valid_runner_registrars:
[
'group'
])
end
context
'when feature flag is enabled'
do
before
do
stub_feature_flags
(
runner_registration_control:
true
)
end
it
'returns 403 error'
do
is_expected
.
to
be_nil
end
end
context
'when feature flag is disabled'
do
it
'registers the runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
errors
).
to
be_empty
expect
(
subject
.
active
).
to
be
true
end
end
end
end
context
'when group token is used'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:token
)
{
group
.
runners_token
}
it
'creates a group runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
errors
).
to
be_empty
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
expect
(
subject
.
token
).
not_to
eq
(
registration_token
)
expect
(
subject
.
token
).
not_to
eq
(
group
.
runners_token
)
expect
(
subject
).
to
be_group_type
end
context
'when it exceeds the application limits'
do
before
do
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
contacted_at:
nil
,
created_at:
1
.
month
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_group_runners:
1
)
end
it
'does not create runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
persisted?
).
to
be_falsey
expect
(
subject
.
errors
.
messages
).
to
eq
(
'runner_namespaces.base'
:
[
'Maximum number of ci registered group runners (1) exceeded'
])
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
end
end
context
'when abandoned runners cause application limits to not be exceeded'
do
before
do
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
created_at:
4
.
months
.
ago
,
contacted_at:
3
.
months
.
ago
)
create
(
:ci_runner
,
runner_type: :group_type
,
groups:
[
group
],
contacted_at:
nil
,
created_at:
4
.
months
.
ago
)
create
(
:plan_limits
,
:default_plan
,
ci_registered_group_runners:
1
)
end
it
'creates runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
errors
).
to
be_empty
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
3
)
expect
(
group
.
runners
.
recent
.
size
).
to
eq
(
1
)
end
end
context
'when valid runner registrars do not include group'
do
before
do
stub_application_setting
(
valid_runner_registrars:
[
'project'
])
end
context
'when feature flag is enabled'
do
before
do
stub_feature_flags
(
runner_registration_control:
true
)
end
it
'returns nil'
do
is_expected
.
to
be_nil
end
end
context
'when feature flag is disabled'
do
it
'registers the runner'
do
is_expected
.
to
be_an_instance_of
(
::
Ci
::
Runner
)
expect
(
subject
.
errors
).
to
be_empty
expect
(
subject
.
active
).
to
be
true
end
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