diff --git a/src/ansys/tools/path/path.py b/src/ansys/tools/path/path.py index 6b15a9f8..3ef212ca 100644 --- a/src/ansys/tools/path/path.py +++ b/src/ansys/tools/path/path.py @@ -69,7 +69,7 @@ def _get_installed_windows_versions( supported_versions: SUPPORTED_VERSIONS_TYPE = SUPPORTED_ANSYS_VERSIONS, -): +): # pragma: no cover """Get the AWP_ROOT environment variable values for supported versions.""" # The student version overwrites the AWP_ROOT env var @@ -108,7 +108,7 @@ def _get_default_linux_base_path(): return None # pragma: no cover -def _get_default_windows_base_path(): +def _get_default_windows_base_path(): # pragma: no cover """Get the default base path of the Ansys unified install on windows.""" base_path = os.path.join(os.environ["PROGRAMFILES"], "ANSYS INC") @@ -279,7 +279,7 @@ def find_mechanical( ans_path, version = _get_unified_install_base_for_version(version, supported_versions) if not ans_path or not version: return "", "" - if is_windows(): + if is_windows(): # pragma: no cover mechanical_bin = os.path.join(ans_path, "aisol", "bin", "winx64", f"AnsysWBU.exe") else: mechanical_bin = os.path.join(ans_path, "aisol", ".workbench") @@ -369,7 +369,7 @@ def is_valid_executable_path(product: PRODUCT_TYPE, exe_loc: str): and re.search(r"ansys\d\d\d", os.path.basename(os.path.normpath(exe_loc))) is not None ) elif product == "mechanical": - if is_windows(): + if is_windows(): # pragma: no cover return ( os.path.isfile(exe_loc) and re.search("AnsysWBU.exe", os.path.basename(os.path.normpath(exe_loc))) @@ -386,42 +386,38 @@ def _is_common_executable_path(product: PRODUCT_TYPE, exe_loc: str) -> bool: if product == "mapdl": path = os.path.normpath(exe_loc) path = path.split(os.sep) - if ( - re.search(r"v(\d\d\d)", exe_loc) is not None - and re.search(r"ansys(\d\d\d)", exe_loc) is not None - ): - equal_version = ( - re.search(r"v(\d\d\d)", exe_loc)[1] == re.search(r"ansys(\d\d\d)", exe_loc)[1] - ) - else: - equal_version = False - + # Look for all v(\d\d\d) to catch the last one + # in case the user has placed the installation folder inside a folder called for example (/ansys/v211) + v_version = re.findall(r"v(\d\d\d)", exe_loc) + ansys_version = re.findall(r"ansys(\d\d\d)", exe_loc, re.IGNORECASE) return ( - is_valid_executable_path("mapdl", exe_loc) - and re.search(r"v\d\d\d", exe_loc) + len(v_version) != 0 + and len(ansys_version) != 0 + and v_version[-1] == ansys_version[-1] + and is_valid_executable_path("mapdl", exe_loc) and "ansys" in path and "bin" in path - and equal_version ) + elif product == "mechanical": path = os.path.normpath(exe_loc) path = path.split(os.sep) - is_valid_path = is_valid_executable_path(exe_loc) + is_valid_path = is_valid_executable_path("mechanical", exe_loc) - if is_windows(): + if is_windows(): # pragma: no cover return ( is_valid_path - and re.search(r"v\d\d\d", exe_loc) + and re.search(r"v\d\d\d", exe_loc) is not None and "aisol" in path - and "bin" in path + and ("bin" in path or "Bin" in path) and "winx64" in path - and "AnsysWBU.exe" in path + and ("AnsysWBU.exe" in path or "ANSYSWBU.exe" in path) ) return ( is_valid_path - and re.search(r"v\d\d\d", exe_loc) + and re.search(r"v\d\d\d", exe_loc) is not None and "aisol" in path and ".workbench" in path ) @@ -515,9 +511,8 @@ def _save_path( _change_default_path(product, exe_loc) return exe_loc - if exe_loc is not None: - if is_valid_executable_path(product, exe_loc): - return exe_loc + if is_valid_executable_path(product, exe_loc): + return exe_loc if allow_prompt: exe_loc = _prompt_path(product) return exe_loc diff --git a/tests/test_path.py b/tests/test_path.py index 22f156c0..fc430ead 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1,4 +1,5 @@ import os +import sys import appdirs import pytest @@ -7,7 +8,9 @@ from ansys.tools.path.path import ( _check_uncommon_executable_path, _clear_config_file, + _is_common_executable_path, change_default_mapdl_path, + find_mechanical, get_available_ansys_installations, get_mapdl_path, is_valid_executable_path, @@ -18,10 +21,36 @@ paths = [ ("/usr/dir_v2019.1/slv/ansys_inc/v211/ansys/bin/ansys211", 211), ("C:/Program Files/ANSYS Inc/v202/ansys/bin/win64/ANSYS202.exe", 202), + ("C:\\Program Files\\ANSYS Inc\\v202\\ansys\\bin\\win64\\ANSYS202.exe", 202), ("/usr/ansys_inc/v211/ansys/bin/mapdl", 211), pytest.param(("/usr/ansys_inc/ansys/bin/mapdl", 211), marks=pytest.mark.xfail), ] +mechanical_paths = [ + ("/usr/install/ansys_inc/v211/ansys/aisol/.workbench", 211), + ("C:\\Program Files\\ANSYS Inc\\v202\\aisol\\Bin\\winx64\\ANSYSWBU.exe", 202), + ("C:/Program Files/ANSYS Inc/v202/aisol/Bin/winx64/ANSYSWBU.exe", 202), +] + +linux_mapdl_executable_paths = [ + ("/usr/dir_v2019.1/slv/ansys_inc/v211/ansys/bin/ansys211", True), + ("/usr/ansys_inc/v211/ansys/bin/mapdl", False), +] + +windows_mapdl_executable_paths = [ + ("C:/Program Files/ANSYS Inc/v202/ansys/bin/win64/ANSYS202.exe", True), + ("C:\\Program Files\\ANSYS Inc\\v202\\ansys\\bin\\win64\\ANSYS202.exe", True), +] + +windows_mechanical_executable_paths = [ + ("C:\\Program Files\\ANSYS Inc\\v221\\aisol\\Bin\\winx64\\ANSYSWBU.exe", True), + ("C:/Program Files/ANSYS Inc/v221/aisol/Bin/winx64/ANSYSWBU.exe", True), +] + +linux_mechanical_executable_paths = [ + ("/usr/install/ansys_inc/v211/ansys/aisol/.workbench", True), +] + skip_if_ansys_not_local = pytest.mark.skipif( os.environ.get("ANSYS_LOCAL", "").upper() != "TRUE", reason="Skipping on CI" @@ -34,6 +63,11 @@ def test_mapdl_version_from_path(path_data): assert version_from_path("mapdl", exec_file) == version +@pytest.mark.parametrize("exec_file,version", mechanical_paths) +def test_mechanical_version_from_path(exec_file, version): + assert version_from_path("mechanical", exec_file) == version + + @skip_if_ansys_not_local def test_find_mapdl_linux(): # assuming Ansys MAPDL is installed, should be able to find it on linux @@ -107,3 +141,58 @@ def test_warn_uncommon_executable_path(): def test_get_mapdl_path(): assert get_mapdl_path() assert get_mapdl_path(version=222) + + +@pytest.fixture +def mock_is_valid_executable_path(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setattr("ansys.tools.path.path.is_valid_executable_path", lambda _1, _2: True) + + +@pytest.mark.skipif(sys.platform != "win32", reason="Test only available on windows") +@pytest.mark.parametrize("path,expected", windows_mapdl_executable_paths) +def test_windows_is_common_executable_path_mapdl(mock_is_valid_executable_path, path, expected): + assert _is_common_executable_path("mapdl", path) == expected + + +@pytest.mark.skipif(sys.platform != "linux", reason="Test only available on linux") +@pytest.mark.parametrize("path,expected", linux_mapdl_executable_paths) +def test_linux_is_common_executable_path_mapdl(mock_is_valid_executable_path, path, expected): + assert _is_common_executable_path("mapdl", path) == expected + + +@pytest.mark.skipif(sys.platform != "win32", reason="Test only available on windows") +@pytest.mark.parametrize("path,expected", windows_mechanical_executable_paths) +def test_windows_is_common_executable_path_mechanical( + mock_is_valid_executable_path, path, expected +): + assert _is_common_executable_path("mechanical", path) == expected + + +@pytest.mark.skipif(sys.platform != "linux", reason="Test only available on linux") +@pytest.mark.parametrize("path,expected", linux_mechanical_executable_paths) +def test_linux_is_common_executable_path_mechanical(mock_is_valid_executable_path, path, expected): + assert _is_common_executable_path("mechanical", path) == expected + + +@pytest.fixture +def mock_default_linux_base_path(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setattr("os.path.isdir", lambda x: (x == "/usr/ansys_inc")) + monkeypatch.setattr("ansys.tools.path.path.glob", lambda _: ["/usr/ansys_inc/v221"]) + + +@pytest.fixture +def mock_empty_linux_base_path(monkeypatch: pytest.MonkeyPatch): + monkeypatch.setattr("os.path.isdir", lambda x: (x == "/usr/ansys_inc")) + monkeypatch.setattr("ansys.tools.path.path.glob", lambda _: []) + + +def test_get_available_ansys_installation(mock_default_linux_base_path): + assert get_available_ansys_installations() == {221: "/usr/ansys_inc/v221"} + + +def test_empty_ansys_inttallation(mock_empty_linux_base_path): + assert get_available_ansys_installations() == {} + + +def test_find_mechanical(mock_default_linux_base_path): + assert find_mechanical() == ("/usr/ansys_inc/v221/aisol/.workbench", 22.1)