comparison Tests/Tests.py @ 397:eb87ec525b53

"ETag" headers for metadata and attachments now allow strong comparison (MD5 is included)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 26 Apr 2021 15:22:59 +0200
parents e87d54a8a204
children dd519677974d
comparison
equal deleted inserted replaced
396:b32b2114155b 397:eb87ec525b53
1129 (headers, body) = DoPutRaw(_REMOTE, '/patients/%s/metadata/5555' % p, 'coucou') 1129 (headers, body) = DoPutRaw(_REMOTE, '/patients/%s/metadata/5555' % p, 'coucou')
1130 self.assertEqual('200', headers['status']) 1130 self.assertEqual('200', headers['status'])
1131 self.assertEqual('', body) 1131 self.assertEqual('', body)
1132 1132
1133 if IsOrthancVersionAbove(_REMOTE, 1, 9, 2): 1133 if IsOrthancVersionAbove(_REMOTE, 1, 9, 2):
1134 self.assertEqual('"0"', headers['etag']) 1134 self.assertEqual('"0-%s"' % ComputeMD5('coucou'), headers['etag'])
1135 else: 1135 else:
1136 self.assertFalse('ETag' in headers) 1136 self.assertFalse('ETag' in headers)
1137 self.assertFalse('etag' in headers) 1137 self.assertFalse('etag' in headers)
1138 1138
1139 m = DoGet(_REMOTE, '/patients/%s/metadata' % p) 1139 m = DoGet(_REMOTE, '/patients/%s/metadata' % p)
1243 self.assertEqual(hello, DoGet(_REMOTE, '/patients/%s/attachments/1025/data' % patient)) 1243 self.assertEqual(hello, DoGet(_REMOTE, '/patients/%s/attachments/1025/data' % patient))
1244 self.assertEqual('world', DoGet(_REMOTE, '/patients/%s/attachments/1026/data' % patient)) 1244 self.assertEqual('world', DoGet(_REMOTE, '/patients/%s/attachments/1026/data' % patient))
1245 DoPost(_REMOTE, '/patients/%s/attachments/1025/verify-md5' % patient) 1245 DoPost(_REMOTE, '/patients/%s/attachments/1025/verify-md5' % patient)
1246 DoPost(_REMOTE, '/patients/%s/attachments/1026/verify-md5' % patient) 1246 DoPost(_REMOTE, '/patients/%s/attachments/1026/verify-md5' % patient)
1247 DoPut(_REMOTE, '/patients/%s/attachments/1026' % patient, 'world2', headers = { 1247 DoPut(_REMOTE, '/patients/%s/attachments/1026' % patient, 'world2', headers = {
1248 'If-Match' : '0' 1248 'If-Match' : '0-%s' % ComputeMD5('world'),
1249 }) 1249 })
1250 1250
1251 (headers, body) = DoGetRaw(_REMOTE, '/patients/%s/attachments/1026/data' % patient) 1251 (headers, body) = DoGetRaw(_REMOTE, '/patients/%s/attachments/1026/data' % patient)
1252 self.assertEqual('200', headers['status']) 1252 self.assertEqual('200', headers['status'])
1253 self.assertEqual('world2', body) 1253 self.assertEqual('world2', body)
1254 1254
1255 self.assertRaises(Exception, lambda: DoDelete(_REMOTE, '/instances/%s/attachments/dicom' % instance)) 1255 self.assertRaises(Exception, lambda: DoDelete(_REMOTE, '/instances/%s/attachments/dicom' % instance))
1256 DoDelete(_REMOTE, '/patients/%s/attachments/1025' % patient, headers = { 1256 DoDelete(_REMOTE, '/patients/%s/attachments/1025' % patient, headers = {
1257 'If-Match' : '0' 1257 'If-Match' : '0-%s' % ComputeMD5(hello),
1258 }) 1258 })
1259 self.assertEqual(int(DoGet(_REMOTE, '/patients/%s/statistics' % patient)['DiskSize']), 1259 self.assertEqual(int(DoGet(_REMOTE, '/patients/%s/statistics' % patient)['DiskSize']),
1260 int(DoGet(_REMOTE, '/statistics')['TotalDiskSize'])) 1260 int(DoGet(_REMOTE, '/statistics')['TotalDiskSize']))
1261 self.assertEqual(int(DoGet(_REMOTE, '/patients/%s/statistics' % patient)['DiskSize']), 1261 self.assertEqual(int(DoGet(_REMOTE, '/patients/%s/statistics' % patient)['DiskSize']),
1262 size + int(DoGet(_REMOTE, '/patients/%s/attachments/1026/compressed-size' % patient))) 1262 size + int(DoGet(_REMOTE, '/patients/%s/attachments/1026/compressed-size' % patient)))
6616 # https://docs.couchdb.org/en/stable/api/document/common.html 6616 # https://docs.couchdb.org/en/stable/api/document/common.html
6617 i = UploadInstance(_REMOTE, 'DummyCT.dcm') ['ID'] 6617 i = UploadInstance(_REMOTE, 'DummyCT.dcm') ['ID']
6618 6618
6619 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i) 6619 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i)
6620 self.assertEqual('200', headers['status']) 6620 self.assertEqual('200', headers['status'])
6621 self.assertEqual('"0"', headers['etag']) 6621 self.assertEqual('"0-%s"' % ComputeMD5('1.2.840.10008.1.2.4.70'), headers['etag'])
6622 self.assertEqual('1.2.840.10008.1.2.4.70', body) 6622 self.assertEqual('1.2.840.10008.1.2.4.70', body)
6623 6623
6624 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = { 6624 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = {
6625 'If-None-Match' : '"0"' 6625 'If-None-Match' : '"aaa"'
6626 })
6627 self.assertEqual('400', headers['status']) # Bad header format
6628
6629 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = {
6630 'If-None-Match' : '"aaa-bbb"'
6631 })
6632 self.assertEqual('400', headers['status']) # Bad header format
6633
6634 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = {
6635 'If-None-Match' : '"0-16de4d7060d0b9d102ef0fca8acc892a"'
6626 }) 6636 })
6627 self.assertEqual('304', headers['status']) # Not modified 6637 self.assertEqual('304', headers['status']) # Not modified
6628 self.assertEqual('"0"', headers['etag']) 6638 self.assertEqual('"0-16de4d7060d0b9d102ef0fca8acc892a"', headers['etag'])
6629 self.assertEqual('', body) # Body must be empty on 304 status 6639 self.assertEqual('', body) # Body must be empty on 304 status
6630 6640
6631 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = { 6641 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = {
6632 'If-None-Match' : '"1"' 6642 'If-None-Match' : '"1-16de4d7060d0b9d102ef0fca8acc892a"' # Bad revision, good MD5
6633 }) 6643 })
6634 self.assertEqual('200', headers['status']) 6644 self.assertEqual('200', headers['status'])
6635 self.assertEqual('"0"', headers['etag']) 6645 self.assertEqual('"0-16de4d7060d0b9d102ef0fca8acc892a"', headers['etag'])
6646 self.assertEqual('1.2.840.10008.1.2.4.70', body)
6647
6648 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, headers = {
6649 'If-None-Match' : '"0-aaa"' # Good revision, bad MD5
6650 })
6651 self.assertEqual('200', headers['status'])
6652 self.assertEqual('"0-16de4d7060d0b9d102ef0fca8acc892a"', headers['etag'])
6636 self.assertEqual('1.2.840.10008.1.2.4.70', body) 6653 self.assertEqual('1.2.840.10008.1.2.4.70', body)
6637 6654
6638 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i) 6655 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i)
6639 self.assertEqual('403', headers['status']) # Forbidden (system metadata) 6656 self.assertEqual('403', headers['status']) # Forbidden (system metadata)
6640 6657
6641 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, 'hello') 6658 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/TransferSyntax' % i, 'hello')
6642 self.assertEqual('403', headers['status']) # Forbidden (system metadata) 6659 self.assertEqual('403', headers['status']) # Forbidden (system metadata)
6643 6660
6644 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello') 6661 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello')
6645 self.assertEqual('200', headers['status']) 6662 self.assertEqual('200', headers['status'])
6646 self.assertEqual('"0"', headers['etag']) 6663 self.assertEqual('"0-%s"' % ComputeMD5('hello'), headers['etag'])
6647 6664
6648 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i) 6665 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i)
6649 self.assertEqual('200', headers['status']) 6666 self.assertEqual('200', headers['status'])
6650 self.assertEqual('"0"', headers['etag']) 6667 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6651 self.assertEqual('hello', body) 6668 self.assertEqual('hello', body)
6652 6669
6653 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6670 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6654 'If-None-Match' : '"0"' 6671 'If-None-Match' : '"0-5d41402abc4b2a76b9719d911017c592"'
6655 }) 6672 })
6656 self.assertEqual('304', headers['status']) 6673 self.assertEqual('304', headers['status'])
6657 self.assertEqual('"0"', headers['etag']) 6674 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6658 self.assertEqual('', body) 6675 self.assertEqual('', body)
6659 6676
6660 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6677 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6661 'If-None-Match' : '"1"' 6678 'If-None-Match' : '"1-tata"'
6662 }) 6679 })
6663 self.assertEqual('200', headers['status']) 6680 self.assertEqual('200', headers['status'])
6664 self.assertEqual('"0"', headers['etag']) 6681 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6665 self.assertEqual('hello', body) 6682 self.assertEqual('hello', body)
6666 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/metadata/1024' % i)) 6683 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/metadata/1024' % i))
6667 6684
6668 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i) 6685 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i)
6669 self.assertEqual('409', headers['status']) # No revision given, but "CheckRevisions" is True 6686 self.assertEqual('409', headers['status']) # No revision given, but "CheckRevisions" is True
6670 6687
6671 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6688 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6672 'If-Match' : '45' 6689 'If-Match' : '45-5d41402abc4b2a76b9719d911017c592'
6673 }) 6690 })
6674 self.assertEqual('409', headers['status']) # Conflict, as bad revision 6691 self.assertEqual('409', headers['status']) # Conflict, as bad revision
6675 6692
6676 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6693 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6677 'If-Match' : '0' 6694 'If-Match' : '0-tata'
6695 })
6696 self.assertEqual('409', headers['status']) # Conflict, as bad MD5
6697
6698 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6699 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6678 }) 6700 })
6679 self.assertEqual('200', headers['status']) 6701 self.assertEqual('200', headers['status'])
6680 6702
6681 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6703 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6682 'If-Match' : '0' 6704 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6683 }) 6705 })
6684 self.assertEqual('404', headers['status']) 6706 self.assertEqual('404', headers['status'])
6685 6707
6686 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i) 6708 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i)
6687 self.assertEqual('404', headers['status']) 6709 self.assertEqual('404', headers['status'])
6688 6710
6689 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/metadata/1024' % i)) 6711 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/metadata/1024' % i))
6690 6712
6691 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello') 6713 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello')
6692 self.assertEqual('200', headers['status']) 6714 self.assertEqual('200', headers['status'])
6693 self.assertEqual('"0"', headers['etag']) 6715 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6694 6716
6695 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello') 6717 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello')
6696 self.assertEqual('409', headers['status']) 6718 self.assertEqual('409', headers['status'])
6697 6719
6698 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6720 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6699 'If-None-Match' : '"0"' 6721 'If-None-Match' : '"0-5d41402abc4b2a76b9719d911017c592"'
6700 }) 6722 })
6701 self.assertEqual('304', headers['status']) # Not modified 6723 self.assertEqual('304', headers['status']) # Not modified
6702 self.assertEqual('"0"', headers['etag']) 6724 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6703 self.assertEqual('', body) # Body must be empty on 304 status 6725 self.assertEqual('', body) # Body must be empty on 304 status
6704 6726
6705 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello', headers = { 6727 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello', headers = {
6706 'If-Match' : '0' 6728 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6707 }) 6729 })
6708 self.assertEqual('200', headers['status']) 6730 self.assertEqual('200', headers['status'])
6709 self.assertEqual('"1"', headers['etag']) 6731 self.assertEqual('"1-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6710 self.assertEqual('', body) 6732 self.assertEqual('', body)
6711 6733
6712 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = { 6734 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/metadata/1024' % i, headers = {
6713 'If-None-Match' : headers['etag'] 6735 'If-None-Match' : headers['etag']
6714 }) 6736 })
6715 6737
6716 if headers['status'] == '200': 6738 if headers['status'] == '200':
6717 print("Your database backend doesn't store revisions") 6739 print("Your database backend doesn't store revisions")
6718 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = { 6740 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = {
6719 'If-Match' : '1' 6741 'If-Match' : '1-5d41402abc4b2a76b9719d911017c592'
6720 }) 6742 })
6721 self.assertEqual('409', headers['status']) 6743 self.assertEqual('409', headers['status'])
6722 6744
6723 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = { 6745 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = {
6724 'If-Match' : '0' 6746 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6725 }) 6747 })
6726 self.assertEqual('200', headers['status']) 6748 self.assertEqual('200', headers['status'])
6727 self.assertEqual('"1"', headers['etag']) 6749 self.assertEqual('"1-6e809cbda0732ac4845916a59016f954"', headers['etag'])
6728 self.assertEqual('', body) 6750 self.assertEqual('', body)
6729 6751
6730 elif headers['status'] == '304': # Revisions are supported 6752 elif headers['status'] == '304': # Revisions are supported
6731 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = { 6753 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = {
6732 'If-Match' : '0' 6754 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6733 }) 6755 })
6734 self.assertEqual('409', headers['status']) 6756 self.assertEqual('409', headers['status'])
6735 6757
6736 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = { 6758 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/metadata/1024' % i, 'hello2', headers = {
6737 'If-Match' : '1' 6759 'If-Match' : '1-5d41402abc4b2a76b9719d911017c592'
6738 }) 6760 })
6739 self.assertEqual('200', headers['status']) 6761 self.assertEqual('200', headers['status'])
6740 self.assertEqual('"2"', headers['etag']) 6762 self.assertEqual('"2-6e809cbda0732ac4845916a59016f954"', headers['etag'])
6741 self.assertEqual('', body) 6763 self.assertEqual('', body)
6742 6764
6743 else: 6765 else:
6744 raise Exception('Internal error') 6766 raise Exception('Internal error')
6745 6767
6752 # "CheckRevisions" is "False". Conventions for HTTP headers 6774 # "CheckRevisions" is "False". Conventions for HTTP headers
6753 # related to revisions mimic CouchDB: 6775 # related to revisions mimic CouchDB:
6754 # https://docs.couchdb.org/en/stable/api/document/common.html 6776 # https://docs.couchdb.org/en/stable/api/document/common.html
6755 i = UploadInstance(_REMOTE, 'DummyCT.dcm') ['ID'] 6777 i = UploadInstance(_REMOTE, 'DummyCT.dcm') ['ID']
6756 6778
6779 with open(GetDatabasePath('DummyCT.dcm'), 'rb') as f:
6780 md5 = ComputeMD5(f.read())
6781
6757 # "/compress", "/uncompress" and "/verify-md5" are POST 6782 # "/compress", "/uncompress" and "/verify-md5" are POST
6758 # methods, and are not affected by revisions 6783 # methods, and are not affected by revisions
6759 for suffix in [ '', '/compressed-data', '/compressed-md5', '/compressed-size', 6784 for suffix in [ '', '/compressed-data', '/compressed-md5', '/compressed-size',
6760 '/data', '/is-compressed', '/md5', '/size' ]: 6785 '/data', '/is-compressed', '/md5', '/size' ]:
6761 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix)) 6786 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix))
6762 self.assertEqual('200', headers['status']) 6787 self.assertEqual('200', headers['status'])
6763 self.assertEqual('"0"', headers['etag']) 6788 self.assertEqual('"0-%s"' % md5, headers['etag'])
6764 6789
6765 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = { 6790 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = {
6766 'If-None-Match' : '"0"' 6791 'If-None-Match' : '"0-3e29b869978b6db4886355a2b1132124"',
6767 }) 6792 })
6768 self.assertEqual('304', headers['status']) # Not modified 6793 self.assertEqual('304', headers['status']) # Not modified
6769 self.assertEqual('"0"', headers['etag']) 6794 self.assertEqual('"0-3e29b869978b6db4886355a2b1132124"', headers['etag'])
6770 self.assertEqual('', body) # Body must be empty on 304 status 6795 self.assertEqual('', body) # Body must be empty on 304 status
6771 6796
6772 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = { 6797 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = {
6773 'If-None-Match' : '"1"' 6798 'If-None-Match' : '"tata"', # Invalid header
6799 })
6800 self.assertEqual('400', headers['status'])
6801
6802 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = {
6803 'If-None-Match' : '"1-%s"' % md5, # Bad revision, good MD5
6774 }) 6804 })
6775 self.assertEqual('200', headers['status']) 6805 self.assertEqual('200', headers['status'])
6776 self.assertEqual('"0"', headers['etag']) 6806 self.assertEqual('"0-3e29b869978b6db4886355a2b1132124"', headers['etag'])
6807
6808 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/dicom/%s' % (i, suffix), headers = {
6809 'If-None-Match' : '"0-tata"' # Good revision, bad MD5
6810 })
6811 self.assertEqual('200', headers['status'])
6812 self.assertEqual('"0-3e29b869978b6db4886355a2b1132124"', headers['etag'])
6777 6813
6778 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/dicom' % i) 6814 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/dicom' % i)
6779 self.assertEqual('403', headers['status']) # Forbidden (system metadata) 6815 self.assertEqual('403', headers['status']) # Forbidden (system metadata)
6780 6816
6781 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/dicom' % i, 'hello') 6817 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/dicom' % i, 'hello')
6782 self.assertEqual('403', headers['status']) # Forbidden (system metadata) 6818 self.assertEqual('403', headers['status']) # Forbidden (system metadata)
6783 6819
6784 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello') 6820 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello')
6785 self.assertEqual('200', headers['status']) 6821 self.assertEqual('200', headers['status'])
6786 self.assertEqual('"0"', headers['etag']) 6822 self.assertEqual('"0-%s"' % ComputeMD5('hello'), headers['etag'])
6787 6823
6788 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i) 6824 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i)
6789 self.assertEqual('200', headers['status']) 6825 self.assertEqual('200', headers['status'])
6790 self.assertEqual('"0"', headers['etag']) 6826 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6791 self.assertEqual('hello', body) 6827 self.assertEqual('hello', body)
6792 6828
6793 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = { 6829 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6794 'If-None-Match' : '"0"' 6830 'If-None-Match' : '"0-5d41402abc4b2a76b9719d911017c592"'
6795 }) 6831 })
6796 self.assertEqual('304', headers['status']) 6832 self.assertEqual('304', headers['status'])
6797 self.assertEqual('"0"', headers['etag']) 6833 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6798 self.assertEqual('', body) 6834 self.assertEqual('', body)
6835
6836 for h in [ '"1-5d41402abc4b2a76b9719d911017c592"', # Bad revision, good MD5
6837 '"0-tata"']: # Good revision, bad MD5
6838 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6839 'If-None-Match' : h
6840 })
6841 self.assertEqual('200', headers['status'])
6842 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6843 self.assertEqual('hello', body)
6799 6844
6800 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = { 6845 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6801 'If-None-Match' : '"1"' 6846 'If-None-Match' : 'tata' # Bad header format
6847 })
6848 self.assertEqual('400', headers['status'])
6849 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6850
6851 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/attachments/1024/data' % i))
6852
6853 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i)
6854 self.assertEqual('409', headers['status']) # No revision given, but "CheckRevisions" is True
6855
6856 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = {
6857 'If-Match' : '45-5d41402abc4b2a76b9719d911017c592'
6858 })
6859 self.assertEqual('409', headers['status']) # Conflict, as bad revision
6860
6861 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = {
6862 'If-Match' : '0-tata'
6863 })
6864 self.assertEqual('409', headers['status']) # Conflict, as bad MD5
6865
6866 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = {
6867 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6802 }) 6868 })
6803 self.assertEqual('200', headers['status']) 6869 self.assertEqual('200', headers['status'])
6804 self.assertEqual('"0"', headers['etag']) 6870
6805 self.assertEqual('hello', body)
6806 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/attachments/1024/data' % i))
6807
6808 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i)
6809 self.assertEqual('409', headers['status']) # No revision given, but "CheckRevisions" is True
6810
6811 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = { 6871 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = {
6812 'If-Match' : '45' 6872 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6813 }) 6873 })
6814 self.assertEqual('409', headers['status']) # Conflict, as bad revision 6874 self.assertEqual('404', headers['status'])
6815 6875
6816 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = { 6876 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i)
6817 'If-Match' : '0' 6877 self.assertEqual('404', headers['status'])
6878
6879 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/attachments/1024' % i))
6880
6881 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello')
6882 self.assertEqual('200', headers['status'])
6883 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6884
6885 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello')
6886 self.assertEqual('409', headers['status'])
6887
6888 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6889 'If-None-Match' : '"0-5d41402abc4b2a76b9719d911017c592"'
6890 })
6891 self.assertEqual('304', headers['status']) # Not modified
6892 self.assertEqual('"0-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6893 self.assertEqual('', body) # Body must be empty on 304 status
6894
6895 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello', headers = {
6896 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6818 }) 6897 })
6819 self.assertEqual('200', headers['status']) 6898 self.assertEqual('200', headers['status'])
6820 6899 self.assertEqual('"1-5d41402abc4b2a76b9719d911017c592"', headers['etag'])
6821 (headers, body) = DoDeleteRaw(_REMOTE, '/instances/%s/attachments/1024' % i, headers = {
6822 'If-Match' : '0'
6823 })
6824 self.assertEqual('404', headers['status'])
6825
6826 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i)
6827 self.assertEqual('404', headers['status'])
6828
6829 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/attachments/1024' % i))
6830
6831 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello')
6832 self.assertEqual('200', headers['status'])
6833 self.assertEqual('"0"', headers['etag'])
6834
6835 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello')
6836 self.assertEqual('409', headers['status'])
6837
6838 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6839 'If-None-Match' : '"0"'
6840 })
6841 self.assertEqual('304', headers['status']) # Not modified
6842 self.assertEqual('"0"', headers['etag'])
6843 self.assertEqual('', body) # Body must be empty on 304 status
6844
6845 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello', headers = {
6846 'If-Match' : '0'
6847 })
6848 self.assertEqual('200', headers['status'])
6849 self.assertEqual('"1"', headers['etag'])
6850 self.assertEqual('{}', body) 6900 self.assertEqual('{}', body)
6851 6901
6852 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = { 6902 (headers, body) = DoGetRaw(_REMOTE, '/instances/%s/attachments/1024/data' % i, headers = {
6853 'If-None-Match' : headers['etag'] 6903 'If-None-Match' : headers['etag']
6854 }) 6904 })
6855 6905
6856 if headers['status'] == '200': 6906 if headers['status'] == '200':
6857 print("Your database backend doesn't store revisions") 6907 print("Your database backend doesn't store revisions")
6858 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = { 6908 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = {
6859 'If-Match' : '1' 6909 'If-Match' : '1-5d41402abc4b2a76b9719d911017c592'
6860 }) 6910 })
6861 self.assertEqual('409', headers['status']) 6911 self.assertEqual('409', headers['status'])
6862 6912
6863 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = { 6913 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = {
6864 'If-Match' : '0' 6914 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6865 }) 6915 })
6866 self.assertEqual('200', headers['status']) 6916 self.assertEqual('200', headers['status'])
6867 self.assertEqual('"1"', headers['etag']) 6917 self.assertEqual('"1-6e809cbda0732ac4845916a59016f954"', headers['etag'])
6868 self.assertEqual('{}', body) 6918 self.assertEqual('{}', body)
6869 6919
6870 elif headers['status'] == '304': # Revisions are supported 6920 elif headers['status'] == '304': # Revisions are supported
6871 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = { 6921 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = {
6872 'If-Match' : '0' 6922 'If-Match' : '0-5d41402abc4b2a76b9719d911017c592'
6873 }) 6923 })
6874 self.assertEqual('409', headers['status']) 6924 self.assertEqual('409', headers['status'])
6875 6925
6876 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = { 6926 (headers, body) = DoPutRaw(_REMOTE, '/instances/%s/attachments/1024' % i, 'hello2', headers = {
6877 'If-Match' : '1' 6927 'If-Match' : '1-5d41402abc4b2a76b9719d911017c592'
6878 }) 6928 })
6879 self.assertEqual('200', headers['status']) 6929 self.assertEqual('200', headers['status'])
6880 self.assertEqual('"2"', headers['etag']) 6930 self.assertEqual('"2-6e809cbda0732ac4845916a59016f954"', headers['etag'])
6881 self.assertEqual('{}', body) 6931 self.assertEqual('{}', body)
6882 6932
6883 else: 6933 else:
6884 raise Exception('Internal error') 6934 raise Exception('Internal error')
6885 6935