comparison Tests/CheckZipStreams.py @ 404:931be0125954

Tests/CheckZipStreams.py
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 03 Jun 2021 17:03:06 +0200
parents
children e769bcf2b94f
comparison
equal deleted inserted replaced
403:e08e15befa0c 404:931be0125954
1 #!/usr/bin/python2.7
2
3 # Orthanc - A Lightweight, RESTful DICOM Store
4 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
5 # Department, University Hospital of Liege, Belgium
6 # Copyright (C) 2017-2021 Osimis S.A., Belgium
7 #
8 # This program is free software: you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation, either version 3 of the
11 # License, or (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
22 import Toolbox
23 import json
24 import os
25 import subprocess
26 import sys
27 import time
28 import zipfile
29 import multiprocessing
30 import threading
31 import queue
32
33
34 if len(sys.argv) != 3:
35 print('Must provide a path to Orthanc binaries and to a sample ZIP archive with one DICOM study')
36 exit(-1)
37
38 if not os.path.isfile(sys.argv[1]):
39 raise Exception('Inexistent path: %s' % sys.argv[1])
40
41 if not os.path.isfile(sys.argv[2]):
42 raise Exception('Inexistent path: %s' % sys.argv[2])
43
44
45 TMP = '/tmp/OrthancTest'
46 CONFIG = os.path.join(TMP, 'Configuration.json')
47
48 if os.path.exists(TMP):
49 print('Temporary path already exists: %s' % TMP)
50 exit(-1)
51
52 os.mkdir(TMP)
53
54
55 ORTHANC = Toolbox.DefineOrthanc(username = 'orthanc',
56 password = 'orthanc')
57
58
59 def GetArchive(config, testFunction):
60 with open(CONFIG, 'w') as f:
61 f.write(json.dumps(config))
62
63 process = subprocess.Popen(
64 [ sys.argv[1], CONFIG, '--no-jobs' ],
65 cwd = TMP,
66 #stdout=subprocess.PIPE,
67 stderr=subprocess.PIPE,
68 #shell=True
69 )
70
71 #time.sleep(1)
72
73 while True:
74 try:
75 system = Toolbox.DoGet(ORTHANC, '/system')
76 break
77 except:
78 time.sleep(0.1)
79
80 try:
81 with open(sys.argv[2], 'rb') as f:
82 Toolbox.DoPost(ORTHANC, '/instances', f.read())
83
84 studies = Toolbox.DoGet(ORTHANC, '/studies')
85 if len(studies) != 1:
86 raise Exception('More than one study is available in Orthanc')
87
88 testFunction(ORTHANC, studies[0])
89
90 finally:
91 process.terminate()
92 process.wait()
93
94
95 def Assert(b):
96 if not b:
97 raise Exception('Bad result')
98
99
100 for streaming in [ False, True, None ]:
101 if streaming == True:
102 suffix = 'with streaming'
103 config = { 'SynchronousZipStream' : True }
104 elif streaming == False:
105 suffix = 'without streaming'
106 config = { 'SynchronousZipStream' : False }
107 else:
108 suffix = 'default streaming'
109 config = { }
110
111
112 print('==== SIMPLE TEST - %s ====' % suffix)
113 def test(ORTHANC, study):
114 instances = Toolbox.DoGet(ORTHANC, '/instances')
115 z = Toolbox.ParseArchive(Toolbox.DoGet(ORTHANC, '/studies/%s/archive' % study))
116 Assert(len(instances) == len(z.namelist()))
117
118 GetArchive(config, test)
119
120
121 print('==== CANCEL SERVER JOB - %s ====' % suffix)
122 def TestCancelServerJob(ORTHANC, study):
123 def CheckCorruptedArchive(queue):
124 try:
125 z = Toolbox.DoGet(ORTHANC, '/studies/%s/archive' % study)
126 Assert(streaming == True or streaming == None)
127
128 try:
129 Toolbox.ParseArchive(z)
130 print('error, got valid archive')
131 queue.put(False) # The archive is not corrupted as expected
132 except zipfile.BadZipfile as e:
133 print('ok, got corrupted archive')
134 queue.put(True)
135
136 except Exception as e:
137 Assert(streaming == False)
138 Assert(e[0] == 500) # HTTP status code 500
139 print('ok, got none archive')
140 queue.put(True)
141
142 def cancel():
143 while True:
144 j = Toolbox.DoGet(ORTHANC, '/jobs?expand')
145 Assert(len(j) <= 1)
146 if len(j) == 1:
147 Assert(j[0]['State'] == 'Running')
148 Toolbox.DoPost(ORTHANC, '/jobs/%s/cancel' % j[0]['ID'], {})
149 return
150 time.sleep(.01)
151
152 q = queue.Queue()
153 t1 = threading.Thread(target=cancel)
154 t2 = threading.Thread(target=CheckCorruptedArchive, args=(q,))
155 t1.start()
156 t2.start()
157 t1.join()
158 t2.join()
159
160 Assert(q.get() == True)
161
162 GetArchive(config, TestCancelServerJob)
163
164
165 print('==== CANCEL HTTP CLIENT - %s ====' % suffix)
166 def TestCancelHttpClient(ORTHANC, study):
167 def DownloadArchive(queue):
168 z = Toolbox.DoGet(ORTHANC, '/studies/%s/archive' % study)
169 queue.put('success')
170
171 q = multiprocessing.Queue()
172 p = multiprocessing.Process(target=DownloadArchive, args=(q, ))
173 p.start()
174 time.sleep(0.05)
175 p.terminate()
176 p.join()
177 Assert(q.qsize() == 0)
178
179 while True:
180 j = Toolbox.DoGet(ORTHANC, '/jobs?expand')
181 Assert(len(j) == 1)
182 if j[0]['State'] == 'Running':
183 continue
184 else:
185 if streaming == False:
186 # The sending of the temporary file is *not* part
187 # of the job in this case
188 Assert(j[0]['State'] == 'Success')
189 else:
190 Assert(j[0]['State'] == 'Failure')
191 Assert(j[0]['ErrorCode'] == 14) # Cannot write to file
192 break
193
194 GetArchive(config, TestCancelHttpClient)
195
196
197 print('Success!')