|
1 | | -import pytest |
| 1 | +import random |
| 2 | +import uuid |
| 3 | + |
| 4 | +from concurrent.futures import ThreadPoolExecutor |
| 5 | +from dataclasses import dataclass |
2 | 6 |
|
3 | 7 | import bcrypt |
| 8 | +import pytest |
4 | 9 |
|
5 | 10 | _test_vectors = [ |
6 | 11 | ( |
|
171 | 176 | ] |
172 | 177 |
|
173 | 178 |
|
174 | | -def test_gensalt_basic(monkeypatch): |
| 179 | +def test_gensalt_basic(): |
175 | 180 | salt = bcrypt.gensalt() |
176 | 181 | assert salt.startswith(b"$2b$12$") |
177 | 182 |
|
@@ -219,7 +224,7 @@ def test_gensalt_bad_prefix(): |
219 | 224 | bcrypt.gensalt(prefix=b"bad") |
220 | 225 |
|
221 | 226 |
|
222 | | -def test_gensalt_2a_prefix(monkeypatch): |
| 227 | +def test_gensalt_2a_prefix(): |
223 | 228 | salt = bcrypt.gensalt(prefix=b"2a") |
224 | 229 | assert salt.startswith(b"$2a$12$") |
225 | 230 |
|
@@ -495,3 +500,40 @@ def test_2a_wraparound_bug(): |
495 | 500 | ) |
496 | 501 | == b"$2a$04$R1lJ2gkNaoPGdafE.H.16.1MKHPvmKwryeulRe225LKProWYwt9Oi" |
497 | 502 | ) |
| 503 | + |
| 504 | + |
| 505 | +@pytest.mark.thread_unsafe() |
| 506 | +def test_multithreading(): |
| 507 | + def get_id(): |
| 508 | + return uuid.uuid4().bytes |
| 509 | + |
| 510 | + class User: |
| 511 | + def __init__(self, id_, pw): |
| 512 | + self.id_ = id_ |
| 513 | + self.salt = bcrypt.gensalt(4) |
| 514 | + self.hash_ = bcrypt.hashpw(pw, self.salt) |
| 515 | + self.key = bcrypt.kdf(pw, self.salt, 32, 50) |
| 516 | + assert self.check(pw) |
| 517 | + |
| 518 | + def check(self, pw): |
| 519 | + return bcrypt.checkpw(pw, self.hash_) |
| 520 | + |
| 521 | + # use UUIDs as both ID and passwords |
| 522 | + NUM_USERS = 50 |
| 523 | + ids = [get_id() for _ in range(NUM_USERS)] |
| 524 | + pws = {id_: get_id() for id_, _ in zip(ids, range(NUM_USERS))} |
| 525 | + |
| 526 | + user_creator = ThreadPoolExecutor(max_workers=4) |
| 527 | + |
| 528 | + def create_user(id_, pw): |
| 529 | + return id_, User(id_, pw) |
| 530 | + |
| 531 | + creator_futures = [ |
| 532 | + user_creator.submit(create_user, id_, pw) for id_, pw in pws.items()] |
| 533 | + |
| 534 | + users = [future.result() for future in creator_futures] |
| 535 | + |
| 536 | + for id_, user in users: |
| 537 | + assert bcrypt.hashpw(pws[id_], user.salt) == user.hash_ |
| 538 | + assert user.check(pws[id_]) |
| 539 | + assert bcrypt.kdf(pws[id_], user.salt, 32, 50) == user.key |
0 commit comments