async def client(
    request: pytest.FixtureRequest,
) -> AsyncGenerator[httpx.AsyncClient, None]:
    marker = request.node.get_closest_marker("fastapi")
    if marker is None:
        raise ValueError("client fixture: the marker fastapi must be provided")
    try:
        app = marker.kwargs["app"]
    except KeyError:
        raise ValueError(
            "client fixture: keyword argument app must be provided in the marker"
        )
    if not isinstance(app, FastAPI):
        raise ValueError("client fixture: app must be a FastAPI instance")

    dependency_overrides = marker.kwargs.get("dependency_overrides")
    if dependency_overrides:
        if not isinstance(dependency_overrides, dict):
            raise ValueError(
                "client fixture: dependency_overrides must be a dictionary"
            )
        app.dependency_overrides = dependency_overrides

    run_lifespan_events = marker.kwargs.get("run_lifespan_events", True)
    if not isinstance(run_lifespan_events, bool):
        raise ValueError("client fixture: run_lifespan_events must be a bool")

    test_client_generator = httpx.AsyncClient(app=app, base_url="http://app.io")
    if run_lifespan_events:
        async with LifespanManager(app):
            async with test_client_generator as test_client:
                yield test_client
    else:
        async with test_client_generator as test_client:
            yield test_client
Пример #2
0
async def client(app: FastAPI) -> AsyncClient:
    async with LifespanManager(app):
        async with AsyncClient(app=app,
                               base_url='http://testserver',
                               headers={'Content-type':
                                        'application/json'}) as client:
            yield client
Пример #3
0
async def app():
    async def startup():
        print("Starting up")

    async def shutdown():
        print("Shutting down")

    async def home(request):
        return PlainTextResponse("Hello, world!")

    async def endless(req: Request):
        async def event_publisher():
            i = 0
            try:
                while True:  # i <= 20:
                    # yield dict(id=..., event=..., data=...)
                    i += 1
                    yield dict(data=i)
                    await asyncio.sleep(0.3)
            except asyncio.CancelledError as e:
                _log.info(f"Disconnected from client (via refresh/close) {req.client}")
                # Do any other cleanup, if any
                raise e

        return EventSourceResponse(event_publisher())

    app = Starlette(
        routes=[Route("/", home), Route("/endless", endpoint=endless)],
        on_startup=[startup],
        on_shutdown=[shutdown],
    )

    async with LifespanManager(app):
        print("We're in!")
        yield app
Пример #4
0
async def director_v2_client(
    minimal_configuration: None,
    loop: asyncio.BaseEventLoop,
    mock_env: None,
    network_name: str,
    monkeypatch,
) -> httpx.AsyncClient:
    monkeypatch.setenv("SC_BOOT_MODE", "production")
    monkeypatch.setenv("DYNAMIC_SIDECAR_EXPOSE_PORT", "true")
    monkeypatch.setenv("SIMCORE_SERVICES_NETWORK_NAME", network_name)
    monkeypatch.delenv("DYNAMIC_SIDECAR_MOUNT_PATH_DEV", raising=False)
    monkeypatch.setenv("DIRECTOR_V2_DYNAMIC_SCHEDULER_ENABLED", "true")

    monkeypatch.setenv("DIRECTOR_V2_CELERY_SCHEDULER_ENABLED", "false")
    monkeypatch.setenv("DIRECTOR_V2_DASK_CLIENT_ENABLED", "false")
    monkeypatch.setenv("DIRECTOR_V2_DASK_SCHEDULER_ENABLED", "false")
    monkeypatch.setenv("POSTGRES_HOST", "mocked_host")
    monkeypatch.setenv("POSTGRES_USER", "mocked_user")
    monkeypatch.setenv("POSTGRES_PASSWORD", "mocked_password")
    monkeypatch.setenv("POSTGRES_DB", "mocked_db")
    monkeypatch.setenv("DIRECTOR_V2_POSTGRES_ENABLED", "false")

    settings = AppSettings.create_from_envs()

    app = init_app(settings)

    async with LifespanManager(app):
        async with httpx.AsyncClient(
                app=app, base_url="http://testserver/v2") as client:
            yield client
Пример #5
0
async def client(app: FastAPI) -> AsyncClient:
    async with LifespanManager(app):
        async with AsyncClient(app=app,
                               base_url="http://testserver",
                               headers={"Content-Type":
                                        "application/json"}) as client:
            yield client
Пример #6
0
async def test_client_some_sensitive(app_generator,
                                     some_sensitive_csrfmiddleware):
    app = app_generator(some_sensitive_csrfmiddleware)
    async with LifespanManager(app):
        async with httpx.AsyncClient(app=app,
                                     base_url="http://app.io") as test_client:
            yield test_client
Пример #7
0
async def app():
    from demo import app

    from fastapi_slack import with_valid_signature

    async with LifespanManager(app):
        app.dependency_overrides[with_valid_signature] = lambda: "signature"
        yield app
Пример #8
0
async def client(app):

    async with LifespanManager(app):
        transport = httpx.ASGITransport(app=app, raise_app_exceptions=False)
        async with httpx.AsyncClient(
                transport=transport,
                base_url="http://example.local") as client:
            yield client
Пример #9
0
async def client():
    # httpx client does not trigger lifespan events on it's own
    # https://github.com/encode/httpx/issues/350
    async with LifespanManager(app):
        async with AsyncClient(app=app,
                               base_url="http://testserver") as test_client:
            test_client.app = app
            yield test_client
Пример #10
0
async def app() -> AsyncIterator[FastAPI]:
    """Return a configured test application.

    Wraps the application in a lifespan manager so that startup and shutdown
    events are sent during test execution.
    """
    async with LifespanManager(main.app):
        yield main.app
Пример #11
0
async def test_01_general(mock_env):
    fake_args = mock.MagicMock()
    fake_args.daemonize = True
    fake_args.bucket = 'test_bucket'
    assert not APP
    run_main(TestBackup, args=fake_args)
    assert BS
    assert not BS.monitoring
    async with LifespanManager(APP):
        assert BS.monitoring
Пример #12
0
async def client() -> Generator:
    """Async client with db connection."""
    nest_asyncio.apply()
    initializer(modules=APP_MODELS)
    app = create_application()
    async with AsyncClient(
            app=app,
            base_url="https://testserver") as test_client, LifespanManager(
                app):
        yield test_client
    finalizer()
Пример #13
0
async def async_client(override_get_db: Callable) -> AsyncGenerator:
    """Create test client to be used to test api endpoints"""
    from app.db.session import get_db
    from app.main import app

    app.dependency_overrides[get_db] = override_get_db

    async with LifespanManager(app):
        async with AsyncClient(app=app,
                               base_url="http://testserver") as client:
            yield client
Пример #14
0
async def initialized_app(monkeypatch: MonkeyPatch) -> Iterator[FastAPI]:
    monkeypatch.setenv("DYNAMIC_SIDECAR_IMAGE",
                       "itisfoundation/dynamic-sidecar:MOCK")
    monkeypatch.setenv("SIMCORE_SERVICES_NETWORK_NAME", "test_network_name")
    monkeypatch.setenv("TRAEFIK_SIMCORE_ZONE", "test_traefik_zone")
    monkeypatch.setenv("SWARM_STACK_NAME", "test_swarm_name")
    monkeypatch.setenv("DIRECTOR_V2_DYNAMIC_SCHEDULER_ENABLED", "false")
    monkeypatch.setenv("SC_BOOT_MODE", "production")

    settings = AppSettings.create_from_envs()
    app = init_app(settings)
    async with LifespanManager(app):
        yield app
Пример #15
0
async def client(app: FastAPI) -> Client:
    async with LifespanManager(app):
        app.state.pool = await FakePool.create_pool(app.state.pool)
        connection: Connection
        async with app.state.pool.acquire() as connection:
            transaction: Transaction = connection.transaction()
            await transaction.start()
            async with Client(
                    app=app,
                    base_url="http://testserver",
                    headers={"Content-Type": "application/json"},
            ) as client:
                yield client
            await transaction.rollback()
        await app.state.pool.close()
Пример #16
0
async def app(
    mock_kubernetes: MockKubernetesApi, podinfo: Path
) -> AsyncIterator[FastAPI]:
    """Return a configured test application.

    Wraps the application in a lifespan manager so that startup and shutdown
    events are sent during test execution.
    """
    assets_path = Path(__file__).parent / "_assets"
    config.m_config_path = str(assets_path / "m.yaml")
    config.quips = str(assets_path / "quips.txt")
    config.moneypenny_timeout = 5
    async with LifespanManager(main.app):
        await moneypenny_dependency.clear_state()
        yield main.app
async def director_v2_client(
    minimal_configuration: None,
    network_name: str,
    monkeypatch,
) -> AsyncIterable[httpx.AsyncClient]:
    # Works as below line in docker.compose.yml
    # ${DOCKER_REGISTRY:-itisfoundation}/dynamic-sidecar:${DOCKER_IMAGE_TAG:-latest}

    registry = os.environ.get("DOCKER_REGISTRY", "local")
    image_tag = os.environ.get("DOCKER_IMAGE_TAG", "production")

    image_name = f"{registry}/dynamic-sidecar:{image_tag}"

    logger.warning("Patching to: DYNAMIC_SIDECAR_IMAGE=%s", image_name)
    monkeypatch.setenv("DYNAMIC_SIDECAR_IMAGE", image_name)
    monkeypatch.setenv("TRAEFIK_SIMCORE_ZONE", "test_traefik_zone")
    monkeypatch.setenv("SWARM_STACK_NAME", "test_swarm_name")

    monkeypatch.setenv("SC_BOOT_MODE", "production")
    monkeypatch.setenv("DYNAMIC_SIDECAR_EXPOSE_PORT", "true")
    monkeypatch.setenv("PROXY_EXPOSE_PORT", "true")
    monkeypatch.setenv("SIMCORE_SERVICES_NETWORK_NAME", network_name)
    monkeypatch.delenv("DYNAMIC_SIDECAR_MOUNT_PATH_DEV", raising=False)
    monkeypatch.setenv("DIRECTOR_V2_DYNAMIC_SCHEDULER_ENABLED", "true")

    monkeypatch.setenv("DIRECTOR_V2_DASK_CLIENT_ENABLED", "false")
    monkeypatch.setenv("DIRECTOR_V2_DASK_SCHEDULER_ENABLED", "false")
    monkeypatch.setenv("POSTGRES_HOST", "mocked_host")
    monkeypatch.setenv("POSTGRES_USER", "mocked_user")
    monkeypatch.setenv("POSTGRES_PASSWORD", "mocked_password")
    monkeypatch.setenv("POSTGRES_DB", "mocked_db")
    monkeypatch.setenv("DIRECTOR_V2_POSTGRES_ENABLED", "false")
    monkeypatch.setenv("R_CLONE_S3_PROVIDER", "MINIO")

    # patch host for dynamic-sidecar, not reachable via localhost
    # the dynamic-sidecar (running inside a container) will use
    # this address to reach the rabbit service
    monkeypatch.setenv("RABBIT_HOST", f"{get_ip()}")

    settings = AppSettings.create_from_envs()

    app = init_app(settings)

    async with LifespanManager(app):
        async with httpx.AsyncClient(
            app=app, base_url="http://testserver/v2"
        ) as client:
            yield client
Пример #18
0
    async def create(cls, tmp_path: Path,
                     httpx_mock: HTTPXMock) -> AsyncIterator[SetupTest]:
        """Create a new `SetupTest` instance.

        This is the only supported way to set up the test environment and
        should be called instead of calling the constructor directly.  It
        initializes and starts the application and configures an
        `httpx.AsyncClient` to talk to it.  Whether to use a real PostgreSQL
        and Redis server or to use SQLite and mock Redis is determined by the
        environment variables set by ``tox``.

        Parameters
        ----------
        tmp_path : `pathlib.Path`
            The path for temporary files.
        httpx_mock : `pytest_httpx.HTTPXMock`
            The mock for simulating `httpx.AsyncClient` calls.
        """
        config = initialize(tmp_path)
        redis = await redis_dependency(config)

        # Create the database session that will be used by SetupTest and by
        # the factory it contains.  The application will use a separate
        # session handled by its middleware.
        connect_args = {}
        if urlparse(config.database_url).scheme == "sqlite":
            connect_args = {"check_same_thread": False}
        engine = create_engine(config.database_url, connect_args=connect_args)
        session = Session(bind=engine)

        # Build the SetupTest object inside all of the contexts required by
        # its components and handle clean shutdown.
        try:
            async with LifespanManager(app):
                base_url = f"https://{TEST_HOSTNAME}"
                async with AsyncClient(app=app, base_url=base_url) as client:
                    yield cls(
                        tmp_path=tmp_path,
                        httpx_mock=httpx_mock,
                        config=config,
                        redis=redis,
                        session=session,
                        client=client,
                    )
        finally:
            await redis_dependency.close()
            session.close()
Пример #19
0
async def app_for_httpx():
    app = Starlette(
        debug=settings.DEBUG,
        routes=routes,
        middleware=middleware,
        exception_handlers=exception_handlers,
    )

    register_tortoise(
        app,
        db_url=settings.DB_URL,
        modules={"models": ["models"]},
        generate_schemas=settings.GENERATE_SCHEMAS,
    )

    async with LifespanManager(app):
        yield app
Пример #20
0
async def _app():
    """Returns our ASGI app, that uses a temporary DB"""
    @app.on_event('startup')
    async def startup():
        db.conn.client = AsyncIOMotorClient(MONGO_URL)

    @app.on_event('shutdown')
    async def shutdown():
        db.conn.client.close()

    async def _get_test_db():
        return db.conn.client.test_db

    app.dependency_overrides[db.get_db] = _get_test_db

    async with LifespanManager(app):
        yield app
async def test_setup_client_instance():
    @dataclass
    class TheClientApi(BaseServiceClientApi):
        x: int = 33

    # setup app
    app = FastAPI()
    assert not TheClientApi.get_instance(app)

    setup_client_instance(
        app,
        api_cls=TheClientApi,
        api_baseurl="http://the_service",
        service_name="the_service",
        health_check_path="/health",
        x=42,
    )
    assert not TheClientApi.get_instance(app)

    # test startup/shutdown
    async with LifespanManager(app):

        # check startup
        assert TheClientApi.get_instance(app)
        api_obj = TheClientApi.get_instance(app)

        # test responsivity
        assert await api_obj.is_responsive() == False

        # now start the server
        with respx.mock(
                base_url="http://the_service",
                assert_all_mocked=True,
        ) as respx_mock:
            respx_mock.get("/health",
                           name="health_check").respond(200, content="healthy")
            # test responsitivity
            assert await api_obj.is_responsive()
            assert respx_mock["health_check"].called

            assert respx_mock["health_check"].call_count == 1

    # check shutdown
    assert not TheClientApi.get_instance(app), "Expected automatically cleaned"
Пример #22
0
async def client(
    request: pytest.FixtureRequest,
) -> AsyncGenerator[httpx.AsyncClient, None]:
    marker = request.node.get_closest_marker("fastapi")
    if marker is None:
        raise ValueError("client fixture: the marker fastapi must be provided")
    try:
        app = marker.kwargs["app"]
    except KeyError:
        raise ValueError(
            "client fixture: keyword argument app must be provided in the marker"
        )
    if not isinstance(app, FastAPI):
        raise ValueError("client fixture: app must be a FastAPI instance")

    async with LifespanManager(app):
        async with httpx.AsyncClient(app=app,
                                     base_url="http://app.io") as test_client:
            yield test_client
Пример #23
0
async def test_fastapi_integration():
    from fastapi_sqla import _Session, setup

    app = FastAPI()
    setup(app)

    @app.get("/one")
    def now():
        session = _Session()
        result = session.execute(text("SELECT 1")).scalar()
        session.close()
        return result

    async with LifespanManager(app):
        async with httpx.AsyncClient(
            app=app, base_url="http://example.local"
        ) as client:
            res = await client.get("/one")

    assert res.json() == 1
Пример #24
0
async def test_http_client(respx_mock: respx.Router) -> None:
    app = FastAPI()
    respx_mock.get("https://www.google.com").respond(200)

    @app.get("/")
    async def handler(
        http_client: AsyncClient = Depends(http_client_dependency),
    ) -> Dict[str, str]:
        assert isinstance(http_client, AsyncClient)
        await http_client.get("https://www.google.com")
        return {}

    @app.on_event("shutdown")
    async def shutdown_event() -> None:
        await http_client_dependency.aclose()

    async with LifespanManager(app):
        async with AsyncClient(app=app, base_url="http://example.com") as c:
            r = await c.get("/")
    assert r.status_code == 200
Пример #25
0
async def main(
    get_raw: bool = False,
    get_nice: bool = False,
    get_basic: bool = False,
    test: str | None = None,
) -> None:
    print("Saving test data ...")
    if not any([get_raw, get_nice, get_basic]):
        get_raw = get_nice = get_basic = True

    async with LifespanManager(app), AsyncClient(app=app, base_url="http://test") as ac:
        for to_download, query_data, endpoint, folder in (
            (get_raw, test_raw_data, "raw", "test_data_raw"),
            (get_nice, test_nice_data, "nice", "test_data_nice"),
            (get_basic, test_basic_data, "basic", "test_data_basic"),
        ):
            if to_download:
                if test and test in query_data:
                    query, file_name = query_data[test]
                    await save_test_data(ac, endpoint, query, folder, file_name)
                else:
                    for query, file_name in query_data.values():
                        await save_test_data(ac, endpoint, query, folder, file_name)
Пример #26
0
async def initialized_app(minimal_app: FastAPI) -> Iterator[FastAPI]:
    async with LifespanManager(minimal_app):
        yield minimal_app
Пример #27
0
async def client() -> AsyncGenerator[AsyncClient, None]:
    async with LifespanManager(app):
        async with AsyncClient(app=app, base_url="http://test") as ac:
            yield ac
Пример #28
0
async def app() -> typing.Generator[FastAPI, None, None]:
    app = FastAPI()
    async with LifespanManager(app):
        yield app
Пример #29
0
 async def _get_test_client(app: ASGIApp) -> AsyncGenerator[httpx.AsyncClient, None]:
     async with LifespanManager(app):
         async with httpx.AsyncClient(
             app=app, base_url="http://app.io"
         ) as test_client:
             yield test_client
Пример #30
0
async def admin_graphql_client():
    async with LifespanManager(app):
        async with AsyncClient(app=app,
                               base_url="http://testserver") as client:
            yield GraphQLClient(client, admin_endpoint=True)