From e8bcb507fda626d4b1e9050a4bd201e2681206ff Mon Sep 17 00:00:00 2001 From: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com> Date: Tue, 2 Jul 2024 18:39:19 +0100 Subject: [PATCH 1/2] More gracefully override JPS `ExtensionApp.config_file_paths` --- cylc/uiserver/app.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/cylc/uiserver/app.py b/cylc/uiserver/app.py index 8e9fb00c..c4caae78 100644 --- a/cylc/uiserver/app.py +++ b/cylc/uiserver/app.py @@ -59,7 +59,7 @@ from pathlib import Path, PurePath import sys from textwrap import dedent -from typing import List +from typing import List, Optional from pkg_resources import parse_version from tornado import ioloop @@ -145,15 +145,6 @@ class CylcUIServer(ExtensionApp): cylc gui --no-browser # Start the server but don't open the browser ''') # type: ignore[assignment] - config_file_paths = get_conf_dir_hierarchy( - [ - SITE_CONF_ROOT, # site configuration - USER_CONF_ROOT, # user configuration - ], filename=False - ) - # Next include currently needed for directory making - config_file_paths.insert(0, str(Path(uis_pkg).parent)) # packaged config - config_file_paths.reverse() # TODO: Add a link to the access group table mappings in cylc documentation # https://github.com/cylc/cylc-uiserver/issues/466 AUTH_DESCRIPTION = ''' @@ -405,6 +396,7 @@ def _get_ui_path(self): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._config_file_paths: Optional[List[str]] = None self.executor = ProcessPoolExecutor(max_workers=self.max_workers) self.workflows_mgr = WorkflowsManager(self, log=self.log) self.data_store_mgr = DataStoreMgr( @@ -421,6 +413,21 @@ def __init__(self, *args, **kwargs): workflows_mgr=self.workflows_mgr, ) + @property + def config_file_paths(self) -> List[str]: + if self._config_file_paths is None: + ret = get_conf_dir_hierarchy( + [ + SITE_CONF_ROOT, # site configuration + USER_CONF_ROOT, # user configuration + ], filename=False + ) + # Next include currently needed for directory making + ret.insert(0, str(Path(uis_pkg).parent)) # packaged config + ret.reverse() + self._config_file_paths = ret + return self._config_file_paths + def initialize_settings(self): """Update extension settings. From 2661f84886a499503b4ed390b4b040424484bea5 Mon Sep 17 00:00:00 2001 From: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com> Date: Tue, 2 Jul 2024 18:39:22 +0100 Subject: [PATCH 2/2] Tests: auto-patch to avoid loading user/site configs --- cylc/uiserver/tests/conftest.py | 16 ++++++---------- cylc/uiserver/tests/test_auth.py | 4 +--- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/cylc/uiserver/tests/conftest.py b/cylc/uiserver/tests/conftest.py index d0452220..54cfac5c 100644 --- a/cylc/uiserver/tests/conftest.py +++ b/cylc/uiserver/tests/conftest.py @@ -14,17 +14,14 @@ # along with this program. If not, see . """Test code and fixtures.""" -from getpass import getuser import inspect import logging from pathlib import Path from shutil import rmtree -from socket import gethostname from tempfile import TemporaryDirectory from uuid import uuid4 import pytest -from tornado.web import HTTPError from traitlets.config import Config import zmq @@ -47,6 +44,7 @@ from cylc.flow.parsec.config import ParsecConfig from cylc.flow.parsec.validate import cylc_config_validate + class AsyncClientFixture(WorkflowRuntimeClient): pattern = zmq.REQ host = '' @@ -223,7 +221,7 @@ def mock_authentication_yossarian(monkeypatch): def jp_server_config(jp_template_dir): """Config to turn the CylcUIServer extension on. - Auto-loading, add as an argument in the test function to activate. + Overrides jupyter server fixture of the same name. """ config = { "ServerApp": { @@ -235,12 +233,9 @@ def jp_server_config(jp_template_dir): return config -@pytest.fixture -def patch_conf_files(monkeypatch): - """Auto-patches the CylcUIServer to prevent it loading config files. - - Auto-loading, add as an argument in the test function to activate. - """ +@pytest.fixture(autouse=True) +def patch_conf_files(monkeypatch: pytest.MonkeyPatch): + """Auto-patches the CylcUIServer to prevent it loading config files.""" monkeypatch.setattr( 'cylc.uiserver.app.CylcUIServer.config_file_paths', [] ) @@ -364,6 +359,7 @@ def workflow_run_dir(request): if not request.session.testsfailed: rmtree(run_dir) + @pytest.fixture def mock_glbl_cfg(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): """A Pytest fixture for fiddling global config values. diff --git a/cylc/uiserver/tests/test_auth.py b/cylc/uiserver/tests/test_auth.py index b9bb4e1f..2ffb3f10 100644 --- a/cylc/uiserver/tests/test_auth.py +++ b/cylc/uiserver/tests/test_auth.py @@ -23,7 +23,7 @@ @pytest.mark.integration @pytest.mark.usefixtures("mock_authentication_yossarian") -async def test_cylc_handler(patch_conf_files, jp_fetch): +async def test_cylc_handler(jp_fetch): """The Cylc endpoints have been added and work.""" resp = await jp_fetch( 'cylc', 'userprofile', method='GET' @@ -60,7 +60,6 @@ async def test_cylc_handler(patch_conf_files, jp_fetch): ] ) async def test_authorised_and_authenticated( - patch_conf_files, jp_fetch, endpoint, code, @@ -95,7 +94,6 @@ async def test_authorised_and_authenticated( ] ) async def test_unauthorised( - patch_conf_files, jp_fetch, endpoint, code,