2024-11-10 23:49:10 +01:00
|
|
|
import logging
|
2024-10-08 14:29:45 +02:00
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2024-11-10 23:49:10 +01:00
|
|
|
import time
|
2024-11-11 21:38:13 +01:00
|
|
|
from pathlib import Path
|
2024-10-08 14:29:45 +02:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
from xprocess import ProcessStarter
|
|
|
|
|
2024-11-11 21:38:13 +01:00
|
|
|
from akkudoktoreos.config import EOS_DIR, AppConfig, load_config
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(name="tmp_config")
|
|
|
|
def load_config_tmp(tmp_path: Path) -> AppConfig:
|
|
|
|
"""Creates an AppConfig from default.config.json with a tmp output directory."""
|
|
|
|
config = load_config(tmp_path)
|
2024-11-26 22:28:05 +01:00
|
|
|
config.directories.output = str(tmp_path)
|
2024-11-11 21:38:13 +01:00
|
|
|
return config
|
|
|
|
|
2024-10-08 14:29:45 +02:00
|
|
|
|
2024-11-10 23:49:10 +01:00
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def disable_debug_logging():
|
|
|
|
# Temporarily set logging level higher than DEBUG
|
|
|
|
logging.disable(logging.DEBUG)
|
|
|
|
yield
|
|
|
|
# Re-enable logging back to its original state after the test
|
|
|
|
logging.disable(logging.NOTSET)
|
|
|
|
|
|
|
|
|
2024-11-10 23:22:30 +01:00
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption(
|
|
|
|
"--full-run", action="store_true", default=False, help="Run with all optimization tests."
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def is_full_run(request):
|
|
|
|
yield bool(request.config.getoption("--full-run"))
|
|
|
|
|
|
|
|
|
2024-10-08 14:29:45 +02:00
|
|
|
@pytest.fixture
|
2024-11-11 21:38:13 +01:00
|
|
|
def server(xprocess, tmp_path: Path):
|
2024-11-10 23:49:10 +01:00
|
|
|
"""Fixture to start the server.
|
|
|
|
|
|
|
|
Provides URL of the server.
|
|
|
|
"""
|
|
|
|
|
2024-10-08 14:29:45 +02:00
|
|
|
class Starter(ProcessStarter):
|
|
|
|
# assure server to be installed
|
|
|
|
try:
|
|
|
|
subprocess.run(
|
2024-11-15 22:27:25 +01:00
|
|
|
[sys.executable, "-c", "import akkudoktoreos.server"],
|
2024-10-08 14:29:45 +02:00
|
|
|
check=True,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
)
|
|
|
|
except subprocess.CalledProcessError:
|
2024-11-11 21:38:13 +01:00
|
|
|
project_dir = Path(__file__).parent.parent
|
2024-10-08 14:29:45 +02:00
|
|
|
subprocess.run(
|
|
|
|
[sys.executable, "-m", "pip", "install", "-e", project_dir],
|
|
|
|
check=True,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
)
|
|
|
|
|
|
|
|
# command to start server process
|
2024-11-15 22:27:25 +01:00
|
|
|
args = [sys.executable, "-m", "akkudoktoreos.server.fastapi_server"]
|
2024-11-11 21:38:13 +01:00
|
|
|
env = {EOS_DIR: f"{tmp_path}", **os.environ.copy()}
|
2024-10-08 14:29:45 +02:00
|
|
|
|
|
|
|
# startup pattern
|
2024-11-15 22:27:25 +01:00
|
|
|
pattern = "Application startup complete."
|
2024-11-11 21:38:13 +01:00
|
|
|
# search the first 30 lines for the startup pattern, if not found
|
2024-10-08 14:29:45 +02:00
|
|
|
# a RuntimeError will be raised informing the user
|
2024-11-11 21:38:13 +01:00
|
|
|
max_read_lines = 30
|
2024-10-08 14:29:45 +02:00
|
|
|
|
2024-11-11 21:38:13 +01:00
|
|
|
# will wait for 30 seconds before timing out
|
2024-10-10 12:59:33 +02:00
|
|
|
timeout = 30
|
2024-10-08 14:29:45 +02:00
|
|
|
|
|
|
|
# xprocess will now attempt to clean up upon interruptions
|
|
|
|
terminate_on_interrupt = True
|
|
|
|
|
|
|
|
# ensure process is running and return its logfile
|
2024-11-15 22:27:25 +01:00
|
|
|
logfile = xprocess.ensure("eos", Starter)
|
2024-10-08 14:29:45 +02:00
|
|
|
|
|
|
|
# create url/port info to the server
|
|
|
|
url = "http://127.0.0.1:8503"
|
|
|
|
yield url
|
|
|
|
|
|
|
|
# clean up whole process tree afterwards
|
2024-11-15 22:27:25 +01:00
|
|
|
xprocess.getinfo("eos").terminate()
|
2024-11-10 23:49:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def other_timezone():
|
|
|
|
"""Fixture to temporarily change the timezone.
|
|
|
|
|
|
|
|
Restores the original timezone after the test.
|
|
|
|
"""
|
|
|
|
original_tz = os.environ.get("TZ", None)
|
|
|
|
|
|
|
|
other_tz = "Atlantic/Canary"
|
|
|
|
if original_tz == other_tz:
|
|
|
|
other_tz = "Asia/Singapore"
|
|
|
|
|
|
|
|
# Change the timezone to another
|
|
|
|
os.environ["TZ"] = other_tz
|
|
|
|
time.tzset() # For Unix/Linux to apply the timezone change
|
|
|
|
|
|
|
|
yield os.environ["TZ"] # Yield control back to the test case
|
|
|
|
|
|
|
|
# Restore the original timezone after the test
|
|
|
|
if original_tz:
|
|
|
|
os.environ["TZ"] = original_tz
|
|
|
|
else:
|
|
|
|
del os.environ["TZ"]
|
|
|
|
time.tzset() # Re-apply the original timezone
|