Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
from fastapi import FastAPI

from ...core.settings import ApplicationSettings
from . import routes_external_scheduler, routes_internal_scheduler
from ._utils import set_parent_app
from .routes import router


def initialize_frontend(app: FastAPI) -> None:
settings: ApplicationSettings = app.state.settings

nicegui.app.include_router(router)
if settings.DYNAMIC_SCHEDULER_USE_INTERNAL_SCHEDULER:
nicegui.app.include_router(routes_internal_scheduler.router)
else:
nicegui.app.include_router(routes_external_scheduler.router)

nicegui.ui.run_with(
app,
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
stop_dynamic_service,
)
from settings_library.utils_service import DEFAULT_FASTAPI_PORT
from simcore_service_dynamic_scheduler.services.rabbitmq import get_rabbitmq_rpc_client

from ....core.settings import ApplicationSettings
from ....services.rabbitmq import get_rabbitmq_rpc_client
from ....services.service_tracker import get_tracked_service, remove_tracked_service
from .._utils import get_parent_app, get_settings
from ._render_utils import base_page
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from nicegui import APIRouter

from . import _index

router = APIRouter()

router.include_router(_index.router)

__all__: tuple[str, ...] = ("router",)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from nicegui import APIRouter, ui

router = APIRouter()


@router.page("/")
async def index():
ui.label("PLACEHOLDER for internal scheduler UI")
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pytest


@pytest.fixture
def use_internal_scheduler() -> bool:
return True
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# pylint:disable=redefined-outer-name
# pylint:disable=unused-argument

from helpers import assert_contains_text
from playwright.async_api import Page
from simcore_service_dynamic_scheduler.api.frontend._utils import get_settings

pytest_simcore_core_services_selection = [
"postgres",
"rabbit",
"redis",
]

pytest_simcore_ops_services_selection = [
# "redis-commander",
]


async def test_placeholder_index(
app_runner: None, async_page: Page, server_host_port: str
):
await async_page.goto(
f"{server_host_port}{get_settings().DYNAMIC_SCHEDULER_UI_MOUNT_PATH}"
)

await assert_contains_text(async_page, "PLACEHOLDER for internal scheduler UI")
67 changes: 42 additions & 25 deletions services/dynamic-scheduler/tests/unit/api_frontend/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import subprocess
from collections.abc import AsyncIterable
from contextlib import suppress
from typing import Final
from unittest.mock import AsyncMock

import nicegui
import pytest
import sqlalchemy as sa
from fastapi import FastAPI, status
Expand All @@ -17,6 +14,7 @@
from hypercorn.config import Config
from playwright.async_api import Page, async_playwright
from pytest_mock import MockerFixture
from pytest_simcore.helpers.monkeypatch_envs import setenvs_from_dict
from pytest_simcore.helpers.postgres_tools import PostgresTestConfig
from pytest_simcore.helpers.typing_env import EnvVarsDict
from settings_library.rabbit import RabbitSettings
Expand All @@ -26,57 +24,76 @@
from simcore_service_dynamic_scheduler.core.settings import ApplicationSettings
from tenacity import AsyncRetrying, stop_after_delay, wait_fixed

_MODULE: Final["str"] = "simcore_service_dynamic_scheduler"


@pytest.fixture
def disable_status_monitor_background_task(mocker: MockerFixture) -> None:
mocker.patch(
f"{_MODULE}.services.status_monitor._monitor.Monitor._worker_check_services_require_status_update"
"simcore_service_dynamic_scheduler.services.status_monitor._monitor.Monitor._worker_check_services_require_status_update"
)


@pytest.fixture
def mock_stop_dynamic_service(mocker: MockerFixture) -> AsyncMock:
async_mock = AsyncMock()
mocker.patch(
f"{_MODULE}.api.frontend.routes._service.stop_dynamic_service", async_mock
)
return async_mock


@pytest.fixture
def mock_remove_tracked_service(mocker: MockerFixture) -> AsyncMock:
async_mock = AsyncMock()
mocker.patch(
f"{_MODULE}.api.frontend.routes._service.remove_tracked_service", async_mock
)
return async_mock
def use_internal_scheduler() -> bool:
pytest.fail("please define use_internal_scheduler fixture in your tests folder")


@pytest.fixture
def app_environment(
monkeypatch: pytest.MonkeyPatch,
app_environment: EnvVarsDict,
use_internal_scheduler: bool,
postgres_db: sa.engine.Engine,
postgres_host_config: PostgresTestConfig,
disable_status_monitor_background_task: None,
rabbit_service: RabbitSettings,
redis_service: RedisSettings,
remove_redis_data: None,
) -> EnvVarsDict:
return app_environment
to_set = {
"DYNAMIC_SCHEDULER_USE_INTERNAL_SCHEDULER": f"{use_internal_scheduler}",
}
setenvs_from_dict(monkeypatch, to_set)
return {**app_environment, **to_set}


@pytest.fixture
def server_host_port() -> str:
return f"127.0.0.1:{DEFAULT_FASTAPI_PORT}"


def _reset_nicegui_app() -> None:
# forces rebuild of middleware stack on next test

# below is based on nicegui.testing.general_fixtures.nicegui_reset_globals

from nicegui import Client, app
from starlette.routing import Route

for route in list(app.routes):
if isinstance(route, Route) and route.path.startswith("/_nicegui/auto/static/"):
app.remove_route(route.path)

all_page_routes = set(Client.page_routes.values())
all_page_routes.add("/")
for path in all_page_routes:
app.remove_route(path)

for route in list(app.routes):
if (
isinstance(route, Route)
and "{" in route.path
and "}" in route.path
and not route.path.startswith("/_nicegui/")
):
app.remove_route(route.path)

app.middleware_stack = None
app.user_middleware.clear()


@pytest.fixture
def not_initialized_app(app_environment: EnvVarsDict) -> FastAPI:
# forces rebuild of middleware stack on next test
nicegui.app.user_middleware.clear()
nicegui.app.middleware_stack = None
_reset_nicegui_app()
return create_app()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,5 @@ def get_new_style_service_status(state: str) -> DynamicServiceGet:

def get_legacy_service_status(state: str) -> NodeGet:
return TypeAdapter(NodeGet).validate_python(
NodeGet.model_config["json_schema_extra"]["examples"][0]
| {"service_state": state}
NodeGet.model_json_schema()["examples"][0] | {"service_state": state}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# pylint:disable=redefined-outer-name

from typing import Final
from unittest.mock import AsyncMock

import pytest
from pytest_mock import MockerFixture

_MODULE: Final["str"] = (
"simcore_service_dynamic_scheduler.api.frontend.routes_external_scheduler._service"
)


@pytest.fixture
def use_internal_scheduler() -> bool:
return False


@pytest.fixture
def mock_stop_dynamic_service(mocker: MockerFixture) -> AsyncMock:
async_mock = AsyncMock()
mocker.patch(f"{_MODULE}.stop_dynamic_service", async_mock)
return async_mock


@pytest.fixture
def mock_remove_tracked_service(mocker: MockerFixture) -> AsyncMock:
async_mock = AsyncMock()
mocker.patch(f"{_MODULE}.remove_tracked_service", async_mock)
return async_mock
File renamed without changes.
File renamed without changes.
Loading