247 lines
7.6 KiB
Python
247 lines
7.6 KiB
Python
import contextlib
|
|
import json
|
|
import re
|
|
|
|
from .helpers.common import exec_command
|
|
from .helpers.marathon import app, pod
|
|
from .test_marathon import _list_tasks
|
|
|
|
list_regex = '/stuck-(?:sleep|pod)\W+[^Z]+Z\W+9\W+(?:True|False)' \
|
|
'\W+\d\W+\d\W+[^Z]+Z\W+[^Z]+Z'
|
|
|
|
|
|
def test_debug_list():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'list'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'WAITING' in decoded
|
|
assert '/stuck-sleep' in decoded
|
|
"""A line in the output looks like
|
|
/stuck-sleep $since 9 True 4 3 $last_unsued_offer $last_used_offer
|
|
Therefore `list_regex` tests this
|
|
"""
|
|
assert re.search(list_regex, decoded) is not None
|
|
|
|
|
|
def test_debug_list_json():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'list', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'overdue' in decoded
|
|
assert '/stuck-sleep' in decoded
|
|
assert '"reason": "UnfulfilledConstraint"' in decoded
|
|
|
|
|
|
def test_debug_list_pod():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'list'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'WAITING' in decoded
|
|
assert '/stuck-pod' in decoded
|
|
"""A line in the output looks like
|
|
/stuck-sleep $since 9 True 4 3 $last_unsued_offer $last_used_offer
|
|
Therefore `list_regex` tests this
|
|
"""
|
|
assert re.search(list_regex, decoded) is not None
|
|
|
|
|
|
def test_debug_list_pod_json():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'list', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'overdue' in decoded
|
|
assert '/stuck-pod' in decoded
|
|
assert '"reason": "UnfulfilledConstraint"' in decoded
|
|
|
|
|
|
def test_debug_summary():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'summary', '/stuck-sleep'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'CONSTRAINTS' in decoded
|
|
assert "[['hostname', 'UNIQUE']]" in decoded
|
|
assert '0.00%' in decoded
|
|
|
|
|
|
def test_debug_summary_json():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'summary', '/stuck-sleep', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode().replace(' ', '').replace('\n', '')
|
|
assert '"reason":"UnfulfilledConstraint"' in decoded
|
|
assert '{"declined":0,"processed":0,"reason":"InsufficientCpus"}' \
|
|
in decoded
|
|
|
|
|
|
def test_debug_summary_pod():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'summary', '/stuck-pod'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
assert 'CONSTRAINTS' in decoded
|
|
assert "'operator': 'UNIQUE'" in decoded
|
|
assert "'fieldName': 'hostname'" in decoded
|
|
assert '0.00%' in decoded
|
|
|
|
|
|
def test_debug_summary_pod_json():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'summary', '/stuck-pod', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode().replace(' ', '').replace('\n', '')
|
|
assert '"reason":"UnfulfilledConstraint"' in decoded
|
|
assert '{"declined":0,"processed":0,"reason":"InsufficientCpus"}' \
|
|
in decoded
|
|
|
|
|
|
def test_debug_details():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'details', '/stuck-sleep'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
"""The public agent has all resources to launch this task,
|
|
but not the matching role, therefore the output should be:
|
|
ok - ok ok ok ok
|
|
To avoid formatting issues, whitespaces are ignored.
|
|
"""
|
|
assert 'ok-okokokok' in decoded.replace(' ', '')
|
|
|
|
returncode, stdout, stderr = exec_command(['dcos', 'node', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
agent_count = len(
|
|
[n for n in json.loads(stdout.decode('utf-8'))
|
|
if n['type'] == 'agent']
|
|
)
|
|
|
|
"""The extra two lines come from the heading and the empty line at the
|
|
end of the table.
|
|
"""
|
|
assert len(decoded.split('\n')) == agent_count + 2
|
|
|
|
|
|
def test_debug_details_json():
|
|
with _stuck_app():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'details', '/stuck-sleep', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode().replace(' ', '').replace('\n', '')
|
|
assert '"reason":"UnfulfilledConstraint"' in decoded
|
|
assert '{"declined":0,"processed":0,"reason":"InsufficientCpus"}' \
|
|
in decoded
|
|
|
|
|
|
def test_debug_details_pod():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'details', '/stuck-pod'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode()
|
|
"""The public agent has all resources to launch this task,
|
|
but not the matching role, therefore the output should be:
|
|
ok - ok ok ok ok
|
|
To avoid formatting issues, whitespaces are ignored.
|
|
"""
|
|
assert 'ok-okokokok' in decoded.replace(' ', '')
|
|
|
|
returncode, stdout, stderr = exec_command(['dcos', 'node', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
agent_count = len(
|
|
[n for n in json.loads(stdout.decode('utf-8'))
|
|
if n['type'] == 'agent']
|
|
)
|
|
|
|
"""The extra two lines come from the heading and the empty line at the
|
|
end of the table.
|
|
"""
|
|
assert len(decoded.split('\n')) == agent_count + 2
|
|
|
|
|
|
def test_debug_details_pod_json():
|
|
with _stuck_pod():
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'debug', 'details', '/stuck-pod', '--json'])
|
|
|
|
assert returncode == 0
|
|
assert stderr == b''
|
|
|
|
decoded = stdout.decode().replace(' ', '').replace('\n', '')
|
|
assert '"reason":"UnfulfilledConstraint"' in decoded
|
|
assert '{"declined":0,"processed":0,"reason":"InsufficientCpus"}' \
|
|
in decoded
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def _stuck_app(max_count=300):
|
|
with app('tests/data/marathon/apps/stuck_sleep.json',
|
|
'stuck-sleep', False):
|
|
count = 0
|
|
while count < max_count:
|
|
tasks = _list_tasks(app_id='stuck-sleep')
|
|
if len(tasks) == 1:
|
|
break
|
|
yield
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def _stuck_pod(max_count=300):
|
|
with pod('tests/data/marathon/pods/stuck_sleep.json',
|
|
'/stuck-pod', False):
|
|
count = 0
|
|
while count < max_count:
|
|
returncode, stdout, stderr = exec_command(
|
|
['dcos', 'marathon', 'pod', 'list'])
|
|
if '/stuck-pod1' in str(stdout).replace(' ', ''):
|
|
break
|
|
yield
|