Skip to content

Commit 2281945

Browse files
authored
Merge pull request easybuilders#4578 from Flamefire/fix-checksums-verification-5
Fix the checksum type check
2 parents 2fd30ae + 099fc5b commit 2281945

File tree

2 files changed

+52
-13
lines changed

2 files changed

+52
-13
lines changed

easybuild/framework/easyconfig/types.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,19 +613,39 @@ def ensure_iterable_license_specs(specs):
613613
}))
614614
# checksums is a list of checksums, one entry per file (source/patch)
615615
# each entry can be:
616+
# None
616617
# a single checksum value (string)
617618
# a single checksum value of a specified type (2-tuple, 1st element is checksum type, 2nd element is checksum)
618619
# a list of checksums (of different types, perhaps different formats), which should *all* be valid
619-
# a dictionary with a mapping from filename to checksum value
620-
CHECKSUM_LIST = (list, as_hashable({'elem_types': [str, tuple, STRING_DICT]}))
621-
CHECKSUMS = (list, as_hashable({'elem_types': [str, tuple, STRING_DICT, CHECKSUM_LIST]}))
620+
# a tuple of checksums (of different types, perhaps different formats), where one should be valid
621+
# a dictionary with a mapping from filename to checksum (None, value, type&value, alternatives)
622+
623+
# Type & value, value may be an int for type "size"
624+
# This is a bit too permissive as it allows the first element to be an int and doesn't restrict the number of elements
625+
CHECKSUM_AND_TYPE = (tuple, as_hashable({'elem_types': [str, int]}))
626+
CHECKSUM_LIST = (list, as_hashable({'elem_types': [str, CHECKSUM_AND_TYPE]}))
627+
CHECKSUM_TUPLE = (tuple, as_hashable({'elem_types': [str, CHECKSUM_AND_TYPE]}))
628+
CHECKSUM_DICT = (dict, as_hashable(
629+
{
630+
'elem_types': [type(None), str, CHECKSUM_AND_TYPE, CHECKSUM_TUPLE, CHECKSUM_LIST],
631+
'key_types': [str],
632+
}
633+
))
634+
# At the top-level we allow tuples/lists containing a dict
635+
CHECKSUM_LIST_W_DICT = (list, as_hashable({'elem_types': [str, CHECKSUM_AND_TYPE, CHECKSUM_DICT]}))
636+
CHECKSUM_TUPLE_W_DICT = (tuple, as_hashable({'elem_types': [str, CHECKSUM_AND_TYPE, CHECKSUM_DICT]}))
637+
638+
CHECKSUMS = (list, as_hashable({'elem_types': [type(None), str, CHECKSUM_AND_TYPE,
639+
CHECKSUM_LIST_W_DICT, CHECKSUM_TUPLE_W_DICT, CHECKSUM_DICT]}))
622640

623-
CHECKABLE_TYPES = [CHECKSUM_LIST, CHECKSUMS, DEPENDENCIES, DEPENDENCY_DICT, LIST_OF_STRINGS,
641+
CHECKABLE_TYPES = [CHECKSUM_AND_TYPE, CHECKSUM_LIST, CHECKSUM_TUPLE,
642+
CHECKSUM_LIST_W_DICT, CHECKSUM_TUPLE_W_DICT, CHECKSUM_DICT, CHECKSUMS,
643+
DEPENDENCIES, DEPENDENCY_DICT, LIST_OF_STRINGS,
624644
SANITY_CHECK_PATHS_DICT, SANITY_CHECK_PATHS_ENTRY, STRING_DICT, STRING_OR_TUPLE_LIST,
625645
STRING_OR_TUPLE_DICT, STRING_OR_TUPLE_OR_DICT_LIST, TOOLCHAIN_DICT, TUPLE_OF_STRINGS]
626646

627647
# easy types, that can be verified with isinstance
628-
EASY_TYPES = [str, bool, dict, int, list, str, tuple]
648+
EASY_TYPES = [str, bool, dict, int, list, str, tuple, type(None)]
629649

630650
# type checking is skipped for easyconfig parameters names not listed in PARAMETER_TYPES
631651
PARAMETER_TYPES = {

test/framework/type_checking.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,12 @@ def test_check_type_of_param_value_sanity_check_paths(self):
174174
def test_check_type_of_param_value_checksums(self):
175175
"""Test check_type_of_param_value function for checksums."""
176176

177-
md5_checksum = 'fa618be8435447a017fd1bf2c7ae9224'
178-
sha256_checksum1 = 'fa618be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265'
179-
sha256_checksum2 = 'b5f9cb06105c1d2d30719db5ffb3ea67da60919fb68deaefa583deccd8813551'
180-
sha256_checksum3 = '033be54514a03e255df75c5aee8f9e672f663f93abb723444caec8fe43437bde'
177+
# Using (actually invalid) prefix to better detect those in case of errors
178+
md5_checksum = 'md518be8435447a017fd1bf2c7ae9224'
179+
sha256_checksum1 = 'sha18be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265'
180+
sha256_checksum2 = 'sha2cb06105c1d2d30719db5ffb3ea67da60919fb68deaefa583deccd8813551'
181+
sha256_checksum3 = 'sha3e54514a03e255df75c5aee8f9e672f663f93abb723444caec8fe43437bde'
182+
filesize = 45617379
181183

182184
# valid values for 'checksums' easyconfig parameters
183185
inputs = [
@@ -190,6 +192,7 @@ def test_check_type_of_param_value_checksums(self):
190192
# one checksum of specific type (as 2-tuple)
191193
[('md5', md5_checksum)],
192194
[('sha256', sha256_checksum1)],
195+
[('size', filesize)],
193196
# alternative checksums for a single file (n-tuple)
194197
[(sha256_checksum1, sha256_checksum2)],
195198
[(sha256_checksum1, sha256_checksum2, sha256_checksum3)],
@@ -213,17 +216,33 @@ def test_check_type_of_param_value_checksums(self):
213216
# two checksums for a single file, *both* should match
214217
[sha256_checksum1, md5_checksum],
215218
# three checksums for a single file, *all* should match
216-
[sha256_checksum1, ('md5', md5_checksum), {'foo.txt': sha256_checksum1}],
219+
[sha256_checksum1, ('md5', md5_checksum), ('size', filesize)],
217220
# single checksum for a single file
218221
sha256_checksum1,
219222
# filename-to-checksum mapping
220-
{'foo.txt': sha256_checksum1, 'bar.txt': sha256_checksum2},
223+
{'foo.txt': sha256_checksum1, 'bar.txt': sha256_checksum2, 'baz.txt': ('size', filesize)},
221224
# 3 alternative checksums for a single file, one match is sufficient
222225
(sha256_checksum1, sha256_checksum2, sha256_checksum3),
223-
]
226+
# two alternative checksums for a single file (not to be confused by checksum-type & -value tuple)
227+
(sha256_checksum1, md5_checksum),
228+
# three alternative checksums for a single file of different types
229+
(sha256_checksum1, ('md5', md5_checksum), ('size', filesize)),
230+
# alternative checksums in dicts are also allowed
231+
{'foo.txt': (sha256_checksum2, sha256_checksum3), 'bar.txt': (sha256_checksum1, md5_checksum)},
232+
# Same but with lists -> all must match for each file
233+
{'foo.txt': [sha256_checksum2, sha256_checksum3], 'bar.txt': [sha256_checksum1, md5_checksum]},
234+
],
235+
# None is allowed, meaning skip the checksum
236+
[
237+
None,
238+
# Also in mappings
239+
{'foo.txt': sha256_checksum1, 'bar.txt': None},
240+
],
224241
]
225242
for inp in inputs:
226-
self.assertEqual(check_type_of_param_value('checksums', inp), (True, inp))
243+
type_ok, newval = check_type_of_param_value('checksums', inp)
244+
self.assertIs(type_ok, True, 'Failed for ' + str(inp))
245+
self.assertEqual(newval, inp)
227246

228247
def test_check_type_of_param_value_patches(self):
229248
"""Test check_type_of_param_value function for patches."""

0 commit comments

Comments
 (0)