2022-11-07 09:36:41 +00:00
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import threading
|
2022-11-23 11:15:16 +00:00
|
|
|
from subprocess import Popen
|
2022-11-07 09:36:41 +00:00
|
|
|
|
|
|
|
import psutil
|
|
|
|
import pytest
|
2022-12-20 14:08:27 +00:00
|
|
|
from tests_examples_app.public import _PATH_EXAMPLES
|
2022-11-07 09:36:41 +00:00
|
|
|
|
|
|
|
from lightning_app.storage.path import _storage_root_dir
|
|
|
|
from lightning_app.utilities.component import _set_context
|
|
|
|
from lightning_app.utilities.packaging import cloud_compute
|
|
|
|
from lightning_app.utilities.packaging.app_config import _APP_CONFIG_FILENAME
|
|
|
|
from lightning_app.utilities.state import AppState
|
|
|
|
|
2022-11-23 11:15:16 +00:00
|
|
|
GITHUB_APP_URLS = {
|
|
|
|
"template_react_ui": "https://github.com/Lightning-AI/lightning-template-react.git",
|
|
|
|
}
|
|
|
|
|
2022-11-09 20:46:31 +00:00
|
|
|
os.environ["LIGHTNING_DISPATCHED"] = "1"
|
|
|
|
|
2022-11-07 09:36:41 +00:00
|
|
|
|
2022-11-23 11:15:16 +00:00
|
|
|
def pytest_sessionstart(*_):
|
|
|
|
"""Pytest hook that get called after the Session object has been created and before performing collection and
|
|
|
|
entering the run test loop."""
|
|
|
|
for name, url in GITHUB_APP_URLS.items():
|
2022-12-20 14:08:27 +00:00
|
|
|
app_path = _PATH_EXAMPLES / name
|
|
|
|
if not os.path.exists(app_path):
|
|
|
|
Popen(["git", "clone", url, name], cwd=_PATH_EXAMPLES).wait(timeout=90)
|
2022-11-23 11:15:16 +00:00
|
|
|
else:
|
2022-12-20 14:08:27 +00:00
|
|
|
Popen(["git", "pull", "main"], cwd=app_path).wait(timeout=90)
|
2022-11-23 11:15:16 +00:00
|
|
|
|
|
|
|
|
2022-11-07 09:36:41 +00:00
|
|
|
def pytest_sessionfinish(session, exitstatus):
|
|
|
|
"""Pytest hook that get called after whole test run finished, right before returning the exit status to the
|
|
|
|
system."""
|
|
|
|
# kill all the processes and threads created by parent
|
|
|
|
# TODO this isn't great. We should have each tests doing it's own cleanup
|
|
|
|
current_process = psutil.Process()
|
|
|
|
for child in current_process.children(recursive=True):
|
2022-11-08 12:55:31 +00:00
|
|
|
try:
|
|
|
|
params = child.as_dict() or {}
|
|
|
|
cmd_lines = params.get("cmdline", [])
|
|
|
|
# we shouldn't kill the resource tracker from multiprocessing. If we do,
|
|
|
|
# `atexit` will throw as it uses resource tracker to try to clean up
|
|
|
|
if cmd_lines and "resource_tracker" in cmd_lines[-1]:
|
|
|
|
continue
|
|
|
|
child.kill()
|
|
|
|
except psutil.NoSuchProcess:
|
|
|
|
pass
|
2022-11-07 09:36:41 +00:00
|
|
|
|
|
|
|
main_thread = threading.current_thread()
|
|
|
|
for t in threading.enumerate():
|
|
|
|
if t is not main_thread:
|
|
|
|
t.join(0)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function", autouse=True)
|
|
|
|
def cleanup():
|
|
|
|
from lightning_app.utilities.app_helpers import _LightningAppRef
|
|
|
|
|
|
|
|
yield
|
|
|
|
_LightningAppRef._app_instance = None
|
|
|
|
shutil.rmtree("./storage", ignore_errors=True)
|
|
|
|
shutil.rmtree(_storage_root_dir(), ignore_errors=True)
|
|
|
|
shutil.rmtree("./.shared", ignore_errors=True)
|
|
|
|
if os.path.isfile(_APP_CONFIG_FILENAME):
|
|
|
|
os.remove(_APP_CONFIG_FILENAME)
|
|
|
|
_set_context(None)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function", autouse=True)
|
|
|
|
def clear_app_state_state_variables():
|
|
|
|
"""Resets global variables in order to prevent interference between tests."""
|
|
|
|
yield
|
|
|
|
import lightning_app.utilities.state
|
|
|
|
|
|
|
|
lightning_app.utilities.state._STATE = None
|
|
|
|
lightning_app.utilities.state._LAST_STATE = None
|
|
|
|
AppState._MY_AFFILIATION = ()
|
|
|
|
if hasattr(cloud_compute, "_CLOUD_COMPUTE_STORE"):
|
|
|
|
cloud_compute._CLOUD_COMPUTE_STORE.clear()
|