@@ -171,18 +171,18 @@ def test_check_type_of_param_value_sanity_check_paths(self):
171171 out = {'files' : ['bin/foo' , ('bin/bar' , 'bin/baz' )], 'dirs' : [('lib' , 'lib64' , 'lib32' )]}
172172 self .assertEqual (check_type_of_param_value ('sanity_check_paths' , inp , auto_convert = True ), (True , out ))
173173
174- def test_check_type_of_param_value_checksums (self ):
175- """Test check_type_of_param_value function for checksums."""
174+ @staticmethod
175+ def get_valid_checksums_values ():
176+ """Return list of values valid for the 'checksums' EC parameter"""
176177
177178 # Using (actually invalid) prefix to better detect those in case of errors
178179 md5_checksum = 'md518be8435447a017fd1bf2c7ae9224'
179180 sha256_checksum1 = 'sha18be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265'
180181 sha256_checksum2 = 'sha2cb06105c1d2d30719db5ffb3ea67da60919fb68deaefa583deccd8813551'
181182 sha256_checksum3 = 'sha3e54514a03e255df75c5aee8f9e672f663f93abb723444caec8fe43437bde'
182183 filesize = 45617379
183-
184184 # valid values for 'checksums' easyconfig parameters
185- inputs = [
185+ return [
186186 [],
187187 # single checksum (one file)
188188 [md5_checksum ],
@@ -239,7 +239,11 @@ def test_check_type_of_param_value_checksums(self):
239239 {'foo.txt' : sha256_checksum1 , 'bar.txt' : None },
240240 ],
241241 ]
242- for inp in inputs :
242+
243+ def test_check_type_of_param_value_checksums (self ):
244+ """Test check_type_of_param_value function for checksums."""
245+
246+ for inp in TypeCheckingTest .get_valid_checksums_values ():
243247 type_ok , newval = check_type_of_param_value ('checksums' , inp )
244248 self .assertIs (type_ok , True , 'Failed for ' + str (inp ))
245249 self .assertEqual (newval , inp )
@@ -724,19 +728,94 @@ def test_to_sanity_check_paths_dict(self):
724728
725729 def test_to_checksums (self ):
726730 """Test to_checksums function."""
731+ # Some hand-crafted examples. Only the types are important, values are for easier verification
727732 test_inputs = [
728- ['be662daa971a640e40be5c804d9d7d10' ],
729- ['be662daa971a640e40be5c804d9d7d10' , ('md5' , 'be662daa971a640e40be5c804d9d7d10' )],
730- [['be662daa971a640e40be5c804d9d7d10' , ('md5' , 'be662daa971a640e40be5c804d9d7d10' )]],
731- [('md5' , 'be662daa971a640e40be5c804d9d7d10' )],
732- ['be662daa971a640e40be5c804d9d7d10' , ('adler32' , '0x998410035' ), ('crc32' , '0x1553842328' ),
733- ('md5' , 'be662daa971a640e40be5c804d9d7d10' ), ('sha1' , 'f618096c52244539d0e89867405f573fdb0b55b0' ),
734- ('size' , 273 )],
733+ ['checksumvalue' ],
734+ [('md5' , 'md5checksumvalue' )],
735+ ['file_1_checksum' , ('md5' , 'file_2_md5_checksum' )],
736+ # One checksum per file, some with checksum type
737+ [
738+ 'be662daa971a640e40be5c804d9d7d10' ,
739+ ('adler32' , '0x998410035' ),
740+ ('crc32' , '0x1553842328' ),
741+ ('md5' , 'be662daa971a640e40be5c804d9d7d10' ),
742+ ('sha1' , 'f618096c52244539d0e89867405f573fdb0b55b0' ),
743+ # int type as the 2nd value
744+ ('size' , 273 ),
745+ ],
735746 # None values should not be filtered out, but left in place
736- [None , 'fa618be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265' , None ],
747+ [None , 'checksum' , None ],
748+ # Alternative checksums, not to be confused with multiple checksums for a file
749+ [('main_checksum' , 'alternative_checksum' )],
750+ [('1st_of_3' , '2nd_of_3' , '3rd_of_3' )],
751+ # Lists must be kept: This means all must match
752+ [['checksum_1_in_list' ]],
753+ [['checksum_must_match' , 'this_must_also_match' ]],
754+ [['1st_of_3_list' , '2nd_of_3_list' , '3rd_of_3_list' ]],
755+ # Alternative checksums with types
756+ [
757+ (('adler32' , '1st_adler' ), ('crc32' , '1st_crc' )),
758+ (('adler32' , '2nd_adler' ), ('crc32' , '2nd_crc' ), ('sha1' , '2nd_sha' )),
759+ ],
760+ # Entries can be dicts even containing `None`
761+ [
762+ {
763+ 'src-arm.tgz' : 'arm_checksum' ,
764+ 'src-x86.tgz' : ('mainchecksum' , 'altchecksum' ),
765+ 'src-ppc.tgz' : ('mainchecksum' , ('md5' , 'altchecksum' )),
766+ 'git-clone.tgz' : None ,
767+ },
768+ {
769+ 'src' : ['checksum_must_match' , 'this_must_also_match' ]
770+ },
771+ # 2nd required checksum a dict
772+ ['first_checksum' , {'src-arm' : 'arm_checksum' }]
773+ ],
737774 ]
738775 for checksums in test_inputs :
739776 self .assertEqual (to_checksums (checksums ), checksums )
777+ # Also reuse the checksums we use in test_check_type_of_param_value_checksums
778+ # When a checksum is valid it must not be modified
779+ for checksums in TypeCheckingTest .get_valid_checksums_values ():
780+ self .assertEqual (to_checksums (checksums ), checksums )
781+
782+ # List in list converted to tuple -> alternatives or checksum with type
783+ checksums = [['1stchecksum' , ['md5' , 'md5sum' ]]]
784+ checksums_expected = [['1stchecksum' , ('md5' , 'md5sum' )]]
785+ self .assertEqual (to_checksums (checksums ), checksums_expected )
786+
787+ # Error detection
788+ wrong_nesting = [('1stchecksum' , ('md5' , ('md5sum' , 'altmd5sum' )))]
789+ self .assertErrorRegex (EasyBuildError , 'Unexpected type.*md5' , to_checksums , wrong_nesting )
790+ correct_nesting = [('1stchecksum' , ('md5' , 'md5sum' ), ('md5' , 'altmd5sum' ))]
791+ self .assertEqual (to_checksums (correct_nesting ), correct_nesting )
792+ # YEB (YAML EC) doesn't has tuples so it uses lists instead which need to get converted
793+ correct_nesting_yeb = [[['1stchecksum' , ['md5' , 'md5sum' ], ['md5' , 'altmd5sum' ]]]]
794+ correct_nesting_yeb_conv = [[('1stchecksum' , ('md5' , 'md5sum' ), ('md5' , 'altmd5sum' ))]]
795+ self .assertEqual (to_checksums (correct_nesting_yeb ), correct_nesting_yeb_conv )
796+ self .assertEqual (to_checksums (correct_nesting_yeb_conv ), correct_nesting_yeb_conv )
797+
798+ unexpected_set = [('1stchecksum' , {'md5' , 'md5sum' })]
799+ self .assertErrorRegex (EasyBuildError , 'Unexpected type.*md5' , to_checksums , unexpected_set )
800+ unexpected_dict = [{'src' : ('md5sum' , {'src' : 'shasum' })}]
801+ self .assertErrorRegex (EasyBuildError , 'Unexpected type.*shasum' , to_checksums , unexpected_dict )
802+ correct_dict = [{'src' : ('md5sum' , 'shasum' )}]
803+ self .assertEqual (to_checksums (correct_dict ), correct_dict )
804+ correct_dict_1 = [{'src' : [['md5' , 'md5sum' ], ['sha' , 'shasum' ]]}]
805+ correct_dict_2 = [{'src' : [('md5' , 'md5sum' ), ('sha' , 'shasum' )]}]
806+ self .assertEqual (to_checksums (correct_dict_2 ), correct_dict_2 )
807+ self .assertEqual (to_checksums (correct_dict_1 ), correct_dict_2 ) # inner lists to tuples
808+
809+ unexpected_Nones = [
810+ [('1stchecksum' , None )],
811+ [['1stchecksum' , None ]],
812+ [{'src' : ('md5sum' , None )}],
813+ [{'src' : ['md5sum' , None ]}],
814+ ]
815+ self .assertErrorRegex (EasyBuildError , 'Unexpected None' , to_checksums , unexpected_Nones [0 ])
816+ self .assertErrorRegex (EasyBuildError , 'Unexpected None' , to_checksums , unexpected_Nones [1 ])
817+ self .assertErrorRegex (EasyBuildError , 'Unexpected None' , to_checksums , unexpected_Nones [2 ])
818+ self .assertErrorRegex (EasyBuildError , 'Unexpected None' , to_checksums , unexpected_Nones [3 ])
740819
741820 def test_ensure_iterable_license_specs (self ):
742821 """Test ensure_iterable_license_specs function."""
0 commit comments