Skip to content

Commit b8321fa

Browse files
Add a multithreaded stress test (#199)
* Add a multithreaded stress test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add noqa * add a docstring for the new test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 9143d90 commit b8321fa

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

tests/test_password_hasher.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# SPDX-License-Identifier: MIT
22

3+
import secrets
4+
import sys
5+
import threading
6+
7+
from concurrent.futures import ThreadPoolExecutor
38
from unittest import mock
49

510
import pytest
@@ -194,3 +199,38 @@ def test_params_on_wasm(self, machine):
194199
hash = ph.hash("hello")
195200

196201
assert ph.verify(hash, "hello") is True
202+
203+
204+
def test_multithreaded_hashing():
205+
"""
206+
Hash passwords in a thread pool and check for thread safety
207+
"""
208+
hasher = PasswordHasher(parallelism=2)
209+
210+
num_passwords = 100
211+
212+
passwords = [secrets.token_urlsafe(15) for _ in range(num_passwords)]
213+
214+
def closure(b, passwords):
215+
b.wait()
216+
for password in passwords:
217+
assert hasher.verify(hasher.hash(password), password)
218+
219+
max_workers = 4
220+
221+
chunks = [passwords[i::max_workers] for i in range(max_workers)]
222+
orig_interval = sys.getswitchinterval()
223+
224+
with ThreadPoolExecutor(max_workers=max_workers) as tpe:
225+
barrier = threading.Barrier(max_workers)
226+
futures = []
227+
try:
228+
sys.setswitchinterval(0.00001)
229+
for chunk in chunks:
230+
futures.append(tpe.submit(closure, barrier, chunk)) # noqa: PERF401
231+
finally:
232+
sys.setswitchinterval(orig_interval)
233+
if len(futures) < max_workers:
234+
barrier.abort()
235+
for f in futures:
236+
f.result()

0 commit comments

Comments
 (0)