Skip to content

Commit 800ef9a

Browse files
committed
Fix aidbox_db fixture to work in tests
1 parent ac4abf8 commit 800ef9a

File tree

5 files changed

+51
-43
lines changed

5 files changed

+51
-43
lines changed

aidbox_python_sdk/db.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,34 @@ def create_table(table_name):
7373

7474

7575
class DBProxy:
76-
_client = None
77-
_settings = None
78-
_table_cache = None
76+
_client: ClientSession | None = None
77+
_settings: Settings
78+
_table_cache: dict
7979

80-
def __init__(self, settings: Settings):
80+
def __init__(self, settings: Settings, _table_cache: dict | None = None):
8181
self._settings = settings
82-
self._table_cache = {}
82+
self._table_cache = _table_cache or {}
8383

8484
async def initialize(self):
8585
basic_auth = BasicAuth(
8686
login=self._settings.APP_INIT_CLIENT_ID,
8787
password=self._settings.APP_INIT_CLIENT_SECRET,
8888
)
8989
self._client = ClientSession(auth=basic_auth)
90-
# TODO: remove _init_table_cache
91-
await self._init_table_cache()
90+
if not self._table_cache:
91+
await self._init_table_cache()
9292

9393
async def deinitialize(self):
9494
await self._client.close()
9595

96+
def clone(self) -> "DBProxy":
97+
"""
98+
Create a new DBProxy with the same settings and table cache
99+
NOTE: it should be initialized after cloning
100+
"""
101+
102+
return DBProxy(self._settings, _table_cache=self._table_cache)
103+
96104
async def raw_sql(self, sql_query, *, execute=False):
97105
"""
98106
Executes SQL query and returns result. Specify `execute` to True
@@ -146,7 +154,9 @@ async def _get_all_entities_name(self):
146154

147155
if not result:
148156
# Support legacy instalations with entity attribute data structure
149-
query_url = f"{self._settings.APP_INIT_URL}/Entity?type=resource&_elements=id&_count=999"
157+
query_url = (
158+
f"{self._settings.APP_INIT_URL}/Entity?type=resource&_elements=id&_count=999"
159+
)
150160
async with self._client.get(query_url) as resp:
151161
json_resp = await resp.json()
152162
result = [entry["resource"]["id"] for entry in json_resp.get("entry", [])]

aidbox_python_sdk/pytest_plugin.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,13 @@ def aidbox_client(app):
124124

125125

126126
@pytest.fixture
127-
def aidbox_db(app):
128-
return app[ak.db]
127+
async def aidbox_db(app):
128+
# We clone it to init client session in the test thread
129+
# because app is running in another thread with own loop
130+
db = app[ak.db].clone()
131+
await db.initialize()
132+
yield db
133+
await db.deinitialize()
129134

130135

131136
# Deprecated

envs/app

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ APP_INIT_CLIENT_ID=root
22
APP_INIT_CLIENT_SECRET=secret
33
APP_INIT_URL=http://aidbox:8080
44

5-
APP_ID=backend-test
5+
APP_ID=app-test
66
APP_SECRET=secret
77
APP_URL=http://app:8081
88
APP_PORT=8081

main.py

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import asyncio
22
import logging
3-
import time
43
from datetime import datetime
54

65
import coloredlogs
7-
import sqlalchemy as sa
86
from aiohttp import web
9-
from sqlalchemy.sql.expression import insert, select
7+
from sqlalchemy.sql.expression import select
108

9+
from aidbox_python_sdk.db import DBProxy
1110
from aidbox_python_sdk.handlers import routes
1211
from aidbox_python_sdk.main import create_app as _create_app
1312
from aidbox_python_sdk.sdk import SDK
@@ -129,37 +128,16 @@ async def daily_patient_report(operation, request):
129128
return web.json_response({"type": "report", "success": "Ok", "msg": "Response from APP"})
130129

131130

131+
async def get_app_ids(db: DBProxy):
132+
app = db.App
133+
return await db.alchemy(select(app.c.id))
134+
135+
132136
@routes.get("/db_tests")
133137
async def db_tests(request):
134138
db = request.app["db"]
135-
app = db.App.__table__
136-
app_res = {
137-
"type": "app",
138-
"resources": {
139-
"User": {},
140-
},
141-
}
142-
unique_id = f"abc{time.time()}"
143-
test_statements = [
144-
insert(app)
145-
.values(id=unique_id, txid=123, status="created", resource=app_res)
146-
.returning(app.c.id),
147-
app.update()
148-
.where(app.c.id == unique_id)
149-
.values(resource=app.c.resource.op("||")({"additional": "property"})),
150-
app.select().where(app.c.id == unique_id),
151-
app.select().where(app.c.status == "recreated"),
152-
select([app.c.resource["type"].label("app_type")]),
153-
app.select().where(app.c.resource["resources"].has_key("User")),
154-
select([app.c.id]).where(app.c.resource["type"].astext == "app"),
155-
select([sa.func.count(app.c.id)]).where(app.c.resource.contains({"type": "app"})),
156-
# TODO: got an error for this query.
157-
# select('*').where(app.c.resource['resources'].has_all(array(['User', 'Client']))),
158-
]
159-
for statement in test_statements:
160-
result = await db.alchemy(statement)
161-
logging.debug("Result:\n%s", result)
162-
return web.json_response({})
139+
140+
return web.json_response(await get_app_ids(db))
163141

164142

165143
@sdk.operation(
@@ -169,6 +147,7 @@ async def db_tests(request):
169147
"fhirCode": "observation-custom-op",
170148
"fhirUrl": "http://test.com",
171149
"fhirResource": ["Observation"],
172-
})
150+
},
151+
)
173152
async def observation_custom_op(operation, request):
174153
return {"message": "Observation custom operation response"}

tests/test_sdk.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from fhirpathpy import evaluate
77

88
import main
9+
from aidbox_python_sdk.db import DBProxy
910

1011

1112
@pytest.mark.skip("Skipped because of regression in Aidbox 2510")
@@ -175,3 +176,16 @@ async def test_database_isolation_with_history_in_name__2(aidbox_client, safe_db
175176

176177
resources = await aidbox_client.resources("FamilyMemberHistory").fetch_all()
177178
assert len(resources) == 2
179+
180+
181+
async def test_aidbox_db_fixture(client, aidbox_db: DBProxy, safe_db):
182+
"""
183+
Test that aidbox_db fixture works with isolated DB Proxy from app's instance
184+
"""
185+
response = await client.get("/db_tests")
186+
assert response.status == 200
187+
json = await response.json()
188+
assert json == [{"id": "app-test"}]
189+
190+
app_ids = await main.get_app_ids(aidbox_db)
191+
assert app_ids == [{"id": "app-test"}]

0 commit comments

Comments
 (0)