[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:
yura
2015-08-20 17:14:55 +03:00
parent a628444226
commit c3f3cba854
7 changed files with 146 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,15 @@
{
"groups": [
{
"apps": [
{
"id": "sleep",
"cmd": "sleep 1000",
"instances": 1
}
],
"id": "sleep"
}
],
"id": "scale-group"
}

View File

@@ -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)

View File

@@ -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])

View File

@@ -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.

View File

@@ -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