|
1 | 1 | # pylint:disable=unused-argument |
2 | 2 | # pylint:disable=redefined-outer-name |
| 3 | +# pylint:disable=protected-access |
3 | 4 |
|
| 5 | +import asyncio |
| 6 | +from typing import Final |
4 | 7 | from unittest.mock import AsyncMock |
5 | 8 |
|
6 | 9 | import pytest |
7 | 10 | from fastapi import FastAPI |
| 11 | +from models_library.services import ServiceOutput |
| 12 | +from pydantic import TypeAdapter |
8 | 13 | from pytest_mock import MockerFixture |
9 | 14 | from servicelib.rabbitmq import RabbitMQRPCClient |
10 | 15 | from servicelib.rabbitmq.rpc_interfaces.dynamic_sidecar import container_extensions |
| 16 | +from simcore_service_dynamic_sidecar.core.application import AppState |
11 | 17 | from simcore_service_dynamic_sidecar.core.settings import ApplicationSettings |
12 | 18 | from simcore_service_dynamic_sidecar.modules.inputs import InputsState |
13 | 19 | from simcore_service_dynamic_sidecar.modules.outputs._watcher import OutputsWatcher |
|
16 | 22 | "rabbit", |
17 | 23 | ] |
18 | 24 |
|
| 25 | +_WAIT_FOR_OUTPUTS_WATCHER: Final[float] = 0.1 |
| 26 | + |
19 | 27 |
|
20 | 28 | def _assert_inputs_pulling(app: FastAPI, is_enabled: bool) -> None: |
21 | 29 | inputs_state: InputsState = app.state.inputs_state |
@@ -64,3 +72,62 @@ async def test_toggle_ports_io( |
64 | 72 |
|
65 | 73 | _assert_inputs_pulling(app, enabled) |
66 | 74 | _assert_outputs_event_propagation(spy_output_watcher, enabled) |
| 75 | + |
| 76 | + |
| 77 | +@pytest.fixture |
| 78 | +def mock_outputs_labels() -> dict[str, ServiceOutput]: |
| 79 | + return { |
| 80 | + "output_port_1": TypeAdapter(ServiceOutput).validate_python( |
| 81 | + ServiceOutput.model_json_schema()["examples"][3] |
| 82 | + ), |
| 83 | + "output_port_2": TypeAdapter(ServiceOutput).validate_python( |
| 84 | + ServiceOutput.model_json_schema()["examples"][3] |
| 85 | + ), |
| 86 | + } |
| 87 | + |
| 88 | + |
| 89 | +@pytest.fixture |
| 90 | +def mock_event_filter_enqueue( |
| 91 | + app: FastAPI, monkeypatch: pytest.MonkeyPatch |
| 92 | +) -> AsyncMock: |
| 93 | + mock = AsyncMock(return_value=None) |
| 94 | + outputs_watcher: OutputsWatcher = app.state.outputs_watcher |
| 95 | + monkeypatch.setattr(outputs_watcher._event_filter, "enqueue", mock) # noqa: SLF001 |
| 96 | + return mock |
| 97 | + |
| 98 | + |
| 99 | +async def test_container_create_outputs_dirs( |
| 100 | + app: FastAPI, |
| 101 | + rpc_client: RabbitMQRPCClient, |
| 102 | + mock_outputs_labels: dict[str, ServiceOutput], |
| 103 | + mock_event_filter_enqueue: AsyncMock, |
| 104 | +): |
| 105 | + app_state = AppState(app) |
| 106 | + |
| 107 | + # by default outputs-watcher it is disabled |
| 108 | + result = await container_extensions.toggle_ports_io( |
| 109 | + rpc_client, |
| 110 | + node_id=app_state.settings.DY_SIDECAR_NODE_ID, |
| 111 | + enable_outputs=True, |
| 112 | + enable_inputs=True, |
| 113 | + ) |
| 114 | + assert result is None |
| 115 | + await asyncio.sleep(_WAIT_FOR_OUTPUTS_WATCHER) |
| 116 | + |
| 117 | + assert mock_event_filter_enqueue.call_count == 0 |
| 118 | + |
| 119 | + result = await container_extensions.create_output_dirs( |
| 120 | + rpc_client, |
| 121 | + node_id=app_state.settings.DY_SIDECAR_NODE_ID, |
| 122 | + outputs_labels=mock_outputs_labels, |
| 123 | + ) |
| 124 | + |
| 125 | + for dir_name in mock_outputs_labels: |
| 126 | + assert (app_state.mounted_volumes.disk_outputs_path / dir_name).is_dir() |
| 127 | + |
| 128 | + await asyncio.sleep(_WAIT_FOR_OUTPUTS_WATCHER) |
| 129 | + EXPECT_EVENTS_WHEN_CREATING_OUTPUT_PORT_KEY_DIRS = 0 |
| 130 | + assert ( |
| 131 | + mock_event_filter_enqueue.call_count |
| 132 | + == EXPECT_EVENTS_WHEN_CREATING_OUTPUT_PORT_KEY_DIRS |
| 133 | + ) |
0 commit comments