Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions pytest_dcos/plugin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import os

import pytest
Expand All @@ -6,6 +7,33 @@

logger.setup(os.getenv('LOG_LEVEL', 'DEBUG'))

log = logging.getLogger(__name__)

USER_HOME_DIR = os.path.join(os.path.expanduser('~'))


def order_fixtures(metafunc):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"""Pytest currently does not have a built-in way to ensure fixtures are called in a particular order
https://github.com/pytest-dev/pytest/issues/1216#issuecomment-366496568
"""
print('Original fixture order')
print(metafunc.fixturenames)
metafunc.fixturenames[:] = []
orders = {name: getattr(definition[0].func, "order", None)
for name, definition in metafunc._arg2fixturedefs.items()}
ordered = {name: getattr(order, "args")[0] for name, order in orders.items() if order}
unordered = [name for name, order in orders.items() if not order]
first = {name: order for name, order in ordered.items() if order and order < 0}
last = {name: order for name, order in ordered.items() if order and order > 0}
merged = sorted(first, key=first.get) + unordered + sorted(last, key=last.get)
print('Reordered fixtures:')
print(merged)
metafunc.fixturenames.extend(merged)


def pytest_generate_tests(metafunc):
order_fixtures(metafunc)


@pytest.fixture(scope='session')
def dcos_api_session_factory():
Expand All @@ -22,3 +50,58 @@ def dcos_api_session(dcos_api_session_factory):
api = dcos_api_session_factory.create()
api.wait_for_dcos()
return api


def pytest_addoption(parser):
parser.addoption(
"--diagnostics",
nargs='?',
const=USER_HOME_DIR,
default=None,
help="Download a diagnostics bundle .zip file from the cluster at the end of the test run." +
"Value is directory to put the file in. If no value is set, then it defaults to home directory.")


def _isdir(maybe_dir):
"""os.path.isdir except it won't raise an Exception on non str, int, byte input"""
try:
valid_dir = os.path.isdir(maybe_dir)
except TypeError as e:
valid_dir = False

return valid_dir


@pytest.mark.order(-1)
@pytest.fixture(scope='session', autouse=True)
def make_diagnostics_report(dcos_api_session, pytestconfig):
"""This fixture should be called first so that the diagnostics report code gets run last."""
yield
diagnostics_dir = pytestconfig.getoption('--diagnostics')

if diagnostics_dir is None:
log.info('\nNot downloading diagnostics bundle for this session.')
else:
warning = '{} is not a directory. Writing diagnostics report to home directory {} instead.'.format(
diagnostics_dir, USER_HOME_DIR)
if not _isdir(diagnostics_dir):
log.warn(warning)
diagnostics_dir = USER_HOME_DIR

log.info('Create diagnostics report for all nodes')
dcos_api_session.health.start_diagnostics_job()

last_datapoint = {
'time': None,
'value': 0
}

log.info('\nWait for diagnostics job to complete')
dcos_api_session.health.wait_for_diagnostics_job(last_datapoint)

log.info('\nWait for diagnostics report to become available')
dcos_api_session.health.wait_for_diagnostics_reports()

log.info('\nDownload zipped diagnostics reports')
bundles = dcos_api_session.health.get_diagnostics_reports()
dcos_api_session.health.download_diagnostics_reports(bundles, download_directory=diagnostics_dir)