From 363d3b7c373cef47327aa818cd4fac5b2c36db4d Mon Sep 17 00:00:00 2001 From: klmcadams <58492561+klmcadams@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:13:23 -0400 Subject: [PATCH] add version_range marker, adjust stubs loc search and update tests --- pyproject.toml | 1 + src/ansys/mechanical/core/ide_config.py | 13 +- tests/conftest.py | 13 ++ tests/test_cli.py | 153 +++++++++++++++++++++++- 4 files changed, 167 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6d2cc42c5..41acfe2a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,6 +142,7 @@ markers = [ "remote_session_launch: tests that launch Mechanical and work with gRPC server inside it", "remote_session_connect: tests that connect to Mechanical and work with gRPC server inside it", "minimum_version(num): tests that run if ansys-version is greater than or equal to the minimum version provided", + "version_range(min_revn, max_revn): tests that run if ansys-version is in the range of the minimum and maximum revision numbers inclusive.", "windows_only: tests that run if the testing platform is on Windows", "linux_only: tests that run if the testing platform is on Linux", "cli: tests for the Command Line Interface", diff --git a/src/ansys/mechanical/core/ide_config.py b/src/ansys/mechanical/core/ide_config.py index b3f9129f1..b317ad3bc 100644 --- a/src/ansys/mechanical/core/ide_config.py +++ b/src/ansys/mechanical/core/ide_config.py @@ -25,6 +25,7 @@ import json import os from pathlib import Path +import re import site import sys @@ -40,16 +41,14 @@ def get_stubs_location(): pathlib.Path The path to the ansys-mechanical-stubs installation in site-packages. """ - site_packages_path = "" site_packages = site.getsitepackages() + prefix_path = sys.prefix.replace("\\", "\\\\") + site_packages_regex = re.compile(f"{prefix_path}.*site-packages$") + site_packages_paths = list(filter(site_packages_regex.match, site_packages)) - for loc in site_packages: - if ("site-packages" in loc) and (sys.prefix in loc): - site_packages_path = loc - - if site_packages_path: + if len(site_packages_paths) == 1: # Get the stubs location - stubs_location = Path(site_packages_path) / "ansys" / "mechanical" / "stubs" + stubs_location = Path(site_packages_paths[0]) / "ansys" / "mechanical" / "stubs" return stubs_location raise Exception("Could not retrieve the location of the ansys-mechanical-stubs package.") diff --git a/tests/conftest.py b/tests/conftest.py index 31af6bcd1..dec82b8f3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -385,6 +385,7 @@ def pytest_addoption(parser): def pytest_collection_modifyitems(config, items): """Skips tests marked minimum_version if ansys-version is less than mark argument.""" for item in items: + # Skip tests that are less than the minimum version if "minimum_version" in item.keywords: revn = [mark.args[0] for mark in item.iter_markers(name="minimum_version")] if int(config.getoption("--ansys-version")) < revn[0]: @@ -393,6 +394,18 @@ def pytest_collection_modifyitems(config, items): ) item.add_marker(skip_versions) + # Skip tests that are outside of the provided version range. For example, + # @pytest.mark.version_range(241,242) + if "version_range" in item.keywords: + revns = [mark.args for mark in item.iter_markers(name="version_range")][0] + ansys_version = int(config.getoption("--ansys-version")) + + if (ansys_version < revns[0]) or (ansys_version > revns[1]): + skip_versions = pytest.mark.skip( + reason=f"Requires ansys-version in the range {revns[0]} to {revns[1]}." + ) + item.add_marker(skip_versions) + # Skip on platforms other than Windows if "windows_only" in item.keywords and sys.platform != "win32": skip_except_windows = pytest.mark.skip(reason="Test requires Windows platform.") diff --git a/tests/test_cli.py b/tests/test_cli.py index ece0b8be9..01326a4d6 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -22,6 +22,7 @@ import os from pathlib import Path +import subprocess import sys import pytest @@ -30,6 +31,11 @@ from ansys.mechanical.core.ide_config import get_stubs_location, get_stubs_versions from ansys.mechanical.core.run import _cli_impl +STUBS_LOC = get_stubs_location() +STUBS_REVNS = get_stubs_versions(STUBS_LOC) +MIN_STUBS_REVN = min(STUBS_REVNS) +MAX_STUBS_REVN = max(STUBS_REVNS) + @pytest.mark.cli def test_cli_default(disable_cli): @@ -263,12 +269,18 @@ def test_ideconfig_cli_ide_exception(capfd, pytestconfig): ) -def test_ideconfig_cli_version_exception(pytestconfig): - """Test IDE configuration raises an exception when the version is out of bounds.""" +def get_ideconfig_vars(pytestconfig): revision = int(pytestconfig.getoption("ansys_version")) stubs_location = get_stubs_location() stubs_revns = get_stubs_versions(stubs_location) + return revision, stubs_location, stubs_revns + + +def test_ideconfig_cli_version_exception(pytestconfig): + """Test the IDE configuration raises an exception when the version is out of bounds.""" + revision, stubs_location, stubs_revns = get_ideconfig_vars(pytestconfig) + if revision > max(stubs_revns): with pytest.raises(Exception): ideconfig_cli_impl( @@ -278,7 +290,136 @@ def test_ideconfig_cli_version_exception(pytestconfig): ) -# user settings -# workspace settings -# venv -# default - just ansys-mechanical-ideconfig +@pytest.mark.cli +@pytest.mark.version_range(MIN_STUBS_REVN, MAX_STUBS_REVN) +def test_ideconfig_cli_user_settings(capfd, pytestconfig): + """Test the IDE configuration prints correct information for user settings.""" + # Set the revision number + revision, stubs_location, stubs_revns = get_ideconfig_vars(pytestconfig) + + # Run the IDE configuration command for the user settings type + ideconfig_cli_impl( + ide="vscode", + target="user", + revision=revision, + ) + + # Get output of the IDE configuration command + out, err = capfd.readouterr() + out = out.replace("\\\\", "\\") + + # Get the path to the settings.json file based on operating system env vars + settings_json = get_settings_location() + + assert f"Update {settings_json} with the following information" in out + assert str(stubs_location) in out + + +@pytest.mark.cli +@pytest.mark.version_range(MIN_STUBS_REVN, MAX_STUBS_REVN) +def test_ideconfig_cli_workspace_settings(capfd, pytestconfig): + """Test the IDE configuration prints correct information for workplace settings.""" + # Set the revision number + revision, stubs_location, stubs_revns = get_ideconfig_vars(pytestconfig) + + # Run the IDE configuration command + ideconfig_cli_impl( + ide="vscode", + target="workspace", + revision=revision, + ) + + # Get output of the IDE configuration command + out, err = capfd.readouterr() + out = out.replace("\\\\", "\\") + + # Get the path to the settings.json file based on the current directory & .vscode folder + settings_json = Path.cwd() / ".vscode" / "settings.json" + + # Assert the correct settings.json file and stubs location is in the output + assert f"Update {settings_json} with the following information" in out + assert str(stubs_location) in out + assert "Please ensure the .vscode folder is in the root of your project or repository" in out + + +@pytest.mark.cli +@pytest.mark.python_env +@pytest.mark.version_range(MIN_STUBS_REVN, MAX_STUBS_REVN) +def test_ideconfig_cli_venv(test_env, run_subprocess, rootdir, pytestconfig): + """Test the IDE configuration location when a virtual environment is active.""" + # Set the revision number + revision = pytestconfig.getoption("ansys_version") + + # Install pymechanical + subprocess.check_call( + [test_env.python, "-m", "pip", "install", "-e", "."], + cwd=rootdir, + env=test_env.env, + ) + + # Get the virtual environment location + process, venv_loc, stderr = run_subprocess( + [test_env.python, "-c", "'import sys; print(sys.prefix)'"], + env=test_env.env, + ) + # Decode stdout and fix extra backslashes in paths + venv_loc = venv_loc.decode().replace("\\\\", "\\") + + # Run ansys-mechanical-ideconfig in the test virtual environment + process, stdout, stderr = run_subprocess( + [ + "ansys-mechanical-ideconfig", + "--ide", + "vscode", + "--target", + "user", + "--revision", + str(revision), + ], + env=test_env.env, + ) + # Decode stdout and fix extra backslashes in paths + stdout = stdout.decode().replace("\\\\", "\\") + + # Assert virtual environment is in the stdout + assert venv_loc in stdout + + +@pytest.mark.cli +@pytest.mark.python_env +@pytest.mark.version_range(MIN_STUBS_REVN, MAX_STUBS_REVN) +def test_ideconfig_cli_default(test_env, run_subprocess, rootdir, pytestconfig): + """Test the IDE configuration location when no arguments are supplied.""" + # Get the revision number + revision = pytestconfig.getoption("ansys_version") + # Set part of the settings.json path + settings_json_fragment = Path("Code") / "User" / "settings.json" + + # Install pymechanical + subprocess.check_call( + [test_env.python, "-m", "pip", "install", "-e", "."], + cwd=rootdir, + env=test_env.env, + ) + + # Get the virtual environment location + process, venv_loc, stderr = run_subprocess( + [test_env.python, "-c", "'import sys; print(sys.prefix)'"], + env=test_env.env, + ) + # Decode stdout and fix extra backslashes in paths + venv_loc = venv_loc.decode().replace("\\\\", "\\") + + # Run ansys-mechanical-ideconfig in the test virtual environment + process, stdout, stderr = run_subprocess( + [ + "ansys-mechanical-ideconfig", + ], + env=test_env.env, + ) + # Decode stdout and fix extra backslashes in paths + stdout = stdout.decode().replace("\\\\", "\\") + + assert revision in stdout + assert str(settings_json_fragment) in stdout + assert venv_loc in stdout