Skip to content
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

Improving coverage #2650

Merged
merged 19 commits into from
Jan 12, 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
- main
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '30 4 * * 1,3,5'
- cron: '30 4 * * *'

env:
PROJECT_NAME: 'PyMAPDL'
Expand Down Expand Up @@ -805,7 +805,7 @@ jobs:

release:
if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
needs: [smoke-tests, docs-build, build-test, build-test-ubuntu]
needs: [smoke-tests, docs-build, build-test, build-test-ubuntu, build-test-ubuntu-minimal]
runs-on: ubuntu-latest
steps:
- name: Set up Python
Expand Down
1 change: 1 addition & 0 deletions doc/source/api/mapdl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
Mapdl.open_apdl_log
Mapdl.open_gui
Mapdl.parameters
Mapdl.remove_temp_dir_on_exit
Mapdl.result
Mapdl.run
Mapdl.run_multiline
Expand Down
73 changes: 6 additions & 67 deletions src/ansys/mapdl/core/mapdl_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,6 @@ def save_chunks_to_file(
return file_size


class RepeatingTimer(threading.Timer):
"""Run a function repeately"""

def run(self):
while not self.finished.is_set():
self.function(*self.args, **self.kwargs)
self.finished.wait(self.interval)


class MapdlGrpc(MapdlBase):
"""This class connects to a GRPC MAPDL server and allows commands
to be passed to a persistent session.
Expand Down Expand Up @@ -383,7 +374,7 @@ def __init__(
self._locked: bool = False # being used within MapdlPool
self._stub: Optional[mapdl_grpc.MapdlServiceStub] = None
self._cleanup: bool = cleanup_on_exit
self.__remove_temp_dir_on_exit: bool = remove_temp_dir_on_exit
self.remove_temp_dir_on_exit: bool = remove_temp_dir_on_exit
self._jobname: str = start_parm.get("jobname", "file")
self._path: str = start_parm.get("run_location", None)
self._busy: bool = False # used to check if running a command on the server
Expand Down Expand Up @@ -650,7 +641,7 @@ def _raise_custom_stds_errors(self, errs_message):
raise MapdlConnectionError(
f"A process is already running on the specified port ({self._port}).\n"
"Only one usage of each socket address (protocol/network address/port) is normally permitted.\n"
f"\nFull error message:\n{errs_message.split('########',1)[0]}"
f"\nFull error message:\n{errs_message.split('########', 1)[0]}"
)

else:
Expand Down Expand Up @@ -728,7 +719,7 @@ def __repr__(self):
info = super().__repr__()
return info

def _connect(self, timeout=5, enable_health_check=False):
def _connect(self, timeout=5):
"""Establish a gRPC channel to a remote or local MAPDL instance.

Parameters
Expand Down Expand Up @@ -761,10 +752,6 @@ def _connect(self, timeout=5, enable_health_check=False):
self._timer.daemon = True
self._timer.start()

# enable health check
if enable_health_check:
self._enable_health_check()

return True

@property
Expand Down Expand Up @@ -800,54 +787,6 @@ def _get_server_version(self):
sver = version_string_as_tuple(verstr)
return sver

def _enable_health_check(self):
"""Places the status of the health check in _health_response_queue"""
# lazy imports here to speed up module load
from grpc_health.v1 import health_pb2, health_pb2_grpc

def _consume_responses(response_iterator, response_queue):
try:
for response in response_iterator:
response_queue.put(response)
# NOTE: we're doing absolutely nothing with this as
# this point since the server side health check
# doesn't change state.
except Exception as err:
if self._exiting:
return
self._exited = True
raise MapdlExitedError("Lost connection with MAPDL server") from None

# enable health check
from queue import Queue

request = health_pb2.HealthCheckRequest()
self._health_stub = health_pb2_grpc.HealthStub(self._channel)
rendezvous = self._health_stub.Watch(request)

# health check feature implemented after 2020R2
try:
status = rendezvous.next()
except Exception as err:
if err.code().name != "UNIMPLEMENTED":
raise err
return

if status.status != health_pb2.HealthCheckResponse.SERVING:
raise MapdlRuntimeError(
"Unable to enable health check and/or connect to" " the MAPDL server"
)

self._health_response_queue = Queue()

# allow main process to exit by setting daemon to true
thread = threading.Thread(
target=_consume_responses,
args=(rendezvous, self._health_response_queue),
daemon=True,
)
thread.start()

def _launch(self, start_parm, timeout=10):
"""Launch a local session of MAPDL in gRPC mode.

Expand Down Expand Up @@ -1101,15 +1040,15 @@ def exit(self, save=False, force=False):
if self._local and self._port in _LOCAL_PORTS:
_LOCAL_PORTS.remove(self._port)

def _remove_temp_dir_on_exit(self):
def _remove_temp_dir_on_exit(self, path=None):
"""Removes the temporary directory created by the launcher.

This only runs if the current working directory of MAPDL is within the
user temporary directory.

"""
if self.__remove_temp_dir_on_exit and self._local:
path = self.directory
if self.remove_temp_dir_on_exit and self._local:
path = path or self.directory
tmp_dir = tempfile.gettempdir()
ans_temp_dir = os.path.join(tmp_dir, "ansys_")
if path.startswith(ans_temp_dir):
Expand Down
12 changes: 11 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ def is_exited(mapdl):
assert False # this will fail the test


@pytest.fixture(autouse=True, scope="function")
def run_before_and_after_tests_2(request, mapdl):
"""Make sure we are not changing these properties in tests"""
prev = mapdl.is_local

yield

assert prev == mapdl.is_local


@pytest.fixture(scope="session")
def mapdl_console(request):
if os.name != "posix":
Expand Down Expand Up @@ -461,7 +471,7 @@ def mapdl(request, tmpdir_factory):
###########################################################################
if START_INSTANCE:
mapdl._local = True
mapdl.exit()
mapdl.exit(save=True, force=True)
assert mapdl._exited
assert "MAPDL exited" in str(mapdl)

Expand Down
22 changes: 21 additions & 1 deletion tests/test_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,21 @@ def test_download_result(mapdl, cleared, tmpdir):
assert os.path.exists(os.path.join(target_dir, "file.rst"))

assert not os.path.exists("file.rst")
mapdl.download_result() # with default argument
mapdl.download_result(preference="rst") # with default argument
assert os.path.exists("file.rst")

os.remove("file.rst")

mapdl.download_result(preference="rth")
try:
os.remove("file.rst")
except Exception:
pass
try:
os.remove("file.rth")
except Exception:
pass


def test__channel_str(mapdl):
assert mapdl._channel_str is not None
Expand Down Expand Up @@ -548,3 +558,13 @@ def test_input_compatibility_api_change(mapdl):

with pytest.raises(ValueError, match="A file name must be supplied."):
mapdl.input()


@requires("grpc")
@requires("local")
def test__check_stds(mapdl):
"""Test that the standard input is checked."""

mapdl._read_stds()
assert mapdl._stdout is not None
assert mapdl._stderr is not None
10 changes: 10 additions & 0 deletions tests/test_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,3 +528,13 @@ def test_cpu_checks():
machine_cores = psutil.cpu_count(logical=False)
with pytest.raises(NotEnoughResources):
launch_mapdl(nproc=machine_cores + 2)


def test_fail_channel_port():
with pytest.raises(ValueError):
launch_mapdl(channel="something", port="something")


def test_fail_channel_ip():
with pytest.raises(ValueError):
launch_mapdl(channel="something", ip="something")
24 changes: 24 additions & 0 deletions tests/test_mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from pathlib import Path
import re
import shutil
import tempfile
import time

import grpc
Expand Down Expand Up @@ -2309,3 +2310,26 @@ def test_use_vtk(mapdl):
mapdl.eplot()

mapdl.use_vtk = prev


@requires("local")
def test_remove_temp_dir_on_exit(mapdl, tmpdir):
path = os.path.join(tempfile.gettempdir(), "ansys_" + random_string())
os.makedirs(path)
filename = os.path.join(path, "file.txt")
with open(filename, "w") as f:
f.write("Hello World")
assert os.path.exists(filename)

prev = mapdl.remove_temp_dir_on_exit
mapdl.remove_temp_dir_on_exit = True
mapdl._local = True # Sanity check
mapdl._remove_temp_dir_on_exit(path)
mapdl.remove_temp_dir_on_exit = prev

assert os.path.exists(filename) is False
assert os.path.exists(path) is False


def test_sys(mapdl):
assert "hi" in mapdl.sys("echo 'hi'")
5 changes: 3 additions & 2 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,10 @@ def test_load_file_local(mapdl, tmpdir, file_):
load_file(mapdl, file_path, priority_mapdl_file=False)

if mapdl._local:
with open(os.path.join(mapdl.directory, file_), "r") as fid:
file_name__ = os.path.join(mapdl.directory, file_)
with open(file_name__, "r") as fid:
assert "not that empty" in fid.read()
os.remove(file_)
os.remove(file_name__)
else:
mapdl.download(file_)
with open(os.path.join(file_), "r") as fid:
Expand Down
Loading