testutil: add AtomicCounter() as a threadsafe counter
The existing code in the reqs counting is not really thread safe, this commit fixes that.
This commit is contained in:
parent
b90a5027dc
commit
b9b296a7e5
4 changed files with 39 additions and 8 deletions
29
osbuild/testutil/atomic.py
Normal file
29
osbuild/testutil/atomic.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/python3
|
||||
"""
|
||||
thread/atomic related utilities
|
||||
"""
|
||||
import threading
|
||||
|
||||
|
||||
class AtomicCounter:
|
||||
""" A thread-safe counter """
|
||||
|
||||
def __init__(self, count: int = 0) -> None:
|
||||
self._count = count
|
||||
self._lock = threading.Lock()
|
||||
|
||||
def inc(self) -> None:
|
||||
""" increase the count """
|
||||
with self._lock:
|
||||
self._count += 1
|
||||
|
||||
def dec(self) -> None:
|
||||
""" decrease the count """
|
||||
with self._lock:
|
||||
self._count -= 1
|
||||
|
||||
@property
|
||||
def count(self) -> int:
|
||||
""" get the current count """
|
||||
with self._lock:
|
||||
return self._count
|
||||
|
|
@ -7,6 +7,8 @@ import http.server
|
|||
import socket
|
||||
import threading
|
||||
|
||||
from .atomic import AtomicCounter
|
||||
|
||||
|
||||
def _get_free_port():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
|
@ -23,13 +25,13 @@ class DirHTTPServer(http.server.ThreadingHTTPServer):
|
|||
def __init__(self, *args, directory=None, simulate_failures=0, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.directory = directory
|
||||
self.simulate_failures = simulate_failures
|
||||
self.reqs = 0
|
||||
self.simulate_failures = AtomicCounter(simulate_failures)
|
||||
self.reqs = AtomicCounter()
|
||||
|
||||
def finish_request(self, request, client_address):
|
||||
self.reqs += 1 # racy on non GIL systems
|
||||
if self.simulate_failures > 0:
|
||||
self.simulate_failures -= 1 # racy on non GIL systems
|
||||
self.reqs.inc()
|
||||
if self.simulate_failures.count > 0:
|
||||
self.simulate_failures.dec()
|
||||
SilentHTTPRequestHandler(
|
||||
request, client_address, self, directory="does-not-exists")
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue