|
18 | 18 | import threading |
19 | 19 | import unittest |
20 | 20 | import warnings |
| 21 | +from functools import partial |
| 22 | +from operator import attrgetter |
21 | 23 | from test import support |
22 | 24 | from test.support import _4G, bigmemtest |
23 | 25 | from test.support.import_helper import import_fresh_module |
|
52 | 54 | def get_fips_mode(): |
53 | 55 | return 0 |
54 | 56 |
|
| 57 | + |
| 58 | +try: |
| 59 | + import _md5 |
| 60 | +except ImportError: |
| 61 | + _md5 = None |
| 62 | +requires_md5 = unittest.skipUnless(_md5, 'requires _md5') |
| 63 | + |
| 64 | + |
55 | 65 | try: |
56 | 66 | import _blake2 |
57 | 67 | except ImportError: |
58 | 68 | _blake2 = None |
59 | | - |
60 | 69 | requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2') |
61 | 70 |
|
| 71 | + |
| 72 | +try: |
| 73 | + import _sha1 |
| 74 | +except ImportError: |
| 75 | + _sha1 = None |
| 76 | +requires_sha1 = unittest.skipUnless(_sha1, 'requires _sha1') |
| 77 | + |
| 78 | + |
| 79 | +try: |
| 80 | + import _sha2 |
| 81 | +except ImportError: |
| 82 | + _sha2 = None |
| 83 | +requires_sha2 = unittest.skipUnless(_sha2, 'requires _sha2') |
| 84 | + |
| 85 | + |
| 86 | +try: |
| 87 | + import _sha3 |
| 88 | +except ImportError: |
| 89 | + _sha3 = None |
62 | 90 | # bpo-46913: Don't test the _sha3 extension on a Python UBSAN build |
63 | 91 | # TODO(gh-99108): Revisit this after _sha3 uses HACL*. |
64 | | -SKIP_SHA3 = support.check_sanitizer(ub=True) |
65 | | -requires_sha3 = unittest.skipUnless(not SKIP_SHA3, 'requires _sha3') |
| 92 | +SKIP_SHA3 = _sha3 is None or support.check_sanitizer(ub=True) |
| 93 | +requires_sha3 = unittest.skipUnkess(not SKIP_SHA3, 'requires _sha3') |
66 | 94 |
|
67 | 95 |
|
68 | 96 | def hexstr(s): |
@@ -1273,5 +1301,70 @@ def readable(self): |
1273 | 1301 | hashlib.file_digest(NonBlocking(), hashlib.sha256) |
1274 | 1302 |
|
1275 | 1303 |
|
| 1304 | +@threading_helper.requires_working_threading() |
| 1305 | +class TestTSAN(unittest.TestCase): |
| 1306 | + |
| 1307 | + @threading_helper.reap_threads |
| 1308 | + def check_attribute(self, write, read, expected, nthreads=8): |
| 1309 | + ready = threading.Event() |
| 1310 | + barrier = threading.Barrier(nthreads) |
| 1311 | + |
| 1312 | + def writer(): |
| 1313 | + barrier.wait() |
| 1314 | + while not ready.is_set(): |
| 1315 | + write() |
| 1316 | + |
| 1317 | + def reader(): |
| 1318 | + barrier.wait() |
| 1319 | + while not ready.is_set(): |
| 1320 | + self.assertEqual(read(), expected) |
| 1321 | + |
| 1322 | + targets = [writer if i % 2 else reader for i in range(nthreads)] |
| 1323 | + workers = [threading.Thread(target=target) for target in targets] |
| 1324 | + with threading_helper.start_threads(workers, unlock=ready.set): |
| 1325 | + pass |
| 1326 | + |
| 1327 | + def check_HACL_attribute(self, module, version, attrname): |
| 1328 | + blob = b"A" * 65536 |
| 1329 | + obj = getattr(module, version)() |
| 1330 | + update = partial(obj.update, blob) |
| 1331 | + read = attrgetter(attrname) |
| 1332 | + self.check_attribute(update, partial(read, obj), read(obj)) |
| 1333 | + |
| 1334 | + @requires_md5 |
| 1335 | + @support.subTests("attrname", ["block_size", "digest_size"]) |
| 1336 | + def test_HACL_md5_attributes(self, attrname): |
| 1337 | + self.check_HACL_attribute(_md5, "md5", attrname) |
| 1338 | + |
| 1339 | + @requires_sha1 |
| 1340 | + @support.subTests("attrname", ["block_size", "digest_size"]) |
| 1341 | + def test_HACL_sha1_attributes(self, attrname): |
| 1342 | + self.check_HACL_attribute(_sha1, "sha1", attrname) |
| 1343 | + |
| 1344 | + @requires_sha2 |
| 1345 | + @support.subTests("size", [224, 256, 384, 512]) |
| 1346 | + @support.subTests("attrname", ["block_size", "digest_size"]) |
| 1347 | + def test_HACL_sha2_attributes(self, size, attrname): |
| 1348 | + self.check_HACL_attribute(_sha2, f"sha{size}", attrname) |
| 1349 | + |
| 1350 | + @requires_sha3 |
| 1351 | + @support.subTests("size", [224, 256, 384, 512]) |
| 1352 | + @support.subTests( |
| 1353 | + "attrname", |
| 1354 | + ["block_size", "digest_size", "_capacity_bits", "_rate_bits"], |
| 1355 | + ) |
| 1356 | + def test_HACL_sha3_attributes(self, size, attrname): |
| 1357 | + self.check_HACL_attribute(_sha3, f"sha3_{size}", attrname) |
| 1358 | + |
| 1359 | + @requires_sha3 |
| 1360 | + @support.subTests("size", [128, 256]) |
| 1361 | + @support.subTests( |
| 1362 | + "attrname", |
| 1363 | + ["block_size", "digest_size", "_capacity_bits", "_rate_bits"], |
| 1364 | + ) |
| 1365 | + def test_HACL_shake_attributes(self, size, attrname): |
| 1366 | + self.check_HACL_attribute(_sha3, f"shake_{size}", attrname) |
| 1367 | + |
| 1368 | + |
1276 | 1369 | if __name__ == "__main__": |
1277 | 1370 | unittest.main() |
0 commit comments