Skip to content

Commit 44ed566

Browse files
authored
Use test-only sqlc queries instead of driver queries in test cases (#30)
Introduce a `JobGetByID` in sqlc which we switch to using in tests instead of using the inelegant `job_get_by_kind_and_unique_properties()` from the driver. This also lets us remove `driver` as a test fixture, thus simplifying the whole testing set up and making it easier to understand.
1 parent e8ffe06 commit 44ed566

File tree

3 files changed

+77
-41
lines changed

3 files changed

+77
-41
lines changed

src/riverqueue/driver/riversqlalchemy/dbsqlc/river_job.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818
"""
1919

2020

21+
JOB_GET_BY_ID = """-- name: job_get_by_id \\:one
22+
SELECT id, args, attempt, attempted_at, attempted_by, created_at, errors, finalized_at, kind, max_attempts, metadata, priority, queue, state, scheduled_at, tags
23+
FROM river_job
24+
WHERE id = :p1
25+
"""
26+
27+
2128
JOB_GET_BY_KIND_AND_UNIQUE_PROPERTIES = """-- name: job_get_by_kind_and_unique_properties \\:one
2229
SELECT id, args, attempt, attempted_at, attempted_by, created_at, errors, finalized_at, kind, max_attempts, metadata, priority, queue, state, scheduled_at, tags
2330
FROM river_job
@@ -153,6 +160,29 @@ def job_get_all(self) -> Iterator[models.RiverJob]:
153160
tags=row[15],
154161
)
155162

163+
def job_get_by_id(self, *, id: int) -> Optional[models.RiverJob]:
164+
row = self._conn.execute(sqlalchemy.text(JOB_GET_BY_ID), {"p1": id}).first()
165+
if row is None:
166+
return None
167+
return models.RiverJob(
168+
id=row[0],
169+
args=row[1],
170+
attempt=row[2],
171+
attempted_at=row[3],
172+
attempted_by=row[4],
173+
created_at=row[5],
174+
errors=row[6],
175+
finalized_at=row[7],
176+
kind=row[8],
177+
max_attempts=row[9],
178+
metadata=row[10],
179+
priority=row[11],
180+
queue=row[12],
181+
state=row[13],
182+
scheduled_at=row[14],
183+
tags=row[15],
184+
)
185+
156186
def job_get_by_kind_and_unique_properties(self, arg: JobGetByKindAndUniquePropertiesParams) -> Optional[models.RiverJob]:
157187
row = self._conn.execute(sqlalchemy.text(JOB_GET_BY_KIND_AND_UNIQUE_PROPERTIES), {
158188
"p1": arg.kind,
@@ -263,6 +293,29 @@ async def job_get_all(self) -> AsyncIterator[models.RiverJob]:
263293
tags=row[15],
264294
)
265295

296+
async def job_get_by_id(self, *, id: int) -> Optional[models.RiverJob]:
297+
row = (await self._conn.execute(sqlalchemy.text(JOB_GET_BY_ID), {"p1": id})).first()
298+
if row is None:
299+
return None
300+
return models.RiverJob(
301+
id=row[0],
302+
args=row[1],
303+
attempt=row[2],
304+
attempted_at=row[3],
305+
attempted_by=row[4],
306+
created_at=row[5],
307+
errors=row[6],
308+
finalized_at=row[7],
309+
kind=row[8],
310+
max_attempts=row[9],
311+
metadata=row[10],
312+
priority=row[11],
313+
queue=row[12],
314+
state=row[13],
315+
scheduled_at=row[14],
316+
tags=row[15],
317+
)
318+
266319
async def job_get_by_kind_and_unique_properties(self, arg: JobGetByKindAndUniquePropertiesParams) -> Optional[models.RiverJob]:
267320
row = (await self._conn.execute(sqlalchemy.text(JOB_GET_BY_KIND_AND_UNIQUE_PROPERTIES), {
268321
"p1": arg.kind,

src/riverqueue/driver/riversqlalchemy/dbsqlc/river_job.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ CREATE TABLE river_job(
3939
SELECT *
4040
FROM river_job;
4141

42+
-- name: JobGetByID :one
43+
SELECT *
44+
FROM river_job
45+
WHERE id = @id;
46+
4247
-- name: JobGetByKindAndUniqueProperties :one
4348
SELECT *
4449
FROM river_job

tests/driver/riversqlalchemy/sqlalchemy_driver_test.py

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
UniqueOpts,
1919
)
2020
from riverqueue.driver import riversqlalchemy
21-
from riverqueue.driver.driver_protocol import JobGetByKindAndUniquePropertiesParam
21+
from riverqueue.driver.riversqlalchemy import dbsqlc
2222

2323

2424
class TestAsyncClient:
@@ -40,19 +40,12 @@ async def test_tx(
4040
yield conn_tx
4141
await conn_tx.rollback()
4242

43-
@pytest.fixture
44-
@staticmethod
45-
def driver(
46-
test_tx: sqlalchemy.ext.asyncio.AsyncConnection,
47-
) -> riversqlalchemy.AsyncDriver:
48-
return riversqlalchemy.AsyncDriver(test_tx)
49-
5043
@pytest_asyncio.fixture
5144
@staticmethod
5245
async def client(
53-
driver: riversqlalchemy.AsyncDriver,
46+
test_tx: sqlalchemy.ext.asyncio.AsyncConnection,
5447
) -> AsyncClient:
55-
return AsyncClient(driver)
48+
return AsyncClient(riversqlalchemy.AsyncDriver(test_tx))
5649

5750
#
5851
# tests
@@ -87,26 +80,22 @@ async def test_insert_with_only_args(self, client, simple_args):
8780
assert insert_res.job
8881

8982
@pytest.mark.asyncio
90-
async def test_insert_tx(self, client, driver, engine_async, simple_args, test_tx):
83+
async def test_insert_tx(self, client, engine_async, simple_args, test_tx):
9184
insert_res = await client.insert_tx(test_tx, simple_args)
9285
assert insert_res.job
9386

94-
job = await driver.unwrap_executor(
95-
test_tx
96-
).job_get_by_kind_and_unique_properties(
97-
JobGetByKindAndUniquePropertiesParam(kind=simple_args.kind)
87+
job = await dbsqlc.river_job.AsyncQuerier(test_tx).job_get_by_id(
88+
id=insert_res.job.id
9889
)
99-
assert job == insert_res.job
90+
assert job
10091

101-
async with engine_async.begin() as conn_tx2:
102-
job = await driver.unwrap_executor(
103-
conn_tx2
104-
).job_get_by_kind_and_unique_properties(
105-
JobGetByKindAndUniquePropertiesParam(kind=simple_args.kind)
92+
async with engine_async.begin() as test_tx2:
93+
job = await dbsqlc.river_job.AsyncQuerier(test_tx2).job_get_by_id(
94+
id=insert_res.job.id
10695
)
10796
assert job is None
10897

109-
await conn_tx2.rollback()
98+
await test_tx2.rollback()
11099

111100
@pytest.mark.asyncio
112101
async def test_insert_with_opts(self, client, simple_args):
@@ -206,13 +195,8 @@ def test_tx(engine: sqlalchemy.Engine) -> Iterator[sqlalchemy.Connection]:
206195

207196
@pytest.fixture
208197
@staticmethod
209-
def driver(test_tx: sqlalchemy.Connection) -> riversqlalchemy.Driver:
210-
return riversqlalchemy.Driver(test_tx)
211-
212-
@pytest.fixture
213-
@staticmethod
214-
def client(driver: riversqlalchemy.Driver) -> Client:
215-
return Client(driver)
198+
def client(test_tx: sqlalchemy.Connection) -> Client:
199+
return Client(riversqlalchemy.Driver(test_tx))
216200

217201
#
218202
# tests; should match with tests for the async client above
@@ -222,24 +206,18 @@ def test_insert_with_only_args(self, client, simple_args):
222206
insert_res = client.insert(simple_args)
223207
assert insert_res.job
224208

225-
def test_insert_tx(self, client, driver, engine, simple_args, test_tx):
209+
def test_insert_tx(self, client, engine, simple_args, test_tx):
226210
insert_res = client.insert_tx(test_tx, simple_args)
227211
assert insert_res.job
228212

229-
job = driver.unwrap_executor(test_tx).job_get_by_kind_and_unique_properties(
230-
JobGetByKindAndUniquePropertiesParam(kind=simple_args.kind)
231-
)
232-
assert job == insert_res.job
213+
job = dbsqlc.river_job.Querier(test_tx).job_get_by_id(id=insert_res.job.id)
214+
assert job
233215

234-
with engine.begin() as conn_tx2:
235-
job = driver.unwrap_executor(
236-
conn_tx2
237-
).job_get_by_kind_and_unique_properties(
238-
JobGetByKindAndUniquePropertiesParam(kind=simple_args.kind)
239-
)
216+
with engine.begin() as test_tx2:
217+
job = dbsqlc.river_job.Querier(test_tx2).job_get_by_id(id=insert_res.job.id)
240218
assert job is None
241219

242-
conn_tx2.rollback()
220+
test_tx2.rollback()
243221

244222
def test_insert_with_opts(self, client, simple_args):
245223
insert_opts = InsertOpts(queue="high_priority", unique_opts=None)

0 commit comments

Comments
 (0)