Skip to content

Commit

Permalink
Update to use new pytest marker for mocked hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
CasperWA committed Nov 4, 2024
1 parent 3ead3e0 commit 5e9ae5a
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 53 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
ENTITIES_SERVICE_CA_FILE: docker_security/test-ca.pem
# These are used in the Dockerfile as well as in pytest
ENTITIES_SERVICE_HOST: localhost
ENTITIES_SERVICE_PORT: 8000
ENTITIES_SERVICE_PORT: 7000

steps:
- name: Checkout ${{ github.repository }}
Expand Down Expand Up @@ -136,7 +136,6 @@ jobs:
--env ENTITIES_SERVICE_MONGO_URI \
--env ENTITIES_SERVICE_X509_CERTIFICATE_FILE \
--env ENTITIES_SERVICE_CA_FILE \
--env PORT=${ENTITIES_SERVICE_PORT} \
--name "entities-service" \
--network "host" \
--volume "${PWD}:/app" \
Expand Down
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ RUN python -m pip install -U pip && \
pip install -U setuptools wheel && \
pip install -U -e .[server]

ENV PORT=80
EXPOSE ${PORT}

ENTRYPOINT [ "gunicorn", "entities_service.main:APP", "--bind=0.0.0.0:${PORT}", "--workers=1", "--worker-class=entities_service.uvicorn.UvicornWorker" ]
EXPOSE 7000
ENTRYPOINT [ "gunicorn", "entities_service.main:APP", "--bind=0.0.0.0:7000", "--workers=1", "--worker-class=entities_service.uvicorn.UvicornWorker" ]

ARG CI=0
RUN --mount=type=bind,source=.github/utils/requirements.txt,target=/tmp/requirements_ci.txt \
Expand Down
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ ENTITIES_SERVICE_MONGO_PASSWORD=<your MongoDB Atlas user's password with read-on
Run the service:
```shell
uvicorn entities_service.main:APP --host localhost --port 8000 --no-server-header --header "Server:EntitiesService"
uvicorn entities_service.main:APP --host localhost --port 7000 --no-server-header --header "Server:EntitiesService"
```
Finally, go to [localhost:8000/docs](http://localhost:8000/docs) and try out retrieving an entity.
Finally, go to [localhost:7000/docs](http://localhost:7000/docs) and try out retrieving an entity.
`--log-level debug` can be added to the `uvicorn` command to get more verbose logging.
`--reload` can be added to the `uvicorn` command to enable auto-reloading of the service when any files are changed.
Expand Down Expand Up @@ -102,13 +102,13 @@ docker run --rm -d \
--env "ENTITIES_SERVICE_CA_FILE=docker_security/test-ca.pem" \
--name "entities-service" \
-u "${id -ur}:${id -gr}" \
-p "8000:80" \
-p "7000:7000" \
entities-service
```
Now, fill up the MongoDB with valid entities at the `entities_service` database in the `entities` collection.
Then go to [localhost:8000/docs](http://localhost:8000/docs) and try out retrieving an entity.
Then go to [localhost:7000/docs](http://localhost:7000/docs) and try out retrieving an entity.
---
Expand All @@ -129,8 +129,6 @@ By default the `development` target will be built, to change this, set the `ENTI
ENTITIES_SERVICE_DOCKER_TARGET=production docker compose --env-file=.env up --build
```
Furthermore, the used `localhost` port can be changed via the `PORT` environment variable.
The `--env-file` argument is optional, but if used, it should point to a file containing the environment variables needed by the service.
See the section on [using a file for environment variables](#using-a-file-for-environment-variables) for more information.
Expand Down Expand Up @@ -239,13 +237,13 @@ To test uploading entities using the CLI, one must note that validation of the e
The validation that is most tricky when testing locally is the namespace validation, as the service will validate the namespace against the `ENTITIES_SERVICE_BASE_URL` environment variable set when starting the service, which defaults to `http://onto-ns.com/meta`.
However, if using this namespace in the CLI, the CLI will connect to the publicly running service at `http://onto-ns.com/meta`, which will not work when testing locally.
So to make all this work together, one should start the service with the `ENTITIES_SERVICE_BASE_URL` environment variable set to `http://localhost:8000` (which is done through the locally available environment variable `ENTITIES_SERVICE_HOST`), and then use the CLI to upload entities to the service running at `http://localhost:8000`.
So to make all this work together, one should start the service with the `ENTITIES_SERVICE_BASE_URL` environment variable set to `http://localhost:7000` (which is done through the locally available environment variable `ENTITIES_SERVICE_HOST`), and then use the CLI to upload entities to the service running at `http://localhost:7000`.
In practice, this will look like this:
```shell
# Set the relevant environment variables
export ENTITIES_SERVICE_BASE_URL=http://localhost:8000
export ENTITIES_SERVICE_BASE_URL=http://localhost:7000
export ENTITIES_SERVICE_HOST=${ENTITIES_SERVICE_BASE_URL}
# Start the service
Expand All @@ -255,7 +253,7 @@ docker compose up -d
entities-service upload my_entities.yaml --format=yaml
```
The `my_entities.yaml` file should contain one or more entities with `uri` values of the form `http://localhost:8000/...`.
The `my_entities.yaml` file should contain one or more entities with `uri` values of the form `http://localhost:7000/...`.
### Extra pytest markers
Expand Down
9 changes: 2 additions & 7 deletions docker-compose.yml → compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
context: "."
target: "${ENTITIES_SERVICE_DOCKER_TARGET:-development}"
ports:
- "${ENTITIES_SERVICE_PORT:-8000}:80"
- "${ENTITIES_SERVICE_PORT:-7000}:7000"
environment:
ENTITIES_SERVICE_BASE_URL: "${ENTITIES_SERVICE_HOST:-http://onto-ns.com/meta}"
ENTITIES_SERVICE_BACKEND: mongodb
Expand All @@ -28,14 +28,9 @@ services:
image: mongo:8
restart: always
ports:
- "${MONGO_PORT:-27017}:27017"
environment:
IN_DOCKER: "true"
HOST_USER: "${USER}"
- "27017:27017"
networks:
- entities_service_net
expose:
- 27017
volumes:
- "./.github/docker_init/create_x509_user.js:/docker-entrypoint-initdb.d/0_create_x509_user.js"
- "./docker_security:/mongo_tls"
Expand Down
2 changes: 1 addition & 1 deletion docs/example/dlite_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
" - Local `entities_service` package.\n",
" - `requests`\n",
" - `DLite-Python`\n",
"- Running Entities Service at `http://localhost:8000` setup to connect to SOFT Cluster on MongoDB Atlas."
"- Running Entities Service at `http://localhost:7000` setup to connect to SOFT Cluster on MongoDB Atlas."
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/example/dlite_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def get_instance(uri: str) -> Instance:
uri = uri.replace("http://onto-ns.com/meta", "http://localhost:8000")
uri = uri.replace("http://onto-ns.com/meta", "http://localhost:7000")
response = requests.get(uri)
if not response.ok:
error_message = (
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/commands/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def _mock_config_base_url(monkeypatch: pytest.MonkeyPatch, live_backend: bool) -
from pydantic import AnyHttpUrl

host, port = os.getenv("ENTITIES_SERVICE_HOST", "localhost"), os.getenv(
"ENTITIES_SERVICE_PORT", "8000"
"ENTITIES_SERVICE_PORT", "7000"
)

live_base_url = f"http://{host}"
Expand Down
38 changes: 10 additions & 28 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from typing import Any, Literal, Protocol, TypedDict

from fastapi.testclient import TestClient
from httpx import Client
from httpx import Client, Request
from pytest_httpx import HTTPXMock

from entities_service.service.backend.mongodb import MongoDBBackend
Expand Down Expand Up @@ -124,13 +124,9 @@ def pytest_collection_modifyitems(
"""Called after collection has been performed. May filter or re-order the items
in-place."""
if config.getoption("--live-backend"):
import os

from entities_service.service.config import CONFIG

# If the tests are run with a live backend, do the following:
# - skip the tests marked with 'skip_if_live_backend'
# - add non-mocked hosts list to the httpx_mock marker
# - add list of hosts to be mocked to the httpx_mock marker
# (if the tests are from the cli.commands module)
prefix_reason = "Live backend used: {reason}"
default_reason = "Test is skipped when using a live backend"
Expand Down Expand Up @@ -165,37 +161,23 @@ def pytest_collection_modifyitems(
if "cli/commands/" not in str(item.path):
continue

host, port = os.getenv("ENTITIES_SERVICE_HOST", "localhost"), os.getenv(
"ENTITIES_SERVICE_PORT", "8000"
)

localhost = f"localhost:{port}" if port else "localhost"
non_mocked_hosts = [localhost, host]

if (
CONFIG.base_url.host
and CONFIG.base_url.host not in non_mocked_hosts
and CONFIG.base_url.host not in ("onto-ns.com", "www.onto-ns.com")
):
non_mocked_hosts.append(CONFIG.base_url.host)
def _mock_hosts(request: Request) -> bool:
"""Mock the hosts."""
return request.url.host in ["onto-ns.com", "www.onto-ns.com"]

# Handle the case of the httpx_mock marker already being present
if "httpx_mock" in item.keywords:
marker: pytest.Mark = item.keywords["httpx_mock"]

# The marker already has non-mocked hosts - ignore
if "non_mocked_hosts" in marker.kwargs:
# The marker already has should mock hosts - ignore
if "should_mock" in marker.kwargs:
continue

# Add the non-mocked hosts to the marker
item.add_marker(
pytest.mark.httpx_mock(non_mocked_hosts=non_mocked_hosts)
)
item.add_marker(pytest.mark.httpx_mock(should_mock=_mock_hosts))
else:
# Add the httpx_mock marker with the non-mocked hosts
item.add_marker(
pytest.mark.httpx_mock(non_mocked_hosts=non_mocked_hosts)
)
item.add_marker(pytest.mark.httpx_mock(should_mock=_mock_hosts))
else:
# If the tests are run with the mock backend, skip the tests marked with
# 'skip_if_not_live_backend'
Expand Down Expand Up @@ -864,7 +846,7 @@ def _client(
)

host, port = os.getenv("ENTITIES_SERVICE_HOST", "localhost"), os.getenv(
"ENTITIES_SERVICE_PORT", "8000"
"ENTITIES_SERVICE_PORT", "7000"
)

base_url = f"http://{host}"
Expand Down

0 comments on commit 5e9ae5a

Please sign in to comment.