Skip to content

Commit c3641b6

Browse files
committed
✅ Test storage_analyses utils, task
1 parent 2621eb5 commit c3641b6

File tree

4 files changed

+210
-2
lines changed

4 files changed

+210
-2
lines changed

tests/files/fixtures.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ def _make(nrows=10, filename="upload_manifest.tsv"):
3333
version = VersionFactory()
3434
df = pandas.DataFrame(
3535
[
36-
{c: c for c in MANIFEST_SCHEMA["required"]}
37-
for i in range(nrows)
36+
{
37+
"Source File Name": f"foo{i}.tsv",
38+
"Hash": f"hash{i}",
39+
"Hash Algorithm": "MD5",
40+
"Size": i * 100,
41+
} for i in range(nrows)
3842
]
3943
)
4044
content = df.to_csv(sep="\t", index=False)

tests/storage_analyses/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import pytest
2+
import pandas
3+
4+
from creator.files.models import AuditPrepState
5+
from creator.files.factories import VersionFactory
6+
from creator.studies.factories import StudyFactory
7+
from creator.storage_analyses.tasks import expected_file as task
8+
from creator.storage_analyses.factories import ExpectedFileFactory
9+
from creator.storage_analyses.models import AuditState, ExpectedFile
10+
11+
from ..files.fixtures import make_file_upload_manifest
12+
13+
14+
def test_bulk_update_audit_state(db):
15+
"""
16+
Test helper _bulk_update_audit_state
17+
"""
18+
files = ExpectedFileFactory.create_batch(
19+
5, audit_state=AuditState.NOT_SUBMITTED
20+
)
21+
task._bulk_update_audit_state(files, "start_submission")
22+
for f in files:
23+
assert f.audit_state == AuditState.SUBMITTING
24+
25+
26+
def test_dataframe_to_expected_files(db, mocker):
27+
"""
28+
Test helper _dataframe_to_expected_files
29+
"""
30+
study = StudyFactory()
31+
mock_logger = mocker.patch(
32+
"creator.storage_analyses.tasks.expected_file.logger"
33+
)
34+
rows = [
35+
{
36+
"Source File Name": f"foo{i}.tsv",
37+
"Hash": f"hash{i}",
38+
"Hash Algorithm": "MD5",
39+
"Size": i * 100,
40+
"Foo": "Bar"
41+
} for i in range(5)
42+
]
43+
missing_req = {
44+
"Hash": "1234",
45+
"Hash Algorithm": "MD5"
46+
}
47+
df = pandas.DataFrame(rows + [rows[0].copy(), missing_req])
48+
files = task._dataframe_to_expected_files(df, study)
49+
50+
assert len(files) == 5
51+
assert files[0]["study_id"] == study.pk
52+
assert files[0]["custom_fields"] == {"Foo": "Bar"}
53+
assert "source_file_name" in files[0]
54+
assert mock_logger.warning.call_count == 2
55+
56+
57+
def test_prepare_audit_submission(db, mocker, make_file_upload_manifest):
58+
"""
59+
Test task to prepare audit submission
60+
"""
61+
mock_django_rq = mocker.patch(
62+
"creator.storage_analyses.tasks.expected_file.django_rq"
63+
)
64+
# Success
65+
version = make_file_upload_manifest(nrows=10)
66+
version.start_audit_prep()
67+
version.save()
68+
task.prepare_audit_submission(version.pk)
69+
version.refresh_from_db()
70+
assert mock_django_rq.enqueue.call_count == 1
71+
assert version.audit_prep_state == AuditPrepState.COMPLETED
72+
assert ExpectedFile.objects.count() == 10
73+
74+
# Failure
75+
version = VersionFactory()
76+
version.start_audit_prep()
77+
version.save()
78+
with pytest.raises(Exception):
79+
task.prepare_audit_submission(version.pk)
80+
version.refresh_from_db()
81+
assert version.audit_prep_state == AuditPrepState.FAILED
82+
83+
84+
def test_submit_study_for_audit(db, mocker):
85+
"""
86+
Test task to submit study for audit
87+
"""
88+
mock_logger = mocker.patch(
89+
"creator.storage_analyses.tasks.expected_file.logger"
90+
)
91+
mock_dewrangle = mocker.patch(
92+
"creator.storage_analyses.tasks.expected_file.DewrangleClient"
93+
)
94+
mock_client = mock_dewrangle()
95+
study = StudyFactory()
96+
ExpectedFileFactory.create_batch(
97+
10, audit_state=AuditState.NOT_SUBMITTED, study=study
98+
)
99+
ExpectedFileFactory.create_batch(
100+
8, audit_state=AuditState.SUBMITTING, study=study
101+
)
102+
ExpectedFileFactory.create_batch(
103+
5, audit_state=AuditState.FAILED, study=study
104+
)
105+
task.submit_study_for_audit(study.pk)
106+
assert ExpectedFile.objects.filter(
107+
audit_state=AuditState.SUBMITTED
108+
).count() == 15
109+
assert ExpectedFile.objects.filter(
110+
audit_state=AuditState.SUBMITTING
111+
).count() == 8
112+
assert mock_client.upsert_organization.call_count == 1
113+
assert mock_client.upsert_study.call_count == 1
114+
assert mock_client.bulk_upsert_expected_files.call_count == 1
115+
116+
117+
def test_submit_study_for_audit_errors(db, mocker):
118+
"""
119+
Test task to submit study for audit error cases
120+
"""
121+
mock_logger = mocker.patch(
122+
"creator.storage_analyses.tasks.expected_file.logger"
123+
)
124+
mock_dewrangle = mocker.patch(
125+
"creator.storage_analyses.tasks.expected_file.DewrangleClient"
126+
)
127+
mock_client = mock_dewrangle()
128+
study = StudyFactory()
129+
130+
# No expected files to submit
131+
task.submit_study_for_audit(study.pk)
132+
assert mock_logger.info.call_count == 1
133+
134+
# Error in submitting
135+
ExpectedFileFactory.create_batch(
136+
5, audit_state=AuditState.NOT_SUBMITTED, study=study
137+
)
138+
mock_client.bulk_upsert_expected_files.side_effect = Exception
139+
with pytest.raises(Exception):
140+
task.submit_study_for_audit(study.pk)

tests/storage_analyses/test_utils.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
3+
from creator.studies.factories import StudyFactory
4+
from creator.storage_analyses.factories import ExpectedFileFactory
5+
from creator.storage_analyses import utils
6+
from creator.storage_analyses.models import ExpectedFile
7+
8+
from ..files.fixtures import make_file_upload_manifest
9+
10+
11+
def test_chunked_dataframe_reader(db, mocker, make_file_upload_manifest):
12+
"""
13+
Test utils.chunked_dataframe_reader
14+
"""
15+
# Success
16+
version = make_file_upload_manifest(nrows=100)
17+
for i, df in enumerate(
18+
utils.chunked_dataframe_reader(version, batch_size=10)
19+
):
20+
assert df.shape[0] == 10
21+
assert i == 9
22+
23+
# Unknown file format
24+
version = make_file_upload_manifest(filename="foo.bar")
25+
with pytest.raises(IOError):
26+
next(utils.chunked_dataframe_reader(version))
27+
28+
# Problem reading data
29+
mock_logger = mocker.patch("creator.storage_analyses.utils.logger")
30+
with pytest.raises(Exception):
31+
next(utils.chunked_dataframe_reader(version, batchsize="foo"))
32+
assert mock_logger.exception.call_count == 1
33+
34+
35+
def test_batched_queryset_iterator(db):
36+
"""
37+
Test utils.batched_queryset_iterator
38+
"""
39+
files = ExpectedFileFactory.create_batch(10)
40+
for i, batch in (
41+
enumerate(utils.batched_queryset_iterator(ExpectedFile.objects, 5))
42+
):
43+
assert len(batch) == 5
44+
assert i == 1
45+
46+
47+
def test_bulk_upsert_expected_files(db):
48+
"""
49+
Test utils.bulk_upsert_expected_files
50+
"""
51+
study = StudyFactory()
52+
files = [
53+
{
54+
"study": study,
55+
"source_file_name": f"myfile{i}.tsv",
56+
"hash": f"foobar{i}",
57+
"hash_algorithm": "MD5",
58+
"size": i * 100
59+
60+
} for i in range(5)
61+
]
62+
assert ExpectedFile.objects.count() == 0
63+
utils.bulk_upsert_expected_files(files)
64+
assert ExpectedFile.objects.count() == 5

0 commit comments

Comments
 (0)