Skip to content

Commit

Permalink
Merge pull request #10 from bento-platform/chore/tests
Browse files Browse the repository at this point in the history
chore: tests
  • Loading branch information
v-rocheleau authored Nov 25, 2024
2 parents 0e62475 + b89c424 commit 3508a04
Show file tree
Hide file tree
Showing 22 changed files with 40,280 additions and 30 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Test

on:
push:
branches:
- main
pull_request:

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.10", "3.12" ]
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Tweak Postgres
run: |
docker exec ${{ job.services.postgres.id }} sh -c 'echo "max_connections=200" >> /var/lib/postgresql/data/postgresql.conf'
docker kill --signal=SIGHUP ${{ job.services.postgres.id }}
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
name: Set up Python
with:
python-version: ${{ matrix.python-version }}
- name: Install poetry
run: pip install poetry
- name: Install dependencies
run: poetry install
- name: Setup authz plugin
run: |
mkdir lib
cp authz_plugins/api_key/authz.module.py lib/
cp authz_plugins/api_key/example.env lib/.env
- name: Test
run: |
export DATABASE_URI="postgres://postgres:postgres@localhost:5432/postgres"
poetry run pytest -svv --cov=transcriptomics_data_service --cov-branch --cov-report xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
5 changes: 1 addition & 4 deletions authz_plugins/api_key/authz.module.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from logging import Logger
from typing import Annotated, Any, Awaitable, Callable, Coroutine, Sequence
from fastapi import Depends, FastAPI, HTTPException, Header, Request, Response
from fastapi import Depends, HTTPException, Header, Request, Response
from fastapi.responses import JSONResponse

from transcriptomics_data_service.authz.middleware_base import BaseAuthzMiddleware
Expand Down Expand Up @@ -40,9 +40,6 @@ def __init__(self, config: Config, logger: Logger) -> None:

# Middleware lifecycle

def attach(self, app: FastAPI):
app.middleware("http")(self.dispatch)

async def dispatch(
self, request: Request, call_next: Callable[[Request], Awaitable[Response]]
) -> Coroutine[Any, Any, Response]:
Expand Down
33 changes: 33 additions & 0 deletions docker-compose.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Standalone docker-compose file to run local tests using the PG database

services:
tds:
build:
context: .
dockerfile: ./dev.Dockerfile
container_name: tds
depends_on:
- tds-db
environment:
- BENTO_UID=${UID}
- DATABASE_URI=postgres://tds_user:tds_password@tds-db:5432/tds_db
- CORS_ORIGINS="*"
- BENTO_AUTHZ_SERVICE_URL=""
volumes:
# Mounts local repository
- $PWD:/tds
# Use API key plugin for authz testing
- $PWD/authz_plugins/api_key:/tds/lib
- $PWD/authz_plugins/api_key/example.env:/tds/lib/.env # map example.env to .env
ports:
- "5000:5000"

tds-db:
image: postgres:16
container_name: tds-db
environment:
- POSTGRES_USER=tds_user
- POSTGRES_PASSWORD=tds_password
- POSTGRES_DB=tds_db
expose:
- 5432
16 changes: 16 additions & 0 deletions test-docker.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
export UID=$(id -u)

docker compose -f docker-compose.test.yaml down
docker compose -f docker-compose.test.yaml up -d --build --wait

docker exec tds /bin/bash -c "
cd /tds &&
/poetry_user_install_dev.bash &&
pytest -svv --cov=transcriptomics_data_service --cov-branch &&
coverage html
"

docker compose -f docker-compose.test.yaml down

docker rmi transcriptomics_data_service-tds:latest
75 changes: 75 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from typing import AsyncGenerator
import asyncpg
from fastapi.testclient import TestClient
import pytest
import os
import pytest_asyncio
from httpx._types import HeaderTypes

from tests.test_db import TEST_EXPERIMENT_RESULT
from transcriptomics_data_service.db import Database, get_db
from transcriptomics_data_service.logger import get_logger

os.environ["BENTO_DEBUG"] = "true"
os.environ["BENTO_VALIDATE_SSL"] = "false"
os.environ["CORS_ORIGINS"] = "*"
os.environ["BENTO_AUTHZ_SERVICE_URL"] = "https://authz.local"

from transcriptomics_data_service.config import Config, get_config
from transcriptomics_data_service.main import app


@pytest.fixture
def config() -> Config:
return get_config()


async def get_test_db() -> AsyncGenerator[Database, None]:
config = get_config()
db = Database(config, get_logger(config))
await db.initialize(pool_size=1)
yield db


db_fixture = pytest_asyncio.fixture(get_test_db, name="db")


@pytest_asyncio.fixture
async def db_cleanup(db: Database):
yield
conn: asyncpg.Connection
async with db.connect() as conn:
await conn.execute(
"""
DROP TABLE IF EXISTS gene_expressions;
DROP TABLE IF EXISTS experiment_results;
DROP INDEX IF EXISTS idx_gene_code;
DROP INDEX IF EXISTS idx_sample_id;
DROP INDEX IF EXISTS idx_experiment_result_id;
"""
)
await db.close()


@pytest_asyncio.fixture
async def db_with_experiment(db: Database):
await db.create_experiment_result(TEST_EXPERIMENT_RESULT)


@pytest.fixture
def test_client(db: Database):
with TestClient(app) as client:
app.dependency_overrides[get_db] = get_test_db
yield client


@pytest.fixture
def authz_headers(config) -> HeaderTypes:
api_key = config.model_extra.get("api_key")
return {"x-api-key": api_key}


@pytest.fixture
def authz_headers_bad() -> HeaderTypes:
return {"x-api-key": "bad key"}
Loading

0 comments on commit 3508a04

Please sign in to comment.