Skip to content

Commit

Permalink
FEAT: Update private app data creation and add tests (#986)
Browse files Browse the repository at this point in the history
Co-authored-by: pyansys-ci-bot <[email protected]>
Co-authored-by: Kerry McAdams <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Nov 20, 2024
1 parent cb0043b commit af612b6
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 38 deletions.
1 change: 1 addition & 0 deletions doc/changelog.d/986.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update private app data creation and add tests
3 changes: 2 additions & 1 deletion src/ansys/mechanical/core/embedding/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ def __init__(self, db_file=None, private_appdata=False, **kwargs):
configuration = kwargs.get("config", _get_default_addin_configuration())

if private_appdata:
copy_profile = kwargs.get("copy_profile", True)
new_profile_name = f"PyMechanical-{os.getpid()}"
profile = UniqueUserProfile(new_profile_name)
profile = UniqueUserProfile(new_profile_name, copy_profile=copy_profile)
profile.update_environment(os.environ)
atexit.register(_cleanup_private_appdata, profile)

Expand Down
9 changes: 5 additions & 4 deletions src/ansys/mechanical/core/embedding/appdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@
class UniqueUserProfile:
"""Create Unique User Profile (for AppData)."""

def __init__(self, profile_name: str, dry_run: bool = False):
def __init__(self, profile_name: str, copy_profile: bool = True, dry_run: bool = False):
"""Initialize UniqueUserProfile class."""
self._default_profile = os.path.expanduser("~")
self._location = os.path.join(self._default_profile, "PyMechanical-AppData", profile_name)
self._dry_run = dry_run
self.copy_profile = copy_profile
self.initialize()

def initialize(self, copy_profiles=True) -> None:
def initialize(self) -> None:
"""
Initialize the new profile location.
Args:
copy_profiles (bool): If False, the copy_profiles method will be skipped.
copy_profile (bool): If False, the copy_profile method will be skipped.
"""
if self._dry_run:
return
if self.exists():
self.cleanup()
self.mkdirs()
if copy_profiles:
if self.copy_profile:
self.copy_profiles()

def cleanup(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/mechanical/core/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def _cli_impl(
profile: UniqueUserProfile = None
if private_appdata:
new_profile_name = f"Mechanical-{os.getpid()}"
profile = UniqueUserProfile(new_profile_name, DRY_RUN)
profile = UniqueUserProfile(new_profile_name, dry_run=DRY_RUN)
profile.update_environment(env)

if not DRY_RUN:
Expand Down
31 changes: 0 additions & 31 deletions tests/embedding/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,37 +239,6 @@ def test_warning_message(test_env, pytestconfig, run_subprocess, rootdir):
assert warning, "UserWarning should appear in the output of the script"


@pytest.mark.embedding_scripts
@pytest.mark.python_env
def test_private_appdata(pytestconfig, run_subprocess, rootdir):
"""Test embedded instance does not save ShowTriad using a test-scoped Python environment."""

version = pytestconfig.getoption("ansys_version")
embedded_py = os.path.join(rootdir, "tests", "scripts", "run_embedded_app.py")

run_subprocess([sys.executable, embedded_py, version, "True", "Set"])
process, stdout, stderr = run_subprocess([sys.executable, embedded_py, version, "True", "Run"])
stdout = stdout.decode()
assert "ShowTriad value is True" in stdout


@pytest.mark.embedding_scripts
@pytest.mark.python_env
def test_normal_appdata(pytestconfig, run_subprocess, rootdir):
"""Test embedded instance saves ShowTriad value using a test-scoped Python environment."""
version = pytestconfig.getoption("ansys_version")

embedded_py = os.path.join(rootdir, "tests", "scripts", "run_embedded_app.py")

run_subprocess([sys.executable, embedded_py, version, "False", "Set"])
process, stdout, stderr = run_subprocess([sys.executable, embedded_py, version, "False", "Run"])
run_subprocess([sys.executable, embedded_py, version, "False", "Reset"])

stdout = stdout.decode()
# Assert ShowTriad was set to False for regular embedded session
assert "ShowTriad value is False" in stdout


@pytest.mark.embedding_scripts
def test_building_gallery(pytestconfig, run_subprocess, rootdir):
"""Test for building gallery check.
Expand Down
112 changes: 112 additions & 0 deletions tests/embedding/test_appdata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright (C) 2022 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""Embedding tests related to app data"""

import os
from pathlib import Path
import sys
from unittest import mock

import pytest

from ansys.mechanical.core.embedding.appdata import UniqueUserProfile


@pytest.mark.embedding_scripts
@pytest.mark.python_env
def test_private_appdata(pytestconfig, run_subprocess, rootdir):
"""Test embedded instance does not save ShowTriad using a test-scoped Python environment."""

version = pytestconfig.getoption("ansys_version")
embedded_py = os.path.join(rootdir, "tests", "scripts", "run_embedded_app.py")

run_subprocess([sys.executable, embedded_py, version, "True", "Set"])
process, stdout, stderr = run_subprocess([sys.executable, embedded_py, version, "True", "Run"])
stdout = stdout.decode()
assert "ShowTriad value is True" in stdout


@pytest.mark.embedding_scripts
@pytest.mark.python_env
def test_normal_appdata(pytestconfig, run_subprocess, rootdir):
"""Test embedded instance saves ShowTriad value using a test-scoped Python environment."""
version = pytestconfig.getoption("ansys_version")

embedded_py = os.path.join(rootdir, "tests", "scripts", "run_embedded_app.py")

run_subprocess([sys.executable, embedded_py, version, "False", "Set"])
process, stdout, stderr = run_subprocess([sys.executable, embedded_py, version, "False", "Run"])
run_subprocess([sys.executable, embedded_py, version, "False", "Reset"])

stdout = stdout.decode()
# Assert ShowTriad was set to False for regular embedded session
assert "ShowTriad value is False" in stdout


@pytest.mark.embedding
def test_uniqueprofile_creation():
"""Test profile is copied when copy_profile is ``True`` and is not copied when ``False``."""
folder_to_check = Path("AppData") / "Local" / "Ansys" if os.name == "nt" else Path(".mw")

# Create private app data without copying profiles
private_data2 = UniqueUserProfile(profile_name="test1", copy_profile=False)
assert not os.path.exists(os.path.join(private_data2.location, folder_to_check))

# Check if location is same with same profile name
private_data1 = UniqueUserProfile(profile_name="test1")
assert private_data1.location == private_data2.location

# Check if folder exists after copying profiles
assert Path(private_data1.location / folder_to_check).exists()

# Create new profile
private_data3 = UniqueUserProfile(profile_name="test2")
assert private_data2.location != private_data3.location


@pytest.mark.embedding
def test_uniqueprofile_env():
"""Test the environment is correctly updated for the profile based on operating system."""
profile = UniqueUserProfile("test_env")
env = {}
platforms = ["win32", "linux"]

for platform in platforms:
with mock.patch.object(sys, "platform", platform):
profile.update_environment(env)

if platform == "win32":
env["USERPROFILE"] = profile.location
env["APPDATA"] = Path(profile.location) / "AppData" / "Roaming"
env["LOCALAPPDATA"] = Path(profile.location) / "AppData" / "Local"
env["TMP"] = Path(profile.location) / "AppData" / "Local" / "Temp"
env["TEMP"] = Path(profile.location) / "AppData" / "Local " / "Temp"
else:
env["HOME"] = profile.location


@pytest.mark.embedding
def test_uniqueprofile_dryrun():
"""Test the profile is not copied during dry runs."""
profile = UniqueUserProfile("test_dry_run", dry_run=True)
assert not Path(profile.location).exists()
2 changes: 1 addition & 1 deletion tests/scripts/run_embedded_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
def launch_app(version, private_appdata):
"""Launch embedded instance of app."""
# Configuration.configure(level=logging.DEBUG, to_stdout=True, base_directory=None)
app = pymechanical.App(version=version, private_appdata=private_appdata)
app = pymechanical.App(version=version, private_appdata=private_appdata, copy_profile=True)
return app


Expand Down

0 comments on commit af612b6

Please sign in to comment.