Mercurial > hg > orthanc-tests
annotate Tests/Toolbox.py @ 391:227d9a932467
testing revisions in metadata
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 16 Apr 2021 17:13:53 +0200 |
parents | 79ce0f7a9714 |
children | 9528e2a03d3c |
rev | line source |
---|---|
0 | 1 #!/usr/bin/python |
2 | |
1 | 3 # Orthanc - A Lightweight, RESTful DICOM Store |
73 | 4 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
1 | 5 # Department, University Hospital of Liege, Belgium |
363
79ce0f7a9714
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
342
diff
changeset
|
6 # Copyright (C) 2017-2021 Osimis S.A., Belgium |
1 | 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/>. | |
0 | 20 |
21 | |
22 import hashlib | |
23 import httplib2 | |
24 import json | |
4 | 25 import os |
1 | 26 import re |
4 | 27 import signal |
1 | 28 import subprocess |
291
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
29 import tempfile |
4 | 30 import threading |
83 | 31 import sys |
0 | 32 import time |
1 | 33 import zipfile |
0 | 34 |
337
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
35 from xml.dom import minidom |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
36 |
304 | 37 from PIL import Image, ImageChops |
38 import math | |
39 import operator | |
40 | |
83 | 41 |
42 if (sys.version_info >= (3, 0)): | |
43 from urllib.parse import urlencode | |
44 from io import StringIO | |
45 from io import BytesIO | |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
46 from urllib.parse import unquote |
83 | 47 |
48 else: | |
49 from urllib import urlencode | |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
50 from urlparse import unquote |
83 | 51 |
52 # http://stackoverflow.com/a/1313868/881731 | |
53 try: | |
54 from cStringIO import StringIO | |
55 except: | |
56 from StringIO import StringIO | |
3 | 57 |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
58 |
83 | 59 def _DecodeJson(s): |
60 t = s | |
61 | |
62 if (sys.version_info >= (3, 0)): | |
63 try: | |
64 t = s.decode() | |
65 except: | |
66 pass | |
67 | |
68 try: | |
69 return json.loads(t) | |
70 except: | |
71 return t | |
0 | 72 |
73 | |
13 | 74 def DefineOrthanc(server = 'localhost', |
75 restPort = 8042, | |
1 | 76 username = None, |
77 password = None, | |
78 aet = 'ORTHANC', | |
79 dicomPort = 4242): | |
13 | 80 #m = re.match(r'(http|https)://([^:]+):([^@]+)@([^@]+)', url) |
81 #if m != None: | |
82 # url = m.groups()[0] + '://' + m.groups()[3] | |
83 # username = m.groups()[1] | |
84 # password = m.groups()[2] | |
0 | 85 |
13 | 86 #if not url.endswith('/'): |
87 # url += '/' | |
0 | 88 |
1 | 89 return { |
13 | 90 'Server' : server, |
91 'Url' : 'http://%s:%d/' % (server, restPort), | |
1 | 92 'Username' : username, |
93 'Password' : password, | |
94 'DicomAet' : aet, | |
95 'DicomPort' : dicomPort | |
96 } | |
0 | 97 |
98 | |
99 def _SetupCredentials(orthanc, http): | |
1 | 100 if (orthanc['Username'] != None and |
101 orthanc['Password'] != None): | |
102 http.add_credentials(orthanc['Username'], orthanc['Password']) | |
0 | 103 |
28 | 104 def DoGetRaw(orthanc, uri, data = {}, body = None, headers = {}): |
0 | 105 d = '' |
106 if len(data.keys()) > 0: | |
107 d = '?' + urlencode(data) | |
108 | |
109 http = httplib2.Http() | |
21
2a29bcff60a7
tests of image decoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
110 http.follow_redirects = False |
0 | 111 _SetupCredentials(orthanc, http) |
112 | |
1 | 113 resp, content = http.request(orthanc['Url'] + uri + d, 'GET', body = body, |
0 | 114 headers = headers) |
28 | 115 return (resp, content) |
116 | |
117 | |
118 def DoGet(orthanc, uri, data = {}, body = None, headers = {}): | |
119 (resp, content) = DoGetRaw(orthanc, uri, data = data, body = body, headers = headers) | |
120 | |
0 | 121 if not (resp.status in [ 200 ]): |
239
8980bd19e31d
dicomweb: test_allowed_methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
222
diff
changeset
|
122 raise Exception(resp.status, resp) |
0 | 123 else: |
83 | 124 return _DecodeJson(content) |
0 | 125 |
126 def _DoPutOrPost(orthanc, uri, method, data, contentType, headers): | |
127 http = httplib2.Http() | |
21
2a29bcff60a7
tests of image decoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
13
diff
changeset
|
128 http.follow_redirects = False |
0 | 129 _SetupCredentials(orthanc, http) |
130 | |
83 | 131 if isinstance(data, (str, bytearray, bytes)): |
0 | 132 body = data |
133 if len(contentType) != 0: | |
134 headers['content-type'] = contentType | |
135 else: | |
136 body = json.dumps(data) | |
137 headers['content-type'] = 'application/json' | |
138 | |
139 headers['expect'] = '' | |
140 | |
1 | 141 resp, content = http.request(orthanc['Url'] + uri, method, |
0 | 142 body = body, |
143 headers = headers) | |
391
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
144 return (resp, content) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
145 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
146 def DoDeleteRaw(orthanc, uri, headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
147 http = httplib2.Http() |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
148 http.follow_redirects = False |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
149 _SetupCredentials(orthanc, http) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
150 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
151 resp, content = http.request(orthanc['Url'] + uri, 'DELETE', headers = headers) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
152 return (resp, content) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
153 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
154 def DoDelete(orthanc, uri, headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
155 (resp, content) = DoDeleteRaw(orthanc, uri, headers) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
156 if not (resp.status in [ 200 ]): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
157 raise Exception(resp.status, resp) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
158 else: |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
159 return _DecodeJson(content) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
160 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
161 def DoPutRaw(orthanc, uri, data = {}, contentType = '', headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
162 return _DoPutOrPost(orthanc, uri, 'PUT', data, contentType, headers) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
163 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
164 def DoPut(orthanc, uri, data = {}, contentType = '', headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
165 (resp, content) = DoPutRaw(orthanc, uri, data, contentType, headers) |
342
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
166 if not (resp.status in [ 200, 201, 302 ]): |
239
8980bd19e31d
dicomweb: test_allowed_methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
222
diff
changeset
|
167 raise Exception(resp.status, resp) |
0 | 168 else: |
83 | 169 return _DecodeJson(content) |
0 | 170 |
391
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
171 def DoPostRaw(orthanc, uri, data = {}, contentType = '', headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
172 return _DoPutOrPost(orthanc, uri, 'POST', data, contentType, headers) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
173 |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
174 def DoPost(orthanc, uri, data = {}, contentType = '', headers = {}): |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
175 (resp, content) = DoPostRaw(orthanc, uri, data, contentType, headers) |
227d9a932467
testing revisions in metadata
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
363
diff
changeset
|
176 if not (resp.status in [ 200, 201, 302 ]): |
239
8980bd19e31d
dicomweb: test_allowed_methods
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
222
diff
changeset
|
177 raise Exception(resp.status, resp) |
0 | 178 else: |
83 | 179 return _DecodeJson(content) |
0 | 180 |
13 | 181 def GetDatabasePath(filename): |
182 return os.path.join(os.path.dirname(__file__), '..', 'Database', filename) | |
183 | |
0 | 184 def UploadInstance(orthanc, filename): |
83 | 185 with open(GetDatabasePath(filename), 'rb') as f: |
186 d = f.read() | |
187 | |
0 | 188 return DoPost(orthanc, '/instances', d, 'application/dicom') |
189 | |
190 def UploadFolder(orthanc, path): | |
13 | 191 for i in os.listdir(GetDatabasePath(path)): |
1 | 192 try: |
193 UploadInstance(orthanc, os.path.join(path, i)) | |
194 except: | |
195 pass | |
0 | 196 |
197 def DropOrthanc(orthanc): | |
198 # Reset the Lua callbacks | |
199 DoPost(orthanc, '/tools/execute-script', 'function OnStoredInstance(instanceId, tags, metadata) end', 'application/lua') | |
200 | |
201 DoDelete(orthanc, '/exports') | |
202 | |
203 for s in DoGet(orthanc, '/patients'): | |
204 DoDelete(orthanc, '/patients/%s' % s) | |
205 | |
174 | 206 def InstallLuaScriptFromPath(orthanc, path): |
207 with open(GetDatabasePath(path), 'r') as f: | |
208 InstallLuaScript(orthanc, f.read()) | |
209 | |
210 def InstallLuaScript(orthanc, script): | |
211 DoPost(orthanc, '/tools/execute-script', script, 'application/lua') | |
212 | |
213 def UninstallLuaCallbacks(orthanc): | |
214 DoPost(orthanc, '/tools/execute-script', 'function OnStoredInstance() end', 'application/lua') | |
215 InstallLuaScriptFromPath(orthanc, 'Lua/TransferSyntaxEnable.lua') | |
216 | |
217 | |
0 | 218 def ComputeMD5(data): |
219 m = hashlib.md5() | |
220 m.update(data) | |
221 return m.hexdigest() | |
222 | |
249
24e5c8ca9440
DICOMweb: test_rendered
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
239
diff
changeset
|
223 def UncompressImage(data): |
83 | 224 if (sys.version_info >= (3, 0)): |
225 return Image.open(BytesIO(data)) | |
226 else: | |
227 return Image.open(StringIO(data)) | |
0 | 228 |
249
24e5c8ca9440
DICOMweb: test_rendered
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
239
diff
changeset
|
229 def GetImage(orthanc, uri, headers = {}): |
24e5c8ca9440
DICOMweb: test_rendered
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
239
diff
changeset
|
230 # http://www.pythonware.com/library/pil/handbook/introduction.htm |
24e5c8ca9440
DICOMweb: test_rendered
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
239
diff
changeset
|
231 return UncompressImage(DoGet(orthanc, uri, headers = headers)) |
24e5c8ca9440
DICOMweb: test_rendered
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
239
diff
changeset
|
232 |
0 | 233 def GetArchive(orthanc, uri): |
234 # http://stackoverflow.com/a/1313868/881731 | |
235 s = DoGet(orthanc, uri) | |
83 | 236 |
237 if (sys.version_info >= (3, 0)): | |
238 return zipfile.ZipFile(BytesIO(s), "r") | |
239 else: | |
240 return zipfile.ZipFile(StringIO(s), "r") | |
0 | 241 |
192 | 242 def PostArchive(orthanc, uri, body): |
243 # http://stackoverflow.com/a/1313868/881731 | |
244 s = DoPost(orthanc, uri, body) | |
245 | |
246 if (sys.version_info >= (3, 0)): | |
247 return zipfile.ZipFile(BytesIO(s), "r") | |
248 else: | |
249 return zipfile.ZipFile(StringIO(s), "r") | |
250 | |
1 | 251 def IsDefinedInLua(orthanc, name): |
0 | 252 s = DoPost(orthanc, '/tools/execute-script', 'print(type(%s))' % name, 'application/lua') |
253 return (s.strip() != 'nil') | |
254 | |
1 | 255 def WaitEmpty(orthanc): |
0 | 256 while True: |
1 | 257 if len(DoGet(orthanc, '/instances')) == 0: |
0 | 258 return |
342
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
259 time.sleep(0.01) |
0 | 260 |
137
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
261 def WaitJobDone(orthanc, job): |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
262 while True: |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
263 s = DoGet(orthanc, '/jobs/%s' % job) ['State'] |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
264 |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
265 if s == 'Success': |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
266 return True |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
267 elif s == 'Failure': |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
268 return False |
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
269 |
342
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
270 time.sleep(0.01) |
137
412d5f70447e
testing asynchronous c-move
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
130
diff
changeset
|
271 |
138 | 272 def MonitorJob(orthanc, func): # "func" is a lambda |
273 a = set(DoGet(orthanc, '/jobs')) | |
274 func() | |
275 b = set(DoGet(orthanc, '/jobs')) | |
276 | |
277 diff = list(b - a) | |
278 if len(diff) != 1: | |
279 print('No job was created!') | |
280 return False | |
281 else: | |
282 return WaitJobDone(orthanc, diff[0]) | |
283 | |
179
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
284 def MonitorJob2(orthanc, func): # "func" is a lambda |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
285 a = set(DoGet(orthanc, '/jobs')) |
181 | 286 job = func() |
179
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
287 b = set(DoGet(orthanc, '/jobs')) |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
288 |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
289 diff = list(b - a) |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
290 if len(diff) != 1: |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
291 print('No job was created!') |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
292 return None |
181 | 293 elif (not 'ID' in job or |
294 diff[0] != job['ID']): | |
295 print('Mismatch in the job ID') | |
296 return None | |
179
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
297 elif WaitJobDone(orthanc, diff[0]): |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
298 return diff[0] |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
299 else: |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
300 print('Error while executing the job') |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
301 return None |
8a2dd77d4035
testing split/merge
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
174
diff
changeset
|
302 |
220 | 303 def WaitAllNewJobsDone(orthanc, func): # "func" is a lambda |
304 a = set(DoGet(orthanc, '/jobs')) | |
305 func() | |
306 | |
307 first = True | |
308 | |
309 while True: | |
310 b = set(DoGet(orthanc, '/jobs')) | |
311 | |
312 diff = list(b - a) | |
313 if len(diff) == 0: | |
314 if first: | |
315 raise Exception('No job was created') | |
316 else: | |
317 return # We're done | |
318 else: | |
319 first = False | |
320 | |
321 if WaitJobDone(orthanc, diff[0]): | |
322 a.add(diff[0]) | |
323 else: | |
324 raise Exception('Error while executing the job') | |
325 | |
326 | |
1 | 327 def GetDockerHostAddress(): |
328 route = subprocess.check_output([ '/sbin/ip', 'route' ]) | |
329 m = re.search(r'default via ([0-9.]+)', route) | |
330 if m == None: | |
331 return 'localhost' | |
332 else: | |
333 return m.groups()[0] | |
4 | 334 |
44
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
335 def FindExecutable(name): |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
336 p = os.path.join('/usr/local/bin', name) |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
337 if os.path.isfile(p): |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
338 return p |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
339 |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
340 p = os.path.join('/usr/local/sbin', name) |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
341 if os.path.isfile(p): |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
342 return p |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
343 |
ffa542cce638
Toolbox.FindExecutable()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
28
diff
changeset
|
344 return name |
4 | 345 |
173 | 346 def IsOrthancVersionAbove(orthanc, major, minor, revision): |
347 v = DoGet(orthanc, '/system')['Version'] | |
348 | |
349 if v == 'mainline': | |
350 return True | |
351 else: | |
352 tmp = v.split('.') | |
353 a = int(tmp[0]) | |
354 b = int(tmp[1]) | |
355 c = int(tmp[2]) | |
356 return (a > major or | |
357 (a == major and b > minor) or | |
358 (a == major and b == minor and c >= revision)) | |
4 | 359 |
360 | |
361 class ExternalCommandThread: | |
362 @staticmethod | |
363 def ExternalCommandFunction(arg, stop_event, command, env): | |
318
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
364 with open(os.devnull, 'w') as devnull: |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
365 external = subprocess.Popen(command, env = env, stderr = devnull) |
4 | 366 |
318
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
367 while (not stop_event.is_set()): |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
368 error = external.poll() |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
369 if error != None: |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
370 # http://stackoverflow.com/a/1489838/881731 |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
371 os._exit(-1) |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
372 stop_event.wait(0.1) |
4 | 373 |
83 | 374 print('Stopping the external command') |
4 | 375 external.terminate() |
9 | 376 external.communicate() # Wait for the command to stop |
4 | 377 |
378 def __init__(self, command, env = None): | |
379 self.thread_stop = threading.Event() | |
380 self.thread = threading.Thread(target = self.ExternalCommandFunction, | |
381 args = (10, self.thread_stop, command, env)) | |
9 | 382 #self.daemon = True |
4 | 383 self.thread.start() |
384 | |
385 def stop(self): | |
386 self.thread_stop.set() | |
387 self.thread.join() | |
220 | 388 |
389 | |
222
0f03ee6ffa80
DICOMweb: test_wado_hierarchy, test_wado_bulk, test_bitbucket_issue_112
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
220
diff
changeset
|
390 def AssertAlmostEqualRecursive(self, a, b, places = 7, ignoreKeys = []): |
220 | 391 if type(a) is dict: |
392 self.assertTrue(type(b) is dict) | |
393 self.assertEqual(a.keys(), b.keys()) | |
394 for key, value in a.items(): | |
222
0f03ee6ffa80
DICOMweb: test_wado_hierarchy, test_wado_bulk, test_bitbucket_issue_112
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
220
diff
changeset
|
395 if not key in ignoreKeys: |
0f03ee6ffa80
DICOMweb: test_wado_hierarchy, test_wado_bulk, test_bitbucket_issue_112
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
220
diff
changeset
|
396 AssertAlmostEqualRecursive(self, a[key], b[key], places) |
220 | 397 |
398 elif type(a) is list: | |
399 self.assertTrue(type(b) is list) | |
400 self.assertEqual(len(a), len(b)) | |
401 for i in range(len(a)): | |
402 AssertAlmostEqualRecursive(self, a[i], b[i], places) | |
403 | |
404 else: | |
405 self.assertAlmostEqual(a, b, places = places) | |
291
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
406 |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
407 |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
408 def GetTransferSyntax(dicom): |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
409 with tempfile.NamedTemporaryFile(delete = True) as f: |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
410 f.write(dicom) |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
411 f.flush() |
318
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
412 |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
413 with open(os.devnull, 'w') as devnull: |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
414 data = subprocess.check_output([ FindExecutable('dcm2xml'), f.name ], |
bac7cc80f240
dicomweb: test_wado_transcoding
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
304
diff
changeset
|
415 stderr = devnull) |
291
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
416 |
cfa785074c64
test_modify_transcode
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
417 return re.search('<data-set xfer="(.*?)"', data).group(1) |
304 | 418 |
419 | |
420 def HasGdcmPlugin(orthanc): | |
421 plugins = DoGet(orthanc, '/plugins') | |
422 return ('gdcm' in plugins) | |
423 | |
424 | |
425 def _GetMaxImageDifference(im1, im2): | |
426 h = ImageChops.difference(im1, im2).histogram() | |
427 | |
428 if len(h) < 256: | |
429 raise Exception() | |
430 | |
431 i = len(h) - 1 | |
432 while h[i] == 0: | |
433 i -= 1 | |
434 | |
435 return i | |
436 | |
437 | |
438 def GetMaxImageDifference(im1, im2): | |
439 if im1.mode != im2.mode: | |
440 raise Exception('Incompatible image modes') | |
441 | |
442 if im1.mode == 'RGB': | |
443 red1, green1, blue1 = im1.split() | |
444 red2, green2, blue2 = im2.split() | |
445 return max([ _GetMaxImageDifference(red1, red2), | |
446 _GetMaxImageDifference(green1, green2), | |
447 _GetMaxImageDifference(blue1, blue2) ]) | |
448 else: | |
449 return _GetMaxImageDifference(im1, im2) | |
337
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
450 |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
451 |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
452 def DoPropFind(orthanc, uri, depth): |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
453 http = httplib2.Http() |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
454 http.follow_redirects = False |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
455 _SetupCredentials(orthanc, http) |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
456 |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
457 resp, content = http.request(orthanc['Url'] + uri, 'PROPFIND', headers = { 'Depth' : str(depth) }) |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
458 |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
459 if not (resp.status in [ 207 ]): |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
460 raise Exception(resp.status, resp) |
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
461 else: |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
462 xml = minidom.parseString(content) |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
463 |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
464 if (xml.documentElement.nodeName != 'D:multistatus' or |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
465 xml.documentElement.attributes['xmlns:D'].value != 'DAV:'): |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
466 raise Exception() |
337
ec13ace43bde
trying webdav tests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
318
diff
changeset
|
467 |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
468 result = {} |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
469 |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
470 for i in xml.documentElement.childNodes: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
471 if i.nodeType == minidom.Node.ELEMENT_NODE: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
472 if i.nodeName != 'D:response': |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
473 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
474 href = None |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
475 prop = None |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
476 for j in i.childNodes: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
477 if j.nodeType == minidom.Node.ELEMENT_NODE: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
478 if j.nodeName == 'D:href': |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
479 if href == None: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
480 href = unquote(j.firstChild.nodeValue) |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
481 else: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
482 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
483 elif j.nodeName == 'D:propstat': |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
484 for k in j.childNodes: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
485 if k.nodeName == 'D:status': |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
486 if k.firstChild.nodeValue != 'HTTP/1.1 200 OK': |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
487 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
488 elif k.nodeType == minidom.Node.ELEMENT_NODE: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
489 if (k.nodeName != 'D:prop' or |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
490 prop != None): |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
491 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
492 prop = k |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
493 else: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
494 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
495 if href == None or prop == None: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
496 raise Exception() |
342
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
497 |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
498 info = {} |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
499 |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
500 for j in prop.childNodes: |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
501 if j.nodeType == minidom.Node.ELEMENT_NODE: |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
502 if j.nodeName == 'D:displayname': |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
503 info['displayname'] = j.firstChild.nodeValue if j.firstChild != None else '' |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
504 elif j.nodeName == 'D:creationdate': |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
505 info['creationdate'] = j.firstChild.nodeValue |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
506 elif j.nodeName == 'D:getlastmodified': |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
507 info['lastmodified'] = j.firstChild.nodeValue |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
508 elif j.nodeName == 'D:resourcetype': |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
509 k = j.getElementsByTagName('D:collection') |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
510 info['folder'] = (len(k) == 1) |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
511 |
bf8369ea3ff1
more tests of webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
341
diff
changeset
|
512 result[href] = info |
341
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
513 elif i.nodeType != minidom.Node.TEXT_NODE: |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
514 raise Exception() |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
515 |
66a36befb208
extending Toolbox.DoPropFind()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
337
diff
changeset
|
516 return result |