-
-
Notifications
You must be signed in to change notification settings - Fork 120
Closed
Description
Both cases of test_del hang indefinitely on PyPy. This is probably due to the differences of how PyPy does (not) perform GC.
Here's a traceback from pytest after adding a timeout:
$ pytest -v --timeout=15 test.py
=============================================================== test session starts ===============================================================
platform linux2 -- Python 2.7.13[pypy-6.0.0-final], pytest-3.8.2, py-1.5.4, pluggy-0.7.1 -- /usr/bin/pypy
cachedir: .pytest_cache
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/py-filelock/.hypothesis/examples')
rootdir: /tmp/py-filelock, inifile:
plugins: virtualenv-1.2.11, timeout-1.2.1, shutil-1.2.11, mock-1.10.0, hypothesis-3.74.3, backports.unittest-mock-1.4
timeout: 15.0s method: signal
collected 23 items
test.py::FileLockTest::test_context PASSED [ 4%]
test.py::FileLockTest::test_context1 PASSED [ 8%]
test.py::FileLockTest::test_default_timeout PASSED [ 13%]
test.py::FileLockTest::test_del FAILED [ 17%]
test.py::FileLockTest::test_nested PASSED [ 21%]
test.py::FileLockTest::test_nested1 PASSED [ 26%]
test.py::FileLockTest::test_nested_forced_release PASSED [ 30%]
test.py::FileLockTest::test_simple PASSED [ 34%]
test.py::FileLockTest::test_threaded PASSED [ 39%]
test.py::FileLockTest::test_threaded1 PASSED [ 43%]
test.py::FileLockTest::test_timeout PASSED [ 47%]
test.py::SoftFileLockTest::test_cleanup PASSED [ 52%]
test.py::SoftFileLockTest::test_context PASSED [ 56%]
test.py::SoftFileLockTest::test_context1 PASSED [ 60%]
test.py::SoftFileLockTest::test_default_timeout PASSED [ 65%]
test.py::SoftFileLockTest::test_del FAILED [ 69%]
test.py::SoftFileLockTest::test_nested PASSED [ 73%]
test.py::SoftFileLockTest::test_nested1 PASSED [ 78%]
test.py::SoftFileLockTest::test_nested_forced_release PASSED [ 82%]
test.py::SoftFileLockTest::test_simple PASSED [ 86%]
test.py::SoftFileLockTest::test_threaded PASSED [ 91%]
test.py::SoftFileLockTest::test_threaded1 PASSED [ 95%]
test.py::SoftFileLockTest::test_timeout PASSED [100%]
==================================================================== FAILURES =====================================================================
______________________________________________________________ FileLockTest.test_del ______________________________________________________________
self = <test.FileLockTest testMethod=test_del>
def test_del(self):
"""
Tests, if the lock is released, when the object is deleted.
"""
lock1 = self.LOCK_TYPE(self.LOCK_PATH)
lock2 = self.LOCK_TYPE(self.LOCK_PATH)
# Acquire lock 1.
lock1.acquire()
self.assertTrue(lock1.is_locked)
self.assertFalse(lock2.is_locked)
# Try to acquire lock 2.
self.assertRaises(filelock.Timeout, lock2.acquire, timeout = 1) # FIXME (SoftFileLock)
# Delete lock 1 and try to acquire lock 2 again.
del lock1
> lock2.acquire()
test.py:355:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <filelock.UnixFileLock object at 0x000055eb24d21328>, timeout = -1.0, poll_intervall = 0.05
def acquire(self, timeout=None, poll_intervall=0.05):
"""
Acquires the file lock or fails with a :exc:`Timeout` error.
.. code-block:: python
# You can use this method in the context manager (recommended)
with lock.acquire():
pass
# Or use an equivalent try-finally construct:
lock.acquire()
try:
pass
finally:
lock.release()
:arg float timeout:
The maximum time waited for the file lock.
If ``timeout <= 0``, there is no timeout and this method will
block until the lock could be acquired.
If ``timeout`` is None, the default :attr:`~timeout` is used.
:arg float poll_intervall:
We check once in *poll_intervall* seconds if we can acquire the
file lock.
:raises Timeout:
if the lock could not be acquired in *timeout* seconds.
.. versionchanged:: 2.0.0
This method returns now a *proxy* object instead of *self*,
so that it can be used in a with statement without side effects.
"""
# Use the default timeout, if no timeout is provided.
if timeout is None:
timeout = self.timeout
# Increment the number right at the beginning.
# We can still undo it, if something fails.
with self._thread_lock:
self._lock_counter += 1
lock_id = id(self)
lock_filename = self._lock_file
start_time = time.time()
try:
while True:
with self._thread_lock:
if not self.is_locked:
logger().debug('Attempting to acquire lock %s on %s', lock_id, lock_filename)
self._acquire()
if self.is_locked:
logger().info('Lock %s acquired on %s', lock_id, lock_filename)
break
elif timeout >= 0 and time.time() - start_time > timeout:
logger().debug('Timeout on acquiring lock %s on %s', lock_id, lock_filename)
raise Timeout(self._lock_file)
else:
logger().debug(
'Lock %s not acquired on %s, waiting %s seconds ...',
lock_id, lock_filename, poll_intervall
)
> time.sleep(poll_intervall)
E Failed: Timeout >15.0s
filelock.py:284: Failed
____________________________________________________________ SoftFileLockTest.test_del ____________________________________________________________
self = <test.SoftFileLockTest testMethod=test_del>
def test_del(self):
"""
Tests, if the lock is released, when the object is deleted.
"""
lock1 = self.LOCK_TYPE(self.LOCK_PATH)
lock2 = self.LOCK_TYPE(self.LOCK_PATH)
# Acquire lock 1.
lock1.acquire()
self.assertTrue(lock1.is_locked)
self.assertFalse(lock2.is_locked)
# Try to acquire lock 2.
self.assertRaises(filelock.Timeout, lock2.acquire, timeout = 1) # FIXME (SoftFileLock)
# Delete lock 1 and try to acquire lock 2 again.
del lock1
> lock2.acquire()
test.py:355:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <filelock.SoftFileLock object at 0x00007fb06012fbb0>, timeout = -1.0, poll_intervall = 0.05
def acquire(self, timeout=None, poll_intervall=0.05):
"""
Acquires the file lock or fails with a :exc:`Timeout` error.
.. code-block:: python
# You can use this method in the context manager (recommended)
with lock.acquire():
pass
# Or use an equivalent try-finally construct:
lock.acquire()
try:
pass
finally:
lock.release()
:arg float timeout:
The maximum time waited for the file lock.
If ``timeout <= 0``, there is no timeout and this method will
block until the lock could be acquired.
If ``timeout`` is None, the default :attr:`~timeout` is used.
:arg float poll_intervall:
We check once in *poll_intervall* seconds if we can acquire the
file lock.
:raises Timeout:
if the lock could not be acquired in *timeout* seconds.
.. versionchanged:: 2.0.0
This method returns now a *proxy* object instead of *self*,
so that it can be used in a with statement without side effects.
"""
# Use the default timeout, if no timeout is provided.
if timeout is None:
timeout = self.timeout
# Increment the number right at the beginning.
# We can still undo it, if something fails.
with self._thread_lock:
self._lock_counter += 1
lock_id = id(self)
lock_filename = self._lock_file
start_time = time.time()
try:
while True:
with self._thread_lock:
if not self.is_locked:
logger().debug('Attempting to acquire lock %s on %s', lock_id, lock_filename)
self._acquire()
if self.is_locked:
logger().info('Lock %s acquired on %s', lock_id, lock_filename)
break
elif timeout >= 0 and time.time() - start_time > timeout:
logger().debug('Timeout on acquiring lock %s on %s', lock_id, lock_filename)
raise Timeout(self._lock_file)
else:
logger().debug(
'Lock %s not acquired on %s, waiting %s seconds ...',
lock_id, lock_filename, poll_intervall
)
> time.sleep(poll_intervall)
E Failed: Timeout >15.0s
filelock.py:284: Failed
====================================================== 2 failed, 21 passed in 38.50 seconds =======================================================
Metadata
Metadata
Assignees
Labels
No labels