diff --git a/doc/changelog.d/4171.fixed.md b/doc/changelog.d/4171.fixed.md new file mode 100644 index 000000000000..9c8f09a3f717 --- /dev/null +++ b/doc/changelog.d/4171.fixed.md @@ -0,0 +1 @@ +container timeout issue and new environment variables \ No newline at end of file diff --git a/doc/source/contributing/environment_variables.rst b/doc/source/contributing/environment_variables.rst index 615fc9af6247..940f177f83a7 100644 --- a/doc/source/contributing/environment_variables.rst +++ b/doc/source/contributing/environment_variables.rst @@ -43,6 +43,10 @@ Following is a list of environment variables that can be set to control various - Specifies the port of the Fluent server in :func:`connect_to_fluent() `. * - PYFLUENT_FLUENT_ROOT - Specifies the Fluent root directory while launching Fluent in :func:`launch_fluent() `. + * - PYFLUENT_FLUENT_LAUNCH_TIMEOUT + - Specifies the timeout, in seconds, for launching Fluent through :func:`launch_fluent() `. + * - PYFLUENT_FLUENT_AUTOMATIC_TRANSCRIPT + - Can be used to enable automatic writing of transcript .trn file by Fluent. By default, it is disabled. * - PYFLUENT_GRPC_LOG_BYTES_LIMIT - Specifies the length of gRPC logging messages. Set to 0 to disable the limit. * - PYFLUENT_LAUNCH_CONTAINER diff --git a/src/ansys/fluent/core/__init__.py b/src/ansys/fluent/core/__init__.py index f3c17ac080bf..4131e06d8631 100644 --- a/src/ansys/fluent/core/__init__.py +++ b/src/ansys/fluent/core/__init__.py @@ -73,7 +73,7 @@ SolverIcing, ) from ansys.fluent.core.streaming_services.events_streaming import * # noqa: F401, F403 -from ansys.fluent.core.utils import fldoc, get_examples_download_dir +from ansys.fluent.core.utils import env_var_to_bool, fldoc, get_examples_download_dir from ansys.fluent.core.utils.fluent_version import FluentVersion # noqa: F401 from ansys.fluent.core.utils.setup_for_fluent import setup_for_fluent # noqa: F401 @@ -155,7 +155,7 @@ def version_info() -> str: FLUENT_SHOW_MESH_AFTER_CASE_READ = False # Whether to write the automatic transcript in Fluent -FLUENT_AUTOMATIC_TRANSCRIPT = False +FLUENT_AUTOMATIC_TRANSCRIPT = env_var_to_bool("PYFLUENT_FLUENT_AUTOMATIC_TRANSCRIPT") # Whether to interrupt Fluent solver from PyFluent SUPPORT_SOLVER_INTERRUPT = False diff --git a/src/ansys/fluent/core/codegen/tuigen.py b/src/ansys/fluent/core/codegen/tuigen.py index 63c9180cb9c9..6aec70dbbc2e 100644 --- a/src/ansys/fluent/core/codegen/tuigen.py +++ b/src/ansys/fluent/core/codegen/tuigen.py @@ -56,6 +56,7 @@ convert_path_to_grpc_path, convert_tui_menu_to_func_name, ) +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.fix_doc import escape_wildcards from ansys.fluent.core.utils.fluent_version import ( FluentVersion, @@ -95,7 +96,7 @@ def _get_tui_docdir(mode: str): def _copy_tui_help_xml_file(version: str): - if os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1": + if env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER"): image_tag = os.getenv("FLUENT_IMAGE_TAG", "v25.1.0") image_name = f"ghcr.io/ansys/pyfluent:{image_tag}" container_name = uuid.uuid4().hex @@ -346,7 +347,7 @@ def generate(version, static_infos: dict, verbose: bool = False): api_tree[""] = TUIGenerator( "solver", version, static_infos, verbose ).generate() - if os.getenv("PYFLUENT_HIDE_LOG_SECRETS") != "1": + if not env_var_to_bool("PYFLUENT_HIDE_LOG_SECRETS"): logger.info( "XML help is available but not picked for the following %i paths: ", len(_XML_HELPSTRINGS), diff --git a/src/ansys/fluent/core/examples/downloads.py b/src/ansys/fluent/core/examples/downloads.py index ecaee2c0ce74..bc91146ae27b 100644 --- a/src/ansys/fluent/core/examples/downloads.py +++ b/src/ansys/fluent/core/examples/downloads.py @@ -30,6 +30,7 @@ import zipfile import ansys.fluent.core as pyfluent +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.networking import check_url_exists, get_url_content logger = logging.getLogger("pyfluent.networking") @@ -180,7 +181,7 @@ def download_file( 'bracket.iges' """ if return_without_path is None: - if os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1": + if env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER"): if pyfluent.USE_FILE_TRANSFER_SERVICE: return_without_path = False else: diff --git a/src/ansys/fluent/core/fluent_connection.py b/src/ansys/fluent/core/fluent_connection.py index 98bd27605703..161882f0c9dc 100644 --- a/src/ansys/fluent/core/fluent_connection.py +++ b/src/ansys/fluent/core/fluent_connection.py @@ -746,13 +746,16 @@ def exit( env_timeout = os.getenv("PYFLUENT_TIMEOUT_FORCE_EXIT") if env_timeout: - logger.debug("Found PYFLUENT_TIMEOUT_FORCE_EXIT env var") + logger.debug( + f"Found PYFLUENT_TIMEOUT_FORCE_EXIT env var: '{env_timeout}'" + ) try: timeout = float(env_timeout) logger.debug(f"Setting TIMEOUT_FORCE_EXIT to {timeout}") except ValueError: logger.debug( - "Off or unrecognized PYFLUENT_TIMEOUT_FORCE_EXIT value, not enabling timeout force exit" + "Off or unrecognized PYFLUENT_TIMEOUT_FORCE_EXIT value (floats and integers are also supported), " + "disabling timeout forced exit." ) if timeout is None: diff --git a/src/ansys/fluent/core/launcher/container_launcher.py b/src/ansys/fluent/core/launcher/container_launcher.py index a9ffe62aff2e..723c8a2a8e21 100644 --- a/src/ansys/fluent/core/launcher/container_launcher.py +++ b/src/ansys/fluent/core/launcher/container_launcher.py @@ -216,13 +216,17 @@ def __call__(self): if is_compose(): port, config_dict, container = start_fluent_container( - self._args, self.argvals["container_dict"] + self._args, + self.argvals["container_dict"], + self.argvals["start_timeout"], ) _, _, password = _get_server_info_from_container(config_dict=config_dict) else: port, password, container = start_fluent_container( - self._args, self.argvals["container_dict"] + self._args, + self.argvals["container_dict"], + self.argvals["start_timeout"], ) fluent_connection = FluentConnection( diff --git a/src/ansys/fluent/core/launcher/error_handler.py b/src/ansys/fluent/core/launcher/error_handler.py index de0ab0ef5920..3867b69435b6 100644 --- a/src/ansys/fluent/core/launcher/error_handler.py +++ b/src/ansys/fluent/core/launcher/error_handler.py @@ -70,7 +70,7 @@ class LaunchFluentError(Exception): def __init__(self, launch_string): """__init__ method of LaunchFluentError class.""" - details = "\n" + "Fluent Launch string: " + launch_string + details = "\n" + "Fluent Launch command: " + launch_string super().__init__(details) diff --git a/src/ansys/fluent/core/launcher/fluent_container.py b/src/ansys/fluent/core/launcher/fluent_container.py index 63a5175884b7..55e850df161a 100644 --- a/src/ansys/fluent/core/launcher/fluent_container.py +++ b/src/ansys/fluent/core/launcher/fluent_container.py @@ -77,10 +77,15 @@ from pprint import pformat import tempfile from typing import Any, List +import warnings import ansys.fluent.core as pyfluent from ansys.fluent.core.docker.docker_compose import ComposeBasedLauncher +from ansys.fluent.core.launcher.error_handler import ( + LaunchFluentError, +) from ansys.fluent.core.launcher.launcher_utils import is_compose +from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning from ansys.fluent.core.session import _parse_server_info_file from ansys.fluent.core.utils.deprecate import all_deprecators from ansys.fluent.core.utils.execution import timeout_loop @@ -155,7 +160,7 @@ def configure_container_dict( args: List[str], mount_source: str | Path | None = None, mount_target: str | Path | None = None, - timeout: int = 60, + timeout: int | None = None, port: int | None = None, license_server: str | None = None, container_server_info_file: str | Path | None = None, @@ -180,7 +185,9 @@ def configure_container_dict( Path inside the container where ``mount_source`` will be mounted. This will be the working directory path visible to the Fluent process running inside the container. timeout : int, optional - Time limit for the Fluent container to start, in seconds. By default, 30 seconds. + Time limit for the Fluent container to start, in seconds. + .. deprecated:: v0.33.dev0 + Use the ``start_timeout`` argument of ``launch_fluent`` instead. port : int, optional Port for Fluent container to use. license_server : str, optional @@ -231,6 +238,12 @@ def configure_container_dict( See also :func:`start_fluent_container`. """ + if timeout is not None: + warnings.warn( + "configure_container_dict(timeout) is deprecated, use launch_fluent(start_timeout) instead.", + PyFluentDeprecationWarning, + ) + logger.debug(f"container_dict before processing:\n{dict_to_str(container_dict)}") # Starting with 'mount_source' because it is not tied to the 'working_dir'. @@ -444,7 +457,7 @@ def configure_container_dict( container_dict["mount_target"] = mount_target logger.debug( - f"Fluent container timeout: {timeout}, container_grpc_port: {container_grpc_port}, " + f"Fluent container container_grpc_port: {container_grpc_port}, " f"host_server_info_file: '{host_server_info_file}', " f"remove_server_info_file: {remove_server_info_file}" ) @@ -460,7 +473,7 @@ def configure_container_dict( def start_fluent_container( - args: List[str], container_dict: dict | None = None + args: List[str], container_dict: dict | None = None, start_timeout: int = 60 ) -> tuple[int, str, Any]: """Start a Fluent container. @@ -470,6 +483,9 @@ def start_fluent_container( List of Fluent launch arguments. container_dict : dict, optional Dictionary with Docker container configuration. + start_timeout : int, optional + Timeout in seconds for the container to start. If not specified, it defaults to 60 + seconds. Returns ------- @@ -503,6 +519,14 @@ def start_fluent_container( host_server_info_file, remove_server_info_file, ) = container_vars + launch_string = " ".join(config_dict["command"]) + + if timeout: + logger.warning( + "launch_fluent(start_timeout) overridden by configure_container_dict(timeout) value." + ) + start_timeout = timeout + del timeout try: if is_compose(): @@ -536,18 +560,36 @@ def start_fluent_container( config_dict.pop("fluent_image"), **config_dict ) + logger.debug( + f"Waiting for Fluent container for up to {start_timeout} seconds..." + ) + success = timeout_loop( - lambda: host_server_info_file.stat().st_mtime > last_mtime, timeout + lambda: host_server_info_file.stat().st_mtime > last_mtime, + start_timeout, ) if not success: - raise TimeoutError( - "Fluent container launch has timed out, stop container manually." - ) + try: + container.stop() + except Exception as stop_ex: + logger.error(f"Failed to stop container: {stop_ex}") + raise TimeoutError( + f"Fluent container launch has timed out after {start_timeout} seconds. " + f"Additionally, stopping the container failed: {stop_ex}" + ) from stop_ex + else: + raise TimeoutError( + f"Fluent container launch has timed out after {start_timeout} seconds." + " The container was stopped." + ) else: _, _, password = _parse_server_info_file(str(host_server_info_file)) return port, password, container + except Exception as ex: + logger.error(f"Exception caught - {type(ex).__name__}: {ex}") + raise LaunchFluentError(launch_string) from ex finally: if remove_server_info_file and host_server_info_file.exists(): host_server_info_file.unlink() diff --git a/src/ansys/fluent/core/launcher/launch_options.py b/src/ansys/fluent/core/launcher/launch_options.py index 35ffe915be76..e501f88a89f2 100644 --- a/src/ansys/fluent/core/launcher/launch_options.py +++ b/src/ansys/fluent/core/launcher/launch_options.py @@ -36,6 +36,7 @@ from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_aero import SolverAero from ansys.fluent.core.session_solver_icing import SolverIcing +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.fluent_version import FluentVersion import ansys.platform.instancemanagement as pypim @@ -271,7 +272,7 @@ def _get_fluent_launch_mode(start_container, container_dict, scheduler_options): fluent_launch_mode = LaunchMode.PIM elif start_container is True or ( start_container is None - and (container_dict or os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1") + and (container_dict or env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER")) ): fluent_launch_mode = LaunchMode.CONTAINER # Currently, only Slurm scheduler is supported and within SlurmLauncher we check the value of the scheduler diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index fffe60cdab44..d2c1226ac096 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -58,6 +58,7 @@ from ansys.fluent.core.session_pure_meshing import PureMeshing from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_icing import SolverIcing +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.deprecate import all_deprecators from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -103,7 +104,7 @@ def _show_gui_to_ui_mode(old_arg_val, **kwds): return UIMode.NO_GUI elif container_dict: return UIMode.NO_GUI - elif os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1": + elif env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER"): return UIMode.NO_GUI else: return UIMode.GUI @@ -322,6 +323,9 @@ def launch_fluent( if env is None: env = {} + if start_timeout is None: + start_timeout = int(os.getenv("PYFLUENT_FLUENT_LAUNCH_TIMEOUT", "60")) + def _mode_to_launcher_type(fluent_launch_mode: LaunchMode): launcher_mode_type = { LaunchMode.CONTAINER: DockerLauncher, diff --git a/src/ansys/fluent/core/launcher/watchdog.py b/src/ansys/fluent/core/launcher/watchdog.py index 4b9c8eaaae4b..bb69ff165265 100644 --- a/src/ansys/fluent/core/launcher/watchdog.py +++ b/src/ansys/fluent/core/launcher/watchdog.py @@ -35,6 +35,7 @@ import time import ansys.fluent.core as pyfluent +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.execution import timeout_loop logger = pyfluent.logger.get_logger("pyfluent.launcher") @@ -76,8 +77,8 @@ def launch( ) ) - env_watchdog_debug = os.getenv("PYFLUENT_WATCHDOG_DEBUG", "off").upper() - if env_watchdog_debug in ("1", "ON"): + debug_watchdog = env_var_to_bool("PYFLUENT_WATCHDOG_DEBUG") + if debug_watchdog: logger.debug( f"PYFLUENT_WATCHDOG_DEBUG environment variable found, " f"enabling debugging for watchdog ID {watchdog_id}..." @@ -131,7 +132,7 @@ def launch( watchdog_id, ] - if env_watchdog_debug in ("1", "ON"): + if debug_watchdog: logger.debug(f"Starting Watchdog logging to directory {os.getcwd()}") kwargs = {"env": watchdog_env, "stdin": subprocess.DEVNULL, "close_fds": True} @@ -151,7 +152,7 @@ def launch( if os.name == "posix": kwargs.update(start_new_session=True) - if env_watchdog_debug in ("1", "ON") and os.name != "nt": + if debug_watchdog and os.name != "nt": kwargs.update( stdout=open(f"pyfluent_watchdog_out_{watchdog_id}.log", mode="w"), stderr=open(f"pyfluent_watchdog_err_{watchdog_id}.log", mode="w"), diff --git a/src/ansys/fluent/core/launcher/watchdog_exec b/src/ansys/fluent/core/launcher/watchdog_exec index 6ba3562f3134..72f83a49ea7b 100644 --- a/src/ansys/fluent/core/launcher/watchdog_exec +++ b/src/ansys/fluent/core/launcher/watchdog_exec @@ -20,6 +20,7 @@ if __name__ == "__main__": _pid_exists, get_container, ) + from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.execution import timeout_exec, timeout_loop watchdog_id = sys.argv[5] @@ -34,7 +35,7 @@ if __name__ == "__main__": logger = pyfluent.logger.get_logger("pyfluent.watchdog") - if os.getenv("PYFLUENT_WATCHDOG_DEBUG", "OFF").upper() in ("1", "ON"): + if env_var_to_bool("PYFLUENT_WATCHDOG_DEBUG"): pyfluent.logger.enable(custom_config=log_config) logger.setLevel("DEBUG") logger.handlers = pyfluent.logger.get_logger( diff --git a/src/ansys/fluent/core/report.py b/src/ansys/fluent/core/report.py index 94ca90aba36c..561111ceaa90 100644 --- a/src/ansys/fluent/core/report.py +++ b/src/ansys/fluent/core/report.py @@ -44,6 +44,8 @@ "PYFLUENT_FLUENT_IP", "PYFLUENT_FLUENT_PORT", "PYFLUENT_FLUENT_ROOT", + "PYFLUENT_FLUENT_LAUNCH_TIMEOUT", + "PYFLUENT_FLUENT_AUTOMATIC_TRANSCRIPT", "PYFLUENT_GRPC_LOG_BYTES_LIMIT", "PYFLUENT_LAUNCH_CONTAINER", "PYFLUENT_LOGGING", diff --git a/src/ansys/fluent/core/services/interceptors.py b/src/ansys/fluent/core/services/interceptors.py index f6e77cb9ccb7..e57920caa27e 100644 --- a/src/ansys/fluent/core/services/interceptors.py +++ b/src/ansys/fluent/core/services/interceptors.py @@ -32,6 +32,7 @@ import grpc from ansys.fluent.core.services.batch_ops import BatchOps +from ansys.fluent.core.utils import env_var_to_bool network_logger: logging.Logger = logging.getLogger("pyfluent.networking") log_bytes_limit: int = int(os.getenv("PYFLUENT_GRPC_LOG_BYTES_LIMIT", 1000)) @@ -75,7 +76,7 @@ def _intercept_call( if not response.exception(): # call _truncate_grpc_str early to get the size warning even when hiding secrets response_str = _truncate_grpc_str(response.result()) - if os.getenv("PYFLUENT_HIDE_LOG_SECRETS") != "1": + if not env_var_to_bool("PYFLUENT_HIDE_LOG_SECRETS"): network_logger.debug(f"GRPC_TRACE: response = {response_str}") return response diff --git a/src/ansys/fluent/core/streaming_services/datamodel_event_streaming.py b/src/ansys/fluent/core/streaming_services/datamodel_event_streaming.py index 2aa4304ab82c..a00c1b60f506 100644 --- a/src/ansys/fluent/core/streaming_services/datamodel_event_streaming.py +++ b/src/ansys/fluent/core/streaming_services/datamodel_event_streaming.py @@ -23,7 +23,6 @@ """Provides a module for datamodel event streaming.""" import logging -import os import threading from typing import Callable @@ -32,6 +31,7 @@ from ansys.api.fluent.v0 import datamodel_se_pb2 as DataModelProtoModule from ansys.fluent.core.services.datamodel_se import _convert_variant_to_value from ansys.fluent.core.streaming_services.streaming import StreamingService +from ansys.fluent.core.utils import env_var_to_bool network_logger: logging.Logger = logging.getLogger("pyfluent.networking") @@ -69,7 +69,7 @@ def _process_streaming(self, id, stream_begin_method, started_evt, *args, **kwar while True: try: response: DataModelProtoModule.EventResponse = next(responses) - if os.getenv("PYFLUENT_HIDE_LOG_SECRETS") != "1": + if not env_var_to_bool("PYFLUENT_HIDE_LOG_SECRETS"): network_logger.debug( f"GRPC_TRACE: RPC = /grpcRemoting.DataModel/BeginEventStreaming, response = {MessageToDict(response)}" ) diff --git a/src/ansys/fluent/core/utils/__init__.py b/src/ansys/fluent/core/utils/__init__.py index 72adbcc352e7..96b6ab9d16dc 100644 --- a/src/ansys/fluent/core/utils/__init__.py +++ b/src/ansys/fluent/core/utils/__init__.py @@ -24,6 +24,7 @@ import importlib.util import logging +import os from pathlib import Path import sys @@ -55,3 +56,12 @@ def get_user_data_dir(): return Path.home() / "AppData" / "Local" / "Ansys" / "ansys_fluent_core" else: return Path.home() / ".local" / "share" / "Ansys" / "ansys_fluent_core" + + +def env_var_to_bool(var_name: str, default: str = "false") -> bool: + """Converts environment variable to boolean. By default, returns 'False' if the variable is not set.""" + value = os.getenv(var_name, default).strip().lower() + if value in ("0", "off", "false", "no"): + return False + else: + return True diff --git a/tests/conftest.py b/tests/conftest.py index 6d872e92145d..b3af85bb8d9d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,6 +35,7 @@ import ansys.fluent.core as pyfluent from ansys.fluent.core.examples.downloads import download_file +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.file_transfer_service import ContainerFileTransferStrategy from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -63,10 +64,9 @@ def pytest_addoption(parser): def pytest_runtest_setup(item): - if ( - any(mark.name == "standalone" for mark in item.iter_markers()) - and os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1" - ): + if any( + mark.name == "standalone" for mark in item.iter_markers() + ) and env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER"): pytest.skip() is_nightly = item.config.getoption("--nightly") diff --git a/tests/parametric/test_parametric_workflow.py b/tests/parametric/test_parametric_workflow.py index 50bf5393d5f7..0261e478761a 100644 --- a/tests/parametric/test_parametric_workflow.py +++ b/tests/parametric/test_parametric_workflow.py @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import os from pathlib import Path, PurePosixPath import tempfile @@ -29,6 +28,7 @@ import ansys.fluent.core as pyfluent from ansys.fluent.core import examples +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.file_transfer_service import ContainerFileTransferStrategy from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -47,7 +47,7 @@ def test_parametric_workflow(): import_file_name = examples.download_file( "Static_Mixer_main.cas.h5", "pyfluent/static_mixer", save_path=tmp_save_path ) - if os.getenv("PYFLUENT_LAUNCH_CONTAINER") == "1": + if env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER"): inside_container = True config_dict = {} config_dict.update(mount_source=tmp_save_path) diff --git a/tests/test_fluent_session.py b/tests/test_fluent_session.py index 9c9e23413dd9..f940083558ed 100644 --- a/tests/test_fluent_session.py +++ b/tests/test_fluent_session.py @@ -35,6 +35,7 @@ get_container, ) from ansys.fluent.core.launcher.error_handler import IpPortNotProvided +from ansys.fluent.core.utils import env_var_to_bool from ansys.fluent.core.utils.execution import asynchronous, timeout_loop from ansys.fluent.core.utils.fluent_version import FluentVersion from docker.models.containers import Container @@ -257,7 +258,7 @@ def test_interrupt(static_mixer_case_session): def test_fluent_exit(monkeypatch: pytest.MonkeyPatch): monkeypatch.delenv("PYFLUENT_LOGGING") monkeypatch.delenv("PYFLUENT_WATCHDOG_DEBUG") - inside_container = os.getenv("PYFLUENT_LAUNCH_CONTAINER") + inside_container = env_var_to_bool("PYFLUENT_LAUNCH_CONTAINER") import ansys.fluent.core as pyfluent solver = pyfluent.launch_fluent(start_watchdog=False) diff --git a/tests/test_launcher.py b/tests/test_launcher.py index b18b1766f8d4..7fbf2158becb 100644 --- a/tests/test_launcher.py +++ b/tests/test_launcher.py @@ -39,6 +39,7 @@ LaunchFluentError, _raise_non_gui_exception_in_windows, ) +from ansys.fluent.core.launcher.fluent_container import configure_container_dict from ansys.fluent.core.launcher.launch_options import ( FluentLinuxGraphicsDriver, FluentMode, @@ -88,15 +89,35 @@ def test_mode(): ) -@pytest.mark.standalone def test_unsuccessful_fluent_connection(): - # start-timeout is intentionally provided to be 2s for the connection to fail + # start-timeout is intentionally provided to be 1s for the connection to fail with pytest.raises(LaunchFluentError) as ex: - pyfluent.launch_fluent(mode="solver", start_timeout=2) + pyfluent.launch_fluent(mode="solver", start_timeout=1) # TimeoutError -> LaunchFluentError assert isinstance(ex.value.__context__, TimeoutError) +def test_container_timeout_deprecation(): + with pytest.warns(PyFluentDeprecationWarning): + configure_container_dict([], timeout=0) + + with pytest.warns(PyFluentDeprecationWarning): + pyfluent.launch_fluent( + start_container=True, container_dict=dict(timeout=0), dry_run=True + ) + + +def test_container_timeout_deprecation_override(caplog): + # timeout should override start_timeout + with pytest.raises(LaunchFluentError) as ex: + with pytest.warns(PyFluentDeprecationWarning): + pyfluent.launch_fluent( + start_container=True, container_dict=dict(timeout=1), start_timeout=60 + ) + assert isinstance(ex.value.__context__, TimeoutError) + assert "overridden" in caplog.text + + @pytest.mark.fluent_version("<24.1") def test_non_gui_in_windows_throws_exception(): default_windows_flag = launcher_utils.is_windows()