Skip to content

feat: launching a specific version of Sherlock #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/431.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat: launching a specific version of Sherlock
43 changes: 36 additions & 7 deletions src/ansys/sherlock/core/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@


def launch_sherlock(
host=LOCALHOST, port=SHERLOCK_DEFAULT_PORT, single_project_path="", sherlock_cmd_args=""
):
host: str = LOCALHOST,
port: int = SHERLOCK_DEFAULT_PORT,
single_project_path: str = "",
sherlock_cmd_args: str = "",
year: int = None,
release_number: int = None,
) -> Sherlock:
r"""Launch Sherlock and start gRPC on a given host and port.

Parameters
Expand All @@ -48,6 +53,12 @@
Path to the Sherlock project if invoking Sherlock in the single-project mode.
sherlock_cmd_args : str, optional
Additional command arguments for launching Sherlock.
year : int, optional
4-digit year of the Sherlock release to launch. If not provided,
the latest installed version of Sherlock will be launched.
release_number : int, optional
Release number of Sherlock to launch. If not provided,
the latest installed version of Sherlock will be launched.

Returns
-------
Expand All @@ -60,7 +71,7 @@
>>> launcher.launch_sherlock()

>>> from ansys.sherlock.core import launcher
>>> launcher.launch_sherlock(port=9092)
>>> launcher.launch_sherlock(port=9092, year=2024, release_number=1)

>>> from ansys.sherlock.core import launcher
>>> project = "C:\\Default Projects Directory\\ODB++ Tutorial"
Expand All @@ -74,7 +85,7 @@
return None

try:
args = [_get_sherlock_exe_path()]
args = [_get_sherlock_exe_path(year=year, release_number=release_number)]

Check warning on line 88 in src/ansys/sherlock/core/launcher.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/sherlock/core/launcher.py#L88

Added line #L88 was not covered by tests
args.append("-grpcPort=" + str(port))
if single_project_path != "":
args.append("-singleProject")
Expand Down Expand Up @@ -132,13 +143,25 @@
return SHERLOCK


def _get_base_ansys():
def _get_base_ansys(year: int = None, release_number: int = None) -> str:
supported_installed_versions = {
env_key: path
for env_key, path in os.environ.items()
if env_key.startswith("AWP_ROOT") and os.path.isdir(path)
}

if year is not None and release_number is not None:
try:
year = _extract_sherlock_version_year(year)
version_key = f"AWP_ROOT{year}{release_number}"
if version_key in supported_installed_versions:
return supported_installed_versions[version_key]
else:
raise ValueError(f"Sherlock {year} {release_number} is not installed.")
except ValueError as e:
LOG.error(f"Error extracting Sherlock version year: {e}")
raise

Check warning on line 163 in src/ansys/sherlock/core/launcher.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/sherlock/core/launcher.py#L160-L163

Added lines #L160 - L163 were not covered by tests

for key in sorted(supported_installed_versions, reverse=True):
ansys_version = _get_ansys_version_from_awp_root(key)
if ansys_version >= EARLIEST_SUPPORTED_VERSION:
Expand All @@ -153,12 +176,18 @@
return ""


def _get_sherlock_exe_path():
ansys_base = _get_base_ansys()
def _get_sherlock_exe_path(year: int = None, release_number: int = None) -> str:
ansys_base = _get_base_ansys(year=year, release_number=release_number)
if not ansys_base:
return ""
if os.name == "nt":
sherlock_bin = os.path.join(ansys_base, "sherlock", "SherlockClient.exe")
else:
sherlock_bin = os.path.join(ansys_base, "sherlock", "runSherlock")
return sherlock_bin


def _extract_sherlock_version_year(year: int) -> int:
if 1000 <= year <= 9999:
return year % 100
raise ValueError("Year must be a 4-digit integer.")
26 changes: 26 additions & 0 deletions tests/test_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ def test_get_sherlock_exe_path(self, mock_get_base_ansys):
launcher._get_sherlock_exe_path(),
)

def test_extract_sherlock_version_year_with_two_digits(self):
with self.assertRaises(ValueError) as context:
launcher._extract_sherlock_version_year(999)
self.assertEqual(str(context.exception), "Year must be a 4-digit integer.")

def test_extract_sherlock_version_year_with_four_digits(self):
self.assertEqual(24, launcher._extract_sherlock_version_year(2024))

@patch.dict(
os.environ,
{
"AWP_ROOT241": "C:\\Program Files\\ANSYS Inc\\v241",
"AWP_ROOT232": "C:\\Program Files\\ANSYS Inc\\v232",
},
clear=True,
)
@patch("os.path.isdir")
@patch("ansys.sherlock.core.launcher._extract_sherlock_version_year")
def test_get_base_ansys_calls_extract_sherlock_version_year(
self, mock_extract_year, mock_os_path_isdir
):
mock_os_path_isdir.return_value = True
mock_extract_year.return_value = 24
launcher._get_base_ansys(year=2024, release_number=1)
mock_extract_year.assert_called_once_with(2024)


if __name__ == "__main__":
unittest.main()
Loading