Skip to content

Commit

Permalink
tests: db utils full test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
v-rocheleau committed Nov 15, 2024
1 parent fe3773d commit 063e1e1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 19 deletions.
3 changes: 2 additions & 1 deletion docker-compose.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ services:
command: /bin/bash -c '
cd /tds &&
/poetry_user_install_dev.bash &&
pytest -svv --cov=transcriptomics_data_service --cov-branch
pytest -svv --cov=transcriptomics_data_service --cov-branch &&
coverage html
'
tds-db:
Expand Down
90 changes: 79 additions & 11 deletions tests/test_db.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,84 @@
from asyncpg import Connection, UniqueViolationError
import pytest
from transcriptomics_data_service.db import Database
from transcriptomics_data_service.models import ExperimentResult
from transcriptomics_data_service.models import ExperimentResult, GeneExpression

TEST_EXPERIMENT_RESULT_ID = "test-experiment-id"
TEST_EXPERIMENT_RESULT = ExperimentResult(
experiment_result_id=TEST_EXPERIMENT_RESULT_ID,
assembly_id="assembly_test_id",
assembly_name="assembly_test_name",
)
TEST_GENE_EXPRESSION = GeneExpression(
experiment_result_id=TEST_EXPERIMENT_RESULT_ID,
gene_code="test-gene-code",
sample_id="test-sample-id",
raw_count=90,
)

##########################
# CRUD: experiment_results
##########################


@pytest.mark.asyncio
async def test_create_read_experiment_result(db: Database, db_cleanup):
# exp_result = await _create_experiment_result(db)
await db.create_experiment_result(TEST_EXPERIMENT_RESULT)
db_exp_result = await db.read_experiment_result(TEST_EXPERIMENT_RESULT_ID)
assert TEST_EXPERIMENT_RESULT == db_exp_result


@pytest.mark.asyncio
async def test_update_experiment_result(db: Database, db_cleanup):
await db.create_experiment_result(TEST_EXPERIMENT_RESULT)
new_exp = TEST_EXPERIMENT_RESULT.model_copy()
new_exp.assembly_name = "updated_assembly_name"
await db.update_experiment_result(new_exp)
db_exp_result = await db.read_experiment_result(new_exp.experiment_result_id)
assert db_exp_result.assembly_name == new_exp.assembly_name


@pytest.mark.asyncio
async def test_delete_experiment_result(db: Database, db_cleanup):
await db.create_experiment_result(TEST_EXPERIMENT_RESULT)
await db.delete_experiment_result(TEST_EXPERIMENT_RESULT_ID)
db_exp_result = await db.read_experiment_result(TEST_EXPERIMENT_RESULT_ID)
assert db_exp_result == None


########################
# CRUD: gene_expressions
########################


@pytest.mark.asyncio
async def test_gene_expression(db: Database, db_cleanup):
async with db.transaction_connection() as conn:
await db.create_experiment_result(TEST_EXPERIMENT_RESULT, conn)
await db.create_gene_expressions([TEST_GENE_EXPRESSION], conn)

# read all
db_expressions = await db.fetch_expressions()
assert len(db_expressions) == 1
assert db_expressions[0] == TEST_GENE_EXPRESSION

# read by ExperimentResult ID
db_expressions = await db.fetch_expressions(experiment_result_id=TEST_EXPERIMENT_RESULT_ID)
assert db_expressions[0] == TEST_GENE_EXPRESSION


# TEST TRANSACTIONS
@pytest.mark.asyncio
async def test_create_experiment_result(db: Database, db_cleanup):
exp_id = "exp_test"
exp_result = ExperimentResult(
experiment_result_id=exp_id,
assembly_id="assembly_test_id",
assembly_name="assembly_test_name",
)
await db.create_experiment_result(exp_result)
db_exp_result = await db.read_experiment_result(exp_id)
assert exp_result == db_exp_result
async def test_transaction(db: Database, db_cleanup):
async with db.transaction_connection() as conn:
try:
await db.create_experiment_result(TEST_EXPERIMENT_RESULT, conn)
await db.create_gene_expressions([TEST_GENE_EXPRESSION, TEST_GENE_EXPRESSION], conn)
assert False
except:
assert True
db_exp = await db.read_experiment_result(TEST_EXPERIMENT_RESULT_ID)
db_gene_expr = await db.fetch_expressions()
assert db_exp == None
assert len(db_gene_expr) == 0
12 changes: 5 additions & 7 deletions transcriptomics_data_service/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ async def create_gene_expressions(self, expressions: list[GeneExpression], trans
Rows on gene_expressions can only be created as part of an RCM ingestion.
Ingestion is all-or-nothing, hence the transaction.
"""
async with transaction_conn.transaction():
# sub-transaction
for gene_expression in expressions:
await self._create_gene_expression(gene_expression, transaction_conn)
for gene_expression in expressions:
await self._create_gene_expression(gene_expression, transaction_conn)

async def _create_gene_expression(self, expression: GeneExpression, transaction_conn: asyncpg.Connection):
# Creates a row on gene_expressions within a transaction.
Expand All @@ -112,15 +110,15 @@ async def _create_gene_expression(self, expression: GeneExpression, transaction_
expression.tmm_count,
)

async def fetch_expressions(self) -> tuple[GeneExpression, ...]:
return tuple([r async for r in self._select_expressions(None)])
async def fetch_expressions(self, experiment_result_id: str | None = None) -> tuple[GeneExpression, ...]:
return tuple([r async for r in self._select_expressions(exp_id=experiment_result_id)])

async def _select_expressions(self, exp_id: str | None) -> AsyncIterator[GeneExpression]:
conn: asyncpg.Connection
where_clause = "WHERE experiment_result_id = $1" if exp_id is not None else ""
query = f"SELECT * FROM gene_expressions {where_clause}"
async with self.connect() as conn:
res = await conn.fetch(query, *((exp_id) if exp_id is not None else ()))
res = await conn.fetch(query, *((exp_id,) if exp_id is not None else ()))
for r in map(lambda g: self._deserialize_gene_expression(g), res):
yield r

Expand Down

0 comments on commit 063e1e1

Please sign in to comment.