mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-03 06:58:42 +00:00
[Config] Fix callLater func missing args
In a6840296
, a refactor to the `config` class was introduced.
The change included an internal wrapper for `reactor.callLater`, for lazy
import, but didn't wrap it correctly and therefor, no args/kwargs were
passed to the wrapped method.
Furthermore, the exception was silently ignored.
This caused changes to be ignored and not applied, including
`preferencesmanager._on_config_value_change` callback.
Closes: https://github.com/deluge-torrent/deluge/pull/372
This commit is contained in:
parent
374997a8d7
commit
f8f997a6eb
3 changed files with 56 additions and 3 deletions
|
@ -144,11 +144,11 @@ class Config:
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
def callLater(self, period, func): # noqa: N802 ignore camelCase
|
def callLater(self, period, func, *args, **kwargs): # noqa: N802 ignore camelCase
|
||||||
"""Wrapper around reactor.callLater for test purpose."""
|
"""Wrapper around reactor.callLater for test purpose."""
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
|
|
||||||
return reactor.callLater(period, func)
|
return reactor.callLater(period, func, *args, **kwargs)
|
||||||
|
|
||||||
def __contains__(self, item):
|
def __contains__(self, item):
|
||||||
return item in self.__config
|
return item in self.__config
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import unittest.mock
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import pytest_twisted
|
import pytest_twisted
|
||||||
from twisted.internet.defer import maybeDeferred
|
from twisted.internet import reactor
|
||||||
|
from twisted.internet.defer import Deferred, maybeDeferred
|
||||||
from twisted.internet.error import CannotListenError
|
from twisted.internet.error import CannotListenError
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
|
|
||||||
|
@ -31,6 +33,29 @@ def listen_port(request):
|
||||||
return DEFAULT_LISTEN_PORT
|
return DEFAULT_LISTEN_PORT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_callback():
|
||||||
|
"""Returns a `Mock` object which can be registered as a callback to test against.
|
||||||
|
|
||||||
|
If callback was not called within `timeout` seconds, it will raise a TimeoutError.
|
||||||
|
The returned Mock instance will have a `deferred` attribute which will complete when the callback has been called.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def reset():
|
||||||
|
if mock.called:
|
||||||
|
original_reset_mock()
|
||||||
|
deferred = Deferred()
|
||||||
|
deferred.addTimeout(0.5, reactor)
|
||||||
|
mock.side_effect = lambda *args, **kw: deferred.callback((args, kw))
|
||||||
|
mock.deferred = deferred
|
||||||
|
|
||||||
|
mock = unittest.mock.Mock()
|
||||||
|
original_reset_mock = mock.reset_mock
|
||||||
|
mock.reset_mock = reset
|
||||||
|
mock.reset_mock()
|
||||||
|
return mock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def config_dir(tmp_path):
|
def config_dir(tmp_path):
|
||||||
deluge.configmanager.set_config_dir(tmp_path)
|
deluge.configmanager.set_config_dir(tmp_path)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import os
|
||||||
from codecs import getwriter
|
from codecs import getwriter
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import task
|
from twisted.internet import task
|
||||||
|
|
||||||
from deluge.common import JSON_FORMAT
|
from deluge.common import JSON_FORMAT
|
||||||
|
@ -83,6 +84,33 @@ class TestConfig:
|
||||||
|
|
||||||
config._save_timer.cancel()
|
config._save_timer.cancel()
|
||||||
|
|
||||||
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_on_changed_callback(self, mock_callback):
|
||||||
|
config = Config('test.conf', config_dir=self.config_dir)
|
||||||
|
config.register_change_callback(mock_callback)
|
||||||
|
config['foo'] = 1
|
||||||
|
assert config['foo'] == 1
|
||||||
|
await mock_callback.deferred
|
||||||
|
mock_callback.assert_called_once_with('foo', 1)
|
||||||
|
|
||||||
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_key_function_callback(self, mock_callback):
|
||||||
|
config = Config(
|
||||||
|
'test.conf', defaults={'foo': 1, 'bar': 1}, config_dir=self.config_dir
|
||||||
|
)
|
||||||
|
|
||||||
|
assert config['foo'] == 1
|
||||||
|
config.register_set_function('foo', mock_callback)
|
||||||
|
await mock_callback.deferred
|
||||||
|
mock_callback.assert_called_once_with('foo', 1)
|
||||||
|
|
||||||
|
mock_callback.reset_mock()
|
||||||
|
config.register_set_function('bar', mock_callback, apply_now=False)
|
||||||
|
mock_callback.assert_not_called()
|
||||||
|
config['bar'] = 2
|
||||||
|
await mock_callback.deferred
|
||||||
|
mock_callback.assert_called_once_with('bar', 2)
|
||||||
|
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
config = Config('test.conf', config_dir=self.config_dir)
|
config = Config('test.conf', config_dir=self.config_dir)
|
||||||
config['foo'] = 1
|
config['foo'] = 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue