def test_running_service_details_make_status(scheduler_data: SchedulerData,
                                             service_message: str,
                                             service_state: ServiceState):
    running_service_details = RunningDynamicServiceDetails.from_scheduler_data(
        node_uuid=scheduler_data.node_uuid,
        scheduler_data=scheduler_data,
        service_state=service_state,
        service_message=service_message,
    )
    print(running_service_details)
    assert running_service_details

    running_service_details_dict = running_service_details.dict(
        exclude_unset=True, by_alias=True)

    expected_running_service_details = {
        "boot_type": ServiceBootType.V2,
        "project_id": scheduler_data.project_id,
        "service_state": service_state,
        "service_message": service_message,
        "service_uuid": scheduler_data.node_uuid,
        "service_key": scheduler_data.key,
        "service_version": scheduler_data.version,
        "service_host": scheduler_data.service_name,
        "user_id": scheduler_data.user_id,
        "service_port": scheduler_data.service_port,
    }

    assert running_service_details_dict == expected_running_service_details
Exemple #2
0
async def test_get_stack_status(
    ensure_scheduler_runs_once: Callable,
    scheduler: DynamicSidecarsScheduler,
    scheduler_data: SchedulerData,
    docker_swarm: None,
    mocked_dynamic_scheduler_events: None,
) -> None:
    await ensure_scheduler_runs_once()

    await scheduler.add_service(scheduler_data)

    stack_status = await scheduler.get_stack_status(scheduler_data.node_uuid)
    assert stack_status == RunningDynamicServiceDetails.from_scheduler_data(
        node_uuid=scheduler_data.node_uuid,
        scheduler_data=scheduler_data,
        service_state=ServiceState.PENDING,
        service_message="",
    )
Exemple #3
0
async def test_get_stack_status_containers_are_starting(
    scheduler: DynamicSidecarsScheduler,
    scheduler_data: SchedulerData,
    mock_service_running: AsyncMock,
    docker_swarm: None,
    mocked_dynamic_scheduler_events: None,
) -> None:
    async with _assert_get_dynamic_services_mocked(
            scheduler,
            scheduler_data,
            mock_service_running,
            expected_response=httpx.Response(200, json={}),
    ) as stack_status:
        assert stack_status == RunningDynamicServiceDetails.from_scheduler_data(
            node_uuid=scheduler_data.node_uuid,
            scheduler_data=scheduler_data,
            service_state=ServiceState.STARTING,
            service_message="",
        )
Exemple #4
0
async def test_get_stack_status_failing_sidecar(
    scheduler: DynamicSidecarsScheduler,
    scheduler_data: SchedulerData,
    docker_swarm: None,
    mocked_dynamic_scheduler_events: None,
) -> None:
    failing_message = "some_failing_message"
    scheduler_data.dynamic_sidecar.status.update_failing_status(
        failing_message)

    await scheduler.add_service(scheduler_data)

    stack_status = await scheduler.get_stack_status(scheduler_data.node_uuid)
    assert stack_status == RunningDynamicServiceDetails.from_scheduler_data(
        node_uuid=scheduler_data.node_uuid,
        scheduler_data=scheduler_data,
        service_state=ServiceState.FAILED,
        service_message=failing_message,
    )
async def mock_retrieve_features(
    minimal_app: FastAPI,
    client: TestClient,
    service: Dict[str, Any],
    is_legacy: bool,
    scheduler_data_from_http_request: SchedulerData,
) -> AsyncIterator[Optional[MockRouter]]:
    with respx.mock(
            assert_all_called=False,
            assert_all_mocked=True,
    ) as respx_mock:
        if is_legacy:
            service_details = RunningDynamicServiceDetails.parse_obj(
                RunningDynamicServiceDetails.Config.schema_extra["examples"]
                [0])
            respx_mock.post(
                f"{service_details.legacy_service_url}/retrieve",
                name="retrieve").respond(json=RetrieveDataOutEnveloped.Config.
                                         schema_extra["examples"][0])

            yield respx_mock
            # no cleanup required
        else:
            dynamic_sidecar_scheduler = minimal_app.state.dynamic_sidecar_scheduler
            node_uuid = UUID(service["node_uuid"])
            serice_name = "serice_name"

            # pylint: disable=protected-access
            dynamic_sidecar_scheduler._inverse_search_mapping[
                node_uuid] = serice_name
            dynamic_sidecar_scheduler._to_observe[serice_name] = Namespace(
                scheduler_data=scheduler_data_from_http_request)

            respx_mock.post(
                f"{scheduler_data_from_http_request.dynamic_sidecar.endpoint}/v1/containers/ports/inputs:pull",
                name="service_pull_input_ports",
            ).respond(json=42)

            yield respx_mock

            dynamic_sidecar_scheduler._inverse_search_mapping.pop(node_uuid)
            dynamic_sidecar_scheduler._to_observe.pop(serice_name)
Exemple #6
0
async def test_get_stack_status_report_missing_statuses(
    scheduler: DynamicSidecarsScheduler,
    scheduler_data: SchedulerData,
    mock_service_running: AsyncMock,
    docker_swarm: None,
    mocked_dynamic_scheduler_events: None,
) -> None:
    async with _assert_get_dynamic_services_mocked(
            scheduler,
            scheduler_data,
            mock_service_running,
            expected_response=httpx.HTTPError("Mock raised error"),
    ) as stack_status:
        assert stack_status == RunningDynamicServiceDetails.from_scheduler_data(
            node_uuid=scheduler_data.node_uuid,
            scheduler_data=scheduler_data,
            service_state=ServiceState.STARTING,
            service_message=
            "There was an error while trying to fetch the stautes form the contianers",
        )
Exemple #7
0
def mocked_director_service_fcts(
    minimal_app: FastAPI,
    mock_service_key_version: ServiceKeyVersion,
    fake_service_details: ServiceDockerData,
    fake_service_extras: ServiceExtras,
    fake_service_labels: Dict[str, Any],
    fake_running_service_details: RunningDynamicServiceDetails,
):
    with respx.mock(
            base_url=minimal_app.state.settings.DIRECTOR_V0.endpoint,
            assert_all_called=False,
            assert_all_mocked=True,
    ) as respx_mock:
        quoted_key = urllib.parse.quote_plus(mock_service_key_version.key)
        version = mock_service_key_version.version

        respx_mock.get(
            f"/services/{quoted_key}/{version}",
            name="get_service_version").respond(
                json={"data": [fake_service_details.dict(by_alias=True)]})

        respx_mock.get(
            f"/service_extras/{quoted_key}/{version}",
            name="get_service_extras").respond(
                json={"data": fake_service_extras.dict(by_alias=True)})

        respx_mock.get(f"/services/{quoted_key}/{version}/labels",
                       name="get_service_labels").respond(
                           json={"data": fake_service_labels})

        respx_mock.get(
            re.compile(
                r"running_interactive_services/[0-9a-fA-F]{8}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{12}$"
            ),
            name="get_running_service_details",
        ).respond(json={
            "data":
            json.loads(fake_running_service_details.json(by_alias=True))
        })

        yield respx_mock
def test_regression_legacy_service_compatibility() -> None:
    api_response = {
        "published_port": None,
        "entry_point": "",
        "service_uuid": "e5aa2f7a-eac4-4522-bd4f-270b5d8d9fff",
        "service_key": "simcore/services/dynamic/mocked",
        "service_version": "1.6.10",
        "service_host": "mocked_e5aa2f7a-eac4-4522-bd4f-270b5d8d9fff",
        "service_port": 8888,
        "service_basepath": "/x/e5aa2f7a-eac4-4522-bd4f-270b5d8d9fff",
        "service_state": "running",
        "service_message": "",
        "user_id": "1",
        "project_id": "b1ec5c8e-f5bb-11eb-b1d5-02420a000006",
    }
    service_details = RunningDynamicServiceDetails.parse_obj(api_response)

    assert service_details

    service_url = f"http://{service_details.host}:{service_details.internal_port}{service_details.basepath}"
    assert service_url == service_details.legacy_service_url
Exemple #9
0
async def test_get_stack_status_ok(
    loop: asyncio.AbstractEventLoop,
    scheduler: DynamicSidecarsScheduler,
    scheduler_data: SchedulerData,
    mock_service_running: AsyncMock,
    docker_swarm: None,
    mocked_dynamic_scheduler_events: None,
) -> None:
    async with _assert_get_dynamic_services_mocked(
            scheduler,
            scheduler_data,
            mock_service_running,
            expected_response=httpx.Response(
                200, json={"fake_entry": {
                    "Status": "running"
                }}),
    ) as stack_status:
        assert stack_status == RunningDynamicServiceDetails.from_scheduler_data(
            node_uuid=scheduler_data.node_uuid,
            scheduler_data=scheduler_data,
            service_state=ServiceState.RUNNING,
            service_message="",
        )
    def get_stack_status(node_uuid: NodeID) -> RunningDynamicServiceDetails:
        if exp_status_code == status.HTTP_307_TEMPORARY_REDIRECT:
            raise DynamicSidecarNotFoundError(node_uuid)

        return RunningDynamicServiceDetails.parse_obj(
            RunningDynamicServiceDetails.Config.schema_extra["examples"][0])
Exemple #11
0
def fake_running_service_details() -> RunningDynamicServiceDetails:
    sample_data = choice(
        RunningDynamicServiceDetails.Config.schema_extra["examples"])
    return RunningDynamicServiceDetails(**sample_data)