Skip to content

Commit def0152

Browse files
eblanco-ansyspre-commit-ci[bot]pyansys-ci-bot
authored
REFACTOR: Conftest refactoring and local_config cleaning (#6727)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent d7335c0 commit def0152

File tree

77 files changed

+555
-1604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+555
-1604
lines changed

.github/workflows/ci_cd.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ env:
1818
DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com'
1919
ON_CI: True
2020
PYTEST_ARGUMENTS: '-vvv --color=yes -ra --durations=25 --maxfail=10 --cov=ansys.aedt.core --cov-report=html --cov-report=xml --junitxml=junit/test-results.xml'
21+
PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml'
2122

2223
concurrency:
2324
group: ${{ github.workflow }}-${{ github.ref }}

.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,11 @@ dist/
372372
/htmlcov/
373373
/coverage.xml
374374
/tests/system/general/coverage.xml
375-
/tests/system/general/local_config.json
376375
/tests/system/solvers/coverage.xml
377-
/tests/system/solvers/local_config.json
378376
/tests/unit/coverage.xml
379377
test-results.xml
380378
test-output.xml
379+
*local_config.json
381380

382381
# Scratch Jupyter Notebooks
383382
scratch_notebooks/
@@ -397,13 +396,10 @@ model.index\+
397396

398397
# local environment settings used by e.g. Visual Studio Code
399398
/.env
400-
/doc/source/local_config.json
401399
/.venv*
402400

403401
# test coverage output
404402
/.cov/
405-
/tests/system/visualization/local_config.json
406-
/tests/system/general/pyaedt_settings.yaml
407403

408404
# Custom instructions for GitHub Copilot
409405
.github/copilot-instructions.md
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Conftest refactoring and local_config cleaning

tests/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
TESTS_PATH = Path(__file__).resolve().parent
2828
TESTS_SYSTEM_PATH = TESTS_PATH / "system"
2929
TESTS_UNIT_PATH = TESTS_PATH / "unit"
30+
TESTS_EMIT_PATH = TESTS_SYSTEM_PATH / "emit"
31+
TESTS_EXTENSIONS_PATH = TESTS_SYSTEM_PATH / "extensions"
32+
TESTS_FILTER_SOLUTIONS_PATH = TESTS_SYSTEM_PATH / "filter_solutions"
3033
TESTS_GENERAL_PATH = TESTS_SYSTEM_PATH / "general"
3134
TESTS_SOLVERS_PATH = TESTS_SYSTEM_PATH / "solvers"
3235
TESTS_VISUALIZATION_PATH = TESTS_SYSTEM_PATH / "visualization"
33-
TESTS_EXTENSIONS_PATH = TESTS_SYSTEM_PATH / "extensions"
34-
TESTS_FILTER_SOLUTIONS_PATH = TESTS_SYSTEM_PATH / "filter_solutions"

tests/conftest.py

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,24 @@
2222
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
# SOFTWARE.
2424

25+
import json
26+
import os
27+
from pathlib import Path
28+
import random
29+
import shutil
30+
import string
2531
import sys
32+
import tempfile
2633
from typing import List
2734
from unittest.mock import MagicMock
2835

2936
import pytest
3037

38+
from ansys.aedt.core.aedt_logger import pyaedt_logger
39+
from ansys.aedt.core.generic.settings import settings
40+
from ansys.aedt.core.internal.filesystem import Scratch
41+
42+
# Test category prefixes for marker assignment
3143
UNIT_TEST_PREFIX = "tests/unit"
3244
INTEGRATION_TEST_PREFIX = "tests/integration"
3345
SYSTEM_TEST_PREFIX = "tests/system"
@@ -39,6 +51,68 @@
3951
EMIT_TEST_PREFIX = "tests/system/emit"
4052

4153

54+
DEFAULT_CONFIG = {
55+
"desktopVersion": "2025.2",
56+
"NonGraphical": True,
57+
"NewThread": True,
58+
"use_grpc": True,
59+
"close_desktop": True,
60+
"remove_lock": False,
61+
"disable_sat_bounding_box": True,
62+
"use_local_example_data": False,
63+
"local_example_folder": None,
64+
"skip_circuits": False,
65+
"skip_modelithics": True,
66+
}
67+
68+
# Load top-level configuration
69+
local_path = Path(__file__).parent
70+
local_config_file = local_path / "local_config.json"
71+
72+
config = DEFAULT_CONFIG.copy()
73+
if local_config_file.exists():
74+
try:
75+
with open(local_config_file) as f:
76+
local_config = json.load(f)
77+
config.update(local_config)
78+
except Exception as e: # pragma: no cover
79+
# Failed to load local_config.json; report error
80+
print(f"Failed to load local_config.json ({local_config_file}): {e}")
81+
82+
desktop_version = config.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion"))
83+
NONGRAPHICAL = config.get("NonGraphical", DEFAULT_CONFIG.get("NonGraphical"))
84+
new_thread = config.get("NewThread", DEFAULT_CONFIG.get("NewThread"))
85+
settings.use_grpc_api = config.get("use_grpc", DEFAULT_CONFIG.get("use_grpc"))
86+
close_desktop = config.get("close_desktop", DEFAULT_CONFIG.get("close_desktop"))
87+
remove_lock = config.get("remove_lock", DEFAULT_CONFIG.get("remove_lock"))
88+
settings.disable_bounding_box_sat = config.get(
89+
"disable_sat_bounding_box", DEFAULT_CONFIG.get("disable_sat_bounding_box")
90+
)
91+
settings.use_local_example_data = config.get("use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data"))
92+
if settings.use_local_example_data:
93+
settings.local_example_folder = config.get("local_example_folder", DEFAULT_CONFIG.get("local_example_folder"))
94+
95+
logger = pyaedt_logger
96+
os.environ["PYAEDT_SCRIPT_VERSION"] = config.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion"))
97+
98+
99+
# Add current path to sys.path for imports
100+
sys.path.append(str(local_path))
101+
102+
103+
def generate_random_string(length):
104+
"""Generate a random string of specified length."""
105+
characters = string.ascii_letters + string.digits
106+
random_string = "".join(random.sample(characters, length))
107+
return random_string
108+
109+
110+
def generate_random_ident():
111+
"""Generate a random identifier for test folders."""
112+
ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6)
113+
return ident
114+
115+
42116
def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item]):
43117
"""Hook used to apply marker on tests."""
44118
for item in items:
@@ -64,8 +138,41 @@ def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item
64138
item.add_marker(pytest.mark.emit)
65139

66140

141+
# ================================
142+
# SHARED FIXTURES
143+
# ================================
144+
145+
146+
@pytest.fixture(scope="session", autouse=True)
147+
def init_scratch():
148+
"""Initialize a global scratch directory for all tests."""
149+
test_folder_name = "pyaedt_test" + generate_random_ident()
150+
test_folder = Path(tempfile.gettempdir()) / test_folder_name
151+
try:
152+
os.makedirs(test_folder, mode=0o777)
153+
except FileExistsError as e:
154+
print(f"Failed to create {test_folder}. Reason: {e}")
155+
156+
yield test_folder
157+
158+
try:
159+
shutil.rmtree(test_folder, ignore_errors=True)
160+
except Exception as e:
161+
print(f"Failed to delete {test_folder}. Reason: {e}")
162+
163+
164+
@pytest.fixture(scope="module", autouse=True)
165+
def local_scratch(init_scratch):
166+
"""Provide a module-scoped scratch directory."""
167+
tmp_path = init_scratch
168+
scratch = Scratch(tmp_path)
169+
yield scratch
170+
scratch.remove()
171+
172+
67173
@pytest.fixture
68174
def touchstone_file(tmp_path):
175+
"""Create a dummy touchstone file for testing."""
69176
file_path = tmp_path / "dummy.s2p"
70177
file_content = """
71178
! Terminal data exported
@@ -80,6 +187,7 @@ def touchstone_file(tmp_path):
80187

81188
@pytest.fixture()
82189
def patch_graphics_modules(monkeypatch):
190+
"""Patch graphics modules to avoid headless env issues."""
83191
modules = [
84192
"matplotlib",
85193
"matplotlib.pyplot",
@@ -100,9 +208,9 @@ def patch_graphics_modules(monkeypatch):
100208

101209
# Specific action to make a mock an attribute of another mock
102210
mocks["matplotlib"].pyplot = mocks["matplotlib.pyplot"]
103-
mocks["ansys.tools.visualization_interface"].backends = mocks["ansys.tools.visualization_interface.backends"]
104-
mocks["ansys.tools.visualization_interface.backends"].pyvista = mocks[
105-
"ansys.tools.visualization_interface.backends.pyvista"
106-
]
211+
viz_interface = mocks["ansys.tools.visualization_interface"]
212+
viz_backends = mocks["ansys.tools.visualization_interface.backends"]
213+
viz_interface.backends = viz_backends
214+
viz_backends.pyvista = mocks["ansys.tools.visualization_interface.backends.pyvista"]
107215

108216
yield mocks

tests/pyaedt_settings.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# PyAEDT settings configuration for test environment
2+
# This file configures PyAEDT settings for all tests
3+
4+
log:
5+
enable_local_log_file: false
6+
enable_global_log_file: false
7+
enable_desktop_logs: false
8+
9+
general:
10+
number_of_grpc_api_retries: 6
11+
retry_n_times_time_interval: 0.5
12+
enable_error_handler: false
13+
desktop_launch_timeout: 180
14+
release_on_exception: false
15+
wait_for_license: true
16+
enable_pandas_output: true
17+
lsf: {}
18+
# LSF settings are kept at defaults for test environment

0 commit comments

Comments
 (0)