-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added tests and corrected implementation
Corrected implementation of reference cleanup for signals and when exiting normally. Added tests to ensure functionality. The case where exiting normally was tested locally but no test was added due to higher complexity and low marginal benefit now that normal exit behavior will call unregister and use the same codepaths.
- Loading branch information
1 parent
0ea80d3
commit f3af7e6
Showing
2 changed files
with
257 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
import pyterminate | ||
import gc | ||
import weakref | ||
import signal | ||
|
||
|
||
class Canary(): | ||
pass | ||
|
||
|
||
def test_unregister_refcount(): | ||
"""Tests that unregistering cleans up all references.""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
def cleanup(): | ||
print(c) | ||
|
||
pyterminate.register(cleanup) | ||
pyterminate.unregister(cleanup) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) | ||
|
||
|
||
def test_unregister_refcount_with_decorator(): | ||
""" | ||
Tests that unregistering cleans up all references when registered using the | ||
decorator. | ||
""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
@pyterminate.register | ||
def cleanup(): | ||
print(c) | ||
|
||
pyterminate.unregister(cleanup) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) | ||
|
||
|
||
def test_unregister_refcount_duplicate_calls(): | ||
""" | ||
Tests that unregistering cleans up all references when duplicate register | ||
and unregister calls are made. | ||
""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
@pyterminate.register | ||
def cleanup(): | ||
print(c) | ||
|
||
pyterminate.register(cleanup) | ||
pyterminate.register(cleanup) | ||
pyterminate.register(cleanup) | ||
pyterminate.unregister(cleanup) | ||
pyterminate.unregister(cleanup) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) | ||
|
||
|
||
def test_unregister_refcount_multiple_signals(): | ||
""" | ||
Tests that unregistering cleans up all references when multiple signals | ||
are used. | ||
""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
@pyterminate.register( | ||
signals=(signal.SIGINT, signal.SIGSEGV, signal.SIGTERM) | ||
) | ||
def cleanup(): | ||
print(c) | ||
|
||
pyterminate.unregister(cleanup) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) | ||
|
||
|
||
def test_unregister_refcount_multiple_functions(): | ||
""" | ||
Tests that unregistering cleans up all references when multiple functions | ||
are registered. | ||
""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
def cleanup_1(): | ||
print(c) | ||
|
||
def cleanup_2(): | ||
print(c) | ||
|
||
def cleanup_3(): | ||
print(c) | ||
|
||
pyterminate.register(cleanup_1) | ||
pyterminate.register(cleanup_2) | ||
pyterminate.register(cleanup_3) | ||
pyterminate.unregister(cleanup_3) | ||
pyterminate.unregister(cleanup_2) | ||
pyterminate.unregister(cleanup_1) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) | ||
|
||
|
||
def test_unregister_refcount_multiple_functions_out_of_order(): | ||
""" | ||
Tests that unregistering cleans up all references when multiple functions | ||
are registered and then unregistered not in reverse order. | ||
""" | ||
|
||
weakref_c = None | ||
|
||
def func(): | ||
nonlocal weakref_c | ||
|
||
c = Canary() | ||
weakref_c = weakref.ref(c) | ||
|
||
def cleanup_1(): | ||
print(c) | ||
|
||
def cleanup_2(): | ||
print(c) | ||
|
||
def cleanup_3(): | ||
print(c) | ||
|
||
pyterminate.register(cleanup_1) | ||
pyterminate.register(cleanup_2) | ||
pyterminate.register(cleanup_3) | ||
pyterminate.unregister(cleanup_1) | ||
pyterminate.unregister(cleanup_3) | ||
pyterminate.unregister(cleanup_2) | ||
|
||
func() | ||
assert weakref_c() is None, gc.get_referrers(weakref_c()) |