From 605d531538178fad8ac7624f44d8a8332fdbb6f7 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Thu, 5 Sep 2019 16:22:47 +0100 Subject: [PATCH] TEST: update dicom tests --- tests/test_dicom.py | 154 ++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 41 deletions(-) diff --git a/tests/test_dicom.py b/tests/test_dicom.py index 70b5117bc..5354e86e2 100644 --- a/tests/test_dicom.py +++ b/tests/test_dicom.py @@ -1,14 +1,21 @@ #!/usr/bin/env python # -# test_dicom.py - -# -# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# These tests require an internet connection, and will only work on linux. # -import os.path as op -import tarfile +import os.path as op +import os +import functools as ft +import subprocess as sp +import tarfile +import zipfile +import random +import string +import binascii +import contextlib +import urllib.request as request +from unittest import mock -import mock import pytest import fsl.data.dicom as fsldcm @@ -21,14 +28,35 @@ datadir = op.join(op.dirname(__file__), 'testdata') pytestmark = pytest.mark.dicomtest -def setup_module(): +@contextlib.contextmanager +def install_dcm2niix(version='1.0.20190902'): + filenames = { + '1.0.20190902' : 'v1.0.20190902/dcm2niix_lnx.zip', + '1.0.20190410' : 'v1.0.20190410/dcm2niix_11-Apr-2019_lnx.zip', + '1.0.20181125' : 'v1.0.20181125/dcm2niix_25-Nov-2018_lnx.zip', + '1.0.20171017' : 'v1.0.20171017/dcm2niix_18-Oct-2017_lnx.zip', + } + prefix = 'https://github.com/rordenlab/dcm2niix/releases/download/' + url = prefix + filenames[version] - if not fsldcm.enabled(): - raise RuntimeError('dcm2niix is not present - tests cannot be run') + with tempdir.tempdir() as td: + request.urlretrieve(url, 'dcm2niix.zip') + with zipfile.ZipFile('dcm2niix.zip', 'r') as f: + f.extractall('.') + + os.chmod(op.join(td, 'dcm2niix'), 0o755) + + path = op.pathsep.join((op.abspath('.'), os.environ['PATH'])) + + with mock.patch.dict('os.environ', {'PATH' : path}): + try: + yield + finally: + fsldcm.installedVersion.invalidate() -def test_disabled(): +def test_disabled(): with mock.patch('fsl.data.dicom.enabled', return_value=False): with pytest.raises(RuntimeError): fsldcm.scanDir('.') @@ -36,20 +64,37 @@ def test_disabled(): fsldcm.loadSeries({}) + +def test_installedVersion(): + tests = [ + ('1.0.20190902', (1, 0, 2019, 9, 2)), + ('1.0.20181125', (1, 0, 2018, 11, 25)), + ('1.0.20171017', (1, 0, 2017, 10, 17))] + + for version, expect in tests: + fsldcm.installedVersion.invalidate() + with install_dcm2niix(version): + got = fsldcm.installedVersion() + assert got == expect + + + def test_enabled(): try: - fsldcm.enabled.invalidate() - assert fsldcm.enabled() - fsldcm.enabled.invalidate() + with install_dcm2niix('1.0.20190902'): + fsldcm.installedVersion.invalidate() + assert fsldcm.enabled() + # test dcm2niix not present with mock.patch('subprocess.check_output', side_effect=Exception()): + fsldcm.installedVersion.invalidate() assert not fsldcm.enabled() - # test presence of different versions tests = [(b'version v2.1.20191212', True), + (b'version v1.0.20190902', True), (b'version v1.0.20171216', True), (b'version v1.0.20171215', True), (b'version v1.0.20171214', False), @@ -59,19 +104,19 @@ def test_enabled(): (b'version blurgh', False)] for verstr, expected in tests: - fsldcm.enabled.invalidate() + fsldcm.installedVersion.invalidate() with mock.patch('subprocess.check_output', return_value=verstr): assert fsldcm.enabled() == expected finally: - fsldcm.enabled.invalidate() + fsldcm.installedVersion.invalidate() def test_scanDir(): - with tempdir.tempdir() as td: + with install_dcm2niix(): - series = fsldcm.scanDir(td) + series = fsldcm.scanDir('.') assert len(series) == 0 datafile = op.join(datadir, 'example_dicom.tbz2') @@ -79,42 +124,69 @@ def test_scanDir(): with tarfile.open(datafile) as f: f.extractall() - series = fsldcm.scanDir(td) - assert len(series) == 3 + series = fsldcm.scanDir('.') + assert len(series) == 2 for s in series: assert (s['PatientName'] == 'MCCARTHY_PAUL' or s['PatientName'] == 'MCCARTHY_PAUL_2') +def test_sersiesCRC(): + RANDOM = object() + tests = [ + ({'SeriesInstanceUID' : 'hello-world'}, '2983461467'), + ({'SeriesInstanceUID' : RANDOM, 'EchoNumber' : 0}, RANDOM), + ({'SeriesInstanceUID' : RANDOM, 'EchoNumber' : 1}, RANDOM), + ({'SeriesInstanceUID' : RANDOM, 'EchoNumber' : 2}, RANDOM), + ({'SeriesInstanceUID' : RANDOM, 'EchoNumber' : 3}, RANDOM), + ] + + for series, expect in tests: + series = dict(series) + if expect is RANDOM: + expect = ''.join(random.choices( + string.ascii_letters + string.digits, k=30)) + series['SeriesInstanceUID'] = expect + expect = str(binascii.crc32(expect.encode())) + echo = series.get('EchoNumber', 0) + if echo > 1: + expect += '.{}'.format(echo) + assert fsldcm.seriesCRC(series) == expect + + def test_loadSeries(): - with tempdir.tempdir() as td: + # test a pre-CRC and a post-CRC version + for version in ('1.0.20190410', '1.0.20190902'): - datafile = op.join(datadir, 'example_dicom.tbz2') + with install_dcm2niix(version): - with tarfile.open(datafile) as f: - f.extractall() + datafile = op.join(datadir, 'example_dicom.tbz2') + + with tarfile.open(datafile) as f: + f.extractall() - series = fsldcm.scanDir(td) - expShape = (512, 512, 1) - explens = [1, 2] + dcmdir = os.getcwd() + series = fsldcm.scanDir(dcmdir) + expShape = (512, 512, 1) + explens = [1, 1] - for s, explen in zip(series, explens): + for s, explen in zip(series, explens): - imgs = fsldcm.loadSeries(s) + imgs = fsldcm.loadSeries(s) - assert len(imgs) == explen + assert len(imgs) == explen - for img in imgs: + for img in imgs: - assert img.dicomDir == td - assert img.shape == expShape - assert img[:].shape == expShape - assert img.getMeta('PatientName') == 'MCCARTHY_PAUL' or \ - img.getMeta('PatientName') == 'MCCARTHY_PAUL_2' - assert 'PatientName' in img.metaKeys() - assert 'MCCARTHY_PAUL' in img.metaValues() or \ - 'MCCARTHY_PAUL_2' in img.metaValues() - assert ('PatientName', 'MCCARTHY_PAUL') in img.metaItems() or \ - ('PatientName', 'MCCARTHY_PAUL_2') in img.metaItems() + assert img.dicomDir == dcmdir + assert img.shape == expShape + assert img[:].shape == expShape + assert img.getMeta('PatientName') == 'MCCARTHY_PAUL' or \ + img.getMeta('PatientName') == 'MCCARTHY_PAUL_2' + assert 'PatientName' in img.metaKeys() + assert 'MCCARTHY_PAUL' in img.metaValues() or \ + 'MCCARTHY_PAUL_2' in img.metaValues() + assert ('PatientName', 'MCCARTHY_PAUL') in img.metaItems() or \ + ('PatientName', 'MCCARTHY_PAUL_2') in img.metaItems() -- GitLab