# HG changeset patch # User Sebastien Jodogne # Date 1434541554 -7200 # Node ID f8d781d1d267b533f3998f2289d9ec2e1f9f8f52 # Parent 302f06f3bba27ce9ae1fae59d2c229fb646193bd test_changes, test_archive, test_media_archive diff -r 302f06f3bba2 -r f8d781d1d267 Database/README.txt --- a/Database/README.txt Wed Jun 17 12:04:23 2015 +0200 +++ b/Database/README.txt Wed Jun 17 13:45:54 2015 +0200 @@ -40,7 +40,7 @@ Here is the source of each set of sample images: - Brainix/* : From OsiriX, "BRAINIX". -- DummyCT.dcm : From Osirix, "KNEE" with PixelData removed. +- DummyCT.dcm : From Osirix, "KNIX" with PixelData removed. - Phenix/* : From OsiriX, "PHENIX". - Knee/* : From OsiriX, "KNEE". - Multiframe.dcm : From GDCM, "images_of_interest/PHILIPS_Integris_H-8-MONO2-Multiframe.dcm" diff -r 302f06f3bba2 -r f8d781d1d267 Start.sh --- a/Start.sh Wed Jun 17 12:04:23 2015 +0200 +++ b/Start.sh Wed Jun 17 13:45:54 2015 +0200 @@ -1,3 +1,6 @@ #!/bin/bash -sudo docker run --rm -t -i -v `pwd`:/tmp/tests:ro -p 5000:8042 -p 5001:4242 --entrypoint python jodogne/orthanc-tests /tmp/tests/Tests/Run.py --force $* +# Without Docker: +# python ./Tests/Run.py --force + +sudo docker run --rm -t -i -v `pwd`:/tmp/tests:ro -p 5000:5000 -p 5001:5001 --entrypoint python jodogne/orthanc-tests /tmp/tests/Tests/Run.py --docker $* diff -r 302f06f3bba2 -r f8d781d1d267 Tests/Run.py --- a/Tests/Run.py Wed Jun 17 12:04:23 2015 +0200 +++ b/Tests/Run.py Wed Jun 17 13:45:54 2015 +0200 @@ -35,7 +35,7 @@ parser = argparse.ArgumentParser(description = 'Run the integration tests on some instance of Orthanc.') parser.add_argument('--server', - default = GetDockerHostAddress(), + default = 'localhost', help = 'Address of the Orthanc server to test') parser.add_argument('--aet', default = 'ORTHANC', @@ -56,6 +56,8 @@ help = 'Password to the REST API') parser.add_argument('--force', help = 'Do not warn the user', action = 'store_true') +parser.add_argument('--docker', help = 'These tests are run from Docker', + action = 'store_true') parser.add_argument('options', metavar = 'N', nargs = '*', help='Arguments to Python unittest') @@ -79,27 +81,40 @@ ## Orthanc ## +if args.docker: + args.server = GetDockerHostAddress() + CONFIG = '/tmp/Configuration.json' subprocess.check_call([ 'Orthanc', '--config=%s' % CONFIG ]) -with open(CONFIG, 'r') as f: +with open(CONFIG, 'rt') as f: config = f.read() config = re.sub(r'("StorageDirectory"\s*:)\s*".*?"', r'\1 "/tmp/OrthancStorage"', config) config = re.sub(r'("IndexDirectory"\s*:)\s*".*?"', r'\1 "/tmp/OrthancStorage"', config) config = re.sub(r'("DicomAet"\s*:)\s*".*?"', r'\1 "ORTHANCTEST"', config) +config = re.sub(r'("DicomPort"\s*:)\s*.*?,', r'\1 5001,', config) +config = re.sub(r'("HttpPort"\s*:)\s*.*?,', r'\1 5000,', config) config = re.sub(r'("RemoteAccessAllowed"\s*:)\s*false', r'\1 true', config) config = re.sub(r'("AuthenticationEnabled"\s*:)\s*false', r'\1 true', config) -config = re.sub(r'("RegisteredUsers"\s*:)\s*{', r'\1 { "alice" : [ "orthanctest" ]', config) +config = re.sub(r'("RegisteredUsers"\s*:)\s*{', r'\1 { "alice" : "orthanctest"', config) config = re.sub(r'("DicomModalities"\s*:)\s*{', r'\1 { "orthanc" : [ "%s", "%s", "%s" ]' % (args.aet, args.server, args.dicom), config) +with open(CONFIG, 'wt') as f: + f.write(config) + localOrthanc = ExternalCommandThread([ 'Orthanc', CONFIG, #'--verbose' ]) -LOCAL = DefineOrthanc(aet = 'ORTHANCTEST') +LOCAL = DefineOrthanc(aet = 'ORTHANCTEST', + url = 'http://localhost:5000', + dicomPort = 5001, + username = 'alice', + password = 'orthanctest') + REMOTE = DefineOrthanc(url = 'http://%s:%d/' % (args.server, args.rest), username = args.username, password = args.password, @@ -108,7 +123,7 @@ -print('Parameters of the instance of Orthanc to test:') +print('Parameters of the instance of Orthanc being tested:') pprint.pprint(REMOTE) print('') diff -r 302f06f3bba2 -r f8d781d1d267 Tests/Tests.py --- a/Tests/Tests.py Wed Jun 17 12:04:23 2015 +0200 +++ b/Tests/Tests.py Wed Jun 17 13:45:54 2015 +0200 @@ -228,3 +228,136 @@ self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/frames/aaa/preview' % i)) self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/frames/76/preview' % i)) + + def test_changes(self): + # Check emptiness + c = DoGet(_REMOTE, '/changes') + self.assertEqual(0, len(c['Changes'])) + self.assertEqual(0, c['Last']) + self.assertTrue(c['Done']) + c = DoGet(_REMOTE, '/changes?last') + self.assertEqual(0, len(c['Changes'])) + self.assertEqual(0, c['Last']) + self.assertTrue(c['Done']) + + # Add 1 instance + i = UploadInstance(_REMOTE, 'Brainix/Flair/IM-0001-0001.dcm')['ID'] + c = DoGet(_REMOTE, '/changes') + begin = c['Last'] + self.assertEqual(4, len(c['Changes'])) + self.assertTrue(c['Done']) + self.assertEqual(c['Changes'][-1]['Seq'], c['Last']) + + c = DoGet(_REMOTE, '/changes?last') + self.assertEqual(1, len(c['Changes'])) + self.assertEqual(begin, c['Last']) + self.assertTrue(c['Done']) + c = DoGet(_REMOTE, '/changes?limit=1&since=' + str(begin - 1)) + self.assertEqual(1, len(c['Changes'])) + self.assertEqual(begin, c['Last']) + self.assertTrue(c['Done']) + c = DoGet(_REMOTE, '/changes?limit=1&since=' + str(begin - 2)) + self.assertEqual(1, len(c['Changes'])) + self.assertEqual(begin - 1, c['Last']) + self.assertFalse(c['Done']) + c = DoGet(_REMOTE, '/changes?limit=1&since=' + str(begin - 3)) + self.assertEqual(1, len(c['Changes'])) + self.assertEqual(begin - 2, c['Last']) + self.assertFalse(c['Done']) + + UploadFolder(_REMOTE, 'Knee/T1') + UploadFolder(_REMOTE, 'Knee/T2') + since = begin + countPatients = 0 + countStudies = 0 + countSeries = 0 + countInstances = 0 + completed = 0 + while True: + c = DoGet(_REMOTE, '/changes', { 'since' : since, 'limit' : 3 }) + since = c['Last'] + for i in c['Changes']: + if i['ResourceType'] == 'Instance': + countInstances += 1 + if i['ResourceType'] == 'Patient': + countPatients += 1 + if i['ResourceType'] == 'Study': + countStudies += 1 + if i['ResourceType'] == 'Series': + countSeries += 1 + if i['ChangeType'] == 'NewInstance': + countInstances += 1 + if i['ChangeType'] == 'NewPatient': + countPatients += 1 + if i['ChangeType'] == 'NewStudy': + countStudies += 1 + if i['ChangeType'] == 'NewSeries': + countSeries += 1 + if i['ChangeType'] == 'CompletedSeries': + completed += 1 + self.assertTrue('ID' in i) + self.assertTrue('Path' in i) + self.assertTrue('Seq' in i) + if c['Done']: + break + + self.assertEqual(2 * 50, countInstances) + self.assertEqual(2 * 1, countPatients) + self.assertEqual(2 * 1, countStudies) + self.assertEqual(2 * 2, countSeries) + self.assertEqual(0, completed) + + + def test_archive(self): + UploadInstance(_REMOTE, 'Knee/T1/IM-0001-0001.dcm') + UploadInstance(_REMOTE, 'Knee/T2/IM-0001-0001.dcm') + + z = GetArchive(_REMOTE, '/patients/%s/archive' % DoGet(_REMOTE, '/patients')[0]) + self.assertEqual(2, len(z.namelist())) + + z = GetArchive(_REMOTE, '/studies/%s/archive' % DoGet(_REMOTE, '/studies')[0]) + self.assertEqual(2, len(z.namelist())) + + z = GetArchive(_REMOTE, '/series/%s/archive' % DoGet(_REMOTE, '/series')[0]) + self.assertEqual(1, len(z.namelist())) + + UploadInstance(_REMOTE, 'Brainix/Flair/IM-0001-0001.dcm') + + z = GetArchive(_REMOTE, '/patients/%s/archive' % DoGet(_REMOTE, '/patients')[0]) + self.assertEqual(2, len(z.namelist())) + + + def test_media_archive(self): + UploadInstance(_REMOTE, 'Knee/T1/IM-0001-0001.dcm') + UploadInstance(_REMOTE, 'Knee/T2/IM-0001-0001.dcm') + + z = GetArchive(_REMOTE, '/patients/%s/media' % DoGet(_REMOTE, '/patients')[0]) + self.assertEqual(3, len(z.namelist())) + self.assertTrue('IMAGES/IM0' in z.namelist()) + self.assertTrue('IMAGES/IM1' in z.namelist()) + self.assertTrue('DICOMDIR' in z.namelist()) + + try: + os.remove('/tmp/DICOMDIR') + except: + # The file does not exist + pass + + z.extract('DICOMDIR', '/tmp') + a = subprocess.check_output([ 'dciodvfy', '/tmp/DICOMDIR' ], + stderr = subprocess.STDOUT).split('\n') + self.assertEqual(3, len(a)) + self.assertTrue(a[0].startswith('Warning')) + self.assertEqual('BasicDirectory', a[1]) + self.assertEqual('', a[2]) + + a = subprocess.check_output([ 'dcentvfy', '/tmp/DICOMDIR' ], + stderr = subprocess.STDOUT).split('\n') + self.assertEqual(1, len(a)) + self.assertEqual('', a[0]) + + a = subprocess.check_output([ 'dcm2xml', '/tmp/DICOMDIR' ]) + self.assertTrue(re.search('1.3.46.670589.11.17521.5.0.3124.2008081908590448738', a) != None) + self.assertTrue(re.search('1.3.46.670589.11.17521.5.0.3124.2008081909113806560', a) != None) + + os.remove('/tmp/DICOMDIR')