|
18 | 18 | import tempfile |
19 | 19 | import threading |
20 | 20 | import unittest |
| 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 hashlib_helper |
|
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 | + |
62 | 86 | try: |
63 | 87 | import _sha3 |
64 | 88 | except ImportError: |
65 | 89 | _sha3 = None |
66 | | - |
67 | 90 | requires_sha3 = unittest.skipUnless(_sha3, 'requires _sha3') |
68 | 91 |
|
69 | 92 |
|
@@ -1418,5 +1441,61 @@ def scrypt(password=b"password", /, **kwargs): |
1418 | 1441 | self.assertRaises(numeric_exc_types, scrypt, dklen=MAX_DKLEN + 1) |
1419 | 1442 |
|
1420 | 1443 |
|
| 1444 | +@threading_helper.requires_working_threading() |
| 1445 | +class TestTSAN(unittest.TestCase): |
| 1446 | + |
| 1447 | + @threading_helper.reap_threads |
| 1448 | + def check_attribute(self, write, read, expected, nthreads=8): |
| 1449 | + ready = threading.Event() |
| 1450 | + barrier = threading.Barrier(nthreads) |
| 1451 | + |
| 1452 | + def writer(): |
| 1453 | + barrier.wait() |
| 1454 | + while not ready.is_set(): |
| 1455 | + write() |
| 1456 | + |
| 1457 | + def reader(): |
| 1458 | + barrier.wait() |
| 1459 | + while not ready.is_set(): |
| 1460 | + self.assertEqual(read(), expected) |
| 1461 | + |
| 1462 | + targets = [writer if i % 2 else reader for i in range(nthreads)] |
| 1463 | + workers = [threading.Thread(target=target) for target in targets] |
| 1464 | + with threading_helper.start_threads(workers, unlock=ready.set): |
| 1465 | + pass |
| 1466 | + |
| 1467 | + def check_HACL_attribute(self, module, version, attrname): |
| 1468 | + blob = b"A" * 65536 |
| 1469 | + obj = getattr(module, version)() |
| 1470 | + update = partial(obj.update, blob) |
| 1471 | + read = attrgetter(attrname) |
| 1472 | + self.check_attribute(update, partial(read, obj), read(obj)) |
| 1473 | + |
| 1474 | + @requires_md5 |
| 1475 | + @support.subTests("attrname", ['digest_size', 'block_size']) |
| 1476 | + def test_HACL_md5_attributes(self, attrname): |
| 1477 | + self.check_HACL_attribute(_md5, "md5", attrname) |
| 1478 | + |
| 1479 | + @requires_sha1 |
| 1480 | + @support.subTests("attrname", ['digest_size', 'block_size']) |
| 1481 | + def test_HACL_sha1_attributes(self, attrname): |
| 1482 | + self.check_HACL_attribute(_sha1, "sha1", attrname) |
| 1483 | + |
| 1484 | + @requires_sha2 |
| 1485 | + @support.subTests("attrname", ['digest_size', 'block_size']) |
| 1486 | + @support.subTests("size", [224, 256, 384, 512]) |
| 1487 | + def test_HACL_sha2_attributes(self, attrname, size): |
| 1488 | + self.check_HACL_attribute(_sha2, f"sha{size}", attrname) |
| 1489 | + |
| 1490 | + @requires_sha3 |
| 1491 | + @support.subTests( |
| 1492 | + "attrname", |
| 1493 | + ['digest_size', 'block_size', '_capacity_bits', '_rate_bits'], |
| 1494 | + ) |
| 1495 | + @support.subTests("size", [224, 256, 384, 512]) |
| 1496 | + def test_HACL_sha3_attributes(self, attrname, size): |
| 1497 | + self.check_HACL_attribute(_sha3, f"sha3_{size}", attrname) |
| 1498 | + |
| 1499 | + |
1421 | 1500 | if __name__ == "__main__": |
1422 | 1501 | unittest.main() |
0 commit comments