From 66dfeac4afd4cf9338b287c8f8b48e42e83dad5a Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 10:35:22 -0700 Subject: [PATCH 1/9] add option to make diagnostics bundle to pytest plugin --- pytest_dcos/plugin.py | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index a65c62b..d34b3d6 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -7,6 +7,25 @@ logger.setup(os.getenv('LOG_LEVEL', 'DEBUG')) +def order_fixtures(metafunc): + """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 + """ + 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) + metafunc.fixturenames.extend(merged) + + +def pytest_generate_tests(metafunc): + order_fixtures(metafunc) + + @pytest.fixture(scope='session') def dcos_api_session_factory(): is_enterprise = os.getenv('DCOS_ENTERPRISE', 'false').lower() == 'true' @@ -22,3 +41,48 @@ 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.") + + +@pytest.mark.order(-1) +@pytest.fixture(scope='session', autouse=True) +def make_diagnostics_report(dcos_api_session): + """This fixture should be called first so that the diagnostics report code gets run last.""" + yield + diagnostics_dir = config.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) From e55ea9e9b85b6917c43ae3e18e9a5fa5b8601a9a Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 11:07:10 -0700 Subject: [PATCH 2/9] add missing USER_HOME_DIR constant --- pytest_dcos/plugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index d34b3d6..0a2e1c9 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -6,6 +6,8 @@ logger.setup(os.getenv('LOG_LEVEL', 'DEBUG')) +USER_HOME_DIR = os.path.join(os.path.expanduser('~')) + def order_fixtures(metafunc): """Pytest currently does not have a built-in way to ensure fixtures are called in a particular order From 5db0ef1092dde8dd5f57a9d2d7bc2835f7fa592a Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 11:37:00 -0700 Subject: [PATCH 3/9] add missing helper fn and logger --- pytest_dcos/plugin.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index 0a2e1c9..fa903d7 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -6,6 +6,8 @@ logger.setup(os.getenv('LOG_LEVEL', 'DEBUG')) +log = logging.getLogger(__name__) + USER_HOME_DIR = os.path.join(os.path.expanduser('~')) @@ -55,6 +57,15 @@ def pytest_addoption(parser): "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): From 94065633a4263246d51d7b18af6aca2391f58f5e Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 11:47:13 -0700 Subject: [PATCH 4/9] fix syntax spacing error --- pytest_dcos/plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index fa903d7..1191b47 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -63,7 +63,8 @@ def _isdir(maybe_dir): valid_dir = os.path.isdir(maybe_dir) except TypeError as e: valid_dir = False -return valid_dir + + return valid_dir @pytest.mark.order(-1) From 207b10932f6a960ac26d5045ec03565e601a1b45 Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 11:58:08 -0700 Subject: [PATCH 5/9] import logging --- pytest_dcos/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index 1191b47..f7baa2a 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -1,3 +1,4 @@ +import logging import os import pytest From 43920c3fd23197025a1496f483be02ce1c3882ea Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 13:05:50 -0700 Subject: [PATCH 6/9] try without reordering --- pytest_dcos/plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index f7baa2a..9dcb8d9 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -28,7 +28,8 @@ def order_fixtures(metafunc): def pytest_generate_tests(metafunc): - order_fixtures(metafunc) + pass + # order_fixtures(metafunc) @pytest.fixture(scope='session') From 8ae89663d732e272194caf239d133cfdd5f70e83 Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 14:12:37 -0700 Subject: [PATCH 7/9] use the pytestconfig fixture --- pytest_dcos/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index 9dcb8d9..2fbbcb1 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -65,16 +65,16 @@ def _isdir(maybe_dir): 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): +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 = config.getoption('--diagnostics') + diagnostics_dir = pytestconfig.getoption('--diagnostics') if diagnostics_dir is None: log.info('\nNot downloading diagnostics bundle for this session.') From 810dcab0b135925db60b32f40608a657c71f0673 Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 14:13:22 -0700 Subject: [PATCH 8/9] put back the call to the ordering func --- pytest_dcos/plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index 2fbbcb1..9b23517 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -28,8 +28,7 @@ def order_fixtures(metafunc): def pytest_generate_tests(metafunc): - pass - # order_fixtures(metafunc) + order_fixtures(metafunc) @pytest.fixture(scope='session') From f582b04b700bbf970dbf026f0331093735dcb5f9 Mon Sep 17 00:00:00 2001 From: Margaret Sy Date: Thu, 22 Mar 2018 14:28:50 -0700 Subject: [PATCH 9/9] debug prints for order_fixtures --- pytest_dcos/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pytest_dcos/plugin.py b/pytest_dcos/plugin.py index 9b23517..5a0fa46 100644 --- a/pytest_dcos/plugin.py +++ b/pytest_dcos/plugin.py @@ -16,6 +16,8 @@ def order_fixtures(metafunc): """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()} @@ -24,6 +26,8 @@ def order_fixtures(metafunc): 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)