Skip to content

Commit

Permalink
TestThreadSafeFile
Browse files Browse the repository at this point in the history
  • Loading branch information
0x00b1 committed May 19, 2024
1 parent 249460f commit 516f9ff
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/beignet/io/_thread_safe_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ def __getattr__(self, name: str) -> object:
return getattr(self.file, name)

def __getstate__(self) -> dict[str, Any]:
return {k: v for k, v in self.__dict__.items() if k != "_local"}
state = self.__dict__.copy()

if "storage" in state:
del state["storage"]

return state

def __setstate__(self, state: dict[str, Any]) -> None:
self.__dict__ = state
Expand Down
97 changes: 97 additions & 0 deletions tests/beignet/io/test__thread_safe_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import operator
import threading
from tempfile import NamedTemporaryFile
from typing import Callable
from unittest.mock import MagicMock

from beignet.io import ThreadSafeFile


class TestThreadSafeFile:
def test___init__(self):
with NamedTemporaryFile() as temporary_file:
thread_safe_file = ThreadSafeFile(temporary_file.name)

assert thread_safe_file.path == temporary_file.name

assert isinstance(thread_safe_file.open, Callable)

assert isinstance(thread_safe_file.close, Callable)

assert isinstance(thread_safe_file.storage, threading.local)

def test___del__(self):
with NamedTemporaryFile() as temporary_file:
close = MagicMock()

thread_safe_file = ThreadSafeFile(temporary_file.name, close=close)

thread_safe_file.storage.file = MagicMock()

del thread_safe_file

close.assert_called_once()

def test___getattr__(self):
with NamedTemporaryFile() as temporary_file:
file = MagicMock()

thread_safe_file = ThreadSafeFile(temporary_file.name)

thread_safe_file.storage.file = file

assert thread_safe_file.read == file.read
assert thread_safe_file.write == file.write

def test___getstate__(self):
with NamedTemporaryFile() as temporary_file:
thread_safe_file = ThreadSafeFile(temporary_file.name)

state = thread_safe_file.__getstate__()

assert "path" in state

assert "open" in state

assert "close" in state

assert "storage" not in state

def test___setstate__(self):
with NamedTemporaryFile() as temporary_file:
thread_safe_file = ThreadSafeFile(temporary_file.name)

thread_safe_file.__setstate__(
{
"path": temporary_file.name,
"open": operator.methodcaller("open"),
"close": operator.methodcaller("close"),
},
)

assert thread_safe_file.path == temporary_file.name

assert isinstance(thread_safe_file.open, Callable)

assert isinstance(thread_safe_file.close, Callable)

assert isinstance(thread_safe_file.storage, threading.local)

def test_file(self):
with NamedTemporaryFile() as temporary_file:
open = MagicMock(return_value=MagicMock())

thread_safe_file = ThreadSafeFile(
temporary_file.name,
open=open,
)

file = thread_safe_file.file

open.assert_called_once_with(temporary_file.name)

assert thread_safe_file.storage.file == file
assert thread_safe_file.file == file

assert thread_safe_file.file == file
assert open.call_count == 1

0 comments on commit 516f9ff

Please sign in to comment.