harlowja / fasteners

A python package that provides useful locks.
Apache License 2.0
243 stars 45 forks source link

Tests hang with eventlet support #101

Closed musicinmybrain closed 1 year ago

musicinmybrain commented 1 year ago

On Fedora Linux 36, x86_64, test_no_concurrent_writers always hangs beginning with 383d9b6. It never hangs with 59dec43 and earlier.

$ git checkout 383d9b6
$ python3 -m venv _e
$ . _e/bin/activate
(_e) $ pip install -e .
(_e) $ pip install -r requirements-test.txt
(_e) $ pytest -v
================================================ test session starts =================================================
platform linux -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0 -- /home/ben/src/forks/fasteners/_e/bin/python3
cachedir: .pytest_cache
rootdir: /home/ben/src/forks/fasteners
collected 44 items                                                                                                   

tests/test_decorators.py::test_locked PASSED                                                                   [  2%]
tests/test_decorators.py::test_many_locked PASSED                                                              [  4%]
tests/test_decorators.py::test_read_write_locked PASSED                                                        [  6%]
tests/test_helpers.py::test_try_lock PASSED                                                                    [  9%]
tests/test_lock.py::test_no_double_writers PASSED                                                              [ 11%]
tests/test_lock.py::test_no_concurrent_readers_writers PASSED                                                  [ 13%]
tests/test_lock.py::test_writer_abort PASSED                                                                   [ 15%]
tests/test_lock.py::test_reader_abort PASSED                                                                   [ 18%]
tests/test_lock.py::test_double_reader_abort PASSED                                                            [ 20%]
tests/test_lock.py::test_double_reader_writer PASSED                                                           [ 22%]
tests/test_lock.py::test_reader_chaotic PASSED                                                                 [ 25%]
tests/test_lock.py::test_writer_chaotic PASSED                                                                 [ 27%]
tests/test_lock.py::test_writer_reader_writer PASSED                                                           [ 29%]
tests/test_lock.py::test_single_reader_writer PASSED                                                           [ 31%]
tests/test_lock.py::test_reader_to_writer PASSED                                                               [ 34%]
tests/test_lock.py::test_writer_to_reader PASSED                                                               [ 36%]
tests/test_lock.py::test_double_writer PASSED                                                                  [ 38%]
tests/test_lock.py::test_double_reader PASSED                                                                  [ 40%]
tests/test_lock.py::test_multi_reader_multi_writer PASSED                                                      [ 43%]
tests/test_lock.py::test_multi_reader_single_writer PASSED                                                     [ 45%]
tests/test_lock.py::test_multi_writer PASSED                                                                   [ 47%]
tests/test_lock.py::test_deadlock_reproducer PASSED                                                            [ 50%]
tests/test_process_lock.py::test_lock_acquire_release_file_lock PASSED                                         [ 52%]
tests/test_process_lock.py::test_nested_synchronized_external_works PASSED                                     [ 54%]
tests/test_process_lock.py::test_lock_externally PASSED                                                        [ 56%]
tests/test_process_lock.py::test_lock_externally_lock_dir_not_exist PASSED                                     [ 59%]
tests/test_process_lock.py::test_lock_file_exists PASSED                                                       [ 61%]
tests/test_process_lock.py::test_bad_release PASSED                                                            [ 63%]
tests/test_process_lock.py::test_interprocess_lock PASSED                                                      [ 65%]
tests/test_process_lock.py::test_non_destructive PASSED                                                        [ 68%]
tests/test_process_lock.py::test_bad_acquire PASSED                                                            [ 70%]
tests/test_process_lock.py::test_lock_twice PASSED                                                             [ 72%]
tests/test_reader_writer_lock.py::test_lock PASSED                                                             [ 75%]
tests/test_reader_writer_lock.py::test_no_concurrent_writers 

Beginning with 1875874, test_double_reader_writer also hangs:

(_e) $ git checkout 1875874
(_e) $ pytest -v
================================================ test session starts =================================================
platform linux -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0 -- /home/ben/src/forks/fasteners/_e/bin/python3
cachedir: .pytest_cache
rootdir: /home/ben/src/forks/fasteners
collected 44 items                                                                                                   

tests/test_decorators.py::test_locked PASSED                                                                   [  2%]
tests/test_decorators.py::test_many_locked PASSED                                                              [  4%]
tests/test_decorators.py::test_read_write_locked PASSED                                                        [  6%]
tests/test_helpers.py::test_try_lock PASSED                                                                    [  9%]
tests/test_lock.py::test_no_double_writers PASSED                                                              [ 11%]
tests/test_lock.py::test_no_concurrent_readers_writers PASSED                                                  [ 13%]
tests/test_lock.py::test_writer_abort PASSED                                                                   [ 15%]
tests/test_lock.py::test_reader_abort PASSED                                                                   [ 18%]
tests/test_lock.py::test_double_reader_abort PASSED                                                            [ 20%]
tests/test_lock.py::test_double_reader_writer 
psarka commented 1 year ago

Thank you, I'm aware of this issue.The culprit is eventlet monkey patching, which does not play well with multiprocessing. I did not manage to figure out how to isolate the test cases, nor how to isolate eventlet. So I physically separated the tests into two directories and I run them now as

pytest tests/
pytest tests_eventlet/

Is this something you could do as well? The only alternative that comes to my mind is to try run the eventlet tests in a child process, so that the monkey patch would not affect the main one.

psarka commented 1 year ago

Hang on, I think running in a child works fine. Give me a sec :running_man:

musicinmybrain commented 1 year ago

Thank you, I'm aware of this issue.The culprit is eventlet monkey patching, which does not play well with multiprocessing. I did not manage to figure out how to isolate the test cases, nor how to isolate eventlet. So I physically separated the tests into two directories and I run them now as


pytest tests/
pytest tests_eventlet/

Thank you. This works for me, too.

psarka commented 1 year ago

I fixed it in https://github.com/harlowja/fasteners/commit/80a3eaed75276faf21034e7e6c626fd19485ea39 on my side as well - eventlet test is back in main, and I run it in a subprocess, so there is no more conflict.

musicinmybrain commented 1 year ago

I fixed it in 80a3eae on my side as well - eventlet test is back in main, and I run it in a subprocess, so there is no more conflict.

Thanks again; I can confirm that commit works for me, too.