Skip to content

Commit ba3c3fe

Browse files
Merge pull request #188 from stac-utils/patch/switch-to-pytest-postgresql
switch to pytest-postgresql
2 parents a2280a9 + fbad9b6 commit ba3c3fe

File tree

3 files changed

+48
-39
lines changed

3 files changed

+48
-39
lines changed

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ test = [
5757
"pytest-asyncio",
5858
"httpx",
5959
"pypgstac>=0.7,<=0.9.1",
60-
"psycopg2",
61-
"pytest-pgsql",
60+
"pytest-postgresql",
6261
]
6362

6463
[project.urls]

tests/conftest.py

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
import os
44
import warnings
55
from typing import Any, Dict
6+
from urllib.parse import quote_plus as quote
67

78
import psycopg
89
import pytest
9-
import pytest_pgsql
1010
import rasterio
1111
from pypgstac.db import PgstacDB
1212
from pypgstac.load import Loader
1313
from pypgstac.migrate import Migrate
14+
from pytest_postgresql.janitor import DatabaseJanitor
1415
from rasterio.errors import NotGeoreferencedWarning
1516
from rasterio.io import MemoryFile
1617
from starlette.testclient import TestClient
@@ -20,10 +21,6 @@
2021
collection_maxar = os.path.join(DATA_DIR, "maxar_BayOfBengal.json")
2122
items = os.path.join(DATA_DIR, "noaa-eri-nashville2020.json")
2223

23-
test_db = pytest_pgsql.TransactedPostgreSQLTestDB.create_fixture(
24-
"test_db", scope="session", use_restore_state=False
25-
)
26-
2724

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

5249

5350
@pytest.fixture(scope="session")
54-
def database_url(test_db):
55-
"""
56-
Session scoped fixture to launch a postgresql database in a separate process. We use psycopg2 to ingest test data
57-
because pytest-asyncio event loop is a function scoped fixture and cannot be called within the current scope. Yields
58-
a database url which we pass to our application through a monkeypatched environment variable.
59-
"""
60-
with PgstacDB(dsn=str(test_db.connection.engine.url)) as db:
51+
def database(postgresql_proc):
52+
"""Create Database fixture."""
53+
with DatabaseJanitor(
54+
user=postgresql_proc.user,
55+
host=postgresql_proc.host,
56+
port=postgresql_proc.port,
57+
dbname="pgstacrw",
58+
version=postgresql_proc.version,
59+
password="a2Vw:yk=)CdSis[fek]tW=/o",
60+
) as jan:
61+
connection = f"postgresql://{jan.user}:{quote(jan.password)}@{jan.host}:{jan.port}/{jan.dbname}"
62+
63+
# make sure the DB is set to use UTC
64+
with psycopg.connect(connection) as conn:
65+
with conn.cursor() as cur:
66+
cur.execute(f"ALTER DATABASE {jan.dbname} SET TIMEZONE='UTC';")
67+
6168
print("Running to PgSTAC migration...")
62-
migrator = Migrate(db)
63-
version = migrator.run_migration()
64-
assert version
65-
assert test_db.has_schema("pgstac")
66-
print(f"PgSTAC version: {version}")
69+
with PgstacDB(dsn=connection) as db:
70+
migrator = Migrate(db)
71+
version = migrator.run_migration()
72+
assert version
73+
print(f"PgSTAC version: {version}")
6774

68-
print("Load items and collection into PgSTAC")
69-
loader = Loader(db=db)
70-
loader.load_collections(collection)
71-
loader.load_collections(collection_maxar)
72-
loader.load_items(items)
75+
print("Load items and collection into PgSTAC")
76+
loader = Loader(db=db)
77+
loader.load_collections(collection)
78+
loader.load_collections(collection_maxar)
79+
loader.load_items(items)
7380

74-
# Make sure we have 1 collection and 163 items in pgstac
75-
with psycopg.connect(str(test_db.connection.engine.url)) as conn:
76-
with conn.cursor() as cur:
77-
cur.execute("SELECT COUNT(*) FROM pgstac.collections")
78-
val = cur.fetchone()[0]
79-
assert val == 2
81+
# Make sure we have 1 collection and 163 items in pgstac
82+
with psycopg.connect(connection) as conn:
83+
with conn.cursor() as cur:
84+
cur.execute("SELECT COUNT(*) FROM pgstac.collections")
85+
val = cur.fetchone()[0]
86+
assert val == 2
8087

81-
cur.execute("SELECT COUNT(*) FROM pgstac.items")
82-
val = cur.fetchone()[0]
83-
assert val == 163
88+
cur.execute("SELECT COUNT(*) FROM pgstac.items")
89+
val = cur.fetchone()[0]
90+
assert val == 163
8491

85-
return test_db.connection.engine.url
92+
yield jan
8693

8794

8895
@pytest.fixture(autouse=True)
89-
def app(database_url, monkeypatch):
96+
def app(database, monkeypatch):
9097
"""Create app with connection to the pytest database."""
9198
monkeypatch.setenv("AWS_ACCESS_KEY_ID", "jqt")
9299
monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "rde")
@@ -97,8 +104,10 @@ def app(database_url, monkeypatch):
97104
monkeypatch.setenv("TITILER_PGSTAC_API_DEBUG", "TRUE")
98105
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_ASSETS_ENDPOINTS", "TRUE")
99106
monkeypatch.setenv("TITILER_PGSTAC_API_ENABLE_EXTERNAL_DATASET_ENDPOINTS", "TRUE")
100-
101-
monkeypatch.setenv("DATABASE_URL", str(database_url))
107+
monkeypatch.setenv(
108+
"DATABASE_URL",
109+
f"postgresql://{database.user}:{quote(database.password)}@{database.host}:{database.port}/{database.dbname}",
110+
)
102111

103112
from titiler.pgstac.main import app
104113

titiler/pgstac/settings.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from functools import lru_cache
44
from typing import Any, Optional, Set
5+
from urllib.parse import quote_plus as quote
56

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

8485
return PostgresDsn.build(
8586
scheme="postgresql",
86-
username=info.data.get("postgres_user"),
87-
password=info.data.get("postgres_pass"),
87+
username=info.data["postgres_user"],
88+
password=quote(info.data["postgres_pass"]),
8889
host=info.data.get("postgres_host", ""),
8990
port=info.data.get("postgres_port", 5432),
9091
path=info.data.get("postgres_dbname", ""),

0 commit comments

Comments
 (0)