33# pylint: disable=unused-variable
44
55
6+ import logging
67import re
78from pathlib import Path
89from typing import Any
1213from .helpers .monkeypatch_envs import load_dotenv , setenvs_from_dict
1314from .helpers .typing_env import EnvVarsDict
1415
16+ _logger = logging .getLogger (__name__ )
17+
1518
1619def pytest_addoption (parser : pytest .Parser ):
1720 simcore_group = parser .getgroup ("simcore" )
@@ -20,12 +23,17 @@ def pytest_addoption(parser: pytest.Parser):
2023 action = "store" ,
2124 type = Path ,
2225 default = None ,
23- help = "Path to an env file. Consider passing a link to repo configs, i.e. `ln -s /path/to/osparc-ops-config/repo.config`" ,
26+ help = "Path to an env file. Replaces .env-devel in the tests by an external envfile."
27+ "e.g. consider "
28+ " `ln -s /path/to/osparc-ops-config/repo.config .secrets` and then "
29+ " `pytest --external-envfile=.secrets --pdb tests/unit/test_core_settings.py`" ,
2430 )
2531
2632
2733@pytest .fixture (scope = "session" )
28- def external_envfile_dict (request : pytest .FixtureRequest ) -> EnvVarsDict :
34+ def external_envfile_dict (
35+ request : pytest .FixtureRequest , osparc_simcore_root_dir : Path
36+ ) -> EnvVarsDict :
2937 """
3038 If a file under test folder prefixed with `.env-secret` is present,
3139 then this fixture captures it.
@@ -35,19 +43,43 @@ def external_envfile_dict(request: pytest.FixtureRequest) -> EnvVarsDict:
3543 """
3644 envs = {}
3745 if envfile := request .config .getoption ("--external-envfile" ):
38- print ("🚨 EXTERNAL `envfile` option detected. Loading" , envfile , "..." )
46+ _logger .warning (
47+ "🚨 EXTERNAL `envfile` option detected. Loading '%s' ..." , envfile
48+ )
3949
4050 assert isinstance (envfile , Path )
4151 assert envfile .exists ()
4252 assert envfile .is_file ()
4353
54+ envfile = envfile .resolve ()
55+ osparc_simcore_root_dir = osparc_simcore_root_dir .resolve ()
56+
57+ if osparc_simcore_root_dir in envfile .parents and not any (
58+ term in envfile .name .lower () for term in ("ignore" , "secret" )
59+ ):
60+ _logger .warning (
61+ "🚨 CAUTION: The external envfile '%s' may contain sensitive data and could be accidentally versioned. "
62+ "To prevent this, include the words 'secret' or 'ignore' in the filename." ,
63+ envfile .name ,
64+ )
65+
4466 envs = load_dotenv (envfile )
4567
68+ if envs :
69+ response = input (
70+ f"🚨 CAUTION: You are about to run tests using environment variables loaded from '{ envfile } '.\n "
71+ "This may cause tests to interact with or modify real external systems (e.g., production or staging environments).\n "
72+ "Proceeding could result in data loss or unintended side effects.\n "
73+ "Are you sure you want to continue? [y/N]: "
74+ )
75+ if response .strip ().lower () not in ("y" , "yes" ):
76+ pytest .exit ("Aborted by user due to external envfile usage." )
77+
4678 return envs
4779
4880
4981@pytest .fixture (scope = "session" )
50- def skip_if_external_envfile_dict (external_envfile_dict : EnvVarsDict ) -> None :
82+ def skip_if_no_external_envfile (external_envfile_dict : EnvVarsDict ) -> None :
5183 if not external_envfile_dict :
5284 pytest .skip (reason = "Skipping test since external-envfile is not set" )
5385
0 commit comments