[ADD] DCOS-367 As a user, I want to scale the application
fit tests fix scale json fix dcos help test update after review, add negative tests fix help test move parse_float to dcoscli.marathon.main fix test help marathon testx
This commit is contained in:
@@ -22,6 +22,7 @@ Usage:
|
||||
dcos marathon task show <task-id>
|
||||
dcos marathon group add [<group-resource>]
|
||||
dcos marathon group list [--json]
|
||||
dcos marathon group scale [--force] <group-id> <scale-factor>
|
||||
dcos marathon group show [--group-version=<group-version>] <group-id>
|
||||
dcos marathon group remove [--force] <group-id>
|
||||
dcos marathon group update [--force] <group-id> [<properties>...]
|
||||
@@ -96,6 +97,8 @@ Positional Arguments:
|
||||
stdin.
|
||||
|
||||
<task-id> The task id
|
||||
|
||||
<scale-factor> The factor to scale an application group by
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
@@ -240,6 +243,11 @@ def _cmds():
|
||||
arg_keys=['<group-id>', '<properties>', '--force'],
|
||||
function=_group_update),
|
||||
|
||||
cmds.Command(
|
||||
hierarchy=['marathon', 'group', 'scale'],
|
||||
arg_keys=['<group-id>', '<scale-factor>', '--force'],
|
||||
function=_group_scale),
|
||||
|
||||
cmds.Command(
|
||||
hierarchy=['marathon', 'about'],
|
||||
arg_keys=[],
|
||||
@@ -645,6 +653,25 @@ def _update(app_id, properties, force):
|
||||
return 0
|
||||
|
||||
|
||||
def _group_scale(group_id, scale_factor, force):
|
||||
"""
|
||||
:param group_id: the id of the group
|
||||
:type group_id: str
|
||||
:param scale_factor: scale factor for application group
|
||||
:type scale_factor: str
|
||||
:param force: whether to override running deployments
|
||||
:type force: bool
|
||||
:returns: process return code
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
client = marathon.create_client()
|
||||
scale_factor = util.parse_float(scale_factor)
|
||||
deployment = client.scale_group(group_id, scale_factor, force)
|
||||
emitter.publish('Created deployment {}'.format(deployment))
|
||||
return 0
|
||||
|
||||
|
||||
def _validate_update(current_resource, properties, schema):
|
||||
"""
|
||||
Validate resource ("app" or "group") update
|
||||
|
||||
@@ -22,6 +22,7 @@ Usage:
|
||||
dcos marathon task show <task-id>
|
||||
dcos marathon group add [<group-resource>]
|
||||
dcos marathon group list [--json]
|
||||
dcos marathon group scale [--force] <group-id> <scale-factor>
|
||||
dcos marathon group show [--group-version=<group-version>] <group-id>
|
||||
dcos marathon group remove [--force] <group-id>
|
||||
dcos marathon group update [--force] <group-id> [<properties>...]
|
||||
@@ -96,3 +97,5 @@ Positional Arguments:
|
||||
stdin.
|
||||
|
||||
<task-id> The task id
|
||||
|
||||
<scale-factor> The factor to scale an application group by
|
||||
|
||||
15
cli/tests/data/marathon/groups/scale.json
Normal file
15
cli/tests/data/marathon/groups/scale.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"apps": [
|
||||
{
|
||||
"id": "sleep",
|
||||
"cmd": "sleep 1000",
|
||||
"instances": 1
|
||||
}
|
||||
],
|
||||
"id": "sleep"
|
||||
}
|
||||
],
|
||||
"id": "scale-group"
|
||||
}
|
||||
@@ -39,6 +39,7 @@ Usage:
|
||||
dcos marathon task show <task-id>
|
||||
dcos marathon group add [<group-resource>]
|
||||
dcos marathon group list [--json]
|
||||
dcos marathon group scale [--force] <group-id> <scale-factor>
|
||||
dcos marathon group show [--group-version=<group-version>] <group-id>
|
||||
dcos marathon group remove [--force] <group-id>
|
||||
dcos marathon group update [--force] <group-id> [<properties>...]
|
||||
@@ -113,6 +114,8 @@ Positional Arguments:
|
||||
stdin.
|
||||
|
||||
<task-id> The task id
|
||||
|
||||
<scale-factor> The factor to scale an application group by
|
||||
"""
|
||||
assert_command(['dcos', 'marathon', '--help'],
|
||||
stdout=stdout)
|
||||
|
||||
@@ -123,6 +123,56 @@ def test_update_missing_field():
|
||||
"Possible properties are: ")
|
||||
|
||||
|
||||
def test_scale_group():
|
||||
_deploy_group('tests/data/marathon/groups/scale.json')
|
||||
returncode, stdout, stderr = exec_command(['dcos', 'marathon', 'group',
|
||||
'scale', 'scale-group', '2'])
|
||||
assert stderr == b''
|
||||
assert returncode == 0
|
||||
watch_all_deployments()
|
||||
returncode, stdout, stderr = exec_command(
|
||||
['dcos', 'marathon', 'group', 'show',
|
||||
'scale-group'])
|
||||
res = json.loads(stdout.decode('utf-8'))
|
||||
|
||||
assert res['groups'][0]['apps'][0]['instances'] == 2
|
||||
_remove_group('scale-group')
|
||||
|
||||
|
||||
def test_scale_group_not_exist():
|
||||
returncode, stdout, stderr = exec_command(['dcos', 'marathon', 'group',
|
||||
'scale', 'scale-group', '2'])
|
||||
assert stderr == b''
|
||||
watch_all_deployments()
|
||||
returncode, stdout, stderr = exec_command(
|
||||
['dcos', 'marathon', 'group', 'show',
|
||||
'scale-group'])
|
||||
res = json.loads(stdout.decode('utf-8'))
|
||||
|
||||
assert len(res['apps']) == 0
|
||||
_remove_group('scale-group')
|
||||
|
||||
|
||||
def test_scale_group_when_scale_factor_negative():
|
||||
_deploy_group('tests/data/marathon/groups/scale.json')
|
||||
returncode, stdout, stderr = exec_command(['dcos', 'marathon', 'group',
|
||||
'scale', 'scale-group', '-2'])
|
||||
assert b'Command not recognized' in stdout
|
||||
assert returncode == 1
|
||||
watch_all_deployments()
|
||||
_remove_group('scale-group')
|
||||
|
||||
|
||||
def test_scale_group_when_scale_factor_not_float():
|
||||
_deploy_group('tests/data/marathon/groups/scale.json')
|
||||
returncode, stdout, stderr = exec_command(['dcos', 'marathon', 'group',
|
||||
'scale', 'scale-group', '1.a'])
|
||||
assert stderr == b'Error parsing string as float\n'
|
||||
assert returncode == 1
|
||||
watch_all_deployments()
|
||||
_remove_group('scale-group')
|
||||
|
||||
|
||||
def _remove_group(group_id):
|
||||
assert_command(['dcos', 'marathon', 'group', 'remove', group_id])
|
||||
|
||||
|
||||
@@ -388,6 +388,35 @@ class Client(object):
|
||||
deployment = response.json()['deploymentId']
|
||||
return deployment
|
||||
|
||||
def scale_group(self, group_id, scale_factor, force=None):
|
||||
"""Scales a group with the requested scale-factor.
|
||||
:param group_id: the ID of the group to scale
|
||||
:type group_id: str
|
||||
:param scale_factor: the requested value of scale-factor
|
||||
:type scale_factor: float
|
||||
:param force: whether to override running deployments
|
||||
:type force: bool
|
||||
:returns: the resulting deployment ID
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
group_id = self.normalize_app_id(group_id)
|
||||
|
||||
if not force:
|
||||
params = None
|
||||
else:
|
||||
params = {'force': 'true'}
|
||||
|
||||
url = self._create_url('v2/groups{}'.format(group_id))
|
||||
|
||||
response = http.put(url,
|
||||
params=params,
|
||||
json={'scaleBy': scale_factor},
|
||||
timeout=self._timeout)
|
||||
|
||||
deployment = response.json()['deploymentId']
|
||||
return deployment
|
||||
|
||||
def stop_app(self, app_id, force=None):
|
||||
"""Scales an application to zero instances.
|
||||
|
||||
|
||||
19
dcos/util.py
19
dcos/util.py
@@ -454,6 +454,25 @@ def parse_int(string):
|
||||
raise DCOSException('Error parsing string as int')
|
||||
|
||||
|
||||
def parse_float(string):
|
||||
"""Parse string and an float
|
||||
|
||||
:param string: string to parse as an float
|
||||
:type string: str
|
||||
:returns: the float value of the string
|
||||
:rtype: float
|
||||
"""
|
||||
|
||||
try:
|
||||
return float(string)
|
||||
except:
|
||||
logger.error(
|
||||
'Unhandled exception while parsing string as float: %r',
|
||||
string)
|
||||
|
||||
raise DCOSException('Error parsing string as float')
|
||||
|
||||
|
||||
def render_mustache_json(template, data):
|
||||
"""Render the supplied mustache template and data as a JSON value
|
||||
|
||||
|
||||
Reference in New Issue
Block a user