changeset 342:bf8369ea3ff1

more tests of webdav
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 15 Oct 2020 17:34:01 +0200
parents 66a36befb208
children 203af01474b6
files Plugins/WebDav/Run.py Tests/Run.py Tests/Tests.py Tests/Toolbox.py
diffstat 4 files changed, 98 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/WebDav/Run.py	Wed Oct 14 19:55:26 2020 +0200
+++ b/Plugins/WebDav/Run.py	Thu Oct 15 17:34:01 2020 +0200
@@ -158,6 +158,9 @@
         self.assertEqual(0, patients[0].size)
         self.assertEqual('', patients[0].contenttype)
 
+        self.assertRaises(Exception, lambda: WEBDAV.delete('/webdav/nope'))
+        self.assertRaises(Exception, lambda: WEBDAV.delete('/webdav/by-uids'))
+
 
     def test_upload(self):
         self.assertEqual(0, len(ListFiles('/webdav/uploads/', True)))
@@ -221,6 +224,11 @@
         self.assertTrue(('/webdav/by-uids/%s/%s/series.json' % (studyUid, seriesUid)) in content)
         self.assertTrue(('/webdav/by-uids/%s/%s/%s.dcm' % (studyUid, seriesUid, sopUid)) in content)
 
+        # Deleting the virtual files "study|series.json" has no
+        # effect, but is needed for recursive DELETE in some file explorers
+        WEBDAV.delete('/webdav/by-uids/%s/study.json' % studyUid)
+        WEBDAV.delete('/webdav/by-uids/%s/%s/series.json' % (studyUid, seriesUid))
+
         info = GetFileInfo('/webdav/by-uids/%s/study.json' % studyUid)
         self.assertEqual(info.contenttype, 'application/json')
         
@@ -377,6 +385,31 @@
         self.assertEqual(0, len(DoGet(ORTHANC, '/instances')))
         self.assertEqual(0, len(ListFiles('/webdav/by-dates/', True)))
 
+
+    def test_delete_folder(self):
+        # These deletes should have no effect
+        UploadInstance(ORTHANC, 'DummyCT.dcm')
+        self.assertEqual(1, len(DoGet(ORTHANC, '/instances')))
+        WEBDAV.delete('/webdav/by-uids/1.2.840.113619.2.176.2025.1499492.7391.1171285944.390/study.json')
+        WEBDAV.delete('/webdav/by-uids/1.2.840.113619.2.176.2025.1499492.7391.1171285944.390/1.2.840.113619.2.176.2025.1499492.7391.1171285944.394/series.json')
+        WEBDAV.delete('/webdav/by-dates/2007/2007-02')
+        WEBDAV.delete('/webdav/by-dates/2006')
+        self.assertEqual(1, len(DoGet(ORTHANC, '/instances')))
+
+        for path in [
+                '/webdav/by-uids/1.2.840.113619.2.176.2025.1499492.7391.1171285944.390/1.2.840.113619.2.176.2025.1499492.7391.1171285944.394/1.2.840.113619.2.176.2025.1499492.7040.1171286242.109.dcm',
+                '/webdav/by-patients/ozp00SjY2xG - KNIX/20070101 - Knee (R)/MR - AX.  FSE PD/66a662ce-7430e543-bad44d47-0dc5a943-ec7a538d.dcm',
+                '/webdav/by-studies/ozp00SjY2xG - KNIX - Knee (R)/MR - AX.  FSE PD/66a662ce-7430e543-bad44d47-0dc5a943-ec7a538d.dcm',
+                '/webdav/by-dates/2007/2007-01/ozp00SjY2xG - KNIX - Knee (R)/MR - AX.  FSE PD/66a662ce-7430e543-bad44d47-0dc5a943-ec7a538d.dcm',
+                ]:
+            tokens = path.split('/')
+            for i in range(4, len(tokens) + 1):
+                p = '/'.join(tokens[0:i])
+                UploadInstance(ORTHANC, 'DummyCT.dcm')
+                self.assertEqual(1, len(DoGet(ORTHANC, '/instances')))        
+                WEBDAV.delete(p)
+                self.assertEqual(0, len(DoGet(ORTHANC, '/instances')))
+
         
 try:
     print('\nStarting the tests...')
--- a/Tests/Run.py	Wed Oct 14 19:55:26 2020 +0200
+++ b/Tests/Run.py	Thu Oct 15 17:34:01 2020 +0200
@@ -59,6 +59,9 @@
                     action = 'store_true')
 parser.add_argument('--docker', help = 'These tests are run from Docker',
                     action = 'store_true')
+parser.add_argument('--orthanc',
+                    default = 'Orthanc',
+                    help = 'Path to the executable of Orthanc')
 parser.add_argument('options', metavar = 'N', nargs = '*',
                     help='Arguments to Python unittest')
 
@@ -83,7 +86,7 @@
 ##
 
 CONFIG = '/tmp/IntegrationTestsConfiguration.json'
-subprocess.check_call([ Toolbox.FindExecutable('Orthanc'), 
+subprocess.check_call([ Toolbox.FindExecutable(args.orthanc),
                         '--config=%s' % CONFIG ])
 
 with open(CONFIG, 'rt') as f:
@@ -113,8 +116,8 @@
     f.write(config)
 
 localOrthanc = ExternalCommandThread([ 
-    'Orthanc', 
-    CONFIG, 
+    Toolbox.FindExecutable(args.orthanc),
+    CONFIG,
     #'--verbose', 
     #'--no-jobs'
     #'/home/jodogne/Subversion/Orthanc/i/Orthanc', CONFIG, '--verbose'
--- a/Tests/Tests.py	Wed Oct 14 19:55:26 2020 +0200
+++ b/Tests/Tests.py	Thu Oct 15 17:34:01 2020 +0200
@@ -5330,7 +5330,7 @@
                 if s['Status'] != 'Pending':
                     return s
                 else:
-                    time.sleep(0.1)
+                    time.sleep(0.01)
         
         instance = UploadInstance(_REMOTE, 'DummyCT.dcm')
         sopClassUid = '1.2.840.10008.5.1.4.1.1.4'
@@ -5414,7 +5414,7 @@
                 if s['Status'] != 'Pending':
                     return s
                 else:
-                    time.sleep(0.1)
+                    time.sleep(0.01)
 
         i = UploadInstance(_REMOTE, 'DummyCT.dcm')['ID']
         self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
@@ -6017,16 +6017,43 @@
     def test_webdav(self):
         self.assertRaises(Exception, lambda: DoPropFind(_REMOTE, '/webdav/', 2))
 
-        xml = DoPropFind(_REMOTE, '/webdav/', 1)
-        pprint.pprint(xml.keys())
-        print(xml['/webdav/'].toprettyxml())
+        for suffix in [ '', '/' ]:
+            f = DoPropFind(_REMOTE, '/webdav' + suffix, 0)
+            self.assertEqual(1, len(f))
+            self.assertTrue('/webdav/' in f.keys())
+            self.assertTrue(f['/webdav/']['folder'])
+            self.assertEqual('webdav', f['/webdav/']['displayname'])
+
+            f = DoPropFind(_REMOTE, '/webdav' + suffix, 1)
+            self.assertEqual(6, len(f))
+            self.assertTrue(f['/webdav/']['folder'])
+            self.assertEqual('webdav', f['/webdav/']['displayname'])
+            
+            for i in [ 'by-dates', 'by-patients', 'by-studies', 'by-uids', 'uploads' ]:
+                self.assertTrue(f['/webdav/%s' % i]['folder'])
+                self.assertEqual(i, f['/webdav/%s' % i]['displayname'])
+
+                for depth in [ 0, 1 ]:
+                    for suffix2 in [ '', '/' ]:
+                        g = DoPropFind(_REMOTE, '/webdav/%s%s' % (i, suffix2), depth)
+
+                        if i == 'uploads':
+                            # Empty folders might still exist in "/uploads/"
+                            self.assertTrue('/webdav/uploads/' in g)
+                            self.assertEqual('uploads', g['/webdav/uploads/']['displayname'])
+                            for j in g.items():
+                                self.assertTrue(g.items()[0][1]['folder'])
+                        else:
+                            self.assertEqual(1, len(g))
+                            self.assertEqual('/webdav/%s/' % i, g.items()[0][0])
+                            self.assertTrue(g.items()[0][1]['folder'])
+                            self.assertEqual(i, g.items()[0][1]['displayname'])
         
-        #print(xml.toprettyxml())
-        #for i in xml.getElementsByTagName('D:response'):
-        #    print(i.getElementsByTagName('D:href')[0].childNodes[0].data)
-        #    print(i.getElementsByTagName('D:prop')[0].toprettyxml())
-
-
+        self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
+        with open(GetDatabasePath('DummyCT.dcm'), 'rb') as f:
+            DoPut(_REMOTE, '/webdav/uploads/dummy', f.read(), 'text/plain')        
+
+        while len(DoGet(_REMOTE, '/patients')) == 0:
+            time.sleep(0.01)
+        self.assertEqual(1, len(DoGet(_REMOTE, '/patients')))
             
-        self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
-        UploadInstance(_REMOTE, 'Comunix/Ct/IM-0001-0001.dcm')
--- a/Tests/Toolbox.py	Wed Oct 14 19:55:26 2020 +0200
+++ b/Tests/Toolbox.py	Thu Oct 15 17:34:01 2020 +0200
@@ -141,7 +141,7 @@
     resp, content = http.request(orthanc['Url'] + uri, method,
                                  body = body,
                                  headers = headers)
-    if not (resp.status in [ 200, 302 ]):
+    if not (resp.status in [ 200, 201, 302 ]):
         raise Exception(resp.status, resp)
     else:
         return _DecodeJson(content)
@@ -241,7 +241,7 @@
     while True:
         if len(DoGet(orthanc, '/instances')) == 0:
             return
-        time.sleep(0.1)
+        time.sleep(0.01)
 
 def WaitJobDone(orthanc, job):
     while True:
@@ -252,7 +252,7 @@
         elif s == 'Failure':
             return False
         
-        time.sleep(0.1)
+        time.sleep(0.01)
 
 def MonitorJob(orthanc, func):  # "func" is a lambda
     a = set(DoGet(orthanc, '/jobs'))
@@ -479,7 +479,22 @@
                             raise Exception()
                 if href == None or prop == None:
                     raise Exception()
-                result[href] = prop
+
+                info = {}
+
+                for j in prop.childNodes:
+                    if j.nodeType == minidom.Node.ELEMENT_NODE:
+                        if j.nodeName == 'D:displayname':
+                            info['displayname'] = j.firstChild.nodeValue if j.firstChild != None else ''
+                        elif j.nodeName == 'D:creationdate':
+                            info['creationdate'] = j.firstChild.nodeValue
+                        elif j.nodeName == 'D:getlastmodified':
+                            info['lastmodified'] = j.firstChild.nodeValue
+                        elif j.nodeName == 'D:resourcetype':
+                            k = j.getElementsByTagName('D:collection')
+                            info['folder'] = (len(k) == 1)
+
+                result[href] = info
             elif i.nodeType != minidom.Node.TEXT_NODE:
                 raise Exception()