Skip to content

Commit

Permalink
Merge pull request #188 from stac-utils/patch/switch-to-pytest-postgr…
Browse files Browse the repository at this point in the history
…esql

switch to pytest-postgresql
  • Loading branch information
vincentsarago authored Sep 3, 2024
2 parents a2280a9 + fbad9b6 commit ba3c3fe
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 39 deletions.
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ test = [
"pytest-asyncio",
"httpx",
"pypgstac>=0.7,<=0.9.1",
"psycopg2",
"pytest-pgsql",
"pytest-postgresql",
]

[project.urls]
Expand Down
79 changes: 44 additions & 35 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import os
import warnings
from typing import Any, Dict
from urllib.parse import quote_plus as quote

import psycopg
import pytest
import pytest_pgsql
import rasterio
from pypgstac.db import PgstacDB
from pypgstac.load import Loader
from pypgstac.migrate import Migrate
from pytest_postgresql.janitor import DatabaseJanitor
from rasterio.errors import NotGeoreferencedWarning
from rasterio.io import MemoryFile
from starlette.testclient import TestClient
Expand All @@ -20,10 +21,6 @@
collection_maxar = os.path.join(DATA_DIR, "maxar_BayOfBengal.json")
items = os.path.join(DATA_DIR, "noaa-eri-nashville2020.json")

test_db = pytest_pgsql.TransactedPostgreSQLTestDB.create_fixture(
"test_db", scope="session", use_restore_state=False
)


def parse_img(content: bytes) -> Dict[Any, Any]:
"""Read tile image and return metadata."""
Expand Down Expand Up @@ -51,42 +48,52 @@ def mock_rasterio_open(asset):


@pytest.fixture(scope="session")
def database_url(test_db):
"""
Session scoped fixture to launch a postgresql database in a separate process. We use psycopg2 to ingest test data
because pytest-asyncio event loop is a function scoped fixture and cannot be called within the current scope. Yields
a database url which we pass to our application through a monkeypatched environment variable.
"""
with PgstacDB(dsn=str(test_db.connection.engine.url)) as db:
def database(postgresql_proc):
"""Create Database fixture."""
with DatabaseJanitor(
user=postgresql_proc.user,
host=postgresql_proc.host,
port=postgresql_proc.port,
dbname="pgstacrw",
version=postgresql_proc.version,
password="a2Vw:yk=)CdSis[fek]tW=/o",
) as jan:
connection = f"postgresql://{jan.user}:{quote(jan.password)}@{jan.host}:{jan.port}/{jan.dbname}"

# make sure the DB is set to use UTC
with psycopg.connect(connection) as conn:
with conn.cursor() as cur:
cur.execute(f"ALTER DATABASE {jan.dbname} SET TIMEZONE='UTC';")

print("Running to PgSTAC migration...")
migrator = Migrate(db)
version = migrator.run_migration()
assert version
assert test_db.has_schema("pgstac")
print(f"PgSTAC version: {version}")
with PgstacDB(dsn=connection) as db:
migrator = Migrate(db)
version = migrator.run_migration()
assert version
print(f"PgSTAC version: {version}")

print("Load items and collection into PgSTAC")
loader = Loader(db=db)
loader.load_collections(collection)
loader.load_collections(collection_maxar)
loader.load_items(items)
print("Load items and collection into PgSTAC")
loader = Loader(db=db)
loader.load_collections(collection)
loader.load_collections(collection_maxar)
loader.load_items(items)

# Make sure we have 1 collection and 163 items in pgstac
with psycopg.connect(str(test_db.connection.engine.url)) as conn:
with conn.cursor() as cur:
cur.execute("SELECT COUNT(*) FROM pgstac.collections")
val = cur.fetchone()[0]
assert val == 2
# Make sure we have 1 collection and 163 items in pgstac
with psycopg.connect(connection) as conn:
with conn.cursor() as cur:
cur.execute("SELECT COUNT(*) FROM pgstac.collections")
val = cur.fetchone()[0]
assert val == 2

cur.execute("SELECT COUNT(*) FROM pgstac.items")
val = cur.fetchone()[0]
assert val == 163
cur.execute("SELECT COUNT(*) FROM pgstac.items")
val = cur.fetchone()[0]
assert val == 163

return test_db.connection.engine.url
yield jan


@pytest.fixture(autouse=True)
def app(database_url, monkeypatch):
def app(database, monkeypatch):
"""Create app with connection to the pytest database."""
monkeypatch.setenv("AWS_ACCESS_KEY_ID", "jqt")
monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "rde")
Expand All @@ -97,8 +104,10 @@ def app(database_url, monkeypatch):
monkeypatch.setenv("TITILER_PGSTAC_API_DEBUG", "TRUE")
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS", "TRUE")
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS", "TRUE")

monkeypatch.setenv("DATABASE_URL", str(database_url))
monkeypatch.setenv(
"DATABASE_URL",
f"postgresql://{database.user}:{quote(database.password)}@{database.host}:{database.port}/{database.dbname}",
)

from titiler.pgstac.main import app

Expand Down
5 changes: 3 additions & 2 deletions titiler/pgstac/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from functools import lru_cache
from typing import Any, Optional, Set
from urllib.parse import quote_plus as quote

from pydantic import (
Field,
Expand Down Expand Up @@ -83,8 +84,8 @@ def assemble_db_connection(cls, v: Optional[str], info: ValidationInfo) -> Any:

return PostgresDsn.build(
scheme="postgresql",
username=info.data.get("postgres_user"),
password=info.data.get("postgres_pass"),
username=info.data["postgres_user"],
password=quote(info.data["postgres_pass"]),
host=info.data.get("postgres_host", ""),
port=info.data.get("postgres_port", 5432),
path=info.data.get("postgres_dbname", ""),
Expand Down

0 comments on commit ba3c3fe

Please sign in to comment.