mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-25 14:04:53 +00:00
[Tests] Transition tests to pure pytest
Convert all the twisted.trial tests to pytest_twisted. Also move off of unittest.TestCase as well. Seems there were several tests which weren't actually testing what they should, and also some code that wasn't doing what the broken test said it should. Goals: Remove twisted.trial tests Move to pytest fixtures, rather than many classess and subclasses with setup and teardown functions Move away from self.assertX to assert style tests FIx broken tests Going forward I think these should be the goals when adding/modifying tests: * Don't use BaseTest or set_up tear_down methods any more. Fixtures should be used either in the test module/class, or make/improve the ones available in conftest.py * For sure don't use unittest or twisted.trial, they mess up the pytest stuff. * Prefer pytest_twisted.ensureDeferred with an async function over inlineCallbacks. - I think the async function syntax is nicer, and it helps catch silly mistakes, e.g. await None is invalid, but yield None isn't, so if some function returns an unexpected thing we try to await on, it will be caught earlier. (I struggled debugging a test for quite a while, then caught it immediately when switching to the new syntax) - Once the maybe_coroutine PR goes in, using the async syntax can also improve tracebacks when debugging tests. Things that should probably be cleaned up going forward: * Remove BaseTestCase * Remove the subclasses like DaemonBase in favor of new fixtures. * I think there are some other utility subclasses that could be removed too * Perhaps use parameterization in the ui_entry tests, rather that the weird combination of subclasses and the set_var fixture I mixed in. * Convert some of the callback stuff to pytest_twisted.ensureDeferred tests, just for nicer readability Details relating to pytest fixtures conftest.py in root dir: * https://github.com/pytest-dev/pytest/issues/5822#issuecomment-697331920 * https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files Closes: https://github.com/deluge-torrent/deluge/pull/354
This commit is contained in:
parent
0fbb3882f2
commit
ece31cf3cf
43 changed files with 1144 additions and 1410 deletions
158
deluge/conftest.py
Normal file
158
deluge/conftest.py
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#
|
||||||
|
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
|
||||||
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
|
# See LICENSE for more details.
|
||||||
|
#
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
|
from twisted.internet.defer import maybeDeferred
|
||||||
|
from twisted.internet.error import CannotListenError
|
||||||
|
from twisted.python.failure import Failure
|
||||||
|
|
||||||
|
import deluge.component as _component
|
||||||
|
import deluge.configmanager
|
||||||
|
from deluge.common import get_localhost_auth
|
||||||
|
from deluge.tests import common
|
||||||
|
from deluge.ui.client import client as _client
|
||||||
|
|
||||||
|
DEFAULT_LISTEN_PORT = 58900
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def listen_port(request):
|
||||||
|
if request and 'daemon' in request.fixturenames:
|
||||||
|
try:
|
||||||
|
return request.getfixturevalue('daemon').listen_port
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return DEFAULT_LISTEN_PORT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def config_dir(tmp_path):
|
||||||
|
deluge.configmanager.set_config_dir(tmp_path)
|
||||||
|
yield tmp_path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest_twisted.async_yield_fixture()
|
||||||
|
async def client(request, config_dir, monkeypatch, listen_port):
|
||||||
|
# monkeypatch.setattr(
|
||||||
|
# _client, 'connect', functools.partial(_client.connect, port=listen_port)
|
||||||
|
# )
|
||||||
|
try:
|
||||||
|
username, password = get_localhost_auth()
|
||||||
|
except Exception:
|
||||||
|
username, password = '', ''
|
||||||
|
await _client.connect(
|
||||||
|
'localhost',
|
||||||
|
port=listen_port,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
)
|
||||||
|
yield _client
|
||||||
|
if _client.connected():
|
||||||
|
await _client.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest_twisted.async_yield_fixture
|
||||||
|
async def daemon(request, config_dir):
|
||||||
|
listen_port = DEFAULT_LISTEN_PORT
|
||||||
|
logfile = f'daemon_{request.node.name}.log'
|
||||||
|
if hasattr(request.cls, 'daemon_custom_script'):
|
||||||
|
custom_script = request.cls.daemon_custom_script
|
||||||
|
else:
|
||||||
|
custom_script = ''
|
||||||
|
|
||||||
|
for dummy in range(10):
|
||||||
|
try:
|
||||||
|
d, daemon = common.start_core(
|
||||||
|
listen_port=listen_port,
|
||||||
|
logfile=logfile,
|
||||||
|
timeout=5,
|
||||||
|
timeout_msg='Timeout!',
|
||||||
|
custom_script=custom_script,
|
||||||
|
print_stdout=True,
|
||||||
|
print_stderr=True,
|
||||||
|
config_directory=config_dir,
|
||||||
|
)
|
||||||
|
await d
|
||||||
|
except CannotListenError as ex:
|
||||||
|
exception_error = ex
|
||||||
|
listen_port += 1
|
||||||
|
except (KeyboardInterrupt, SystemExit):
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise exception_error
|
||||||
|
daemon.listen_port = listen_port
|
||||||
|
yield daemon
|
||||||
|
await daemon.kill()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def common_fixture(config_dir, request, monkeypatch, listen_port):
|
||||||
|
"""Adds some instance attributes to test classes for backwards compatibility with old testing."""
|
||||||
|
|
||||||
|
def fail(self, reason):
|
||||||
|
if isinstance(reason, Failure):
|
||||||
|
reason = reason.value
|
||||||
|
return pytest.fail(str(reason))
|
||||||
|
|
||||||
|
if request.instance:
|
||||||
|
request.instance.patch = monkeypatch.setattr
|
||||||
|
request.instance.config_dir = config_dir
|
||||||
|
request.instance.listen_port = listen_port
|
||||||
|
request.instance.id = lambda: request.node.name
|
||||||
|
request.cls.fail = fail
|
||||||
|
|
||||||
|
|
||||||
|
@pytest_twisted.async_yield_fixture(scope='function')
|
||||||
|
async def component(request):
|
||||||
|
"""Verify component registry is clean, and clean up after test."""
|
||||||
|
if len(_component._ComponentRegistry.components) != 0:
|
||||||
|
warnings.warn(
|
||||||
|
'The component._ComponentRegistry.components is not empty on test setup.\n'
|
||||||
|
'This is probably caused by another test that did not clean up after finishing!: %s'
|
||||||
|
% _component._ComponentRegistry.components
|
||||||
|
)
|
||||||
|
|
||||||
|
yield _component
|
||||||
|
|
||||||
|
await _component.shutdown()
|
||||||
|
_component._ComponentRegistry.components.clear()
|
||||||
|
_component._ComponentRegistry.dependents.clear()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest_twisted.async_yield_fixture(scope='function')
|
||||||
|
async def base_fixture(common_fixture, component, request):
|
||||||
|
"""This fixture is autoused on all tests that subclass BaseTestCase"""
|
||||||
|
self = request.instance
|
||||||
|
|
||||||
|
if hasattr(self, 'set_up'):
|
||||||
|
try:
|
||||||
|
await maybeDeferred(self.set_up)
|
||||||
|
except Exception as exc:
|
||||||
|
warnings.warn('Error caught in test setup!\n%s' % exc)
|
||||||
|
pytest.fail('Error caught in test setup!\n%s' % exc)
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
if hasattr(self, 'tear_down'):
|
||||||
|
try:
|
||||||
|
await maybeDeferred(self.tear_down)
|
||||||
|
except Exception as exc:
|
||||||
|
pytest.fail('Error caught in test teardown!\n%s' % exc)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures('base_fixture')
|
||||||
|
class BaseTestCase:
|
||||||
|
"""This is the base class that should be used for all test classes
|
||||||
|
that create classes that inherit from deluge.component.Component. It
|
||||||
|
ensures that the component registry has been cleaned up when tests
|
||||||
|
have finished.
|
||||||
|
|
||||||
|
"""
|
|
@ -16,7 +16,7 @@ from twisted.internet.defer import Deferred
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
from twisted.web import client, http
|
from twisted.web import client, http
|
||||||
from twisted.web._newclient import HTTPClientParser
|
from twisted.web._newclient import HTTPClientParser
|
||||||
from twisted.web.error import PageRedirect
|
from twisted.web.error import Error, PageRedirect
|
||||||
from twisted.web.http_headers import Headers
|
from twisted.web.http_headers import Headers
|
||||||
from twisted.web.iweb import IAgent
|
from twisted.web.iweb import IAgent
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
@ -122,6 +122,9 @@ class HTTPDownloaderAgent:
|
||||||
location = response.headers.getRawHeaders(b'location')[0]
|
location = response.headers.getRawHeaders(b'location')[0]
|
||||||
error = PageRedirect(response.code, location=location)
|
error = PageRedirect(response.code, location=location)
|
||||||
finished.errback(Failure(error))
|
finished.errback(Failure(error))
|
||||||
|
elif response.code >= 400:
|
||||||
|
error = Error(response.code)
|
||||||
|
finished.errback(Failure(error))
|
||||||
else:
|
else:
|
||||||
headers = response.headers
|
headers = response.headers
|
||||||
body_length = int(headers.getRawHeaders(b'content-length', default=[0])[0])
|
body_length = int(headers.getRawHeaders(b'content-length', default=[0])[0])
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
import pytest
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.common import fsize, fspeed
|
from deluge.common import fsize, fspeed
|
||||||
from deluge.tests import common as tests_common
|
|
||||||
from deluge.tests.basetest import BaseTestCase
|
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,17 +22,17 @@ def print_totals(totals):
|
||||||
print('down:', fsize(totals['total_download'] - totals['total_payload_download']))
|
print('down:', fsize(totals['total_download'] - totals['total_payload_download']))
|
||||||
|
|
||||||
|
|
||||||
class StatsTestCase(BaseTestCase):
|
@pytest.mark.usefixtures('component')
|
||||||
def set_up(self):
|
class TestStatsPlugin:
|
||||||
|
@pytest_twisted.async_yield_fixture(autouse=True)
|
||||||
|
async def set_up(self):
|
||||||
defer.setDebugging(True)
|
defer.setDebugging(True)
|
||||||
tests_common.set_tmp_config_dir()
|
|
||||||
client.start_standalone()
|
client.start_standalone()
|
||||||
client.core.enable_plugin('Stats')
|
client.core.enable_plugin('Stats')
|
||||||
return component.start()
|
await component.start()
|
||||||
|
yield
|
||||||
def tear_down(self):
|
|
||||||
client.stop_standalone()
|
client.stop_standalone()
|
||||||
return component.shutdown()
|
await component.shutdown()
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def test_client_totals(self):
|
def test_client_totals(self):
|
||||||
|
@ -42,10 +41,10 @@ class StatsTestCase(BaseTestCase):
|
||||||
raise unittest.SkipTest('WebUi plugin not available for testing')
|
raise unittest.SkipTest('WebUi plugin not available for testing')
|
||||||
|
|
||||||
totals = yield client.stats.get_totals()
|
totals = yield client.stats.get_totals()
|
||||||
self.assertEqual(totals['total_upload'], 0)
|
assert totals['total_upload'] == 0
|
||||||
self.assertEqual(totals['total_payload_upload'], 0)
|
assert totals['total_payload_upload'] == 0
|
||||||
self.assertEqual(totals['total_payload_download'], 0)
|
assert totals['total_payload_download'] == 0
|
||||||
self.assertEqual(totals['total_download'], 0)
|
assert totals['total_download'] == 0
|
||||||
# print_totals(totals)
|
# print_totals(totals)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
@ -55,10 +54,10 @@ class StatsTestCase(BaseTestCase):
|
||||||
raise unittest.SkipTest('WebUi plugin not available for testing')
|
raise unittest.SkipTest('WebUi plugin not available for testing')
|
||||||
|
|
||||||
totals = yield client.stats.get_session_totals()
|
totals = yield client.stats.get_session_totals()
|
||||||
self.assertEqual(totals['total_upload'], 0)
|
assert totals['total_upload'] == 0
|
||||||
self.assertEqual(totals['total_payload_upload'], 0)
|
assert totals['total_payload_upload'] == 0
|
||||||
self.assertEqual(totals['total_payload_download'], 0)
|
assert totals['total_payload_download'] == 0
|
||||||
self.assertEqual(totals['total_download'], 0)
|
assert totals['total_download'] == 0
|
||||||
# print_totals(totals)
|
# print_totals(totals)
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
|
|
|
@ -5,31 +5,34 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.trial import unittest
|
from twisted.trial import unittest
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
from deluge.core.rpcserver import RPCServer
|
from deluge.core.rpcserver import RPCServer
|
||||||
from deluge.tests import common
|
from deluge.tests import common
|
||||||
from deluge.tests.basetest import BaseTestCase
|
|
||||||
|
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
|
||||||
class WebUIPluginTestCase(BaseTestCase):
|
@pytest.mark.usefixtures('component')
|
||||||
def set_up(self):
|
class TestWebUIPlugin:
|
||||||
common.set_tmp_config_dir()
|
@pytest_twisted.async_yield_fixture(autouse=True)
|
||||||
|
async def set_up(self, request):
|
||||||
|
self = request.instance
|
||||||
self.rpcserver = RPCServer(listen=False)
|
self.rpcserver = RPCServer(listen=False)
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
return component.start()
|
await component.start()
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
def on_shutdown(result):
|
def on_shutdown(result):
|
||||||
del self.rpcserver
|
del self.rpcserver
|
||||||
del self.core
|
del self.core
|
||||||
|
|
||||||
return component.shutdown().addCallback(on_shutdown)
|
await component.shutdown().addCallback(on_shutdown)
|
||||||
|
|
||||||
def test_enable_webui(self):
|
def test_enable_webui(self):
|
||||||
if 'WebUi' not in self.core.get_available_plugins():
|
if 'WebUi' not in self.core.get_available_plugins():
|
||||||
|
@ -40,7 +43,7 @@ class WebUIPluginTestCase(BaseTestCase):
|
||||||
def result_cb(result):
|
def result_cb(result):
|
||||||
if 'WebUi' not in self.core.get_enabled_plugins():
|
if 'WebUi' not in self.core.get_enabled_plugins():
|
||||||
self.fail('Failed to enable WebUi plugin')
|
self.fail('Failed to enable WebUi plugin')
|
||||||
self.assertTrue(result)
|
assert result
|
||||||
|
|
||||||
d.addBoth(result_cb)
|
d.addBoth(result_cb)
|
||||||
return d
|
return d
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
#
|
|
||||||
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
|
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
|
||||||
# See LICENSE for more details.
|
|
||||||
#
|
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from twisted.internet.defer import maybeDeferred
|
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.component as component
|
|
||||||
|
|
||||||
|
|
||||||
class BaseTestCase(unittest.TestCase):
|
|
||||||
"""This is the base class that should be used for all test classes
|
|
||||||
that create classes that inherit from deluge.component.Component. It
|
|
||||||
ensures that the component registry has been cleaned up when tests
|
|
||||||
have finished.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setUp(self): # NOQA: N803
|
|
||||||
|
|
||||||
if len(component._ComponentRegistry.components) != 0:
|
|
||||||
warnings.warn(
|
|
||||||
'The component._ComponentRegistry.components is not empty on test setup.\n'
|
|
||||||
'This is probably caused by another test that did not clean up after finishing!: %s'
|
|
||||||
% component._ComponentRegistry.components
|
|
||||||
)
|
|
||||||
d = maybeDeferred(self.set_up)
|
|
||||||
|
|
||||||
def on_setup_error(error):
|
|
||||||
warnings.warn('Error caught in test setup!\n%s' % error.getTraceback())
|
|
||||||
self.fail()
|
|
||||||
|
|
||||||
return d.addErrback(on_setup_error)
|
|
||||||
|
|
||||||
def tearDown(self): # NOQA: N803
|
|
||||||
d = maybeDeferred(self.tear_down)
|
|
||||||
|
|
||||||
def on_teardown_failed(error):
|
|
||||||
self.fail('Error caught in test teardown!\n%s' % error.getTraceback())
|
|
||||||
|
|
||||||
def on_teardown_complete(result):
|
|
||||||
component._ComponentRegistry.components.clear()
|
|
||||||
component._ComponentRegistry.dependents.clear()
|
|
||||||
|
|
||||||
return d.addCallbacks(on_teardown_complete, on_teardown_failed)
|
|
||||||
|
|
||||||
def set_up(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
pass
|
|
|
@ -8,13 +8,12 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
import pytest
|
||||||
from twisted.internet import defer, protocol, reactor
|
from twisted.internet import defer, protocol, reactor
|
||||||
from twisted.internet.defer import Deferred
|
from twisted.internet.defer import Deferred
|
||||||
from twisted.internet.error import CannotListenError
|
from twisted.internet.error import CannotListenError
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.configmanager
|
import deluge.configmanager
|
||||||
import deluge.core.preferencesmanager
|
import deluge.core.preferencesmanager
|
||||||
|
@ -31,12 +30,6 @@ def disable_new_release_check():
|
||||||
deluge.core.preferencesmanager.DEFAULT_PREFS['new_release_check'] = False
|
deluge.core.preferencesmanager.DEFAULT_PREFS['new_release_check'] = False
|
||||||
|
|
||||||
|
|
||||||
def set_tmp_config_dir():
|
|
||||||
config_directory = tempfile.mkdtemp()
|
|
||||||
deluge.configmanager.set_config_dir(config_directory)
|
|
||||||
return config_directory
|
|
||||||
|
|
||||||
|
|
||||||
def setup_test_logger(level='info', prefix='deluge'):
|
def setup_test_logger(level='info', prefix='deluge'):
|
||||||
deluge.log.setup_logger(level, filename='%s.log' % prefix, twisted_observer=False)
|
deluge.log.setup_logger(level, filename='%s.log' % prefix, twisted_observer=False)
|
||||||
|
|
||||||
|
@ -54,7 +47,7 @@ def todo_test(caller):
|
||||||
|
|
||||||
filename = os.path.basename(traceback.extract_stack(None, 2)[0][0])
|
filename = os.path.basename(traceback.extract_stack(None, 2)[0][0])
|
||||||
funcname = traceback.extract_stack(None, 2)[0][2]
|
funcname = traceback.extract_stack(None, 2)[0][2]
|
||||||
raise unittest.SkipTest(f'TODO: {filename}:{funcname}')
|
pytest.skip(f'TODO: {filename}:{funcname}')
|
||||||
|
|
||||||
|
|
||||||
def add_watchdog(deferred, timeout=0.05, message=None):
|
def add_watchdog(deferred, timeout=0.05, message=None):
|
||||||
|
@ -219,7 +212,7 @@ class ProcessOutputHandler(protocol.ProcessProtocol):
|
||||||
|
|
||||||
|
|
||||||
def start_core(
|
def start_core(
|
||||||
listen_port=58846,
|
listen_port=58900,
|
||||||
logfile=None,
|
logfile=None,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
timeout_msg=None,
|
timeout_msg=None,
|
||||||
|
@ -227,6 +220,7 @@ def start_core(
|
||||||
print_stdout=True,
|
print_stdout=True,
|
||||||
print_stderr=True,
|
print_stderr=True,
|
||||||
extra_callbacks=None,
|
extra_callbacks=None,
|
||||||
|
config_directory='',
|
||||||
):
|
):
|
||||||
"""Start the deluge core as a daemon.
|
"""Start the deluge core as a daemon.
|
||||||
|
|
||||||
|
@ -248,7 +242,6 @@ def start_core(
|
||||||
or upon timeout expiry. The ProcessOutputHandler is the handler for the deluged process.
|
or upon timeout expiry. The ProcessOutputHandler is the handler for the deluged process.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
config_directory = set_tmp_config_dir()
|
|
||||||
daemon_script = """
|
daemon_script = """
|
||||||
import sys
|
import sys
|
||||||
import deluge.core.daemon_entry
|
import deluge.core.daemon_entry
|
||||||
|
@ -268,7 +261,7 @@ except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
sys.stderr.write('Exception raised:\\n %%s' %% traceback.format_exc())
|
sys.stderr.write('Exception raised:\\n %%s' %% traceback.format_exc())
|
||||||
""" % {
|
""" % {
|
||||||
'dir': config_directory.replace('\\', '\\\\'),
|
'dir': config_directory.as_posix(),
|
||||||
'port': listen_port,
|
'port': listen_port,
|
||||||
'script': custom_script,
|
'script': custom_script,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,20 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.component as component
|
|
||||||
import deluge.ui.web.auth
|
import deluge.ui.web.auth
|
||||||
import deluge.ui.web.server
|
import deluge.ui.web.server
|
||||||
from deluge import configmanager
|
from deluge import configmanager
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.ui.web.server import DelugeWeb
|
from deluge.ui.web.server import DelugeWeb
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
from .common import ReactorOverride
|
from .common import ReactorOverride
|
||||||
from .daemon_base import DaemonBase
|
|
||||||
|
|
||||||
|
|
||||||
class WebServerTestBase(BaseTestCase, DaemonBase):
|
@pytest.mark.usefixtures('daemon', 'component')
|
||||||
|
class WebServerTestBase(BaseTestCase):
|
||||||
"""
|
"""
|
||||||
Base class for tests that need a running webapi
|
Base class for tests that need a running webapi
|
||||||
|
|
||||||
|
@ -27,10 +28,7 @@ class WebServerTestBase(BaseTestCase, DaemonBase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.host_id = None
|
self.host_id = None
|
||||||
deluge.ui.web.server.reactor = ReactorOverride()
|
deluge.ui.web.server.reactor = ReactorOverride()
|
||||||
d = self.common_set_up()
|
return self.start_webapi(None)
|
||||||
d.addCallback(self.start_core)
|
|
||||||
d.addCallback(self.start_webapi)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def start_webapi(self, arg):
|
def start_webapi(self, arg):
|
||||||
self.webserver_listen_port = 8999
|
self.webserver_listen_port = 8999
|
||||||
|
@ -47,11 +45,6 @@ class WebServerTestBase(BaseTestCase, DaemonBase):
|
||||||
self.host_id = host[0]
|
self.host_id = host[0]
|
||||||
self.deluge_web.start()
|
self.deluge_web.start()
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
d = component.shutdown()
|
|
||||||
d.addCallback(self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
class WebServerMockBase:
|
class WebServerMockBase:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -15,16 +15,9 @@ import deluge.component as component
|
||||||
from . import common
|
from . import common
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('get_pytest_basetemp')
|
@pytest.mark.usefixtures('config_dir')
|
||||||
class DaemonBase:
|
class DaemonBase:
|
||||||
basetemp = None
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def get_pytest_basetemp(self, request):
|
|
||||||
self.basetemp = request.config.option.basetemp
|
|
||||||
|
|
||||||
def common_set_up(self):
|
def common_set_up(self):
|
||||||
common.set_tmp_config_dir()
|
|
||||||
self.listen_port = 58900
|
self.listen_port = 58900
|
||||||
self.core = None
|
self.core = None
|
||||||
return component.start()
|
return component.start()
|
||||||
|
@ -71,6 +64,7 @@ class DaemonBase:
|
||||||
print_stdout=print_stdout,
|
print_stdout=print_stdout,
|
||||||
print_stderr=print_stderr,
|
print_stderr=print_stderr,
|
||||||
extra_callbacks=extra_callbacks,
|
extra_callbacks=extra_callbacks,
|
||||||
|
config_directory=self.config_dir,
|
||||||
)
|
)
|
||||||
yield d
|
yield d
|
||||||
except CannotListenError as ex:
|
except CannotListenError as ex:
|
||||||
|
|
|
@ -5,12 +5,11 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
class TestAlertManager(BaseTestCase):
|
||||||
class AlertManagerTestCase(BaseTestCase):
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
self.core.config.config['lsd'] = False
|
self.core.config.config['lsd'] = False
|
||||||
|
@ -25,7 +24,7 @@ class AlertManagerTestCase(BaseTestCase):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.am.register_handler('dummy_alert', handler)
|
self.am.register_handler('dummy_alert', handler)
|
||||||
self.assertEqual(self.am.handlers['dummy_alert'], [handler])
|
assert self.am.handlers['dummy_alert'] == [handler]
|
||||||
|
|
||||||
def test_deregister_handler(self):
|
def test_deregister_handler(self):
|
||||||
def handler(alert):
|
def handler(alert):
|
||||||
|
@ -33,4 +32,4 @@ class AlertManagerTestCase(BaseTestCase):
|
||||||
|
|
||||||
self.am.register_handler('dummy_alert', handler)
|
self.am.register_handler('dummy_alert', handler)
|
||||||
self.am.deregister_handler(handler)
|
self.am.deregister_handler(handler)
|
||||||
self.assertEqual(self.am.handlers['dummy_alert'], [])
|
assert self.am.handlers['dummy_alert'] == []
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.common import get_localhost_auth
|
from deluge.common import get_localhost_auth
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core.authmanager import AUTH_LEVEL_ADMIN, AuthManager
|
from deluge.core.authmanager import AUTH_LEVEL_ADMIN, AuthManager
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
class TestAuthManager(BaseTestCase):
|
||||||
class AuthManagerTestCase(BaseTestCase):
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.auth = AuthManager()
|
self.auth = AuthManager()
|
||||||
self.auth.start()
|
self.auth.start()
|
||||||
|
@ -21,4 +20,4 @@ class AuthManagerTestCase(BaseTestCase):
|
||||||
return component.shutdown()
|
return component.shutdown()
|
||||||
|
|
||||||
def test_authorize(self):
|
def test_authorize(self):
|
||||||
self.assertEqual(self.auth.authorize(*get_localhost_auth()), AUTH_LEVEL_ADMIN)
|
assert self.auth.authorize(*get_localhost_auth()) == AUTH_LEVEL_ADMIN
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
from twisted.trial import unittest
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from deluge import bencode
|
from deluge import bencode
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
|
|
||||||
|
|
||||||
class BencodeTestCase(unittest.TestCase):
|
class TestBencode:
|
||||||
def test_bencode_unicode_metainfo(self):
|
def test_bencode_unicode_metainfo(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
with open(filename, 'rb') as _file:
|
with open(filename, 'rb') as _file:
|
||||||
|
@ -18,14 +19,14 @@ class BencodeTestCase(unittest.TestCase):
|
||||||
bencode.bencode({b'info': metainfo})
|
bencode.bencode({b'info': metainfo})
|
||||||
|
|
||||||
def test_bencode_unicode_value(self):
|
def test_bencode_unicode_value(self):
|
||||||
self.assertEqual(bencode.bencode(b'abc'), b'3:abc')
|
assert bencode.bencode(b'abc') == b'3:abc'
|
||||||
self.assertEqual(bencode.bencode('abc'), b'3:abc')
|
assert bencode.bencode('abc') == b'3:abc'
|
||||||
|
|
||||||
def test_bdecode(self):
|
def test_bdecode(self):
|
||||||
self.assertEqual(bencode.bdecode(b'3:dEf'), b'dEf')
|
assert bencode.bdecode(b'3:dEf') == b'dEf'
|
||||||
with self.assertRaises(bencode.BTFailure):
|
with pytest.raises(bencode.BTFailure):
|
||||||
bencode.bdecode('dEf')
|
bencode.bdecode('dEf')
|
||||||
with self.assertRaises(bencode.BTFailure):
|
with pytest.raises(bencode.BTFailure):
|
||||||
bencode.bdecode(b'dEf')
|
bencode.bdecode(b'dEf')
|
||||||
with self.assertRaises(bencode.BTFailure):
|
with pytest.raises(bencode.BTFailure):
|
||||||
bencode.bdecode({'dEf': 123})
|
bencode.bdecode({'dEf': 123})
|
||||||
|
|
|
@ -3,18 +3,15 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
import deluge.component as component
|
|
||||||
from deluge import error
|
from deluge import error
|
||||||
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth
|
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth
|
||||||
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
|
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
|
||||||
from deluge.ui.client import Client, DaemonSSLProxy, client
|
from deluge.ui.client import Client, DaemonSSLProxy, client
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
from .daemon_base import DaemonBase
|
|
||||||
|
|
||||||
|
|
||||||
class NoVersionSendingDaemonSSLProxy(DaemonSSLProxy):
|
class NoVersionSendingDaemonSSLProxy(DaemonSSLProxy):
|
||||||
def authenticate(self, username, password):
|
def authenticate(self, username, password):
|
||||||
|
@ -75,24 +72,13 @@ class NoVersionSendingClient(Client):
|
||||||
self.disconnect_callback()
|
self.disconnect_callback()
|
||||||
|
|
||||||
|
|
||||||
class ClientTestCase(BaseTestCase, DaemonBase):
|
@pytest.mark.usefixtures('daemon', 'client')
|
||||||
def set_up(self):
|
class TestClient:
|
||||||
d = self.common_set_up()
|
|
||||||
d.addCallback(self.start_core)
|
|
||||||
d.addErrback(self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
d = component.shutdown()
|
|
||||||
d.addCallback(self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_connect_no_credentials(self):
|
def test_connect_no_credentials(self):
|
||||||
d = client.connect('localhost', self.listen_port, username='', password='')
|
d = client.connect('localhost', self.listen_port, username='', password='')
|
||||||
|
|
||||||
def on_connect(result):
|
def on_connect(result):
|
||||||
self.assertEqual(client.get_auth_level(), AUTH_LEVEL_ADMIN)
|
assert client.get_auth_level() == AUTH_LEVEL_ADMIN
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
d.addCallbacks(on_connect, self.fail)
|
d.addCallbacks(on_connect, self.fail)
|
||||||
|
@ -105,8 +91,7 @@ class ClientTestCase(BaseTestCase, DaemonBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_connect(result):
|
def on_connect(result):
|
||||||
self.assertEqual(client.get_auth_level(), AUTH_LEVEL_ADMIN)
|
assert client.get_auth_level() == AUTH_LEVEL_ADMIN
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
d.addCallbacks(on_connect, self.fail)
|
d.addCallbacks(on_connect, self.fail)
|
||||||
|
@ -119,21 +104,18 @@ class ClientTestCase(BaseTestCase, DaemonBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_failure(failure):
|
def on_failure(failure):
|
||||||
self.assertEqual(failure.trap(error.BadLoginError), error.BadLoginError)
|
assert failure.trap(error.BadLoginError) == error.BadLoginError
|
||||||
self.assertEqual(failure.value.message, 'Password does not match')
|
assert failure.value.message == 'Password does not match'
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
|
|
||||||
d.addCallbacks(self.fail, on_failure)
|
d.addCallbacks(self.fail, on_failure)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def test_connect_invalid_user(self):
|
def test_connect_invalid_user(self):
|
||||||
username, password = get_localhost_auth()
|
|
||||||
d = client.connect('localhost', self.listen_port, username='invalid-user')
|
d = client.connect('localhost', self.listen_port, username='invalid-user')
|
||||||
|
|
||||||
def on_failure(failure):
|
def on_failure(failure):
|
||||||
self.assertEqual(failure.trap(error.BadLoginError), error.BadLoginError)
|
assert failure.trap(error.BadLoginError) == error.BadLoginError
|
||||||
self.assertEqual(failure.value.message, 'Username does not exist')
|
assert failure.value.message == 'Username does not exist'
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
|
|
||||||
d.addCallbacks(self.fail, on_failure)
|
d.addCallbacks(self.fail, on_failure)
|
||||||
return d
|
return d
|
||||||
|
@ -143,16 +125,16 @@ class ClientTestCase(BaseTestCase, DaemonBase):
|
||||||
d = client.connect('localhost', self.listen_port, username=username)
|
d = client.connect('localhost', self.listen_port, username=username)
|
||||||
|
|
||||||
def on_failure(failure):
|
def on_failure(failure):
|
||||||
self.assertEqual(
|
assert (
|
||||||
failure.trap(error.AuthenticationRequired), error.AuthenticationRequired
|
failure.trap(error.AuthenticationRequired)
|
||||||
|
== error.AuthenticationRequired
|
||||||
)
|
)
|
||||||
self.assertEqual(failure.value.username, username)
|
assert failure.value.username == username
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
|
|
||||||
d.addCallbacks(self.fail, on_failure)
|
d.addCallbacks(self.fail, on_failure)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_connect_with_password(self):
|
def test_connect_with_password(self):
|
||||||
username, password = get_localhost_auth()
|
username, password = get_localhost_auth()
|
||||||
yield client.connect(
|
yield client.connect(
|
||||||
|
@ -163,19 +145,15 @@ class ClientTestCase(BaseTestCase, DaemonBase):
|
||||||
ret = yield client.connect(
|
ret = yield client.connect(
|
||||||
'localhost', self.listen_port, username='testuser', password='testpw'
|
'localhost', self.listen_port, username='testuser', password='testpw'
|
||||||
)
|
)
|
||||||
self.assertEqual(ret, AUTH_LEVEL_NORMAL)
|
assert ret == AUTH_LEVEL_NORMAL
|
||||||
yield
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_invalid_rpc_method_call(self):
|
def test_invalid_rpc_method_call(self):
|
||||||
yield client.connect('localhost', self.listen_port, username='', password='')
|
yield client.connect('localhost', self.listen_port, username='', password='')
|
||||||
d = client.core.invalid_method()
|
d = client.core.invalid_method()
|
||||||
|
|
||||||
def on_failure(failure):
|
def on_failure(failure):
|
||||||
self.assertEqual(
|
assert failure.trap(error.WrappedException) == error.WrappedException
|
||||||
failure.trap(error.WrappedException), error.WrappedException
|
|
||||||
)
|
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
|
|
||||||
d.addCallbacks(self.fail, on_failure)
|
d.addCallbacks(self.fail, on_failure)
|
||||||
yield d
|
yield d
|
||||||
|
@ -188,10 +166,7 @@ class ClientTestCase(BaseTestCase, DaemonBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_failure(failure):
|
def on_failure(failure):
|
||||||
self.assertEqual(
|
assert failure.trap(error.IncompatibleClient) == error.IncompatibleClient
|
||||||
failure.trap(error.IncompatibleClient), error.IncompatibleClient
|
|
||||||
)
|
|
||||||
self.addCleanup(no_version_sending_client.disconnect)
|
|
||||||
|
|
||||||
d.addCallbacks(self.fail, on_failure)
|
d.addCallbacks(self.fail, on_failure)
|
||||||
return d
|
return d
|
||||||
|
|
|
@ -8,7 +8,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
import tarfile
|
||||||
|
|
||||||
from twisted.trial import unittest
|
import pytest
|
||||||
|
|
||||||
from deluge.common import (
|
from deluge.common import (
|
||||||
VersionSplit,
|
VersionSplit,
|
||||||
|
@ -30,93 +30,83 @@ from deluge.common import (
|
||||||
is_url,
|
is_url,
|
||||||
windows_check,
|
windows_check,
|
||||||
)
|
)
|
||||||
from deluge.i18n import setup_translation
|
|
||||||
|
|
||||||
from .common import get_test_data_file, set_tmp_config_dir
|
from .common import get_test_data_file
|
||||||
|
|
||||||
|
|
||||||
class CommonTestCase(unittest.TestCase):
|
class TestCommon:
|
||||||
def setUp(self): # NOQA
|
|
||||||
self.config_dir = set_tmp_config_dir()
|
|
||||||
setup_translation()
|
|
||||||
|
|
||||||
def tearDown(self): # NOQA
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_fsize(self):
|
def test_fsize(self):
|
||||||
self.assertEqual(fsize(0), '0 B')
|
assert fsize(0) == '0 B'
|
||||||
self.assertEqual(fsize(100), '100 B')
|
assert fsize(100) == '100 B'
|
||||||
self.assertEqual(fsize(1023), '1023 B')
|
assert fsize(1023) == '1023 B'
|
||||||
self.assertEqual(fsize(1024), '1.0 KiB')
|
assert fsize(1024) == '1.0 KiB'
|
||||||
self.assertEqual(fsize(1048575), '1024.0 KiB')
|
assert fsize(1048575) == '1024.0 KiB'
|
||||||
self.assertEqual(fsize(1048576), '1.0 MiB')
|
assert fsize(1048576) == '1.0 MiB'
|
||||||
self.assertEqual(fsize(1073741823), '1024.0 MiB')
|
assert fsize(1073741823) == '1024.0 MiB'
|
||||||
self.assertEqual(fsize(1073741824), '1.0 GiB')
|
assert fsize(1073741824) == '1.0 GiB'
|
||||||
self.assertEqual(fsize(112245), '109.6 KiB')
|
assert fsize(112245) == '109.6 KiB'
|
||||||
self.assertEqual(fsize(110723441824), '103.1 GiB')
|
assert fsize(110723441824) == '103.1 GiB'
|
||||||
self.assertEqual(fsize(1099511627775), '1024.0 GiB')
|
assert fsize(1099511627775) == '1024.0 GiB'
|
||||||
self.assertEqual(fsize(1099511627777), '1.0 TiB')
|
assert fsize(1099511627777) == '1.0 TiB'
|
||||||
self.assertEqual(fsize(766148267453245), '696.8 TiB')
|
assert fsize(766148267453245) == '696.8 TiB'
|
||||||
|
|
||||||
def test_fpcnt(self):
|
def test_fpcnt(self):
|
||||||
self.assertTrue(fpcnt(0.9311) == '93.11%')
|
assert fpcnt(0.9311) == '93.11%'
|
||||||
|
|
||||||
def test_fspeed(self):
|
def test_fspeed(self):
|
||||||
self.assertTrue(fspeed(43134) == '42.1 KiB/s')
|
assert fspeed(43134) == '42.1 KiB/s'
|
||||||
|
|
||||||
def test_fpeer(self):
|
def test_fpeer(self):
|
||||||
self.assertTrue(fpeer(10, 20) == '10 (20)')
|
assert fpeer(10, 20) == '10 (20)'
|
||||||
self.assertTrue(fpeer(10, -1) == '10')
|
assert fpeer(10, -1) == '10'
|
||||||
|
|
||||||
def test_ftime(self):
|
def test_ftime(self):
|
||||||
self.assertEqual(ftime(0), '')
|
assert ftime(0) == ''
|
||||||
self.assertEqual(ftime(5), '5s')
|
assert ftime(5) == '5s'
|
||||||
self.assertEqual(ftime(100), '1m 40s')
|
assert ftime(100) == '1m 40s'
|
||||||
self.assertEqual(ftime(3789), '1h 3m')
|
assert ftime(3789) == '1h 3m'
|
||||||
self.assertEqual(ftime(23011), '6h 23m')
|
assert ftime(23011) == '6h 23m'
|
||||||
self.assertEqual(ftime(391187), '4d 12h')
|
assert ftime(391187) == '4d 12h'
|
||||||
self.assertEqual(ftime(604800), '1w 0d')
|
assert ftime(604800) == '1w 0d'
|
||||||
self.assertEqual(ftime(13893086), '22w 6d')
|
assert ftime(13893086) == '22w 6d'
|
||||||
self.assertEqual(ftime(59740269), '1y 46w')
|
assert ftime(59740269) == '1y 46w'
|
||||||
self.assertEqual(ftime(61.25), '1m 1s')
|
assert ftime(61.25) == '1m 1s'
|
||||||
self.assertEqual(ftime(119.9), '1m 59s')
|
assert ftime(119.9) == '1m 59s'
|
||||||
|
|
||||||
def test_fdate(self):
|
def test_fdate(self):
|
||||||
self.assertTrue(fdate(-1) == '')
|
assert fdate(-1) == ''
|
||||||
|
|
||||||
def test_is_url(self):
|
def test_is_url(self):
|
||||||
self.assertTrue(is_url('http://deluge-torrent.org'))
|
assert is_url('http://deluge-torrent.org')
|
||||||
self.assertFalse(is_url('file://test.torrent'))
|
assert not is_url('file://test.torrent')
|
||||||
|
|
||||||
def test_is_magnet(self):
|
def test_is_magnet(self):
|
||||||
self.assertTrue(
|
assert is_magnet('magnet:?xt=urn:btih:SU5225URMTUEQLDXQWRB2EQWN6KLTYKN')
|
||||||
is_magnet('magnet:?xt=urn:btih:SU5225URMTUEQLDXQWRB2EQWN6KLTYKN')
|
assert not is_magnet(None)
|
||||||
)
|
|
||||||
self.assertFalse(is_magnet(None))
|
|
||||||
|
|
||||||
def test_is_infohash(self):
|
def test_is_infohash(self):
|
||||||
self.assertTrue(is_infohash('2dc5d0e71a66fe69649a640d39cb00a259704973'))
|
assert is_infohash('2dc5d0e71a66fe69649a640d39cb00a259704973')
|
||||||
|
|
||||||
def test_get_path_size(self):
|
def test_get_path_size(self):
|
||||||
if windows_check() and sys.version_info < (3, 8):
|
if windows_check() and sys.version_info < (3, 8):
|
||||||
# https://bugs.python.org/issue1311
|
# https://bugs.python.org/issue1311
|
||||||
raise unittest.SkipTest('os.devnull returns False on Windows')
|
pytest.skip('os.devnull returns False on Windows')
|
||||||
self.assertTrue(get_path_size(os.devnull) == 0)
|
assert get_path_size(os.devnull) == 0
|
||||||
self.assertTrue(get_path_size('non-existant.file') == -1)
|
assert get_path_size('non-existant.file') == -1
|
||||||
|
|
||||||
def test_is_ip(self):
|
def test_is_ip(self):
|
||||||
self.assertTrue(is_ip('192.0.2.0'))
|
assert is_ip('192.0.2.0')
|
||||||
self.assertFalse(is_ip('192..0.0'))
|
assert not is_ip('192..0.0')
|
||||||
self.assertTrue(is_ip('2001:db8::'))
|
assert is_ip('2001:db8::')
|
||||||
self.assertFalse(is_ip('2001:db8:'))
|
assert not is_ip('2001:db8:')
|
||||||
|
|
||||||
def test_is_ipv4(self):
|
def test_is_ipv4(self):
|
||||||
self.assertTrue(is_ipv4('192.0.2.0'))
|
assert is_ipv4('192.0.2.0')
|
||||||
self.assertFalse(is_ipv4('192..0.0'))
|
assert not is_ipv4('192..0.0')
|
||||||
|
|
||||||
def test_is_ipv6(self):
|
def test_is_ipv6(self):
|
||||||
self.assertTrue(is_ipv6('2001:db8::'))
|
assert is_ipv6('2001:db8::')
|
||||||
self.assertFalse(is_ipv6('2001:db8:'))
|
assert not is_ipv6('2001:db8:')
|
||||||
|
|
||||||
def get_windows_interface_name(self):
|
def get_windows_interface_name(self):
|
||||||
import winreg
|
import winreg
|
||||||
|
@ -126,9 +116,7 @@ class CommonTestCase(unittest.TestCase):
|
||||||
winreg.HKEY_LOCAL_MACHINE,
|
winreg.HKEY_LOCAL_MACHINE,
|
||||||
r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards',
|
r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards',
|
||||||
) as key:
|
) as key:
|
||||||
self.assertTrue(
|
assert winreg.QueryInfoKey(key)[0] > 0 # must have at least 1 network card
|
||||||
winreg.QueryInfoKey(key)[0] > 0
|
|
||||||
) # must have at least 1 network card
|
|
||||||
network_card = winreg.EnumKey(key, 0)
|
network_card = winreg.EnumKey(key, 0)
|
||||||
# get GUID of network card
|
# get GUID of network card
|
||||||
with winreg.OpenKey(
|
with winreg.OpenKey(
|
||||||
|
@ -144,48 +132,46 @@ class CommonTestCase(unittest.TestCase):
|
||||||
def test_is_interface_name(self):
|
def test_is_interface_name(self):
|
||||||
if windows_check():
|
if windows_check():
|
||||||
interface_name = self.get_windows_interface_name()
|
interface_name = self.get_windows_interface_name()
|
||||||
self.assertFalse(is_interface_name('2001:db8:'))
|
assert not is_interface_name('2001:db8:')
|
||||||
self.assertFalse(
|
assert not is_interface_name('{THIS0000-IS00-ONLY-FOR0-TESTING00000}')
|
||||||
is_interface_name('{THIS0000-IS00-ONLY-FOR0-TESTING00000}')
|
assert is_interface_name(interface_name)
|
||||||
)
|
|
||||||
self.assertTrue(is_interface_name(interface_name))
|
|
||||||
else:
|
else:
|
||||||
self.assertTrue(is_interface_name('lo'))
|
assert is_interface_name('lo')
|
||||||
self.assertFalse(is_interface_name('127.0.0.1'))
|
assert not is_interface_name('127.0.0.1')
|
||||||
self.assertFalse(is_interface_name('eth01101'))
|
assert not is_interface_name('eth01101')
|
||||||
|
|
||||||
def test_is_interface(self):
|
def test_is_interface(self):
|
||||||
if windows_check():
|
if windows_check():
|
||||||
interface_name = self.get_windows_interface_name()
|
interface_name = self.get_windows_interface_name()
|
||||||
self.assertTrue(is_interface('127.0.0.1'))
|
assert is_interface('127.0.0.1')
|
||||||
self.assertTrue(is_interface(interface_name))
|
assert is_interface(interface_name)
|
||||||
self.assertFalse(is_interface('127'))
|
assert not is_interface('127')
|
||||||
self.assertFalse(is_interface('{THIS0000-IS00-ONLY-FOR0-TESTING00000}'))
|
assert not is_interface('{THIS0000-IS00-ONLY-FOR0-TESTING00000}')
|
||||||
else:
|
else:
|
||||||
self.assertTrue(is_interface('lo'))
|
assert is_interface('lo')
|
||||||
self.assertTrue(is_interface('127.0.0.1'))
|
assert is_interface('127.0.0.1')
|
||||||
self.assertFalse(is_interface('127.'))
|
assert not is_interface('127.')
|
||||||
self.assertFalse(is_interface('eth01101'))
|
assert not is_interface('eth01101')
|
||||||
|
|
||||||
def test_version_split(self):
|
def test_version_split(self):
|
||||||
self.assertTrue(VersionSplit('1.2.2') == VersionSplit('1.2.2'))
|
assert VersionSplit('1.2.2') == VersionSplit('1.2.2')
|
||||||
self.assertTrue(VersionSplit('1.2.1') < VersionSplit('1.2.2'))
|
assert VersionSplit('1.2.1') < VersionSplit('1.2.2')
|
||||||
self.assertTrue(VersionSplit('1.1.9') < VersionSplit('1.2.2'))
|
assert VersionSplit('1.1.9') < VersionSplit('1.2.2')
|
||||||
self.assertTrue(VersionSplit('1.2.2') > VersionSplit('1.2.1'))
|
assert VersionSplit('1.2.2') > VersionSplit('1.2.1')
|
||||||
self.assertTrue(VersionSplit('1.2.2') > VersionSplit('1.2.2-dev0'))
|
assert VersionSplit('1.2.2') > VersionSplit('1.2.2-dev0')
|
||||||
self.assertTrue(VersionSplit('1.2.2-dev') < VersionSplit('1.3.0-rc2'))
|
assert VersionSplit('1.2.2-dev') < VersionSplit('1.3.0-rc2')
|
||||||
self.assertTrue(VersionSplit('1.2.2') > VersionSplit('1.2.2-rc2'))
|
assert VersionSplit('1.2.2') > VersionSplit('1.2.2-rc2')
|
||||||
self.assertTrue(VersionSplit('1.2.2-rc2-dev') < VersionSplit('1.2.2-rc2'))
|
assert VersionSplit('1.2.2-rc2-dev') < VersionSplit('1.2.2-rc2')
|
||||||
self.assertTrue(VersionSplit('1.2.2-rc3') > VersionSplit('1.2.2-rc2'))
|
assert VersionSplit('1.2.2-rc3') > VersionSplit('1.2.2-rc2')
|
||||||
self.assertTrue(VersionSplit('0.14.9') == VersionSplit('0.14.9'))
|
assert VersionSplit('0.14.9') == VersionSplit('0.14.9')
|
||||||
self.assertTrue(VersionSplit('0.14.9') > VersionSplit('0.14.5'))
|
assert VersionSplit('0.14.9') > VersionSplit('0.14.5')
|
||||||
self.assertTrue(VersionSplit('0.14.10') >= VersionSplit('0.14.9'))
|
assert VersionSplit('0.14.10') >= VersionSplit('0.14.9')
|
||||||
self.assertTrue(VersionSplit('1.4.0') > VersionSplit('1.3.900.dev123'))
|
assert VersionSplit('1.4.0') > VersionSplit('1.3.900.dev123')
|
||||||
self.assertTrue(VersionSplit('1.3.2rc2.dev1') < VersionSplit('1.3.2-rc2'))
|
assert VersionSplit('1.3.2rc2.dev1') < VersionSplit('1.3.2-rc2')
|
||||||
self.assertTrue(VersionSplit('1.3.900.dev888') > VersionSplit('1.3.900.dev123'))
|
assert VersionSplit('1.3.900.dev888') > VersionSplit('1.3.900.dev123')
|
||||||
self.assertTrue(VersionSplit('1.4.0') > VersionSplit('1.4.0.dev123'))
|
assert VersionSplit('1.4.0') > VersionSplit('1.4.0.dev123')
|
||||||
self.assertTrue(VersionSplit('1.4.0.dev1') < VersionSplit('1.4.0'))
|
assert VersionSplit('1.4.0.dev1') < VersionSplit('1.4.0')
|
||||||
self.assertTrue(VersionSplit('1.4.0a1') < VersionSplit('1.4.0'))
|
assert VersionSplit('1.4.0a1') < VersionSplit('1.4.0')
|
||||||
|
|
||||||
def test_parse_human_size(self):
|
def test_parse_human_size(self):
|
||||||
from deluge.common import parse_human_size
|
from deluge.common import parse_human_size
|
||||||
|
@ -206,9 +192,7 @@ class CommonTestCase(unittest.TestCase):
|
||||||
|
|
||||||
for human_size, byte_size in sizes:
|
for human_size, byte_size in sizes:
|
||||||
parsed = parse_human_size(human_size)
|
parsed = parse_human_size(human_size)
|
||||||
self.assertEqual(
|
assert parsed == byte_size, 'Mismatch when converting: %s' % human_size
|
||||||
parsed, byte_size, 'Mismatch when converting: %s' % human_size
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_archive_files(self):
|
def test_archive_files(self):
|
||||||
arc_filelist = [
|
arc_filelist = [
|
||||||
|
@ -219,10 +203,10 @@ class CommonTestCase(unittest.TestCase):
|
||||||
|
|
||||||
with tarfile.open(arc_filepath, 'r') as tar:
|
with tarfile.open(arc_filepath, 'r') as tar:
|
||||||
for tar_info in tar:
|
for tar_info in tar:
|
||||||
self.assertTrue(tar_info.isfile())
|
assert tar_info.isfile()
|
||||||
self.assertTrue(
|
assert tar_info.name in [
|
||||||
tar_info.name in [os.path.basename(arcf) for arcf in arc_filelist]
|
os.path.basename(arcf) for arcf in arc_filelist
|
||||||
)
|
]
|
||||||
|
|
||||||
def test_archive_files_missing(self):
|
def test_archive_files_missing(self):
|
||||||
"""Archive exists even with file not found."""
|
"""Archive exists even with file not found."""
|
||||||
|
@ -233,8 +217,8 @@ class CommonTestCase(unittest.TestCase):
|
||||||
filelist.remove('missing.file')
|
filelist.remove('missing.file')
|
||||||
|
|
||||||
with tarfile.open(arc_filepath, 'r') as tar:
|
with tarfile.open(arc_filepath, 'r') as tar:
|
||||||
self.assertEqual(tar.getnames(), filelist)
|
assert tar.getnames() == filelist
|
||||||
self.assertTrue(all(tarinfo.isfile() for tarinfo in tar))
|
assert all(tarinfo.isfile() for tarinfo in tar)
|
||||||
|
|
||||||
def test_archive_files_message(self):
|
def test_archive_files_message(self):
|
||||||
filelist = ['test.torrent', 'deluge.png']
|
filelist = ['test.torrent', 'deluge.png']
|
||||||
|
@ -244,9 +228,9 @@ class CommonTestCase(unittest.TestCase):
|
||||||
|
|
||||||
result_files = filelist + ['archive_message.txt']
|
result_files = filelist + ['archive_message.txt']
|
||||||
with tarfile.open(arc_filepath, 'r') as tar:
|
with tarfile.open(arc_filepath, 'r') as tar:
|
||||||
self.assertEqual(tar.getnames(), result_files)
|
assert tar.getnames() == result_files
|
||||||
for tar_info in tar:
|
for tar_info in tar:
|
||||||
self.assertTrue(tar_info.isfile())
|
assert tar_info.isfile()
|
||||||
if tar_info.name == 'archive_message.txt':
|
if tar_info.name == 'archive_message.txt':
|
||||||
result = tar.extractfile(tar_info).read().decode()
|
result = tar.extractfile(tar_info).read().decode()
|
||||||
self.assertEqual(result, 'test')
|
assert result == 'test'
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer, threads
|
from twisted.internet import defer, threads
|
||||||
from twisted.trial.unittest import SkipTest
|
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class ComponentTester(component.Component):
|
class ComponentTester(component.Component):
|
||||||
def __init__(self, name, depend=None):
|
def __init__(self, name, depend=None):
|
||||||
|
@ -67,14 +66,15 @@ class ComponentTesterShutdown(component.Component):
|
||||||
self.stop_count += 1
|
self.stop_count += 1
|
||||||
|
|
||||||
|
|
||||||
class ComponentTestClass(BaseTestCase):
|
@pytest.mark.usefixtures('component')
|
||||||
|
class TestComponent:
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
return component.shutdown()
|
return component.shutdown()
|
||||||
|
|
||||||
def test_start_component(self):
|
def test_start_component(self):
|
||||||
def on_start(result, c):
|
def on_start(result, c):
|
||||||
self.assertEqual(c._component_state, 'Started')
|
assert c._component_state == 'Started'
|
||||||
self.assertEqual(c.start_count, 1)
|
assert c.start_count == 1
|
||||||
|
|
||||||
c = ComponentTester('test_start_c1')
|
c = ComponentTester('test_start_c1')
|
||||||
d = component.start(['test_start_c1'])
|
d = component.start(['test_start_c1'])
|
||||||
|
@ -83,16 +83,16 @@ class ComponentTestClass(BaseTestCase):
|
||||||
|
|
||||||
def test_start_stop_depends(self):
|
def test_start_stop_depends(self):
|
||||||
def on_stop(result, c1, c2):
|
def on_stop(result, c1, c2):
|
||||||
self.assertEqual(c1._component_state, 'Stopped')
|
assert c1._component_state == 'Stopped'
|
||||||
self.assertEqual(c2._component_state, 'Stopped')
|
assert c2._component_state == 'Stopped'
|
||||||
self.assertEqual(c1.stop_count, 1)
|
assert c1.stop_count == 1
|
||||||
self.assertEqual(c2.stop_count, 1)
|
assert c2.stop_count == 1
|
||||||
|
|
||||||
def on_start(result, c1, c2):
|
def on_start(result, c1, c2):
|
||||||
self.assertEqual(c1._component_state, 'Started')
|
assert c1._component_state == 'Started'
|
||||||
self.assertEqual(c2._component_state, 'Started')
|
assert c2._component_state == 'Started'
|
||||||
self.assertEqual(c1.start_count, 1)
|
assert c1.start_count == 1
|
||||||
self.assertEqual(c2.start_count, 1)
|
assert c2.start_count == 1
|
||||||
return component.stop(['test_start_depends_c1']).addCallback(
|
return component.stop(['test_start_depends_c1']).addCallback(
|
||||||
on_stop, c1, c2
|
on_stop, c1, c2
|
||||||
)
|
)
|
||||||
|
@ -123,8 +123,8 @@ class ComponentTestClass(BaseTestCase):
|
||||||
def test_start_all(self):
|
def test_start_all(self):
|
||||||
def on_start(*args):
|
def on_start(*args):
|
||||||
for c in args[1:]:
|
for c in args[1:]:
|
||||||
self.assertEqual(c._component_state, 'Started')
|
assert c._component_state == 'Started'
|
||||||
self.assertEqual(c.start_count, 1)
|
assert c.start_count == 1
|
||||||
|
|
||||||
ret = self.start_with_depends()
|
ret = self.start_with_depends()
|
||||||
ret[0].addCallback(on_start, *ret[1:])
|
ret[0].addCallback(on_start, *ret[1:])
|
||||||
|
@ -133,20 +133,19 @@ class ComponentTestClass(BaseTestCase):
|
||||||
|
|
||||||
def test_register_exception(self):
|
def test_register_exception(self):
|
||||||
ComponentTester('test_register_exception_c1')
|
ComponentTester('test_register_exception_c1')
|
||||||
self.assertRaises(
|
with pytest.raises(component.ComponentAlreadyRegistered):
|
||||||
component.ComponentAlreadyRegistered,
|
ComponentTester(
|
||||||
ComponentTester,
|
|
||||||
'test_register_exception_c1',
|
'test_register_exception_c1',
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_stop_component(self):
|
def test_stop_component(self):
|
||||||
def on_stop(result, c):
|
def on_stop(result, c):
|
||||||
self.assertEqual(c._component_state, 'Stopped')
|
assert c._component_state == 'Stopped'
|
||||||
self.assertFalse(c._component_timer.running)
|
assert not c._component_timer.running
|
||||||
self.assertEqual(c.stop_count, 1)
|
assert c.stop_count == 1
|
||||||
|
|
||||||
def on_start(result, c):
|
def on_start(result, c):
|
||||||
self.assertEqual(c._component_state, 'Started')
|
assert c._component_state == 'Started'
|
||||||
return component.stop(['test_stop_component_c1']).addCallback(on_stop, c)
|
return component.stop(['test_stop_component_c1']).addCallback(on_stop, c)
|
||||||
|
|
||||||
c = ComponentTesterUpdate('test_stop_component_c1')
|
c = ComponentTesterUpdate('test_stop_component_c1')
|
||||||
|
@ -157,12 +156,12 @@ class ComponentTestClass(BaseTestCase):
|
||||||
def test_stop_all(self):
|
def test_stop_all(self):
|
||||||
def on_stop(result, *args):
|
def on_stop(result, *args):
|
||||||
for c in args:
|
for c in args:
|
||||||
self.assertEqual(c._component_state, 'Stopped')
|
assert c._component_state == 'Stopped'
|
||||||
self.assertEqual(c.stop_count, 1)
|
assert c.stop_count == 1
|
||||||
|
|
||||||
def on_start(result, *args):
|
def on_start(result, *args):
|
||||||
for c in args:
|
for c in args:
|
||||||
self.assertEqual(c._component_state, 'Started')
|
assert c._component_state == 'Started'
|
||||||
return component.stop().addCallback(on_stop, *args)
|
return component.stop().addCallback(on_stop, *args)
|
||||||
|
|
||||||
ret = self.start_with_depends()
|
ret = self.start_with_depends()
|
||||||
|
@ -172,9 +171,9 @@ class ComponentTestClass(BaseTestCase):
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
def on_start(result, c1, counter):
|
def on_start(result, c1, counter):
|
||||||
self.assertTrue(c1._component_timer)
|
assert c1._component_timer
|
||||||
self.assertTrue(c1._component_timer.running)
|
assert c1._component_timer.running
|
||||||
self.assertNotEqual(c1.counter, counter)
|
assert c1.counter != counter
|
||||||
return component.stop()
|
return component.stop()
|
||||||
|
|
||||||
c1 = ComponentTesterUpdate('test_update_c1')
|
c1 = ComponentTesterUpdate('test_update_c1')
|
||||||
|
@ -186,13 +185,13 @@ class ComponentTestClass(BaseTestCase):
|
||||||
|
|
||||||
def test_pause(self):
|
def test_pause(self):
|
||||||
def on_pause(result, c1, counter):
|
def on_pause(result, c1, counter):
|
||||||
self.assertEqual(c1._component_state, 'Paused')
|
assert c1._component_state == 'Paused'
|
||||||
self.assertNotEqual(c1.counter, counter)
|
assert c1.counter != counter
|
||||||
self.assertFalse(c1._component_timer.running)
|
assert not c1._component_timer.running
|
||||||
|
|
||||||
def on_start(result, c1, counter):
|
def on_start(result, c1, counter):
|
||||||
self.assertTrue(c1._component_timer)
|
assert c1._component_timer
|
||||||
self.assertNotEqual(c1.counter, counter)
|
assert c1.counter != counter
|
||||||
d = component.pause(['test_pause_c1'])
|
d = component.pause(['test_pause_c1'])
|
||||||
d.addCallback(on_pause, c1, counter)
|
d.addCallback(on_pause, c1, counter)
|
||||||
return d
|
return d
|
||||||
|
@ -204,23 +203,16 @@ class ComponentTestClass(BaseTestCase):
|
||||||
d.addCallback(on_start, c1, cnt)
|
d.addCallback(on_start, c1, cnt)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_component_start_error(self):
|
def test_component_start_error(self):
|
||||||
ComponentTesterUpdate('test_pause_c1')
|
ComponentTesterUpdate('test_pause_c1')
|
||||||
yield component.start(['test_pause_c1'])
|
yield component.start(['test_pause_c1'])
|
||||||
yield component.pause(['test_pause_c1'])
|
yield component.pause(['test_pause_c1'])
|
||||||
test_comp = component.get('test_pause_c1')
|
test_comp = component.get('test_pause_c1')
|
||||||
try:
|
with pytest.raises(component.ComponentException, match='Current state: Paused'):
|
||||||
result = self.failureResultOf(test_comp._component_start())
|
yield test_comp._component_start()
|
||||||
except AttributeError:
|
|
||||||
raise SkipTest(
|
|
||||||
'This test requires trial failureResultOf() in Twisted version >= 13'
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
result.check(component.ComponentException), component.ComponentException
|
|
||||||
)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_start_paused_error(self):
|
def test_start_paused_error(self):
|
||||||
ComponentTesterUpdate('test_pause_c1')
|
ComponentTesterUpdate('test_pause_c1')
|
||||||
yield component.start(['test_pause_c1'])
|
yield component.start(['test_pause_c1'])
|
||||||
|
@ -229,12 +221,10 @@ class ComponentTestClass(BaseTestCase):
|
||||||
# Deferreds that fail in component have to error handler which results in
|
# Deferreds that fail in component have to error handler which results in
|
||||||
# twisted doing a log.err call which causes the test to fail.
|
# twisted doing a log.err call which causes the test to fail.
|
||||||
# Prevent failure by ignoring the exception
|
# Prevent failure by ignoring the exception
|
||||||
self._observer._ignoreErrors(component.ComponentException)
|
# self._observer._ignoreErrors(component.ComponentException)
|
||||||
|
|
||||||
result = yield component.start()
|
result = yield component.start()
|
||||||
self.assertEqual(
|
assert [(result[0][0], result[0][1].value)] == [
|
||||||
[(result[0][0], result[0][1].value)],
|
|
||||||
[
|
|
||||||
(
|
(
|
||||||
defer.FAILURE,
|
defer.FAILURE,
|
||||||
component.ComponentException(
|
component.ComponentException(
|
||||||
|
@ -244,14 +234,13 @@ class ComponentTestClass(BaseTestCase):
|
||||||
'',
|
'',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
]
|
||||||
)
|
|
||||||
|
|
||||||
def test_shutdown(self):
|
def test_shutdown(self):
|
||||||
def on_shutdown(result, c1):
|
def on_shutdown(result, c1):
|
||||||
self.assertTrue(c1.shutdowned)
|
assert c1.shutdowned
|
||||||
self.assertEqual(c1._component_state, 'Stopped')
|
assert c1._component_state == 'Stopped'
|
||||||
self.assertEqual(c1.stop_count, 1)
|
assert c1.stop_count == 1
|
||||||
|
|
||||||
def on_start(result, c1):
|
def on_start(result, c1):
|
||||||
d = component.shutdown()
|
d = component.shutdown()
|
||||||
|
|
|
@ -7,15 +7,13 @@
|
||||||
import os
|
import os
|
||||||
from codecs import getwriter
|
from codecs import getwriter
|
||||||
|
|
||||||
|
import pytest
|
||||||
from twisted.internet import task
|
from twisted.internet import task
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.config
|
import deluge.config
|
||||||
from deluge.common import JSON_FORMAT
|
from deluge.common import JSON_FORMAT
|
||||||
from deluge.config import Config
|
from deluge.config import Config
|
||||||
|
|
||||||
from .common import set_tmp_config_dir
|
|
||||||
|
|
||||||
DEFAULTS = {
|
DEFAULTS = {
|
||||||
'string': 'foobar',
|
'string': 'foobar',
|
||||||
'int': 1,
|
'int': 1,
|
||||||
|
@ -26,34 +24,32 @@ DEFAULTS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ConfigTestCase(unittest.TestCase):
|
class TestConfig:
|
||||||
def setUp(self): # NOQA: N803
|
|
||||||
self.config_dir = set_tmp_config_dir()
|
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
||||||
self.assertEqual(DEFAULTS, config.config)
|
assert DEFAULTS == config.config
|
||||||
|
|
||||||
config = Config('test.conf', config_dir=self.config_dir)
|
config = Config('test.conf', config_dir=self.config_dir)
|
||||||
self.assertEqual({}, config.config)
|
assert {} == config.config
|
||||||
|
|
||||||
def test_set_get_item(self):
|
def test_set_get_item(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
|
||||||
self.assertEqual(config['foo'], 1)
|
assert config['foo'] == 1
|
||||||
self.assertRaises(ValueError, config.set_item, 'foo', 'bar')
|
with pytest.raises(ValueError):
|
||||||
|
config.set_item('foo', 'bar')
|
||||||
|
|
||||||
config['foo'] = 2
|
config['foo'] = 2
|
||||||
self.assertEqual(config.get_item('foo'), 2)
|
assert config.get_item('foo') == 2
|
||||||
|
|
||||||
config['foo'] = '3'
|
config['foo'] = '3'
|
||||||
self.assertEqual(config.get_item('foo'), 3)
|
assert config.get_item('foo') == 3
|
||||||
|
|
||||||
config['unicode'] = 'ВИДЕОФИЛЬМЫ'
|
config['unicode'] = 'ВИДЕОФИЛЬМЫ'
|
||||||
self.assertEqual(config['unicode'], 'ВИДЕОФИЛЬМЫ')
|
assert config['unicode'] == 'ВИДЕОФИЛЬМЫ'
|
||||||
|
|
||||||
config['unicode'] = b'foostring'
|
config['unicode'] = b'foostring'
|
||||||
self.assertFalse(isinstance(config.get_item('unicode'), bytes))
|
assert not isinstance(config.get_item('unicode'), bytes)
|
||||||
|
|
||||||
config._save_timer.cancel()
|
config._save_timer.cancel()
|
||||||
|
|
||||||
|
@ -61,39 +57,39 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
config = Config('test.conf', config_dir=self.config_dir)
|
config = Config('test.conf', config_dir=self.config_dir)
|
||||||
|
|
||||||
config['foo'] = None
|
config['foo'] = None
|
||||||
self.assertIsNone(config['foo'])
|
assert config['foo'] is None
|
||||||
self.assertIsInstance(config['foo'], type(None))
|
assert isinstance(config['foo'], type(None))
|
||||||
|
|
||||||
config['foo'] = 1
|
config['foo'] = 1
|
||||||
self.assertEqual(config.get('foo'), 1)
|
assert config.get('foo') == 1
|
||||||
|
|
||||||
config['foo'] = None
|
config['foo'] = None
|
||||||
self.assertIsNone(config['foo'])
|
assert config['foo'] is None
|
||||||
|
|
||||||
config['bar'] = None
|
config['bar'] = None
|
||||||
self.assertIsNone(config['bar'])
|
assert config['bar'] is None
|
||||||
|
|
||||||
config['bar'] = None
|
config['bar'] = None
|
||||||
self.assertIsNone(config['bar'])
|
assert config['bar'] is None
|
||||||
|
|
||||||
config._save_timer.cancel()
|
config._save_timer.cancel()
|
||||||
|
|
||||||
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
|
||||||
self.assertEqual(config.get('foo'), 1)
|
assert config.get('foo') == 1
|
||||||
self.assertEqual(config.get('foobar'), None)
|
assert config.get('foobar') is None
|
||||||
self.assertEqual(config.get('foobar', 2), 2)
|
assert config.get('foobar', 2) == 2
|
||||||
config['foobar'] = 5
|
config['foobar'] = 5
|
||||||
self.assertEqual(config.get('foobar', 2), 5)
|
assert config.get('foobar', 2) == 5
|
||||||
|
|
||||||
def test_load(self):
|
def test_load(self):
|
||||||
def check_config():
|
def check_config():
|
||||||
config = Config('test.conf', config_dir=self.config_dir)
|
config = Config('test.conf', config_dir=self.config_dir)
|
||||||
|
|
||||||
self.assertEqual(config['string'], 'foobar')
|
assert config['string'] == 'foobar'
|
||||||
self.assertEqual(config['float'], 0.435)
|
assert config['float'] == 0.435
|
||||||
self.assertEqual(config['password'], 'abc123*\\[!]?/<>#{@}=|"+$%(^)~')
|
assert config['password'] == 'abc123*\\[!]?/<>#{@}=|"+$%(^)~'
|
||||||
|
|
||||||
# Test opening a previous 1.2 config file of just a json object
|
# Test opening a previous 1.2 config file of just a json object
|
||||||
import json
|
import json
|
||||||
|
@ -125,19 +121,19 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
# We do this twice because the first time we need to save the file to disk
|
# We do this twice because the first time we need to save the file to disk
|
||||||
# and the second time we do a compare and we should not write
|
# and the second time we do a compare and we should not write
|
||||||
ret = config.save()
|
ret = config.save()
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
ret = config.save()
|
ret = config.save()
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
||||||
config['string'] = 'baz'
|
config['string'] = 'baz'
|
||||||
config['int'] = 2
|
config['int'] = 2
|
||||||
ret = config.save()
|
ret = config.save()
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
del config
|
del config
|
||||||
|
|
||||||
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
||||||
self.assertEqual(config['string'], 'baz')
|
assert config['string'] == 'baz'
|
||||||
self.assertEqual(config['int'], 2)
|
assert config['int'] == 2
|
||||||
|
|
||||||
def test_save_timer(self):
|
def test_save_timer(self):
|
||||||
self.clock = task.Clock()
|
self.clock = task.Clock()
|
||||||
|
@ -146,17 +142,17 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
||||||
config['string'] = 'baz'
|
config['string'] = 'baz'
|
||||||
config['int'] = 2
|
config['int'] = 2
|
||||||
self.assertTrue(config._save_timer.active())
|
assert config._save_timer.active()
|
||||||
|
|
||||||
# Timeout set for 5 seconds in config, so lets move clock by 5 seconds
|
# Timeout set for 5 seconds in config, so lets move clock by 5 seconds
|
||||||
self.clock.advance(5)
|
self.clock.advance(5)
|
||||||
|
|
||||||
def check_config(config):
|
def check_config(config):
|
||||||
self.assertTrue(not config._save_timer.active())
|
assert not config._save_timer.active()
|
||||||
del config
|
del config
|
||||||
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
config = Config('test.conf', defaults=DEFAULTS, config_dir=self.config_dir)
|
||||||
self.assertEqual(config['string'], 'baz')
|
assert config['string'] == 'baz'
|
||||||
self.assertEqual(config['int'], 2)
|
assert config['int'] == 2
|
||||||
|
|
||||||
check_config(config)
|
check_config(config)
|
||||||
|
|
||||||
|
@ -173,7 +169,7 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
from deluge.config import find_json_objects
|
from deluge.config import find_json_objects
|
||||||
|
|
||||||
objects = find_json_objects(s)
|
objects = find_json_objects(s)
|
||||||
self.assertEqual(len(objects), 2)
|
assert len(objects) == 2
|
||||||
|
|
||||||
def test_find_json_objects_curly_brace(self):
|
def test_find_json_objects_curly_brace(self):
|
||||||
"""Test with string containing curly brace"""
|
"""Test with string containing curly brace"""
|
||||||
|
@ -190,7 +186,7 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
from deluge.config import find_json_objects
|
from deluge.config import find_json_objects
|
||||||
|
|
||||||
objects = find_json_objects(s)
|
objects = find_json_objects(s)
|
||||||
self.assertEqual(len(objects), 2)
|
assert len(objects) == 2
|
||||||
|
|
||||||
def test_find_json_objects_double_quote(self):
|
def test_find_json_objects_double_quote(self):
|
||||||
"""Test with string containing double quote"""
|
"""Test with string containing double quote"""
|
||||||
|
@ -208,4 +204,4 @@ class ConfigTestCase(unittest.TestCase):
|
||||||
from deluge.config import find_json_objects
|
from deluge.config import find_json_objects
|
||||||
|
|
||||||
objects = find_json_objects(s)
|
objects = find_json_objects(s)
|
||||||
self.assertEqual(len(objects), 2)
|
assert len(objects) == 2
|
||||||
|
|
|
@ -8,9 +8,9 @@ from base64 import b64encode
|
||||||
from hashlib import sha1 as sha
|
from hashlib import sha1 as sha
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer, reactor, task
|
from twisted.internet import defer, reactor, task
|
||||||
from twisted.internet.error import CannotListenError
|
from twisted.internet.error import CannotListenError
|
||||||
from twisted.python.failure import Failure
|
|
||||||
from twisted.web.http import FORBIDDEN
|
from twisted.web.http import FORBIDDEN
|
||||||
from twisted.web.resource import EncodingResourceWrapper, Resource
|
from twisted.web.resource import EncodingResourceWrapper, Resource
|
||||||
from twisted.web.server import GzipEncoderFactory, Site
|
from twisted.web.server import GzipEncoderFactory, Site
|
||||||
|
@ -20,12 +20,12 @@ import deluge.common
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.core.torrent
|
import deluge.core.torrent
|
||||||
from deluge._libtorrent import lt
|
from deluge._libtorrent import lt
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
from deluge.core.rpcserver import RPCServer
|
from deluge.core.rpcserver import RPCServer
|
||||||
from deluge.error import AddTorrentError, InvalidTorrentError
|
from deluge.error import AddTorrentError, InvalidTorrentError
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
@ -76,9 +76,8 @@ class TopLevelResource(Resource):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CoreTestCase(BaseTestCase):
|
class TestCore(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
common.set_tmp_config_dir()
|
|
||||||
self.rpcserver = RPCServer(listen=False)
|
self.rpcserver = RPCServer(listen=False)
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
self.core.config.config['lsd'] = False
|
self.core.config.config['lsd'] = False
|
||||||
|
@ -127,7 +126,7 @@ class CoreTestCase(BaseTestCase):
|
||||||
torrent_id = self.core.add_torrent_file(filename, filedump, options)
|
torrent_id = self.core.add_torrent_file(filename, filedump, options)
|
||||||
return torrent_id
|
return torrent_id
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_add_torrent_files(self):
|
def test_add_torrent_files(self):
|
||||||
options = {}
|
options = {}
|
||||||
filenames = ['test.torrent', 'test_torrent.file.torrent']
|
filenames = ['test.torrent', 'test_torrent.file.torrent']
|
||||||
|
@ -138,9 +137,9 @@ class CoreTestCase(BaseTestCase):
|
||||||
filedump = b64encode(_file.read())
|
filedump = b64encode(_file.read())
|
||||||
files_to_add.append((filename, filedump, options))
|
files_to_add.append((filename, filedump, options))
|
||||||
errors = yield self.core.add_torrent_files(files_to_add)
|
errors = yield self.core.add_torrent_files(files_to_add)
|
||||||
self.assertEqual(len(errors), 0)
|
assert len(errors) == 0
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_add_torrent_files_error_duplicate(self):
|
def test_add_torrent_files_error_duplicate(self):
|
||||||
options = {}
|
options = {}
|
||||||
filenames = ['test.torrent', 'test.torrent']
|
filenames = ['test.torrent', 'test.torrent']
|
||||||
|
@ -151,10 +150,10 @@ class CoreTestCase(BaseTestCase):
|
||||||
filedump = b64encode(_file.read())
|
filedump = b64encode(_file.read())
|
||||||
files_to_add.append((filename, filedump, options))
|
files_to_add.append((filename, filedump, options))
|
||||||
errors = yield self.core.add_torrent_files(files_to_add)
|
errors = yield self.core.add_torrent_files(files_to_add)
|
||||||
self.assertEqual(len(errors), 1)
|
assert len(errors) == 1
|
||||||
self.assertTrue(str(errors[0]).startswith('Torrent already in session'))
|
assert str(errors[0]).startswith('Torrent already in session')
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_add_torrent_file(self):
|
def test_add_torrent_file(self):
|
||||||
options = {}
|
options = {}
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
|
@ -167,16 +166,15 @@ class CoreTestCase(BaseTestCase):
|
||||||
|
|
||||||
with open(filename, 'rb') as _file:
|
with open(filename, 'rb') as _file:
|
||||||
info_hash = sha(bencode(bdecode(_file.read())[b'info'])).hexdigest()
|
info_hash = sha(bencode(bdecode(_file.read())[b'info'])).hexdigest()
|
||||||
self.assertEqual(torrent_id, info_hash)
|
assert torrent_id == info_hash
|
||||||
|
|
||||||
def test_add_torrent_file_invalid_filedump(self):
|
def test_add_torrent_file_invalid_filedump(self):
|
||||||
options = {}
|
options = {}
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
self.assertRaises(
|
with pytest.raises(AddTorrentError):
|
||||||
AddTorrentError, self.core.add_torrent_file, filename, False, options
|
self.core.add_torrent_file(filename, False, options)
|
||||||
)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_add_torrent_url(self):
|
def test_add_torrent_url(self):
|
||||||
url = (
|
url = (
|
||||||
'http://localhost:%d/ubuntu-9.04-desktop-i386.iso.torrent'
|
'http://localhost:%d/ubuntu-9.04-desktop-i386.iso.torrent'
|
||||||
|
@ -186,78 +184,77 @@ class CoreTestCase(BaseTestCase):
|
||||||
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
||||||
|
|
||||||
torrent_id = yield self.core.add_torrent_url(url, options)
|
torrent_id = yield self.core.add_torrent_url(url, options)
|
||||||
self.assertEqual(torrent_id, info_hash)
|
assert torrent_id == info_hash
|
||||||
|
|
||||||
def test_add_torrent_url_with_cookie(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_add_torrent_url_with_cookie(self):
|
||||||
url = 'http://localhost:%d/cookie' % self.listen_port
|
url = 'http://localhost:%d/cookie' % self.listen_port
|
||||||
options = {}
|
options = {}
|
||||||
headers = {'Cookie': 'password=deluge'}
|
headers = {'Cookie': 'password=deluge'}
|
||||||
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
||||||
|
|
||||||
d = self.core.add_torrent_url(url, options)
|
with pytest.raises(Exception):
|
||||||
d.addCallbacks(self.fail, self.assertIsInstance, errbackArgs=(Failure,))
|
await self.core.add_torrent_url(url, options)
|
||||||
|
|
||||||
d = self.core.add_torrent_url(url, options, headers)
|
result = await self.core.add_torrent_url(url, options, headers)
|
||||||
d.addCallbacks(self.assertEqual, self.fail, callbackArgs=(info_hash,))
|
assert result == info_hash
|
||||||
|
|
||||||
return d
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_add_torrent_url_with_redirect(self):
|
||||||
def test_add_torrent_url_with_redirect(self):
|
|
||||||
url = 'http://localhost:%d/redirect' % self.listen_port
|
url = 'http://localhost:%d/redirect' % self.listen_port
|
||||||
options = {}
|
options = {}
|
||||||
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
||||||
|
|
||||||
d = self.core.add_torrent_url(url, options)
|
result = await self.core.add_torrent_url(url, options)
|
||||||
d.addCallback(self.assertEqual, info_hash)
|
assert result == info_hash
|
||||||
return d
|
|
||||||
|
|
||||||
def test_add_torrent_url_with_partial_download(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_add_torrent_url_with_partial_download(self):
|
||||||
url = 'http://localhost:%d/partial' % self.listen_port
|
url = 'http://localhost:%d/partial' % self.listen_port
|
||||||
options = {}
|
options = {}
|
||||||
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
||||||
|
|
||||||
d = self.core.add_torrent_url(url, options)
|
result = await self.core.add_torrent_url(url, options)
|
||||||
d.addCallback(self.assertEqual, info_hash)
|
assert result == info_hash
|
||||||
return d
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_add_torrent_magnet(self):
|
def test_add_torrent_magnet(self):
|
||||||
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
info_hash = '60d5d82328b4547511fdeac9bf4d0112daa0ce00'
|
||||||
uri = deluge.common.create_magnet_uri(info_hash)
|
uri = deluge.common.create_magnet_uri(info_hash)
|
||||||
options = {}
|
options = {}
|
||||||
torrent_id = yield self.core.add_torrent_magnet(uri, options)
|
torrent_id = yield self.core.add_torrent_magnet(uri, options)
|
||||||
self.assertEqual(torrent_id, info_hash)
|
assert torrent_id == info_hash
|
||||||
|
|
||||||
def test_resume_torrent(self):
|
def test_resume_torrent(self):
|
||||||
tid1 = self.add_torrent('test.torrent', paused=True)
|
tid1 = self.add_torrent('test.torrent', paused=True)
|
||||||
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
||||||
# Assert paused
|
# Assert paused
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertTrue(r1['paused'])
|
assert r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertTrue(r2['paused'])
|
assert r2['paused']
|
||||||
|
|
||||||
self.core.resume_torrent(tid2)
|
self.core.resume_torrent(tid2)
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertTrue(r1['paused'])
|
assert r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertFalse(r2['paused'])
|
assert not r2['paused']
|
||||||
|
|
||||||
def test_resume_torrent_list(self):
|
def test_resume_torrent_list(self):
|
||||||
"""Backward compatibility for list of torrent_ids."""
|
"""Backward compatibility for list of torrent_ids."""
|
||||||
torrent_id = self.add_torrent('test.torrent', paused=True)
|
torrent_id = self.add_torrent('test.torrent', paused=True)
|
||||||
self.core.resume_torrent([torrent_id])
|
self.core.resume_torrent([torrent_id])
|
||||||
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
||||||
self.assertFalse(result['paused'])
|
assert not result['paused']
|
||||||
|
|
||||||
def test_resume_torrents(self):
|
def test_resume_torrents(self):
|
||||||
tid1 = self.add_torrent('test.torrent', paused=True)
|
tid1 = self.add_torrent('test.torrent', paused=True)
|
||||||
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
||||||
self.core.resume_torrents([tid1, tid2])
|
self.core.resume_torrents([tid1, tid2])
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertFalse(r1['paused'])
|
assert not r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertFalse(r2['paused'])
|
assert not r2['paused']
|
||||||
|
|
||||||
def test_resume_torrents_all(self):
|
def test_resume_torrents_all(self):
|
||||||
"""With no torrent_ids param, resume all torrents"""
|
"""With no torrent_ids param, resume all torrents"""
|
||||||
|
@ -265,33 +262,33 @@ class CoreTestCase(BaseTestCase):
|
||||||
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
tid2 = self.add_torrent('test_torrent.file.torrent', paused=True)
|
||||||
self.core.resume_torrents()
|
self.core.resume_torrents()
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertFalse(r1['paused'])
|
assert not r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertFalse(r2['paused'])
|
assert not r2['paused']
|
||||||
|
|
||||||
def test_pause_torrent(self):
|
def test_pause_torrent(self):
|
||||||
tid1 = self.add_torrent('test.torrent')
|
tid1 = self.add_torrent('test.torrent')
|
||||||
tid2 = self.add_torrent('test_torrent.file.torrent')
|
tid2 = self.add_torrent('test_torrent.file.torrent')
|
||||||
# Assert not paused
|
# Assert not paused
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertFalse(r1['paused'])
|
assert not r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertFalse(r2['paused'])
|
assert not r2['paused']
|
||||||
|
|
||||||
self.core.pause_torrent(tid2)
|
self.core.pause_torrent(tid2)
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertFalse(r1['paused'])
|
assert not r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertTrue(r2['paused'])
|
assert r2['paused']
|
||||||
|
|
||||||
def test_pause_torrent_list(self):
|
def test_pause_torrent_list(self):
|
||||||
"""Backward compatibility for list of torrent_ids."""
|
"""Backward compatibility for list of torrent_ids."""
|
||||||
torrent_id = self.add_torrent('test.torrent')
|
torrent_id = self.add_torrent('test.torrent')
|
||||||
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
||||||
self.assertFalse(result['paused'])
|
assert not result['paused']
|
||||||
self.core.pause_torrent([torrent_id])
|
self.core.pause_torrent([torrent_id])
|
||||||
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
result = self.core.get_torrent_status(torrent_id, ['paused'])
|
||||||
self.assertTrue(result['paused'])
|
assert result['paused']
|
||||||
|
|
||||||
def test_pause_torrents(self):
|
def test_pause_torrents(self):
|
||||||
tid1 = self.add_torrent('test.torrent')
|
tid1 = self.add_torrent('test.torrent')
|
||||||
|
@ -299,9 +296,9 @@ class CoreTestCase(BaseTestCase):
|
||||||
|
|
||||||
self.core.pause_torrents([tid1, tid2])
|
self.core.pause_torrents([tid1, tid2])
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertTrue(r1['paused'])
|
assert r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertTrue(r2['paused'])
|
assert r2['paused']
|
||||||
|
|
||||||
def test_pause_torrents_all(self):
|
def test_pause_torrents_all(self):
|
||||||
"""With no torrent_ids param, pause all torrents"""
|
"""With no torrent_ids param, pause all torrents"""
|
||||||
|
@ -310,9 +307,9 @@ class CoreTestCase(BaseTestCase):
|
||||||
|
|
||||||
self.core.pause_torrents()
|
self.core.pause_torrents()
|
||||||
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
r1 = self.core.get_torrent_status(tid1, ['paused'])
|
||||||
self.assertTrue(r1['paused'])
|
assert r1['paused']
|
||||||
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
r2 = self.core.get_torrent_status(tid2, ['paused'])
|
||||||
self.assertTrue(r2['paused'])
|
assert r2['paused']
|
||||||
|
|
||||||
def test_prefetch_metadata_existing(self):
|
def test_prefetch_metadata_existing(self):
|
||||||
"""Check another call with same magnet returns existing deferred."""
|
"""Check another call with same magnet returns existing deferred."""
|
||||||
|
@ -320,7 +317,7 @@ class CoreTestCase(BaseTestCase):
|
||||||
expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
|
expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
|
||||||
|
|
||||||
def on_result(result):
|
def on_result(result):
|
||||||
self.assertEqual(result, expected)
|
assert result == expected
|
||||||
|
|
||||||
d = self.core.prefetch_magnet_metadata(magnet)
|
d = self.core.prefetch_magnet_metadata(magnet)
|
||||||
d.addCallback(on_result)
|
d.addCallback(on_result)
|
||||||
|
@ -329,7 +326,7 @@ class CoreTestCase(BaseTestCase):
|
||||||
self.clock.advance(30)
|
self.clock.advance(30)
|
||||||
return defer.DeferredList([d, d2])
|
return defer.DeferredList([d, d2])
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_remove_torrent(self):
|
def test_remove_torrent(self):
|
||||||
options = {}
|
options = {}
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
|
@ -337,18 +334,17 @@ class CoreTestCase(BaseTestCase):
|
||||||
filedump = b64encode(_file.read())
|
filedump = b64encode(_file.read())
|
||||||
torrent_id = yield self.core.add_torrent_file_async(filename, filedump, options)
|
torrent_id = yield self.core.add_torrent_file_async(filename, filedump, options)
|
||||||
removed = self.core.remove_torrent(torrent_id, True)
|
removed = self.core.remove_torrent(torrent_id, True)
|
||||||
self.assertTrue(removed)
|
assert removed
|
||||||
self.assertEqual(len(self.core.get_session_state()), 0)
|
assert len(self.core.get_session_state()) == 0
|
||||||
|
|
||||||
def test_remove_torrent_invalid(self):
|
def test_remove_torrent_invalid(self):
|
||||||
self.assertRaises(
|
with pytest.raises(InvalidTorrentError):
|
||||||
InvalidTorrentError,
|
self.core.remove_torrent(
|
||||||
self.core.remove_torrent,
|
|
||||||
'torrentidthatdoesntexist',
|
'torrentidthatdoesntexist',
|
||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_remove_torrents(self):
|
def test_remove_torrents(self):
|
||||||
options = {}
|
options = {}
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
|
@ -365,17 +361,17 @@ class CoreTestCase(BaseTestCase):
|
||||||
d = self.core.remove_torrents([torrent_id, torrent_id2], True)
|
d = self.core.remove_torrents([torrent_id, torrent_id2], True)
|
||||||
|
|
||||||
def test_ret(val):
|
def test_ret(val):
|
||||||
self.assertTrue(val == [])
|
assert val == []
|
||||||
|
|
||||||
d.addCallback(test_ret)
|
d.addCallback(test_ret)
|
||||||
|
|
||||||
def test_session_state(val):
|
def test_session_state(val):
|
||||||
self.assertEqual(len(self.core.get_session_state()), 0)
|
assert len(self.core.get_session_state()) == 0
|
||||||
|
|
||||||
d.addCallback(test_session_state)
|
d.addCallback(test_session_state)
|
||||||
yield d
|
yield d
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_remove_torrents_invalid(self):
|
def test_remove_torrents_invalid(self):
|
||||||
options = {}
|
options = {}
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
|
@ -387,57 +383,53 @@ class CoreTestCase(BaseTestCase):
|
||||||
val = yield self.core.remove_torrents(
|
val = yield self.core.remove_torrents(
|
||||||
['invalidid1', 'invalidid2', torrent_id], False
|
['invalidid1', 'invalidid2', torrent_id], False
|
||||||
)
|
)
|
||||||
self.assertEqual(len(val), 2)
|
assert len(val) == 2
|
||||||
self.assertEqual(
|
assert val[0] == ('invalidid1', 'torrent_id invalidid1 not in session.')
|
||||||
val[0], ('invalidid1', 'torrent_id invalidid1 not in session.')
|
assert val[1] == ('invalidid2', 'torrent_id invalidid2 not in session.')
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
val[1], ('invalidid2', 'torrent_id invalidid2 not in session.')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_get_session_status(self):
|
def test_get_session_status(self):
|
||||||
status = self.core.get_session_status(
|
status = self.core.get_session_status(
|
||||||
['net.recv_tracker_bytes', 'net.sent_tracker_bytes']
|
['net.recv_tracker_bytes', 'net.sent_tracker_bytes']
|
||||||
)
|
)
|
||||||
self.assertIsInstance(status, dict)
|
assert isinstance(status, dict)
|
||||||
self.assertEqual(status['net.recv_tracker_bytes'], 0)
|
assert status['net.recv_tracker_bytes'] == 0
|
||||||
self.assertEqual(status['net.sent_tracker_bytes'], 0)
|
assert status['net.sent_tracker_bytes'] == 0
|
||||||
|
|
||||||
def test_get_session_status_all(self):
|
def test_get_session_status_all(self):
|
||||||
status = self.core.get_session_status([])
|
status = self.core.get_session_status([])
|
||||||
self.assertIsInstance(status, dict)
|
assert isinstance(status, dict)
|
||||||
self.assertIn('upload_rate', status)
|
assert 'upload_rate' in status
|
||||||
self.assertIn('net.recv_bytes', status)
|
assert 'net.recv_bytes' in status
|
||||||
|
|
||||||
def test_get_session_status_depr(self):
|
def test_get_session_status_depr(self):
|
||||||
status = self.core.get_session_status(['num_peers', 'num_unchoked'])
|
status = self.core.get_session_status(['num_peers', 'num_unchoked'])
|
||||||
self.assertIsInstance(status, dict)
|
assert isinstance(status, dict)
|
||||||
self.assertEqual(status['num_peers'], 0)
|
assert status['num_peers'] == 0
|
||||||
self.assertEqual(status['num_unchoked'], 0)
|
assert status['num_unchoked'] == 0
|
||||||
|
|
||||||
def test_get_session_status_rates(self):
|
def test_get_session_status_rates(self):
|
||||||
status = self.core.get_session_status(['upload_rate', 'download_rate'])
|
status = self.core.get_session_status(['upload_rate', 'download_rate'])
|
||||||
self.assertIsInstance(status, dict)
|
assert isinstance(status, dict)
|
||||||
self.assertEqual(status['upload_rate'], 0)
|
assert status['upload_rate'] == 0
|
||||||
|
|
||||||
def test_get_session_status_ratio(self):
|
def test_get_session_status_ratio(self):
|
||||||
status = self.core.get_session_status(['write_hit_ratio', 'read_hit_ratio'])
|
status = self.core.get_session_status(['write_hit_ratio', 'read_hit_ratio'])
|
||||||
self.assertIsInstance(status, dict)
|
assert isinstance(status, dict)
|
||||||
self.assertEqual(status['write_hit_ratio'], 0.0)
|
assert status['write_hit_ratio'] == 0.0
|
||||||
self.assertEqual(status['read_hit_ratio'], 0.0)
|
assert status['read_hit_ratio'] == 0.0
|
||||||
|
|
||||||
def test_get_free_space(self):
|
def test_get_free_space(self):
|
||||||
space = self.core.get_free_space('.')
|
space = self.core.get_free_space('.')
|
||||||
self.assertTrue(isinstance(space, int))
|
assert isinstance(space, int)
|
||||||
self.assertTrue(space >= 0)
|
assert space >= 0
|
||||||
self.assertEqual(self.core.get_free_space('/someinvalidpath'), -1)
|
assert self.core.get_free_space('/someinvalidpath') == -1
|
||||||
|
|
||||||
@pytest.mark.slow
|
@pytest.mark.slow
|
||||||
def test_test_listen_port(self):
|
def test_test_listen_port(self):
|
||||||
d = self.core.test_listen_port()
|
d = self.core.test_listen_port()
|
||||||
|
|
||||||
def result(r):
|
def result(r):
|
||||||
self.assertTrue(r in (True, False))
|
assert r in (True, False)
|
||||||
|
|
||||||
d.addCallback(result)
|
d.addCallback(result)
|
||||||
return d
|
return d
|
||||||
|
@ -455,24 +447,22 @@ class CoreTestCase(BaseTestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in pathlist:
|
for key in pathlist:
|
||||||
self.assertEqual(
|
assert (
|
||||||
deluge.core.torrent.sanitize_filepath(key, folder=False), pathlist[key]
|
deluge.core.torrent.sanitize_filepath(key, folder=False)
|
||||||
|
== pathlist[key]
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
|
||||||
deluge.core.torrent.sanitize_filepath(key, folder=True),
|
assert (
|
||||||
pathlist[key] + '/',
|
deluge.core.torrent.sanitize_filepath(key, folder=True)
|
||||||
|
== pathlist[key] + '/'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_set_config_values(self):
|
def test_get_set_config_values(self):
|
||||||
self.assertEqual(
|
assert self.core.get_config_values(['abc', 'foo']) == {'foo': None, 'abc': None}
|
||||||
self.core.get_config_values(['abc', 'foo']), {'foo': None, 'abc': None}
|
assert self.core.get_config_value('foobar') is None
|
||||||
)
|
|
||||||
self.assertEqual(self.core.get_config_value('foobar'), None)
|
|
||||||
self.core.set_config({'abc': 'def', 'foo': 10, 'foobar': 'barfoo'})
|
self.core.set_config({'abc': 'def', 'foo': 10, 'foobar': 'barfoo'})
|
||||||
self.assertEqual(
|
assert self.core.get_config_values(['foo', 'abc']) == {'foo': 10, 'abc': 'def'}
|
||||||
self.core.get_config_values(['foo', 'abc']), {'foo': 10, 'abc': 'def'}
|
assert self.core.get_config_value('foobar') == 'barfoo'
|
||||||
)
|
|
||||||
self.assertEqual(self.core.get_config_value('foobar'), 'barfoo')
|
|
||||||
|
|
||||||
def test_read_only_config_keys(self):
|
def test_read_only_config_keys(self):
|
||||||
key = 'max_upload_speed'
|
key = 'max_upload_speed'
|
||||||
|
@ -481,13 +471,13 @@ class CoreTestCase(BaseTestCase):
|
||||||
old_value = self.core.get_config_value(key)
|
old_value = self.core.get_config_value(key)
|
||||||
self.core.set_config({key: old_value + 10})
|
self.core.set_config({key: old_value + 10})
|
||||||
new_value = self.core.get_config_value(key)
|
new_value = self.core.get_config_value(key)
|
||||||
self.assertEqual(old_value, new_value)
|
assert old_value == new_value
|
||||||
|
|
||||||
self.core.read_only_config_keys = None
|
self.core.read_only_config_keys = None
|
||||||
|
|
||||||
def test__create_peer_id(self):
|
def test__create_peer_id(self):
|
||||||
self.assertEqual(self.core._create_peer_id('2.0.0'), '-DE200s-')
|
assert self.core._create_peer_id('2.0.0') == '-DE200s-'
|
||||||
self.assertEqual(self.core._create_peer_id('2.0.0.dev15'), '-DE200D-')
|
assert self.core._create_peer_id('2.0.0.dev15') == '-DE200D-'
|
||||||
self.assertEqual(self.core._create_peer_id('2.0.1rc1'), '-DE201r-')
|
assert self.core._create_peer_id('2.0.1rc1') == '-DE201r-'
|
||||||
self.assertEqual(self.core._create_peer_id('2.11.0b2'), '-DE2B0b-')
|
assert self.core._create_peer_id('2.11.0b2') == '-DE2B0b-'
|
||||||
self.assertEqual(self.core._create_peer_id('2.4.12b2.dev3'), '-DE24CD-')
|
assert self.core._create_peer_id('2.4.12b2.dev3') == '-DE24CD-'
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
from deluge.decorators import proxy
|
from deluge.decorators import proxy
|
||||||
|
|
||||||
|
|
||||||
class DecoratorsTestCase(unittest.TestCase):
|
class TestDecorators:
|
||||||
def test_proxy_with_simple_functions(self):
|
def test_proxy_with_simple_functions(self):
|
||||||
def negate(func, *args, **kwargs):
|
def negate(func, *args, **kwargs):
|
||||||
return not func(*args, **kwargs)
|
return not func(*args, **kwargs)
|
||||||
|
@ -23,10 +22,10 @@ class DecoratorsTestCase(unittest.TestCase):
|
||||||
def double_nothing(_bool):
|
def double_nothing(_bool):
|
||||||
return _bool
|
return _bool
|
||||||
|
|
||||||
self.assertTrue(something(False))
|
assert something(False)
|
||||||
self.assertFalse(something(True))
|
assert not something(True)
|
||||||
self.assertTrue(double_nothing(True))
|
assert double_nothing(True)
|
||||||
self.assertFalse(double_nothing(False))
|
assert not double_nothing(False)
|
||||||
|
|
||||||
def test_proxy_with_class_method(self):
|
def test_proxy_with_class_method(self):
|
||||||
def negate(func, *args, **kwargs):
|
def negate(func, *args, **kwargs):
|
||||||
|
@ -45,5 +44,5 @@ class DecoratorsTestCase(unittest.TestCase):
|
||||||
return self.diff(number)
|
return self.diff(number)
|
||||||
|
|
||||||
t = Test(5)
|
t = Test(5)
|
||||||
self.assertEqual(t.diff(1), -4)
|
assert t.diff(1) == -4
|
||||||
self.assertEqual(t.no_diff(1), 4)
|
assert t.no_diff(1) == 4
|
||||||
|
|
|
@ -4,48 +4,36 @@
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.error
|
import deluge.error
|
||||||
|
|
||||||
|
|
||||||
class ErrorTestCase(unittest.TestCase):
|
class TestError:
|
||||||
def setUp(self): # NOQA: N803
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self): # NOQA: N803
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_deluge_error(self):
|
def test_deluge_error(self):
|
||||||
msg = 'Some message'
|
msg = 'Some message'
|
||||||
e = deluge.error.DelugeError(msg)
|
e = deluge.error.DelugeError(msg)
|
||||||
self.assertEqual(str(e), msg)
|
assert str(e) == msg
|
||||||
from twisted.internet.defer import DebugInfo
|
from twisted.internet.defer import DebugInfo
|
||||||
|
|
||||||
del DebugInfo.__del__ # Hides all errors
|
del DebugInfo.__del__ # Hides all errors
|
||||||
self.assertEqual(e._args, (msg,))
|
assert e._args == (msg,)
|
||||||
self.assertEqual(e._kwargs, {})
|
assert e._kwargs == {}
|
||||||
|
|
||||||
def test_incompatible_client(self):
|
def test_incompatible_client(self):
|
||||||
version = '1.3.6'
|
version = '1.3.6'
|
||||||
e = deluge.error.IncompatibleClient(version)
|
e = deluge.error.IncompatibleClient(version)
|
||||||
self.assertEqual(
|
assert (
|
||||||
str(e),
|
str(e) == 'Your deluge client is not compatible with the daemon. '
|
||||||
'Your deluge client is not compatible with the daemon. \
|
'Please upgrade your client to %s' % version
|
||||||
Please upgrade your client to %s'
|
|
||||||
% version,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_not_authorized_error(self):
|
def test_not_authorized_error(self):
|
||||||
current_level = 5
|
current_level = 5
|
||||||
required_level = 10
|
required_level = 10
|
||||||
e = deluge.error.NotAuthorizedError(current_level, required_level)
|
e = deluge.error.NotAuthorizedError(current_level, required_level)
|
||||||
self.assertEqual(
|
assert str(e) == 'Auth level too low: %d < %d' % (current_level, required_level)
|
||||||
str(e), 'Auth level too low: %d < %d' % (current_level, required_level)
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_bad_login_error(self):
|
def test_bad_login_error(self):
|
||||||
message = 'Login failed'
|
message = 'Login failed'
|
||||||
username = 'deluge'
|
username = 'deluge'
|
||||||
e = deluge.error.BadLoginError(message, username)
|
e = deluge.error.BadLoginError(message, username)
|
||||||
self.assertEqual(str(e), message)
|
assert str(e) == message
|
||||||
|
|
|
@ -5,15 +5,12 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.i18n import setup_translation
|
from deluge.i18n import setup_translation
|
||||||
|
|
||||||
from . import common
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
libs_available = True
|
libs_available = True
|
||||||
# Allow running other tests without GTKUI dependencies available
|
# Allow running other tests without GTKUI dependencies available
|
||||||
try:
|
try:
|
||||||
|
@ -28,12 +25,11 @@ setup_translation()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
class FilesTabTestCase(BaseTestCase):
|
class TestFilesTab(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
if libs_available is False:
|
if libs_available is False:
|
||||||
raise unittest.SkipTest('GTKUI dependencies not available')
|
pytest.skip('GTKUI dependencies not available')
|
||||||
|
|
||||||
common.set_tmp_config_dir()
|
|
||||||
ConfigManager('gtk3ui.conf', defaults=DEFAULT_PREFS)
|
ConfigManager('gtk3ui.conf', defaults=DEFAULT_PREFS)
|
||||||
self.mainwindow = MainWindow()
|
self.mainwindow = MainWindow()
|
||||||
self.filestab = FilesTab()
|
self.filestab = FilesTab()
|
||||||
|
@ -94,7 +90,7 @@ class FilesTabTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
if not ret:
|
if not ret:
|
||||||
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
||||||
def test_files_tab2(self):
|
def test_files_tab2(self):
|
||||||
self.filestab.files_list[self.t_id] = (
|
self.filestab.files_list[self.t_id] = (
|
||||||
|
@ -112,7 +108,7 @@ class FilesTabTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
if not ret:
|
if not ret:
|
||||||
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
||||||
def test_files_tab3(self):
|
def test_files_tab3(self):
|
||||||
self.filestab.files_list[self.t_id] = (
|
self.filestab.files_list[self.t_id] = (
|
||||||
|
@ -129,7 +125,7 @@ class FilesTabTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
if not ret:
|
if not ret:
|
||||||
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
||||||
def test_files_tab4(self):
|
def test_files_tab4(self):
|
||||||
self.filestab.files_list[self.t_id] = (
|
self.filestab.files_list[self.t_id] = (
|
||||||
|
@ -147,7 +143,7 @@ class FilesTabTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
if not ret:
|
if not ret:
|
||||||
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
||||||
def test_files_tab5(self):
|
def test_files_tab5(self):
|
||||||
self.filestab.files_list[self.t_id] = (
|
self.filestab.files_list[self.t_id] = (
|
||||||
|
@ -164,4 +160,4 @@ class FilesTabTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
if not ret:
|
if not ret:
|
||||||
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
self.print_treestore('Treestore not expected:', self.filestab.treestore)
|
||||||
self.assertTrue(ret)
|
assert ret
|
||||||
|
|
|
@ -8,11 +8,11 @@ import os
|
||||||
import tempfile
|
import tempfile
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.error import CannotListenError
|
from twisted.internet.error import CannotListenError
|
||||||
from twisted.python.failure import Failure
|
from twisted.web.error import Error, PageRedirect
|
||||||
from twisted.trial import unittest
|
|
||||||
from twisted.web.error import PageRedirect
|
|
||||||
from twisted.web.http import NOT_MODIFIED
|
from twisted.web.http import NOT_MODIFIED
|
||||||
from twisted.web.resource import EncodingResourceWrapper, Resource
|
from twisted.web.resource import EncodingResourceWrapper, Resource
|
||||||
from twisted.web.server import GzipEncoderFactory, Site
|
from twisted.web.server import GzipEncoderFactory, Site
|
||||||
|
@ -134,11 +134,13 @@ class TopLevelResource(Resource):
|
||||||
return b'<h1>Deluge HTTP Downloader tests webserver here</h1>'
|
return b'<h1>Deluge HTTP Downloader tests webserver here</h1>'
|
||||||
|
|
||||||
|
|
||||||
class DownloadFileTestCase(unittest.TestCase):
|
class TestDownloadFile:
|
||||||
def get_url(self, path=''):
|
def get_url(self, path=''):
|
||||||
return 'http://localhost:%d/%s' % (self.listen_port, path)
|
return 'http://localhost:%d/%s' % (self.listen_port, path)
|
||||||
|
|
||||||
def setUp(self): # NOQA
|
@pytest_twisted.async_yield_fixture(autouse=True)
|
||||||
|
async def setUp(self, request): # NOQA
|
||||||
|
self = request.instance
|
||||||
setup_logger('warning', fname('log_file'))
|
setup_logger('warning', fname('log_file'))
|
||||||
self.website = Site(TopLevelResource())
|
self.website = Site(TopLevelResource())
|
||||||
self.listen_port = 51242
|
self.listen_port = 51242
|
||||||
|
@ -154,140 +156,136 @@ class DownloadFileTestCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
raise error
|
raise error
|
||||||
|
|
||||||
def tearDown(self): # NOQA
|
yield
|
||||||
return self.webserver.stopListening()
|
|
||||||
|
|
||||||
def assertContains(self, filename, contents): # NOQA
|
await self.webserver.stopListening()
|
||||||
|
|
||||||
|
def assert_contains(self, filename, contents):
|
||||||
with open(filename, encoding='utf8') as _file:
|
with open(filename, encoding='utf8') as _file:
|
||||||
try:
|
try:
|
||||||
self.assertEqual(_file.read(), contents)
|
assert _file.read() == contents
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.fail(ex)
|
pytest.fail(ex)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def assertNotContains(self, filename, contents, file_mode=''): # NOQA
|
def assert_not_contains(self, filename, contents, file_mode=''):
|
||||||
with open(filename, encoding='utf8') as _file:
|
with open(filename, encoding='utf8') as _file:
|
||||||
try:
|
try:
|
||||||
self.assertNotEqual(_file.read(), contents)
|
assert _file.read() != contents
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.fail(ex)
|
pytest.fail(ex)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def test_download(self):
|
@pytest_twisted.ensureDeferred
|
||||||
d = download_file(self.get_url(), fname('index.html'))
|
async def test_download(self):
|
||||||
d.addCallback(self.assertEqual, fname('index.html'))
|
filename = await download_file(self.get_url(), fname('index.html'))
|
||||||
return d
|
assert filename == fname('index.html')
|
||||||
|
|
||||||
def test_download_without_required_cookies(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_without_required_cookies(self):
|
||||||
url = self.get_url('cookie')
|
url = self.get_url('cookie')
|
||||||
d = download_file(url, fname('none'))
|
filename = await download_file(url, fname('none'))
|
||||||
d.addCallback(self.fail)
|
self.assert_contains(filename, 'Password cookie not set!')
|
||||||
d.addErrback(self.assertIsInstance, Failure)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_required_cookies(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_required_cookies(self):
|
||||||
url = self.get_url('cookie')
|
url = self.get_url('cookie')
|
||||||
cookie = {'cookie': 'password=deluge'}
|
cookie = {'cookie': 'password=deluge'}
|
||||||
d = download_file(url, fname('monster'), headers=cookie)
|
filename = await download_file(url, fname('monster'), headers=cookie)
|
||||||
d.addCallback(self.assertEqual, fname('monster'))
|
assert filename == fname('monster')
|
||||||
d.addCallback(self.assertContains, 'COOKIE MONSTER!')
|
self.assert_contains(filename, 'COOKIE MONSTER!')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_rename(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_rename(self):
|
||||||
url = self.get_url('rename?filename=renamed')
|
url = self.get_url('rename?filename=renamed')
|
||||||
d = download_file(url, fname('original'))
|
filename = await download_file(url, fname('original'))
|
||||||
d.addCallback(self.assertEqual, fname('renamed'))
|
assert filename == fname('renamed')
|
||||||
d.addCallback(self.assertContains, 'This file should be called renamed')
|
self.assert_contains(filename, 'This file should be called renamed')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_rename_exists(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_rename_exists(self):
|
||||||
open(fname('renamed'), 'w').close()
|
open(fname('renamed'), 'w').close()
|
||||||
url = self.get_url('rename?filename=renamed')
|
url = self.get_url('rename?filename=renamed')
|
||||||
d = download_file(url, fname('original'))
|
filename = await download_file(url, fname('original'))
|
||||||
d.addCallback(self.assertEqual, fname('renamed-1'))
|
assert filename == fname('renamed-1')
|
||||||
d.addCallback(self.assertContains, 'This file should be called renamed')
|
self.assert_contains(filename, 'This file should be called renamed')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_rename_sanitised(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_rename_sanitised(self):
|
||||||
url = self.get_url('rename?filename=/etc/passwd')
|
url = self.get_url('rename?filename=/etc/passwd')
|
||||||
d = download_file(url, fname('original'))
|
filename = await download_file(url, fname('original'))
|
||||||
d.addCallback(self.assertEqual, fname('passwd'))
|
assert filename == fname('passwd')
|
||||||
d.addCallback(self.assertContains, 'This file should be called /etc/passwd')
|
self.assert_contains(filename, 'This file should be called /etc/passwd')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_attachment_no_filename(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_attachment_no_filename(self):
|
||||||
url = self.get_url('attachment')
|
url = self.get_url('attachment')
|
||||||
d = download_file(url, fname('original'))
|
filename = await download_file(url, fname('original'))
|
||||||
d.addCallback(self.assertEqual, fname('original'))
|
assert filename == fname('original')
|
||||||
d.addCallback(self.assertContains, 'Attachment with no filename set')
|
self.assert_contains(filename, 'Attachment with no filename set')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_rename_prevented(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_rename_prevented(self):
|
||||||
url = self.get_url('rename?filename=spam')
|
url = self.get_url('rename?filename=spam')
|
||||||
d = download_file(url, fname('forced'), force_filename=True)
|
filename = await download_file(url, fname('forced'), force_filename=True)
|
||||||
d.addCallback(self.assertEqual, fname('forced'))
|
assert filename == fname('forced')
|
||||||
d.addCallback(self.assertContains, 'This file should be called spam')
|
self.assert_contains(filename, 'This file should be called spam')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_gzip_encoding(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_gzip_encoding(self):
|
||||||
url = self.get_url('gzip?msg=success')
|
url = self.get_url('gzip?msg=success')
|
||||||
d = download_file(url, fname('gzip_encoded'))
|
filename = await download_file(url, fname('gzip_encoded'))
|
||||||
d.addCallback(self.assertContains, 'success')
|
self.assert_contains(filename, 'success')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_with_gzip_encoding_disabled(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_with_gzip_encoding_disabled(self):
|
||||||
url = self.get_url('gzip?msg=unzip')
|
url = self.get_url('gzip?msg=unzip')
|
||||||
d = download_file(url, fname('gzip_encoded'), allow_compression=False)
|
filename = await download_file(
|
||||||
d.addCallback(self.assertContains, 'unzip')
|
url, fname('gzip_encoded'), allow_compression=False
|
||||||
return d
|
)
|
||||||
|
self.assert_contains(filename, 'unzip')
|
||||||
|
|
||||||
def test_page_redirect_unhandled(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_page_redirect_unhandled(self):
|
||||||
url = self.get_url('redirect')
|
url = self.get_url('redirect')
|
||||||
d = download_file(url, fname('none'))
|
with pytest.raises(PageRedirect):
|
||||||
d.addCallback(self.fail)
|
await download_file(url, fname('none'), handle_redirects=False)
|
||||||
|
|
||||||
def on_redirect(failure):
|
@pytest_twisted.ensureDeferred
|
||||||
self.assertTrue(type(failure), PageRedirect)
|
async def test_page_redirect(self):
|
||||||
|
|
||||||
d.addErrback(on_redirect)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_page_redirect(self):
|
|
||||||
url = self.get_url('redirect')
|
url = self.get_url('redirect')
|
||||||
d = download_file(url, fname('none'), handle_redirects=True)
|
filename = await download_file(url, fname('none'), handle_redirects=True)
|
||||||
d.addCallback(self.assertEqual, fname('none'))
|
assert filename == fname('none')
|
||||||
d.addErrback(self.fail)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_page_not_found(self):
|
@pytest_twisted.ensureDeferred
|
||||||
d = download_file(self.get_url('page/not/found'), fname('none'))
|
async def test_page_not_found(self):
|
||||||
d.addCallback(self.fail)
|
with pytest.raises(Error):
|
||||||
d.addErrback(self.assertIsInstance, Failure)
|
await download_file(self.get_url('page/not/found'), fname('none'))
|
||||||
return d
|
|
||||||
|
|
||||||
def test_page_not_modified(self):
|
@pytest.mark.xfail(reason="Doesn't seem like httpdownloader ever implemented this.")
|
||||||
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_page_not_modified(self):
|
||||||
headers = {'If-Modified-Since': formatdate(usegmt=True)}
|
headers = {'If-Modified-Since': formatdate(usegmt=True)}
|
||||||
d = download_file(self.get_url(), fname('index.html'), headers=headers)
|
with pytest.raises(Error) as exc_info:
|
||||||
d.addCallback(self.fail)
|
await download_file(self.get_url(), fname('index.html'), headers=headers)
|
||||||
d.addErrback(self.assertIsInstance, Failure)
|
assert exc_info.value.status == NOT_MODIFIED
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_text_reencode_charset(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_text_reencode_charset(self):
|
||||||
"""Re-encode as UTF-8 specified charset for text content-type header"""
|
"""Re-encode as UTF-8 specified charset for text content-type header"""
|
||||||
url = self.get_url('attachment')
|
url = self.get_url('attachment')
|
||||||
filepath = fname('test.txt')
|
filepath = fname('test.txt')
|
||||||
headers = {'content-charset': 'Windows-1251', 'content-append': 'бвгде'}
|
headers = {'content-charset': 'Windows-1251', 'content-append': 'бвгде'}
|
||||||
d = download_file(url, filepath, headers=headers)
|
filename = await download_file(url, filepath, headers=headers)
|
||||||
d.addCallback(self.assertEqual, filepath)
|
assert filename == filepath
|
||||||
d.addCallback(self.assertContains, 'Attachment with no filename setбвгде')
|
self.assert_contains(filename, 'Attachment with no filename setбвгде')
|
||||||
return d
|
|
||||||
|
|
||||||
def test_download_binary_ignore_charset(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_download_binary_ignore_charset(self):
|
||||||
"""Ignore charset for binary content-type header e.g. torrent files"""
|
"""Ignore charset for binary content-type header e.g. torrent files"""
|
||||||
url = self.get_url('torrent')
|
url = self.get_url('torrent')
|
||||||
headers = {'content-charset': 'Windows-1251'}
|
headers = {'content-charset': 'Windows-1251'}
|
||||||
filepath = fname('test.torrent')
|
filepath = fname('test.torrent')
|
||||||
d = download_file(url, fname('test.torrent'), headers=headers)
|
filename = await download_file(url, fname('test.torrent'), headers=headers)
|
||||||
d.addCallback(self.assertEqual, filepath)
|
assert filename == filepath
|
||||||
d.addCallback(self.assertContains, 'Binary attachment ignore charset 世丕且\n')
|
self.assert_contains(filename, 'Binary attachment ignore charset 世丕且\n')
|
||||||
return d
|
|
||||||
|
|
|
@ -9,59 +9,32 @@
|
||||||
import json as json_lib
|
import json as json_lib
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from twisted.internet import defer
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.web import server
|
from twisted.web import server
|
||||||
from twisted.web.http import Request
|
from twisted.web.http import Request
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.component as component
|
|
||||||
import deluge.ui.web.auth
|
import deluge.ui.web.auth
|
||||||
import deluge.ui.web.json_api
|
import deluge.ui.web.json_api
|
||||||
from deluge.error import DelugeError
|
from deluge.error import DelugeError
|
||||||
from deluge.ui.client import client
|
|
||||||
from deluge.ui.web.auth import Auth
|
from deluge.ui.web.auth import Auth
|
||||||
from deluge.ui.web.json_api import JSON, JSONException
|
from deluge.ui.web.json_api import JSON, JSONException
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .basetest import BaseTestCase
|
|
||||||
from .common_web import WebServerMockBase
|
from .common_web import WebServerMockBase
|
||||||
from .daemon_base import DaemonBase
|
|
||||||
|
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
|
||||||
class JSONBase(BaseTestCase, DaemonBase):
|
@pytest.mark.usefixtures('daemon', 'client', 'component')
|
||||||
def connect_client(self, *args, **kwargs):
|
class TestJSON:
|
||||||
return client.connect(
|
@pytest_twisted.ensureDeferred
|
||||||
'localhost',
|
async def test_get_remote_methods(self):
|
||||||
self.listen_port,
|
|
||||||
username=kwargs.get('user', ''),
|
|
||||||
password=kwargs.get('password', ''),
|
|
||||||
)
|
|
||||||
|
|
||||||
def disconnect_client(self, *args):
|
|
||||||
return client.disconnect()
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
d = component.shutdown()
|
|
||||||
d.addCallback(self.disconnect_client)
|
|
||||||
d.addCallback(self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
class JSONTestCase(JSONBase):
|
|
||||||
def set_up(self):
|
|
||||||
d = self.common_set_up()
|
|
||||||
d.addCallback(self.start_core)
|
|
||||||
d.addCallbacks(self.connect_client, self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
|
||||||
def test_get_remote_methods(self):
|
|
||||||
json = JSON()
|
json = JSON()
|
||||||
methods = yield json.get_remote_methods()
|
methods = await json.get_remote_methods()
|
||||||
self.assertEqual(type(methods), tuple)
|
assert type(methods) == tuple
|
||||||
self.assertTrue(len(methods) > 0)
|
assert len(methods) > 0
|
||||||
|
|
||||||
def test_render_fail_disconnected(self):
|
def test_render_fail_disconnected(self):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
|
@ -69,7 +42,7 @@ class JSONTestCase(JSONBase):
|
||||||
request.method = b'POST'
|
request.method = b'POST'
|
||||||
request._disconnected = True
|
request._disconnected = True
|
||||||
# When disconnected, returns empty string
|
# When disconnected, returns empty string
|
||||||
self.assertEqual(json.render(request), '')
|
assert json.render(request) == ''
|
||||||
|
|
||||||
def test_render_fail(self):
|
def test_render_fail(self):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
|
@ -79,19 +52,17 @@ class JSONTestCase(JSONBase):
|
||||||
def write(response_str):
|
def write(response_str):
|
||||||
request.write_was_called = True
|
request.write_was_called = True
|
||||||
response = json_lib.loads(response_str.decode())
|
response = json_lib.loads(response_str.decode())
|
||||||
self.assertEqual(response['result'], None)
|
assert response['result'] is None
|
||||||
self.assertEqual(response['id'], None)
|
assert response['id'] is None
|
||||||
self.assertEqual(
|
assert response['error']['message'] == 'JSONException: JSON not decodable'
|
||||||
response['error']['message'], 'JSONException: JSON not decodable'
|
assert response['error']['code'] == 5
|
||||||
)
|
|
||||||
self.assertEqual(response['error']['code'], 5)
|
|
||||||
|
|
||||||
request.write = write
|
request.write = write
|
||||||
request.write_was_called = False
|
request.write_was_called = False
|
||||||
request._disconnected = False
|
request._disconnected = False
|
||||||
request.getHeader.return_value = b'application/json'
|
request.getHeader.return_value = b'application/json'
|
||||||
self.assertEqual(json.render(request), server.NOT_DONE_YET)
|
assert json.render(request) == server.NOT_DONE_YET
|
||||||
self.assertTrue(request.write_was_called)
|
assert request.write_was_called
|
||||||
|
|
||||||
def test_handle_request_invalid_method(self):
|
def test_handle_request_invalid_method(self):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
|
@ -99,20 +70,23 @@ class JSONTestCase(JSONBase):
|
||||||
json_data = {'method': 'no-existing-module.test', 'id': 0, 'params': []}
|
json_data = {'method': 'no-existing-module.test', 'id': 0, 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
request_id, result, error = json._handle_request(request)
|
request_id, result, error = json._handle_request(request)
|
||||||
self.assertEqual(error, {'message': 'Unknown method', 'code': 2})
|
assert error == {'message': 'Unknown method', 'code': 2}
|
||||||
|
|
||||||
def test_handle_request_invalid_json_request(self):
|
def test_handle_request_invalid_json_request(self):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
request = MagicMock()
|
request = MagicMock()
|
||||||
json_data = {'id': 0, 'params': []}
|
json_data = {'id': 0, 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
self.assertRaises(JSONException, json._handle_request, request)
|
with pytest.raises(JSONException):
|
||||||
|
json._handle_request(request)
|
||||||
json_data = {'method': 'some.method', 'params': []}
|
json_data = {'method': 'some.method', 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
self.assertRaises(JSONException, json._handle_request, request)
|
with pytest.raises(JSONException):
|
||||||
|
json._handle_request(request)
|
||||||
json_data = {'method': 'some.method', 'id': 0}
|
json_data = {'method': 'some.method', 'id': 0}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
self.assertRaises(JSONException, json._handle_request, request)
|
with pytest.raises(JSONException):
|
||||||
|
json._handle_request(request)
|
||||||
|
|
||||||
def test_on_json_request_invalid_content_type(self):
|
def test_on_json_request_invalid_content_type(self):
|
||||||
"""Test for exception with content type not application/json"""
|
"""Test for exception with content type not application/json"""
|
||||||
|
@ -121,18 +95,14 @@ class JSONTestCase(JSONBase):
|
||||||
request.getHeader.return_value = b'text/plain'
|
request.getHeader.return_value = b'text/plain'
|
||||||
json_data = {'method': 'some.method', 'id': 0, 'params': []}
|
json_data = {'method': 'some.method', 'id': 0, 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
self.assertRaises(JSONException, json._on_json_request, request)
|
with pytest.raises(JSONException):
|
||||||
|
json._on_json_request(request)
|
||||||
|
|
||||||
|
|
||||||
class JSONCustomUserTestCase(JSONBase):
|
@pytest.mark.usefixtures('daemon', 'client', 'component')
|
||||||
def set_up(self):
|
class TestJSONCustomUserTestCase:
|
||||||
d = self.common_set_up()
|
@pytest_twisted.inlineCallbacks
|
||||||
d.addCallback(self.start_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
|
||||||
def test_handle_request_auth_error(self):
|
def test_handle_request_auth_error(self):
|
||||||
yield self.connect_client()
|
|
||||||
json = JSON()
|
json = JSON()
|
||||||
auth_conf = {'session_timeout': 10, 'sessions': {}}
|
auth_conf = {'session_timeout': 10, 'sessions': {}}
|
||||||
Auth(auth_conf) # Must create the component
|
Auth(auth_conf) # Must create the component
|
||||||
|
@ -145,13 +115,12 @@ class JSONCustomUserTestCase(JSONBase):
|
||||||
json_data = {'method': 'core.get_libtorrent_version', 'id': 0, 'params': []}
|
json_data = {'method': 'core.get_libtorrent_version', 'id': 0, 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
request_id, result, error = json._handle_request(request)
|
request_id, result, error = json._handle_request(request)
|
||||||
self.assertEqual(error, {'message': 'Not authenticated', 'code': 1})
|
assert error == {'message': 'Not authenticated', 'code': 1}
|
||||||
|
|
||||||
|
|
||||||
class RPCRaiseDelugeErrorJSONTestCase(JSONBase):
|
@pytest.mark.usefixtures('daemon', 'client', 'component')
|
||||||
def set_up(self):
|
class TestRPCRaiseDelugeErrorJSON:
|
||||||
d = self.common_set_up()
|
daemon_custom_script = """
|
||||||
custom_script = """
|
|
||||||
from deluge.error import DelugeError
|
from deluge.error import DelugeError
|
||||||
from deluge.core.rpcserver import export
|
from deluge.core.rpcserver import export
|
||||||
class TestClass(object):
|
class TestClass(object):
|
||||||
|
@ -162,12 +131,9 @@ class RPCRaiseDelugeErrorJSONTestCase(JSONBase):
|
||||||
test = TestClass()
|
test = TestClass()
|
||||||
daemon.rpcserver.register_object(test)
|
daemon.rpcserver.register_object(test)
|
||||||
"""
|
"""
|
||||||
d.addCallback(self.start_core, custom_script=custom_script)
|
|
||||||
d.addCallbacks(self.connect_client, self.terminate_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.ensureDeferred
|
||||||
def test_handle_request_method_raise_delugeerror(self):
|
async def test_handle_request_method_raise_delugeerror(self):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
|
|
||||||
def get_session_id(s_id):
|
def get_session_id(s_id):
|
||||||
|
@ -179,9 +145,9 @@ class RPCRaiseDelugeErrorJSONTestCase(JSONBase):
|
||||||
request = Request(MagicMock(), False)
|
request = Request(MagicMock(), False)
|
||||||
request.base = b''
|
request.base = b''
|
||||||
auth._create_session(request)
|
auth._create_session(request)
|
||||||
methods = yield json.get_remote_methods()
|
methods = await json.get_remote_methods()
|
||||||
# Verify the function has been registered
|
# Verify the function has been registered
|
||||||
self.assertTrue('testclass.test' in methods)
|
assert 'testclass.test' in methods
|
||||||
|
|
||||||
request = MagicMock()
|
request = MagicMock()
|
||||||
session_id = list(auth.config['sessions'])[0]
|
session_id = list(auth.config['sessions'])[0]
|
||||||
|
@ -189,18 +155,13 @@ class RPCRaiseDelugeErrorJSONTestCase(JSONBase):
|
||||||
json_data = {'method': 'testclass.test', 'id': 0, 'params': []}
|
json_data = {'method': 'testclass.test', 'id': 0, 'params': []}
|
||||||
request.json = json_lib.dumps(json_data).encode()
|
request.json = json_lib.dumps(json_data).encode()
|
||||||
request_id, result, error = json._handle_request(request)
|
request_id, result, error = json._handle_request(request)
|
||||||
result.addCallback(self.fail)
|
with pytest.raises(DelugeError):
|
||||||
|
await result
|
||||||
def on_error(error):
|
|
||||||
self.assertEqual(error.type, DelugeError)
|
|
||||||
|
|
||||||
result.addErrback(on_error)
|
|
||||||
yield result
|
|
||||||
|
|
||||||
|
|
||||||
class JSONRequestFailedTestCase(JSONBase, WebServerMockBase):
|
class TestJSONRequestFailed(WebServerMockBase):
|
||||||
def set_up(self):
|
@pytest_twisted.async_yield_fixture(autouse=True)
|
||||||
d = self.common_set_up()
|
async def set_up(self, config_dir):
|
||||||
custom_script = """
|
custom_script = """
|
||||||
from deluge.error import DelugeError
|
from deluge.error import DelugeError
|
||||||
from deluge.core.rpcserver import export
|
from deluge.core.rpcserver import export
|
||||||
|
@ -231,28 +192,29 @@ class JSONRequestFailedTestCase(JSONBase, WebServerMockBase):
|
||||||
}
|
}
|
||||||
|
|
||||||
def on_test_raise(*args):
|
def on_test_raise(*args):
|
||||||
self.assertTrue('Unhandled error in Deferred:' in self.core.stderr_out)
|
assert 'Unhandled error in Deferred:' in self.core.stderr_out
|
||||||
self.assertTrue('in test_raise_error' in self.core.stderr_out)
|
assert 'in test_raise_error' in self.core.stderr_out
|
||||||
|
|
||||||
extra_callback['deferred'].addCallback(on_test_raise)
|
extra_callback['deferred'].addCallback(on_test_raise)
|
||||||
d.addCallback(
|
d, daemon = common.start_core(
|
||||||
self.start_core,
|
|
||||||
custom_script=custom_script,
|
custom_script=custom_script,
|
||||||
print_stdout=False,
|
print_stdout=False,
|
||||||
print_stderr=False,
|
print_stderr=False,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
extra_callbacks=[extra_callback],
|
extra_callbacks=[extra_callback],
|
||||||
|
config_directory=config_dir,
|
||||||
)
|
)
|
||||||
d.addCallbacks(self.connect_client, self.terminate_core)
|
await d
|
||||||
return d
|
yield
|
||||||
|
await daemon.kill()
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_render_on_rpc_request_failed(self):
|
def test_render_on_rpc_request_failed(self, component, client):
|
||||||
json = JSON()
|
json = JSON()
|
||||||
|
|
||||||
methods = yield json.get_remote_methods()
|
methods = yield json.get_remote_methods()
|
||||||
# Verify the function has been registered
|
# Verify the function has been registered
|
||||||
self.assertTrue('testclass.test' in methods)
|
assert 'testclass.test' in methods
|
||||||
|
|
||||||
request = MagicMock()
|
request = MagicMock()
|
||||||
|
|
||||||
|
@ -263,14 +225,14 @@ class JSONRequestFailedTestCase(JSONBase, WebServerMockBase):
|
||||||
def write(response_str):
|
def write(response_str):
|
||||||
request.write_was_called = True
|
request.write_was_called = True
|
||||||
response = json_lib.loads(response_str.decode())
|
response = json_lib.loads(response_str.decode())
|
||||||
self.assertEqual(response['result'], None, 'BAD RESULT')
|
assert response['result'] is None, 'BAD RESULT'
|
||||||
self.assertEqual(response['id'], 0)
|
assert response['id'] == 0
|
||||||
self.assertEqual(
|
assert (
|
||||||
response['error']['message'],
|
response['error']['message']
|
||||||
'Failure: [Failure instance: Traceback (failure with no frames):'
|
== 'Failure: [Failure instance: Traceback (failure with no frames):'
|
||||||
" <class 'deluge.error.DelugeError'>: DelugeERROR\n]",
|
" <class 'deluge.error.DelugeError'>: DelugeERROR\n]"
|
||||||
)
|
)
|
||||||
self.assertEqual(response['error']['code'], 4)
|
assert response['error']['code'] == 4
|
||||||
|
|
||||||
request.write = write
|
request.write = write
|
||||||
request.write_was_called = False
|
request.write_was_called = False
|
||||||
|
@ -281,8 +243,8 @@ class JSONRequestFailedTestCase(JSONBase, WebServerMockBase):
|
||||||
d = json._on_json_request(request)
|
d = json._on_json_request(request)
|
||||||
|
|
||||||
def on_success(arg):
|
def on_success(arg):
|
||||||
self.assertEqual(arg, server.NOT_DONE_YET)
|
assert arg == server.NOT_DONE_YET
|
||||||
return True
|
return True
|
||||||
|
|
||||||
d.addCallbacks(on_success, self.fail)
|
d.addCallbacks(on_success, pytest.fail)
|
||||||
yield d
|
yield d
|
||||||
|
|
|
@ -10,12 +10,11 @@
|
||||||
import logging
|
import logging
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.log import setup_logger
|
from deluge.log import setup_logger
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
class TestLog(BaseTestCase):
|
||||||
class LogTestCase(BaseTestCase):
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
setup_logger(logging.DEBUG)
|
setup_logger(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ class LogTestCase(BaseTestCase):
|
||||||
# Cause all warnings to always be triggered.
|
# Cause all warnings to always be triggered.
|
||||||
warnings.simplefilter('always')
|
warnings.simplefilter('always')
|
||||||
LOG.debug('foo')
|
LOG.debug('foo')
|
||||||
self.assertEqual(w[-1].category, DeprecationWarning)
|
assert w[-1].category == DeprecationWarning
|
||||||
|
|
||||||
# def test_twisted_error_log(self):
|
# def test_twisted_error_log(self):
|
||||||
# from twisted.internet import defer
|
# from twisted.internet import defer
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
from deluge import maketorrent
|
from deluge import maketorrent
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +22,7 @@ def check_torrent(filename):
|
||||||
TorrentInfo(filename)
|
TorrentInfo(filename)
|
||||||
|
|
||||||
|
|
||||||
class MakeTorrentTestCase(unittest.TestCase):
|
class TestMakeTorrent:
|
||||||
def test_save_multifile(self):
|
def test_save_multifile(self):
|
||||||
# Create a temporary folder for torrent creation
|
# Create a temporary folder for torrent creation
|
||||||
tmp_path = tempfile.mkdtemp()
|
tmp_path = tempfile.mkdtemp()
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
from deluge import metafile
|
from deluge import metafile
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +22,7 @@ def check_torrent(filename):
|
||||||
TorrentInfo(filename)
|
TorrentInfo(filename)
|
||||||
|
|
||||||
|
|
||||||
class MetafileTestCase(unittest.TestCase):
|
class TestMetafile:
|
||||||
def test_save_multifile(self):
|
def test_save_multifile(self):
|
||||||
# Create a temporary folder for torrent creation
|
# Create a temporary folder for torrent creation
|
||||||
tmp_path = tempfile.mkdtemp()
|
tmp_path = tempfile.mkdtemp()
|
||||||
|
|
|
@ -8,26 +8,20 @@
|
||||||
|
|
||||||
from deluge.pluginmanagerbase import PluginManagerBase
|
from deluge.pluginmanagerbase import PluginManagerBase
|
||||||
|
|
||||||
from . import common
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class PluginManagerBaseTestCase(BaseTestCase):
|
|
||||||
def set_up(self):
|
|
||||||
common.set_tmp_config_dir()
|
|
||||||
|
|
||||||
|
class TestPluginManagerBase:
|
||||||
def test_get_plugin_info(self):
|
def test_get_plugin_info(self):
|
||||||
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
||||||
for p in pm.get_available_plugins():
|
for p in pm.get_available_plugins():
|
||||||
for key, value in pm.get_plugin_info(p).items():
|
for key, value in pm.get_plugin_info(p).items():
|
||||||
self.assertIsInstance(key, str)
|
assert isinstance(key, str)
|
||||||
self.assertIsInstance(value, str)
|
assert isinstance(value, str)
|
||||||
|
|
||||||
def test_get_plugin_info_invalid_name(self):
|
def test_get_plugin_info_invalid_name(self):
|
||||||
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
||||||
for key, value in pm.get_plugin_info('random').items():
|
for key, value in pm.get_plugin_info('random').items():
|
||||||
result = 'not available' if key in ('Name', 'Version') else ''
|
result = 'not available' if key in ('Name', 'Version') else ''
|
||||||
self.assertEqual(value, result)
|
assert value == result
|
||||||
|
|
||||||
def test_parse_pkg_info_metadata_2_1(self):
|
def test_parse_pkg_info_metadata_2_1(self):
|
||||||
pkg_info = """Metadata-Version: 2.1
|
pkg_info = """Metadata-Version: 2.1
|
||||||
|
@ -44,6 +38,6 @@ Monitors folders for .torrent files.
|
||||||
"""
|
"""
|
||||||
plugin_info = PluginManagerBase.parse_pkg_info(pkg_info)
|
plugin_info = PluginManagerBase.parse_pkg_info(pkg_info)
|
||||||
for value in plugin_info.values():
|
for value in plugin_info.values():
|
||||||
self.assertNotEqual(value, '')
|
assert value != ''
|
||||||
result = 'Monitors folders for .torrent files.'
|
result = 'Monitors folders for .torrent files.'
|
||||||
self.assertEqual(plugin_info['Description'], result)
|
assert plugin_info['Description'] == result
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.error
|
import deluge.error
|
||||||
from deluge.common import get_localhost_auth
|
from deluge.common import get_localhost_auth
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core import rpcserver
|
from deluge.core import rpcserver
|
||||||
from deluge.core.authmanager import AuthManager
|
from deluge.core.authmanager import AuthManager
|
||||||
from deluge.core.rpcserver import DelugeRPCProtocol, RPCServer
|
from deluge.core.rpcserver import DelugeRPCProtocol, RPCServer
|
||||||
from deluge.log import setup_logger
|
from deluge.log import setup_logger
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
setup_logger('none')
|
setup_logger('none')
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ class DelugeRPCProtocolTester(DelugeRPCProtocol):
|
||||||
self.messages.append(data)
|
self.messages.append(data)
|
||||||
|
|
||||||
|
|
||||||
class RPCServerTestCase(BaseTestCase):
|
class TestRPCServer(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.rpcserver = RPCServer(listen=False)
|
self.rpcserver = RPCServer(listen=False)
|
||||||
self.rpcserver.factory.protocol = DelugeRPCProtocolTester
|
self.rpcserver.factory.protocol = DelugeRPCProtocolTester
|
||||||
|
@ -57,15 +56,15 @@ class RPCServerTestCase(BaseTestCase):
|
||||||
e = TorrentFolderRenamedEvent(*data)
|
e = TorrentFolderRenamedEvent(*data)
|
||||||
self.rpcserver.emit_event_for_session_id(self.session_id, e)
|
self.rpcserver.emit_event_for_session_id(self.session_id, e)
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_EVENT, str(msg))
|
assert msg[0] == rpcserver.RPC_EVENT, str(msg)
|
||||||
self.assertEqual(msg[1], 'TorrentFolderRenamedEvent', str(msg))
|
assert msg[1] == 'TorrentFolderRenamedEvent', str(msg)
|
||||||
self.assertEqual(msg[2], data, str(msg))
|
assert msg[2] == data, str(msg)
|
||||||
|
|
||||||
def test_invalid_client_login(self):
|
def test_invalid_client_login(self):
|
||||||
self.protocol.dispatch(self.request_id, 'daemon.login', [1], {})
|
self.protocol.dispatch(self.request_id, 'daemon.login', [1], {})
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_ERROR)
|
assert msg[0] == rpcserver.RPC_ERROR
|
||||||
self.assertEqual(msg[1], self.request_id)
|
assert msg[1] == self.request_id
|
||||||
|
|
||||||
def test_valid_client_login(self):
|
def test_valid_client_login(self):
|
||||||
self.authmanager = AuthManager()
|
self.authmanager = AuthManager()
|
||||||
|
@ -74,9 +73,9 @@ class RPCServerTestCase(BaseTestCase):
|
||||||
self.request_id, 'daemon.login', auth, {'client_version': 'Test'}
|
self.request_id, 'daemon.login', auth, {'client_version': 'Test'}
|
||||||
)
|
)
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_RESPONSE, str(msg))
|
assert msg[0] == rpcserver.RPC_RESPONSE, str(msg)
|
||||||
self.assertEqual(msg[1], self.request_id, str(msg))
|
assert msg[1] == self.request_id, str(msg)
|
||||||
self.assertEqual(msg[2], rpcserver.AUTH_LEVEL_ADMIN, str(msg))
|
assert msg[2] == rpcserver.AUTH_LEVEL_ADMIN, str(msg)
|
||||||
|
|
||||||
def test_client_login_error(self):
|
def test_client_login_error(self):
|
||||||
# This test causes error log prints while running the test...
|
# This test causes error log prints while running the test...
|
||||||
|
@ -87,24 +86,24 @@ class RPCServerTestCase(BaseTestCase):
|
||||||
self.request_id, 'daemon.login', auth, {'client_version': 'Test'}
|
self.request_id, 'daemon.login', auth, {'client_version': 'Test'}
|
||||||
)
|
)
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_ERROR)
|
assert msg[0] == rpcserver.RPC_ERROR
|
||||||
self.assertEqual(msg[1], self.request_id)
|
assert msg[1] == self.request_id
|
||||||
self.assertEqual(msg[2], 'WrappedException')
|
assert msg[2] == 'WrappedException'
|
||||||
self.assertEqual(msg[3][1], 'AttributeError')
|
assert msg[3][1] == 'AttributeError'
|
||||||
|
|
||||||
def test_client_invalid_method_call(self):
|
def test_client_invalid_method_call(self):
|
||||||
self.authmanager = AuthManager()
|
self.authmanager = AuthManager()
|
||||||
auth = get_localhost_auth()
|
auth = get_localhost_auth()
|
||||||
self.protocol.dispatch(self.request_id, 'invalid_function', auth, {})
|
self.protocol.dispatch(self.request_id, 'invalid_function', auth, {})
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_ERROR)
|
assert msg[0] == rpcserver.RPC_ERROR
|
||||||
self.assertEqual(msg[1], self.request_id)
|
assert msg[1] == self.request_id
|
||||||
self.assertEqual(msg[2], 'WrappedException')
|
assert msg[2] == 'WrappedException'
|
||||||
self.assertEqual(msg[3][1], 'AttributeError')
|
assert msg[3][1] == 'AttributeError'
|
||||||
|
|
||||||
def test_daemon_info(self):
|
def test_daemon_info(self):
|
||||||
self.protocol.dispatch(self.request_id, 'daemon.info', [], {})
|
self.protocol.dispatch(self.request_id, 'daemon.info', [], {})
|
||||||
msg = self.protocol.messages.pop()
|
msg = self.protocol.messages.pop()
|
||||||
self.assertEqual(msg[0], rpcserver.RPC_RESPONSE, str(msg))
|
assert msg[0] == rpcserver.RPC_RESPONSE, str(msg)
|
||||||
self.assertEqual(msg[1], self.request_id, str(msg))
|
assert msg[1] == self.request_id, str(msg)
|
||||||
self.assertEqual(msg[2], deluge.common.get_version(), str(msg))
|
assert msg[2] == deluge.common.get_version(), str(msg)
|
||||||
|
|
|
@ -13,9 +13,9 @@ import deluge.component as component
|
||||||
import deluge.ui.web.server
|
import deluge.ui.web.server
|
||||||
from deluge import configmanager
|
from deluge import configmanager
|
||||||
from deluge.common import windows_check
|
from deluge.common import windows_check
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.ui.web.server import DelugeWeb
|
from deluge.ui.web.server import DelugeWeb
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
from .common import get_test_data_file
|
from .common import get_test_data_file
|
||||||
from .common_web import WebServerTestBase
|
from .common_web import WebServerTestBase
|
||||||
from .daemon_base import DaemonBase
|
from .daemon_base import DaemonBase
|
||||||
|
@ -23,15 +23,10 @@ from .daemon_base import DaemonBase
|
||||||
SECURITY_TESTS = bool(os.getenv('SECURITY_TESTS', False))
|
SECURITY_TESTS = bool(os.getenv('SECURITY_TESTS', False))
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: This whole module has not been tested since migrating tests fully to pytest
|
||||||
class SecurityBaseTestCase:
|
class SecurityBaseTestCase:
|
||||||
if windows_check():
|
@pytest.fixture(autouse=True)
|
||||||
skip = 'windows cannot run .sh files'
|
def setvars(self):
|
||||||
elif not SECURITY_TESTS:
|
|
||||||
skip = 'Skipping security tests'
|
|
||||||
|
|
||||||
http_err = 'cannot run http tests on daemon'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.home_dir = os.path.expanduser('~')
|
self.home_dir = os.path.expanduser('~')
|
||||||
self.port = 8112
|
self.port = 8112
|
||||||
|
|
||||||
|
@ -54,10 +49,10 @@ class SecurityBaseTestCase:
|
||||||
|
|
||||||
if test == '-e':
|
if test == '-e':
|
||||||
results = results[0].split(b'\n')[7:-6]
|
results = results[0].split(b'\n')[7:-6]
|
||||||
self.assertTrue(len(results) > 3)
|
assert len(results) > 3
|
||||||
else:
|
else:
|
||||||
self.assertIn(b'OK', results[0])
|
assert b'OK' in results[0]
|
||||||
self.assertNotIn(b'NOT ok', results[0])
|
assert b'NOT ok' not in results[0]
|
||||||
|
|
||||||
d.addCallback(on_result)
|
d.addCallback(on_result)
|
||||||
return d
|
return d
|
||||||
|
@ -74,18 +69,12 @@ class SecurityBaseTestCase:
|
||||||
def test_secured_webserver_css_injection_vulnerability(self):
|
def test_secured_webserver_css_injection_vulnerability(self):
|
||||||
return self._run_test('-I')
|
return self._run_test('-I')
|
||||||
|
|
||||||
def test_secured_webserver_ticketbleed_vulnerability(self):
|
|
||||||
return self._run_test('-T')
|
|
||||||
|
|
||||||
def test_secured_webserver_renegotiation_vulnerabilities(self):
|
def test_secured_webserver_renegotiation_vulnerabilities(self):
|
||||||
return self._run_test('-R')
|
return self._run_test('-R')
|
||||||
|
|
||||||
def test_secured_webserver_crime_vulnerability(self):
|
def test_secured_webserver_crime_vulnerability(self):
|
||||||
return self._run_test('-C')
|
return self._run_test('-C')
|
||||||
|
|
||||||
def test_secured_webserver_breach_vulnerability(self):
|
|
||||||
return self._run_test('-B')
|
|
||||||
|
|
||||||
def test_secured_webserver_poodle_vulnerability(self):
|
def test_secured_webserver_poodle_vulnerability(self):
|
||||||
return self._run_test('-O')
|
return self._run_test('-O')
|
||||||
|
|
||||||
|
@ -119,33 +108,14 @@ class SecurityBaseTestCase:
|
||||||
def test_secured_webserver_preference(self):
|
def test_secured_webserver_preference(self):
|
||||||
return self._run_test('-P')
|
return self._run_test('-P')
|
||||||
|
|
||||||
def test_secured_webserver_headers(self):
|
|
||||||
return self._run_test('-h')
|
|
||||||
|
|
||||||
def test_secured_webserver_ciphers(self):
|
def test_secured_webserver_ciphers(self):
|
||||||
return self._run_test('-e')
|
return self._run_test('-e')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(windows_check(), reason='windows cannot run .sh files')
|
||||||
|
@pytest.mark.skipif(not SECURITY_TESTS, reason='skipping security tests')
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
class DaemonSecurityTestCase(BaseTestCase, DaemonBase, SecurityBaseTestCase):
|
class TestDaemonSecurity(BaseTestCase, DaemonBase, SecurityBaseTestCase):
|
||||||
|
|
||||||
if windows_check():
|
|
||||||
skip = 'windows cannot start_core not enough arguments for format string'
|
|
||||||
|
|
||||||
def __init__(self, testname):
|
|
||||||
super().__init__(testname)
|
|
||||||
DaemonBase.__init__(self)
|
|
||||||
SecurityBaseTestCase.__init__(self)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
skip = False
|
|
||||||
for not_http_test in ('breach', 'headers', 'ticketbleed'):
|
|
||||||
if not_http_test in self.id().split('.')[-1]:
|
|
||||||
self.skipTest(SecurityBaseTestCase.http_err)
|
|
||||||
skip = True
|
|
||||||
if not skip:
|
|
||||||
super().setUp()
|
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
d = self.common_set_up()
|
d = self.common_set_up()
|
||||||
self.port = self.listen_port
|
self.port = self.listen_port
|
||||||
|
@ -159,12 +129,10 @@ class DaemonSecurityTestCase(BaseTestCase, DaemonBase, SecurityBaseTestCase):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(windows_check(), reason='windows cannot run .sh files')
|
||||||
|
@pytest.mark.skipif(not SECURITY_TESTS, reason='skipping security tests')
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
class WebUISecurityTestBase(WebServerTestBase, SecurityBaseTestCase):
|
class TestWebUISecurity(WebServerTestBase, SecurityBaseTestCase):
|
||||||
def __init__(self, testname):
|
|
||||||
super().__init__(testname)
|
|
||||||
SecurityBaseTestCase.__init__(self)
|
|
||||||
|
|
||||||
def start_webapi(self, arg):
|
def start_webapi(self, arg):
|
||||||
self.port = self.webserver_listen_port = 8999
|
self.port = self.webserver_listen_port = 8999
|
||||||
|
|
||||||
|
@ -180,3 +148,12 @@ class WebUISecurityTestBase(WebServerTestBase, SecurityBaseTestCase):
|
||||||
self.deluge_web.web_api.hostlist.config['hosts'][0] = tuple(host)
|
self.deluge_web.web_api.hostlist.config['hosts'][0] = tuple(host)
|
||||||
self.host_id = host[0]
|
self.host_id = host[0]
|
||||||
self.deluge_web.start()
|
self.deluge_web.start()
|
||||||
|
|
||||||
|
def test_secured_webserver_headers(self):
|
||||||
|
return self._run_test('-h')
|
||||||
|
|
||||||
|
def test_secured_webserver_breach_vulnerability(self):
|
||||||
|
return self._run_test('-B')
|
||||||
|
|
||||||
|
def test_secured_webserver_ticketbleed_vulnerability(self):
|
||||||
|
return self._run_test('-T')
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet.defer import maybeDeferred, succeed
|
from twisted.internet.defer import maybeDeferred, succeed
|
||||||
from twisted.internet.task import Clock
|
from twisted.internet.task import Clock
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.ui.sessionproxy
|
import deluge.ui.sessionproxy
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
|
@ -102,7 +101,7 @@ class Client:
|
||||||
client = Client()
|
client = Client()
|
||||||
|
|
||||||
|
|
||||||
class SessionProxyTestCase(BaseTestCase):
|
class TestSessionProxy(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.clock = Clock()
|
self.clock = Clock()
|
||||||
self.patch(deluge.ui.sessionproxy, 'time', self.clock.seconds)
|
self.patch(deluge.ui.sessionproxy, 'time', self.clock.seconds)
|
||||||
|
@ -124,38 +123,38 @@ class SessionProxyTestCase(BaseTestCase):
|
||||||
return component.deregister(self.sp)
|
return component.deregister(self.sp)
|
||||||
|
|
||||||
def test_startup(self):
|
def test_startup(self):
|
||||||
self.assertEqual(client.core.torrents['a'], self.sp.torrents['a'][1])
|
assert client.core.torrents['a'] == self.sp.torrents['a'][1]
|
||||||
|
|
||||||
def test_get_torrent_status_no_change(self):
|
@pytest_twisted.ensureDeferred
|
||||||
d = self.sp.get_torrent_status('a', [])
|
async def test_get_torrent_status_no_change(self):
|
||||||
d.addCallback(self.assertEqual, client.core.torrents['a'])
|
result = await self.sp.get_torrent_status('a', [])
|
||||||
return d
|
assert result == client.core.torrents['a']
|
||||||
|
|
||||||
def test_get_torrent_status_change_with_cache(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_torrent_status_change_with_cache(self):
|
||||||
client.core.torrents['a']['key1'] = 2
|
client.core.torrents['a']['key1'] = 2
|
||||||
d = self.sp.get_torrent_status('a', ['key1'])
|
result = await self.sp.get_torrent_status('a', ['key1'])
|
||||||
d.addCallback(self.assertEqual, {'key1': 1})
|
assert result == {'key1': 1}
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_torrent_status_change_without_cache(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_torrent_status_change_without_cache(self):
|
||||||
client.core.torrents['a']['key1'] = 2
|
client.core.torrents['a']['key1'] = 2
|
||||||
self.clock.advance(self.sp.cache_time + 0.1)
|
self.clock.advance(self.sp.cache_time + 0.1)
|
||||||
d = self.sp.get_torrent_status('a', [])
|
result = await self.sp.get_torrent_status('a', [])
|
||||||
d.addCallback(self.assertEqual, client.core.torrents['a'])
|
assert result == client.core.torrents['a']
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_torrent_status_key_not_updated(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_torrent_status_key_not_updated(self):
|
||||||
self.clock.advance(self.sp.cache_time + 0.1)
|
self.clock.advance(self.sp.cache_time + 0.1)
|
||||||
self.sp.get_torrent_status('a', ['key1'])
|
self.sp.get_torrent_status('a', ['key1'])
|
||||||
client.core.torrents['a']['key2'] = 99
|
client.core.torrents['a']['key2'] = 99
|
||||||
d = self.sp.get_torrent_status('a', ['key2'])
|
result = await self.sp.get_torrent_status('a', ['key2'])
|
||||||
d.addCallback(self.assertEqual, {'key2': 99})
|
assert result == {'key2': 99}
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_torrents_status_key_not_updated(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_torrents_status_key_not_updated(self):
|
||||||
self.clock.advance(self.sp.cache_time + 0.1)
|
self.clock.advance(self.sp.cache_time + 0.1)
|
||||||
self.sp.get_torrents_status({'id': ['a']}, ['key1'])
|
self.sp.get_torrents_status({'id': ['a']}, ['key1'])
|
||||||
client.core.torrents['a']['key2'] = 99
|
client.core.torrents['a']['key2'] = 99
|
||||||
d = self.sp.get_torrents_status({'id': ['a']}, ['key2'])
|
result = await self.sp.get_torrents_status({'id': ['a']}, ['key2'])
|
||||||
d.addCallback(self.assertEqual, {'a': {'key2': 99}})
|
assert result == {'a': {'key2': 99}}
|
||||||
return d
|
|
||||||
|
|
|
@ -9,30 +9,28 @@ import time
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import defer, reactor
|
||||||
from twisted.internet.task import deferLater
|
from twisted.internet.task import deferLater
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.core.torrent
|
import deluge.core.torrent
|
||||||
import deluge.tests.common as common
|
import deluge.tests.common as common
|
||||||
from deluge._libtorrent import lt
|
from deluge._libtorrent import lt
|
||||||
from deluge.common import VersionSplit, utf8_encode_structure
|
from deluge.common import VersionSplit, utf8_encode_structure
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
from deluge.core.rpcserver import RPCServer
|
from deluge.core.rpcserver import RPCServer
|
||||||
from deluge.core.torrent import Torrent
|
from deluge.core.torrent import Torrent
|
||||||
from deluge.core.torrentmanager import TorrentManager, TorrentState
|
from deluge.core.torrentmanager import TorrentManager, TorrentState
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
class TestTorrent(BaseTestCase):
|
||||||
class TorrentTestCase(BaseTestCase):
|
|
||||||
def setup_config(self):
|
def setup_config(self):
|
||||||
config_dir = common.set_tmp_config_dir()
|
|
||||||
core_config = deluge.config.Config(
|
core_config = deluge.config.Config(
|
||||||
'core.conf',
|
'core.conf',
|
||||||
defaults=deluge.core.preferencesmanager.DEFAULT_PREFS,
|
defaults=deluge.core.preferencesmanager.DEFAULT_PREFS,
|
||||||
config_dir=config_dir,
|
config_dir=self.config_dir,
|
||||||
)
|
)
|
||||||
core_config.save()
|
core_config.save()
|
||||||
|
|
||||||
|
@ -64,7 +62,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
|
|
||||||
def assert_state(self, torrent, state):
|
def assert_state(self, torrent, state):
|
||||||
torrent.update_state()
|
torrent.update_state()
|
||||||
self.assertEqual(torrent.state, state)
|
assert torrent.state == state
|
||||||
|
|
||||||
def get_torrent_atp(self, filename):
|
def get_torrent_atp(self, filename):
|
||||||
filename = common.get_test_data_file(filename)
|
filename = common.get_test_data_file(filename)
|
||||||
|
@ -88,11 +86,11 @@ class TorrentTestCase(BaseTestCase):
|
||||||
torrent = Torrent(handle, {})
|
torrent = Torrent(handle, {})
|
||||||
|
|
||||||
result = torrent.get_file_priorities()
|
result = torrent.get_file_priorities()
|
||||||
self.assertTrue(all(x == 4 for x in result))
|
assert all(x == 4 for x in result)
|
||||||
|
|
||||||
new_priorities = [3, 1, 2, 0, 5, 6, 7]
|
new_priorities = [3, 1, 2, 0, 5, 6, 7]
|
||||||
torrent.set_file_priorities(new_priorities)
|
torrent.set_file_priorities(new_priorities)
|
||||||
self.assertEqual(torrent.get_file_priorities(), new_priorities)
|
assert torrent.get_file_priorities() == new_priorities
|
||||||
|
|
||||||
# Test with handle.piece_priorities as handle.file_priorities async
|
# Test with handle.piece_priorities as handle.file_priorities async
|
||||||
# updates and will return old value. Also need to remove a priority
|
# updates and will return old value. Also need to remove a priority
|
||||||
|
@ -100,7 +98,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
time.sleep(0.6) # Delay to wait for alert from lt
|
time.sleep(0.6) # Delay to wait for alert from lt
|
||||||
piece_prio = handle.piece_priorities()
|
piece_prio = handle.piece_priorities()
|
||||||
result = all(p in piece_prio for p in [3, 2, 0, 5, 6, 7])
|
result = all(p in piece_prio for p in [3, 2, 0, 5, 6, 7])
|
||||||
self.assertTrue(result)
|
assert result
|
||||||
|
|
||||||
def test_set_prioritize_first_last_pieces(self):
|
def test_set_prioritize_first_last_pieces(self):
|
||||||
piece_indexes = [
|
piece_indexes = [
|
||||||
|
@ -145,14 +143,14 @@ class TorrentTestCase(BaseTestCase):
|
||||||
priorities = handle.piece_priorities()
|
priorities = handle.piece_priorities()
|
||||||
|
|
||||||
# The length of the list of new priorites is the same as the original
|
# The length of the list of new priorites is the same as the original
|
||||||
self.assertEqual(len(priorities_original), len(priorities))
|
assert len(priorities_original) == len(priorities)
|
||||||
|
|
||||||
# Test the priority of all the pieces against the calculated indexes.
|
# Test the priority of all the pieces against the calculated indexes.
|
||||||
for idx, priority in enumerate(priorities):
|
for idx, priority in enumerate(priorities):
|
||||||
if idx in prioritized_piece_indexes:
|
if idx in prioritized_piece_indexes:
|
||||||
self.assertEqual(priorities[idx], 7)
|
assert priorities[idx] == 7
|
||||||
else:
|
else:
|
||||||
self.assertEqual(priorities[idx], 4)
|
assert priorities[idx] == 4
|
||||||
|
|
||||||
# self.print_priority_list(priorities)
|
# self.print_priority_list(priorities)
|
||||||
|
|
||||||
|
@ -168,7 +166,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
|
|
||||||
# Test the priority of the prioritized pieces
|
# Test the priority of the prioritized pieces
|
||||||
for i in priorities:
|
for i in priorities:
|
||||||
self.assertEqual(priorities[i], 4)
|
assert priorities[i] == 4
|
||||||
|
|
||||||
# self.print_priority_list(priorities)
|
# self.print_priority_list(priorities)
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
|
|
||||||
def test_torrent_error_resume_data_unaltered(self):
|
def test_torrent_error_resume_data_unaltered(self):
|
||||||
if VersionSplit(lt.__version__) >= VersionSplit('1.2.0.0'):
|
if VersionSplit(lt.__version__) >= VersionSplit('1.2.0.0'):
|
||||||
raise unittest.SkipTest('Test not working as expected on lt 1.2 or greater')
|
pytest.skip('Test not working as expected on lt 1.2 or greater')
|
||||||
|
|
||||||
resume_data = {
|
resume_data = {
|
||||||
'active_time': 13399,
|
'active_time': 13399,
|
||||||
|
@ -277,7 +275,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
tm_resume_data = lt.bdecode(
|
tm_resume_data = lt.bdecode(
|
||||||
self.core.torrentmanager.resume_data[torrent.torrent_id]
|
self.core.torrentmanager.resume_data[torrent.torrent_id]
|
||||||
)
|
)
|
||||||
self.assertEqual(tm_resume_data, resume_data)
|
assert tm_resume_data == resume_data
|
||||||
|
|
||||||
return deferLater(reactor, 0.5, assert_resume_data)
|
return deferLater(reactor, 0.5, assert_resume_data)
|
||||||
|
|
||||||
|
@ -285,7 +283,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
||||||
handle = self.session.add_torrent(atp)
|
handle = self.session.add_torrent(atp)
|
||||||
self.torrent = Torrent(handle, {})
|
self.torrent = Torrent(handle, {})
|
||||||
self.assertEqual(self.torrent.get_eta(), 0)
|
assert self.torrent.get_eta() == 0
|
||||||
self.torrent.status = mock.MagicMock()
|
self.torrent.status = mock.MagicMock()
|
||||||
|
|
||||||
self.torrent.status.upload_payload_rate = 5000
|
self.torrent.status.upload_payload_rate = 5000
|
||||||
|
@ -295,18 +293,18 @@ class TorrentTestCase(BaseTestCase):
|
||||||
self.torrent.is_finished = True
|
self.torrent.is_finished = True
|
||||||
self.torrent.options = {'stop_at_ratio': False}
|
self.torrent.options = {'stop_at_ratio': False}
|
||||||
# Test finished and uploading but no stop_at_ratio set.
|
# Test finished and uploading but no stop_at_ratio set.
|
||||||
self.assertEqual(self.torrent.get_eta(), 0)
|
assert self.torrent.get_eta() == 0
|
||||||
|
|
||||||
self.torrent.options = {'stop_at_ratio': True, 'stop_ratio': 1.5}
|
self.torrent.options = {'stop_at_ratio': True, 'stop_ratio': 1.5}
|
||||||
result = self.torrent.get_eta()
|
result = self.torrent.get_eta()
|
||||||
self.assertEqual(result, 2)
|
assert result == 2
|
||||||
self.assertIsInstance(result, int)
|
assert isinstance(result, int)
|
||||||
|
|
||||||
def test_get_eta_downloading(self):
|
def test_get_eta_downloading(self):
|
||||||
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
||||||
handle = self.session.add_torrent(atp)
|
handle = self.session.add_torrent(atp)
|
||||||
self.torrent = Torrent(handle, {})
|
self.torrent = Torrent(handle, {})
|
||||||
self.assertEqual(self.torrent.get_eta(), 0)
|
assert self.torrent.get_eta() == 0
|
||||||
|
|
||||||
self.torrent.status = mock.MagicMock()
|
self.torrent.status = mock.MagicMock()
|
||||||
self.torrent.status.download_payload_rate = 50
|
self.torrent.status.download_payload_rate = 50
|
||||||
|
@ -314,15 +312,15 @@ class TorrentTestCase(BaseTestCase):
|
||||||
self.torrent.status.total_wanted_done = 5000
|
self.torrent.status.total_wanted_done = 5000
|
||||||
|
|
||||||
result = self.torrent.get_eta()
|
result = self.torrent.get_eta()
|
||||||
self.assertEqual(result, 100)
|
assert result == 100
|
||||||
self.assertIsInstance(result, int)
|
assert isinstance(result, int)
|
||||||
|
|
||||||
def test_get_name_unicode(self):
|
def test_get_name_unicode(self):
|
||||||
"""Test retrieving a unicode torrent name from libtorrent."""
|
"""Test retrieving a unicode torrent name from libtorrent."""
|
||||||
atp = self.get_torrent_atp('unicode_file.torrent')
|
atp = self.get_torrent_atp('unicode_file.torrent')
|
||||||
handle = self.session.add_torrent(atp)
|
handle = self.session.add_torrent(atp)
|
||||||
self.torrent = Torrent(handle, {})
|
self.torrent = Torrent(handle, {})
|
||||||
self.assertEqual(self.torrent.get_name(), 'সুকুমার রায়.txt')
|
assert self.torrent.get_name() == 'সুকুমার রায়.txt'
|
||||||
|
|
||||||
def test_rename_unicode(self):
|
def test_rename_unicode(self):
|
||||||
"""Test renaming file/folders with unicode filenames."""
|
"""Test renaming file/folders with unicode filenames."""
|
||||||
|
@ -333,15 +331,15 @@ class TorrentTestCase(BaseTestCase):
|
||||||
TorrentManager.save_resume_data = mock.MagicMock
|
TorrentManager.save_resume_data = mock.MagicMock
|
||||||
|
|
||||||
result = self.torrent.rename_folder('unicode_filenames', 'Горбачёв')
|
result = self.torrent.rename_folder('unicode_filenames', 'Горбачёв')
|
||||||
self.assertIsInstance(result, defer.DeferredList)
|
assert isinstance(result, defer.DeferredList)
|
||||||
|
|
||||||
result = self.torrent.rename_files([[0, 'new_рбачёв']])
|
result = self.torrent.rename_files([[0, 'new_рбачёв']])
|
||||||
self.assertIsNone(result)
|
assert result is None
|
||||||
|
|
||||||
def test_connect_peer_port(self):
|
def test_connect_peer_port(self):
|
||||||
"""Test to ensure port is int for libtorrent"""
|
"""Test to ensure port is int for libtorrent"""
|
||||||
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
atp = self.get_torrent_atp('test_torrent.file.torrent')
|
||||||
handle = self.session.add_torrent(atp)
|
handle = self.session.add_torrent(atp)
|
||||||
self.torrent = Torrent(handle, {})
|
self.torrent = Torrent(handle, {})
|
||||||
self.assertFalse(self.torrent.connect_peer('127.0.0.1', 'text'))
|
assert not self.torrent.connect_peer('127.0.0.1', 'text')
|
||||||
self.assertTrue(self.torrent.connect_peer('127.0.0.1', '1234'))
|
assert self.torrent.connect_peer('127.0.0.1', '1234')
|
||||||
|
|
|
@ -11,24 +11,24 @@ from base64 import b64encode
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from twisted.internet import defer, task
|
import pytest_twisted
|
||||||
|
from twisted.internet import task
|
||||||
|
|
||||||
from deluge import component
|
from deluge import component
|
||||||
from deluge.bencode import bencode
|
from deluge.bencode import bencode
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.core.core import Core
|
from deluge.core.core import Core
|
||||||
from deluge.core.rpcserver import RPCServer
|
from deluge.core.rpcserver import RPCServer
|
||||||
from deluge.error import InvalidTorrentError
|
from deluge.error import InvalidTorrentError
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
warnings.filterwarnings('ignore', category=RuntimeWarning)
|
warnings.filterwarnings('ignore', category=RuntimeWarning)
|
||||||
warnings.resetwarnings()
|
warnings.resetwarnings()
|
||||||
|
|
||||||
|
|
||||||
class TorrentmanagerTestCase(BaseTestCase):
|
class TestTorrentmanager(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
self.config_dir = common.set_tmp_config_dir()
|
|
||||||
self.rpcserver = RPCServer(listen=False)
|
self.rpcserver = RPCServer(listen=False)
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
self.core.config.config['lsd'] = False
|
self.core.config.config['lsd'] = False
|
||||||
|
@ -44,7 +44,7 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
|
|
||||||
return component.shutdown().addCallback(on_shutdown)
|
return component.shutdown().addCallback(on_shutdown)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_remove_torrent(self):
|
def test_remove_torrent(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
with open(filename, 'rb') as _file:
|
with open(filename, 'rb') as _file:
|
||||||
|
@ -52,9 +52,9 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
torrent_id = yield self.core.add_torrent_file_async(
|
torrent_id = yield self.core.add_torrent_file_async(
|
||||||
filename, b64encode(filedump), {}
|
filename, b64encode(filedump), {}
|
||||||
)
|
)
|
||||||
self.assertTrue(self.tm.remove(torrent_id, False))
|
assert self.tm.remove(torrent_id, False)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_remove_magnet(self):
|
def test_remove_magnet(self):
|
||||||
"""Test remove magnet before received metadata and delete_copies is True"""
|
"""Test remove magnet before received metadata and delete_copies is True"""
|
||||||
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
|
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
|
||||||
|
@ -62,9 +62,10 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
self.core.config.config['copy_torrent_file'] = True
|
self.core.config.config['copy_torrent_file'] = True
|
||||||
self.core.config.config['del_copy_torrent_file'] = True
|
self.core.config.config['del_copy_torrent_file'] = True
|
||||||
torrent_id = yield self.core.add_torrent_magnet(magnet, options)
|
torrent_id = yield self.core.add_torrent_magnet(magnet, options)
|
||||||
self.assertTrue(self.tm.remove(torrent_id, False))
|
assert self.tm.remove(torrent_id, False)
|
||||||
|
|
||||||
def test_prefetch_metadata(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_prefetch_metadata(self):
|
||||||
from deluge._libtorrent import lt
|
from deluge._libtorrent import lt
|
||||||
|
|
||||||
with open(common.get_test_data_file('test.torrent'), 'rb') as _file:
|
with open(common.get_test_data_file('test.torrent'), 'rb') as _file:
|
||||||
|
@ -114,14 +115,16 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.assertEqual(expected, self.successResultOf(d))
|
assert expected == await d
|
||||||
|
|
||||||
def test_prefetch_metadata_timeout(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_prefetch_metadata_timeout(self):
|
||||||
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
|
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
|
||||||
d = self.tm.prefetch_metadata(magnet, 30)
|
d = self.tm.prefetch_metadata(magnet, 30)
|
||||||
self.clock.advance(30)
|
self.clock.advance(30)
|
||||||
|
result = await d
|
||||||
expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
|
expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', b'')
|
||||||
return d.addCallback(self.assertEqual, expected)
|
assert result == expected
|
||||||
|
|
||||||
@pytest.mark.todo
|
@pytest.mark.todo
|
||||||
def test_remove_torrent_false(self):
|
def test_remove_torrent_false(self):
|
||||||
|
@ -129,9 +132,8 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
common.todo_test(self)
|
common.todo_test(self)
|
||||||
|
|
||||||
def test_remove_invalid_torrent(self):
|
def test_remove_invalid_torrent(self):
|
||||||
self.assertRaises(
|
with pytest.raises(InvalidTorrentError):
|
||||||
InvalidTorrentError, self.tm.remove, 'torrentidthatdoesntexist'
|
self.tm.remove('torrentidthatdoesntexist')
|
||||||
)
|
|
||||||
|
|
||||||
def test_open_state(self):
|
def test_open_state(self):
|
||||||
"""Open a state with a UTF-8 encoded torrent filename."""
|
"""Open a state with a UTF-8 encoded torrent filename."""
|
||||||
|
@ -141,4 +143,4 @@ class TorrentmanagerTestCase(BaseTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
state = self.tm.open_state()
|
state = self.tm.open_state()
|
||||||
self.assertEqual(len(state.torrents), 1)
|
assert len(state.torrents) == 1
|
||||||
|
|
|
@ -8,15 +8,12 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.i18n import setup_translation
|
from deluge.i18n import setup_translation
|
||||||
|
|
||||||
from . import common
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
# Allow running other tests without GTKUI dependencies available
|
# Allow running other tests without GTKUI dependencies available
|
||||||
try:
|
try:
|
||||||
# pylint: disable=ungrouped-imports
|
# pylint: disable=ungrouped-imports
|
||||||
|
@ -37,7 +34,7 @@ setup_translation()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
class TorrentviewTestCase(BaseTestCase):
|
class TestTorrentview(BaseTestCase):
|
||||||
|
|
||||||
default_column_index = [
|
default_column_index = [
|
||||||
'filter',
|
'filter',
|
||||||
|
@ -107,9 +104,8 @@ class TorrentviewTestCase(BaseTestCase):
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
if libs_available is False:
|
if libs_available is False:
|
||||||
raise unittest.SkipTest('GTKUI dependencies not available')
|
pytest.skip('GTKUI dependencies not available')
|
||||||
|
|
||||||
common.set_tmp_config_dir()
|
|
||||||
# MainWindow loads this config file, so lets make sure it contains the defaults
|
# MainWindow loads this config file, so lets make sure it contains the defaults
|
||||||
ConfigManager('gtk3ui.conf', defaults=DEFAULT_PREFS)
|
ConfigManager('gtk3ui.conf', defaults=DEFAULT_PREFS)
|
||||||
self.mainwindow = MainWindow()
|
self.mainwindow = MainWindow()
|
||||||
|
@ -121,36 +117,23 @@ class TorrentviewTestCase(BaseTestCase):
|
||||||
return component.shutdown()
|
return component.shutdown()
|
||||||
|
|
||||||
def test_torrentview_columns(self):
|
def test_torrentview_columns(self):
|
||||||
|
assert self.torrentview.column_index == self.default_column_index
|
||||||
self.assertEqual(
|
assert self.torrentview.liststore_columns == self.default_liststore_columns
|
||||||
self.torrentview.column_index, TorrentviewTestCase.default_column_index
|
assert self.torrentview.columns['Download Folder'].column_indices == [30]
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.liststore_columns,
|
|
||||||
TorrentviewTestCase.default_liststore_columns,
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.columns['Download Folder'].column_indices, [30]
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_add_column(self):
|
def test_add_column(self):
|
||||||
|
|
||||||
# Add a text column
|
# Add a text column
|
||||||
test_col = 'Test column'
|
test_col = 'Test column'
|
||||||
self.torrentview.add_text_column(test_col, status_field=['label'])
|
self.torrentview.add_text_column(test_col, status_field=['label'])
|
||||||
self.assertEqual(
|
assert (
|
||||||
len(self.torrentview.liststore_columns),
|
len(self.torrentview.liststore_columns)
|
||||||
len(TorrentviewTestCase.default_liststore_columns) + 1,
|
== len(self.default_liststore_columns) + 1
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
assert len(self.torrentview.column_index) == len(self.default_column_index) + 1
|
||||||
len(self.torrentview.column_index),
|
assert self.torrentview.column_index[-1] == test_col
|
||||||
len(TorrentviewTestCase.default_column_index) + 1,
|
assert self.torrentview.columns[test_col].column_indices == [33]
|
||||||
)
|
|
||||||
self.assertEqual(self.torrentview.column_index[-1], test_col)
|
|
||||||
self.assertEqual(self.torrentview.columns[test_col].column_indices, [33])
|
|
||||||
|
|
||||||
def test_add_columns(self):
|
def test_add_columns(self):
|
||||||
|
|
||||||
# Add a text column
|
# Add a text column
|
||||||
test_col = 'Test column'
|
test_col = 'Test column'
|
||||||
self.torrentview.add_text_column(test_col, status_field=['label'])
|
self.torrentview.add_text_column(test_col, status_field=['label'])
|
||||||
|
@ -159,50 +142,35 @@ class TorrentviewTestCase(BaseTestCase):
|
||||||
test_col2 = 'Test column2'
|
test_col2 = 'Test column2'
|
||||||
self.torrentview.add_text_column(test_col2, status_field=['label2'])
|
self.torrentview.add_text_column(test_col2, status_field=['label2'])
|
||||||
|
|
||||||
self.assertEqual(
|
assert (
|
||||||
len(self.torrentview.liststore_columns),
|
len(self.torrentview.liststore_columns)
|
||||||
len(TorrentviewTestCase.default_liststore_columns) + 2,
|
== len(self.default_liststore_columns) + 2
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(self.torrentview.column_index),
|
|
||||||
len(TorrentviewTestCase.default_column_index) + 2,
|
|
||||||
)
|
)
|
||||||
|
assert len(self.torrentview.column_index) == len(self.default_column_index) + 2
|
||||||
# test_col
|
# test_col
|
||||||
self.assertEqual(self.torrentview.column_index[-2], test_col)
|
assert self.torrentview.column_index[-2] == test_col
|
||||||
self.assertEqual(self.torrentview.columns[test_col].column_indices, [33])
|
assert self.torrentview.columns[test_col].column_indices == [33]
|
||||||
|
|
||||||
# test_col2
|
# test_col2
|
||||||
self.assertEqual(self.torrentview.column_index[-1], test_col2)
|
assert self.torrentview.column_index[-1] == test_col2
|
||||||
self.assertEqual(self.torrentview.columns[test_col2].column_indices, [34])
|
assert self.torrentview.columns[test_col2].column_indices == [34]
|
||||||
|
|
||||||
def test_remove_column(self):
|
def test_remove_column(self):
|
||||||
|
|
||||||
# Add and remove text column
|
# Add and remove text column
|
||||||
test_col = 'Test column'
|
test_col = 'Test column'
|
||||||
self.torrentview.add_text_column(test_col, status_field=['label'])
|
self.torrentview.add_text_column(test_col, status_field=['label'])
|
||||||
self.torrentview.remove_column(test_col)
|
self.torrentview.remove_column(test_col)
|
||||||
|
|
||||||
self.assertEqual(
|
assert len(self.torrentview.liststore_columns) == len(
|
||||||
len(self.torrentview.liststore_columns),
|
self.default_liststore_columns
|
||||||
len(TorrentviewTestCase.default_liststore_columns),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(self.torrentview.column_index),
|
|
||||||
len(TorrentviewTestCase.default_column_index),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.column_index[-1],
|
|
||||||
TorrentviewTestCase.default_column_index[-1],
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.columns[
|
|
||||||
TorrentviewTestCase.default_column_index[-1]
|
|
||||||
].column_indices,
|
|
||||||
[32],
|
|
||||||
)
|
)
|
||||||
|
assert len(self.torrentview.column_index) == len(self.default_column_index)
|
||||||
|
assert self.torrentview.column_index[-1] == self.default_column_index[-1]
|
||||||
|
assert self.torrentview.columns[
|
||||||
|
self.default_column_index[-1]
|
||||||
|
].column_indices == [32]
|
||||||
|
|
||||||
def test_remove_columns(self):
|
def test_remove_columns(self):
|
||||||
|
|
||||||
# Add two columns
|
# Add two columns
|
||||||
test_col = 'Test column'
|
test_col = 'Test column'
|
||||||
self.torrentview.add_text_column(test_col, status_field=['label'])
|
self.torrentview.add_text_column(test_col, status_field=['label'])
|
||||||
|
@ -211,74 +179,47 @@ class TorrentviewTestCase(BaseTestCase):
|
||||||
|
|
||||||
# Remove test_col
|
# Remove test_col
|
||||||
self.torrentview.remove_column(test_col)
|
self.torrentview.remove_column(test_col)
|
||||||
self.assertEqual(
|
assert (
|
||||||
len(self.torrentview.liststore_columns),
|
len(self.torrentview.liststore_columns)
|
||||||
len(TorrentviewTestCase.default_liststore_columns) + 1,
|
== len(self.default_liststore_columns) + 1
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
assert len(self.torrentview.column_index) == len(self.default_column_index) + 1
|
||||||
len(self.torrentview.column_index),
|
assert self.torrentview.column_index[-1] == test_col2
|
||||||
len(TorrentviewTestCase.default_column_index) + 1,
|
assert self.torrentview.columns[test_col2].column_indices == [33]
|
||||||
)
|
|
||||||
self.assertEqual(self.torrentview.column_index[-1], test_col2)
|
|
||||||
self.assertEqual(self.torrentview.columns[test_col2].column_indices, [33])
|
|
||||||
|
|
||||||
# Remove test_col2
|
# Remove test_col2
|
||||||
self.torrentview.remove_column(test_col2)
|
self.torrentview.remove_column(test_col2)
|
||||||
self.assertEqual(
|
assert len(self.torrentview.liststore_columns) == len(
|
||||||
len(self.torrentview.liststore_columns),
|
self.default_liststore_columns
|
||||||
len(TorrentviewTestCase.default_liststore_columns),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(self.torrentview.column_index),
|
|
||||||
len(TorrentviewTestCase.default_column_index),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.column_index[-1],
|
|
||||||
TorrentviewTestCase.default_column_index[-1],
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.columns[
|
|
||||||
TorrentviewTestCase.default_column_index[-1]
|
|
||||||
].column_indices,
|
|
||||||
[32],
|
|
||||||
)
|
)
|
||||||
|
assert len(self.torrentview.column_index) == len(self.default_column_index)
|
||||||
|
assert self.torrentview.column_index[-1] == self.default_column_index[-1]
|
||||||
|
assert self.torrentview.columns[
|
||||||
|
self.default_column_index[-1]
|
||||||
|
].column_indices == [32]
|
||||||
|
|
||||||
def test_add_remove_column_multiple_types(self):
|
def test_add_remove_column_multiple_types(self):
|
||||||
|
|
||||||
# Add a column with multiple column types
|
# Add a column with multiple column types
|
||||||
test_col3 = 'Test column3'
|
test_col3 = 'Test column3'
|
||||||
self.torrentview.add_progress_column(
|
self.torrentview.add_progress_column(
|
||||||
test_col3, status_field=['progress', 'label3'], col_types=[float, str]
|
test_col3, status_field=['progress', 'label3'], col_types=[float, str]
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
assert (
|
||||||
len(self.torrentview.liststore_columns),
|
len(self.torrentview.liststore_columns)
|
||||||
len(TorrentviewTestCase.default_liststore_columns) + 2,
|
== len(self.default_liststore_columns) + 2
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
assert len(self.torrentview.column_index) == len(self.default_column_index) + 1
|
||||||
len(self.torrentview.column_index),
|
assert self.torrentview.column_index[-1] == test_col3
|
||||||
len(TorrentviewTestCase.default_column_index) + 1,
|
assert self.torrentview.columns[test_col3].column_indices == [33, 34]
|
||||||
)
|
|
||||||
self.assertEqual(self.torrentview.column_index[-1], test_col3)
|
|
||||||
self.assertEqual(self.torrentview.columns[test_col3].column_indices, [33, 34])
|
|
||||||
|
|
||||||
# Remove multiple column-types column
|
# Remove multiple column-types column
|
||||||
self.torrentview.remove_column(test_col3)
|
self.torrentview.remove_column(test_col3)
|
||||||
|
|
||||||
self.assertEqual(
|
assert len(self.torrentview.liststore_columns) == len(
|
||||||
len(self.torrentview.liststore_columns),
|
self.default_liststore_columns
|
||||||
len(TorrentviewTestCase.default_liststore_columns),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(self.torrentview.column_index),
|
|
||||||
len(TorrentviewTestCase.default_column_index),
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.column_index[-1],
|
|
||||||
TorrentviewTestCase.default_column_index[-1],
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self.torrentview.columns[
|
|
||||||
TorrentviewTestCase.default_column_index[-1]
|
|
||||||
].column_indices,
|
|
||||||
[32],
|
|
||||||
)
|
)
|
||||||
|
assert len(self.torrentview.column_index) == len(self.default_column_index)
|
||||||
|
assert self.torrentview.column_index[-1] == self.default_column_index[-1]
|
||||||
|
assert self.torrentview.columns[
|
||||||
|
self.default_column_index[-1]
|
||||||
|
].column_indices == [32]
|
||||||
|
|
|
@ -5,20 +5,20 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.ui.tracker_icons
|
import deluge.ui.tracker_icons
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.ui.tracker_icons import TrackerIcon, TrackerIcons
|
from deluge.ui.tracker_icons import TrackerIcon, TrackerIcons
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
common.set_tmp_config_dir()
|
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.internet
|
@pytest.mark.internet
|
||||||
class TrackerIconsTestCase(BaseTestCase):
|
class TestTrackerIcons(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
# Disable resizing with Pillow for consistency.
|
# Disable resizing with Pillow for consistency.
|
||||||
self.patch(deluge.ui.tracker_icons, 'Image', None)
|
self.patch(deluge.ui.tracker_icons, 'Image', None)
|
||||||
|
@ -27,48 +27,43 @@ class TrackerIconsTestCase(BaseTestCase):
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
return component.shutdown()
|
return component.shutdown()
|
||||||
|
|
||||||
def test_get_deluge_png(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_deluge_png(self):
|
||||||
# Deluge has a png favicon link
|
# Deluge has a png favicon link
|
||||||
icon = TrackerIcon(common.get_test_data_file('deluge.png'))
|
icon = TrackerIcon(common.get_test_data_file('deluge.png'))
|
||||||
d = self.icons.fetch('deluge-torrent.org')
|
result = await self.icons.fetch('deluge-torrent.org')
|
||||||
d.addCallback(self.assertNotIdentical, None)
|
assert result == icon
|
||||||
d.addCallback(self.assertEqual, icon)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_google_ico(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_google_ico(self):
|
||||||
# Google doesn't have any icon links
|
# Google doesn't have any icon links
|
||||||
# So instead we'll grab its favicon.ico
|
# So instead we'll grab its favicon.ico
|
||||||
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
||||||
d = self.icons.fetch('www.google.com')
|
result = await self.icons.fetch('www.google.com')
|
||||||
d.addCallback(self.assertNotIdentical, None)
|
assert result == icon
|
||||||
d.addCallback(self.assertEqual, icon)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_google_ico_hebrew(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_google_ico_hebrew(self):
|
||||||
"""Test that Google.co.il page is read as UTF-8"""
|
"""Test that Google.co.il page is read as UTF-8"""
|
||||||
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
||||||
d = self.icons.fetch('www.google.co.il')
|
result = await self.icons.fetch('www.google.co.il')
|
||||||
d.addCallback(self.assertNotIdentical, None)
|
assert result == icon
|
||||||
d.addCallback(self.assertEqual, icon)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_google_ico_with_redirect(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_google_ico_with_redirect(self):
|
||||||
# google.com redirects to www.google.com
|
# google.com redirects to www.google.com
|
||||||
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
icon = TrackerIcon(common.get_test_data_file('google.ico'))
|
||||||
d = self.icons.fetch('google.com')
|
result = await self.icons.fetch('google.com')
|
||||||
d.addCallback(self.assertNotIdentical, None)
|
assert result == icon
|
||||||
d.addCallback(self.assertEqual, icon)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_seo_svg_with_sni(self):
|
@pytest_twisted.ensureDeferred
|
||||||
|
async def test_get_seo_svg_with_sni(self):
|
||||||
# seo using certificates with SNI support only
|
# seo using certificates with SNI support only
|
||||||
icon = TrackerIcon(common.get_test_data_file('seo.svg'))
|
icon = TrackerIcon(common.get_test_data_file('seo.svg'))
|
||||||
d = self.icons.fetch('www.seo.com')
|
result = await self.icons.fetch('www.seo.com')
|
||||||
d.addCallback(self.assertNotIdentical, None)
|
assert result == icon
|
||||||
d.addCallback(self.assertEqual, icon)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def test_get_empty_string_tracker(self):
|
@pytest_twisted.ensureDeferred
|
||||||
d = self.icons.fetch('')
|
async def test_get_empty_string_tracker(self):
|
||||||
d.addCallback(self.assertIdentical, None)
|
result = await self.icons.fetch('')
|
||||||
return d
|
assert result is None
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
import pytest
|
||||||
import rencode
|
import rencode
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
import deluge.log
|
import deluge.log
|
||||||
from deluge.transfer import DelugeTransferProtocol
|
from deluge.transfer import DelugeTransferProtocol
|
||||||
|
@ -109,8 +109,9 @@ class TransferTestClass(DelugeTransferProtocol):
|
||||||
self.message_received(request)
|
self.message_received(request)
|
||||||
|
|
||||||
|
|
||||||
class DelugeTransferProtocolTestCase(unittest.TestCase):
|
class TestDelugeTransferProtocol:
|
||||||
def setUp(self): # NOQA: N803
|
@pytest.fixture(autouse=True)
|
||||||
|
def set_up(self):
|
||||||
"""
|
"""
|
||||||
The expected messages corresponds to the test messages (msg1, msg2) after they've been processed
|
The expected messages corresponds to the test messages (msg1, msg2) after they've been processed
|
||||||
by DelugeTransferProtocol.send, which means that they've first been encoded with rencode,
|
by DelugeTransferProtocol.send, which means that they've first been encoded with rencode,
|
||||||
|
@ -157,7 +158,7 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
# Get the data as sent by DelugeTransferProtocol
|
# Get the data as sent by DelugeTransferProtocol
|
||||||
messages = self.transfer.get_messages_out_joined()
|
messages = self.transfer.get_messages_out_joined()
|
||||||
base64_encoded = base64.b64encode(messages)
|
base64_encoded = base64.b64encode(messages)
|
||||||
self.assertEqual(base64_encoded, self.msg1_expected_compressed_base64)
|
assert base64_encoded == self.msg1_expected_compressed_base64
|
||||||
|
|
||||||
def test_receive_one_message(self):
|
def test_receive_one_message(self):
|
||||||
"""
|
"""
|
||||||
|
@ -170,7 +171,7 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
# Get the data as sent by DelugeTransferProtocol
|
# Get the data as sent by DelugeTransferProtocol
|
||||||
messages = self.transfer.get_messages_in().pop(0)
|
messages = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(messages))
|
assert rencode.dumps(self.msg1) == rencode.dumps(messages)
|
||||||
|
|
||||||
def test_receive_old_message(self):
|
def test_receive_old_message(self):
|
||||||
"""
|
"""
|
||||||
|
@ -178,9 +179,9 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.transfer.dataReceived(rencode.dumps(self.msg1))
|
self.transfer.dataReceived(rencode.dumps(self.msg1))
|
||||||
self.assertEqual(len(self.transfer.get_messages_in()), 0)
|
assert len(self.transfer.get_messages_in()) == 0
|
||||||
self.assertEqual(self.transfer._message_length, 0)
|
assert self.transfer._message_length == 0
|
||||||
self.assertEqual(len(self.transfer._buffer), 0)
|
assert len(self.transfer._buffer) == 0
|
||||||
|
|
||||||
def test_receive_two_concatenated_messages(self):
|
def test_receive_two_concatenated_messages(self):
|
||||||
"""
|
"""
|
||||||
|
@ -195,9 +196,9 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
|
|
||||||
# Get the data as sent by DelugeTransferProtocol
|
# Get the data as sent by DelugeTransferProtocol
|
||||||
message1 = self.transfer.get_messages_in().pop(0)
|
message1 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message1))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message1)
|
||||||
message2 = self.transfer.get_messages_in().pop(0)
|
message2 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg2), rencode.dumps(message2))
|
assert rencode.dumps(self.msg2) == rencode.dumps(message2)
|
||||||
|
|
||||||
def test_receive_three_messages_in_parts(self):
|
def test_receive_three_messages_in_parts(self):
|
||||||
"""
|
"""
|
||||||
|
@ -234,17 +235,15 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
expected_msgs_received_count = 0
|
expected_msgs_received_count = 0
|
||||||
# Verify that the expected number of complete messages has arrived
|
# Verify that the expected number of complete messages has arrived
|
||||||
self.assertEqual(
|
assert expected_msgs_received_count == len(self.transfer.get_messages_in())
|
||||||
expected_msgs_received_count, len(self.transfer.get_messages_in())
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get the data as received by DelugeTransferProtocol
|
# Get the data as received by DelugeTransferProtocol
|
||||||
message1 = self.transfer.get_messages_in().pop(0)
|
message1 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message1))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message1)
|
||||||
message2 = self.transfer.get_messages_in().pop(0)
|
message2 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg2), rencode.dumps(message2))
|
assert rencode.dumps(self.msg2) == rencode.dumps(message2)
|
||||||
message3 = self.transfer.get_messages_in().pop(0)
|
message3 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message3))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message3)
|
||||||
|
|
||||||
# Remove underscore to enable test, or run the test directly:
|
# Remove underscore to enable test, or run the test directly:
|
||||||
# tests $ trial test_transfer.DelugeTransferProtocolTestCase._test_rencode_fail_protocol
|
# tests $ trial test_transfer.DelugeTransferProtocolTestCase._test_rencode_fail_protocol
|
||||||
|
@ -314,11 +313,11 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
|
|
||||||
# Get the data as received by DelugeTransferProtocol
|
# Get the data as received by DelugeTransferProtocol
|
||||||
message1 = self.transfer.get_messages_in().pop(0)
|
message1 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message1))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message1)
|
||||||
message2 = self.transfer.get_messages_in().pop(0)
|
message2 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg2), rencode.dumps(message2))
|
assert rencode.dumps(self.msg2) == rencode.dumps(message2)
|
||||||
message3 = self.transfer.get_messages_in().pop(0)
|
message3 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message3))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message3)
|
||||||
|
|
||||||
def test_receive_middle_of_header(self):
|
def test_receive_middle_of_header(self):
|
||||||
"""
|
"""
|
||||||
|
@ -341,19 +340,19 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
|
||||||
self.transfer.dataReceived(two_concatenated[: first_len + 2])
|
self.transfer.dataReceived(two_concatenated[: first_len + 2])
|
||||||
|
|
||||||
# Should be 1 message in the list
|
# Should be 1 message in the list
|
||||||
self.assertEqual(1, len(self.transfer.get_messages_in()))
|
assert 1 == len(self.transfer.get_messages_in())
|
||||||
|
|
||||||
# Send the rest
|
# Send the rest
|
||||||
self.transfer.dataReceived(two_concatenated[first_len + 2 :])
|
self.transfer.dataReceived(two_concatenated[first_len + 2 :])
|
||||||
|
|
||||||
# Should be 2 messages in the list
|
# Should be 2 messages in the list
|
||||||
self.assertEqual(2, len(self.transfer.get_messages_in()))
|
assert 2 == len(self.transfer.get_messages_in())
|
||||||
|
|
||||||
# Get the data as sent by DelugeTransferProtocol
|
# Get the data as sent by DelugeTransferProtocol
|
||||||
message1 = self.transfer.get_messages_in().pop(0)
|
message1 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg1), rencode.dumps(message1))
|
assert rencode.dumps(self.msg1) == rencode.dumps(message1)
|
||||||
message2 = self.transfer.get_messages_in().pop(0)
|
message2 = self.transfer.get_messages_in().pop(0)
|
||||||
self.assertEqual(rencode.dumps(self.msg2), rencode.dumps(message2))
|
assert rencode.dumps(self.msg2) == rencode.dumps(message2)
|
||||||
|
|
||||||
# Needs file containing big data structure e.g. like thetorrent list as it is transfered by the daemon
|
# Needs file containing big data structure e.g. like thetorrent list as it is transfered by the daemon
|
||||||
# def test_simulate_big_transfer(self):
|
# def test_simulate_big_transfer(self):
|
||||||
|
|
|
@ -5,26 +5,19 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
from deluge.ui.common import TorrentInfo
|
from deluge.ui.common import TorrentInfo
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
|
|
||||||
|
|
||||||
class UICommonTestCase(unittest.TestCase):
|
class TestUICommon:
|
||||||
def setUp(self): # NOQA: N803
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self): # NOQA: N803
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_hash_optional_single_file(self):
|
def test_hash_optional_single_file(self):
|
||||||
"""Ensure single file with `ed2k` and `sha1` keys are not in filetree output."""
|
"""Ensure single file with `ed2k` and `sha1` keys are not in filetree output."""
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
files_tree = {'azcvsupdater_2.6.2.jar': (0, 307949, True)}
|
files_tree = {'azcvsupdater_2.6.2.jar': (0, 307949, True)}
|
||||||
ti = TorrentInfo(filename, filetree=1)
|
ti = TorrentInfo(filename, filetree=1)
|
||||||
self.assertEqual(ti.files_tree, files_tree)
|
assert ti.files_tree == files_tree
|
||||||
|
|
||||||
files_tree2 = {
|
files_tree2 = {
|
||||||
'contents': {
|
'contents': {
|
||||||
|
@ -37,7 +30,7 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ti = TorrentInfo(filename, filetree=2)
|
ti = TorrentInfo(filename, filetree=2)
|
||||||
self.assertEqual(ti.files_tree, files_tree2)
|
assert ti.files_tree == files_tree2
|
||||||
|
|
||||||
def test_hash_optional_multi_file(self):
|
def test_hash_optional_multi_file(self):
|
||||||
"""Ensure multi-file with `filehash` and `ed2k` are keys not in filetree output."""
|
"""Ensure multi-file with `filehash` and `ed2k` are keys not in filetree output."""
|
||||||
|
@ -49,7 +42,7 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ti = TorrentInfo(filename, filetree=1)
|
ti = TorrentInfo(filename, filetree=1)
|
||||||
self.assertEqual(ti.files_tree, files_tree)
|
assert ti.files_tree == files_tree
|
||||||
|
|
||||||
filestree2 = {
|
filestree2 = {
|
||||||
'contents': {
|
'contents': {
|
||||||
|
@ -78,14 +71,14 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
'type': 'dir',
|
'type': 'dir',
|
||||||
}
|
}
|
||||||
ti = TorrentInfo(filename, filetree=2)
|
ti = TorrentInfo(filename, filetree=2)
|
||||||
self.assertEqual(ti.files_tree, filestree2)
|
assert ti.files_tree == filestree2
|
||||||
|
|
||||||
def test_hash_optional_md5sum(self):
|
def test_hash_optional_md5sum(self):
|
||||||
# Ensure `md5sum` key is not included in filetree output
|
# Ensure `md5sum` key is not included in filetree output
|
||||||
filename = common.get_test_data_file('md5sum.torrent')
|
filename = common.get_test_data_file('md5sum.torrent')
|
||||||
files_tree = {'test': {'lol': (0, 4, True), 'rofl': (1, 5, True)}}
|
files_tree = {'test': {'lol': (0, 4, True), 'rofl': (1, 5, True)}}
|
||||||
ti = TorrentInfo(filename, filetree=1)
|
ti = TorrentInfo(filename, filetree=1)
|
||||||
self.assertEqual(ti.files_tree, files_tree)
|
assert ti.files_tree == files_tree
|
||||||
ti = TorrentInfo(filename, filetree=2)
|
ti = TorrentInfo(filename, filetree=2)
|
||||||
files_tree2 = {
|
files_tree2 = {
|
||||||
'contents': {
|
'contents': {
|
||||||
|
@ -113,12 +106,12 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
},
|
},
|
||||||
'type': 'dir',
|
'type': 'dir',
|
||||||
}
|
}
|
||||||
self.assertEqual(ti.files_tree, files_tree2)
|
assert ti.files_tree == files_tree2
|
||||||
|
|
||||||
def test_utf8_encoded_paths(self):
|
def test_utf8_encoded_paths(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
ti = TorrentInfo(filename)
|
ti = TorrentInfo(filename)
|
||||||
self.assertTrue('azcvsupdater_2.6.2.jar' in ti.files_tree)
|
assert 'azcvsupdater_2.6.2.jar' in ti.files_tree
|
||||||
|
|
||||||
def test_utf8_encoded_paths2(self):
|
def test_utf8_encoded_paths2(self):
|
||||||
filename = common.get_test_data_file('unicode_filenames.torrent')
|
filename = common.get_test_data_file('unicode_filenames.torrent')
|
||||||
|
@ -133,11 +126,11 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
|
|
||||||
ti = TorrentInfo(filename)
|
ti = TorrentInfo(filename)
|
||||||
files_tree = ti.files_tree['unicode_filenames']
|
files_tree = ti.files_tree['unicode_filenames']
|
||||||
self.assertIn(filepath1, files_tree)
|
assert filepath1 in files_tree
|
||||||
self.assertIn(filepath2, files_tree)
|
assert filepath2 in files_tree
|
||||||
self.assertIn(filepath3, files_tree)
|
assert filepath3 in files_tree
|
||||||
self.assertIn(filepath4, files_tree)
|
assert filepath4 in files_tree
|
||||||
self.assertIn(filepath5, files_tree)
|
assert filepath5 in files_tree
|
||||||
|
|
||||||
result_files = [
|
result_files = [
|
||||||
{
|
{
|
||||||
|
@ -163,4 +156,4 @@ class UICommonTestCase(unittest.TestCase):
|
||||||
{'download': True, 'path': 'unicode_filenames/' + filepath1, 'size': 1771},
|
{'download': True, 'path': 'unicode_filenames/' + filepath1, 'size': 1771},
|
||||||
]
|
]
|
||||||
|
|
||||||
self.assertCountEqual(ti.files, result_files)
|
assert len(ti.files) == len(result_files)
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from deluge.ui.console.cmdline.commands.add import Command
|
from deluge.ui.console.cmdline.commands.add import Command
|
||||||
from deluge.ui.console.cmdline.commands.config import json_eval
|
from deluge.ui.console.cmdline.commands.config import json_eval
|
||||||
from deluge.ui.console.widgets.fields import TextInput
|
from deluge.ui.console.widgets.fields import TextInput
|
||||||
|
|
||||||
from .basetest import BaseTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class MockParent:
|
class MockParent:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -20,13 +20,11 @@ class MockParent:
|
||||||
self.encoding = 'utf8'
|
self.encoding = 'utf8'
|
||||||
|
|
||||||
|
|
||||||
class UIConsoleFieldTestCase(BaseTestCase):
|
class TestUIConsoleField:
|
||||||
def setUp(self): # NOQA: N803
|
@pytest.fixture(autouse=True)
|
||||||
|
def set_up(self):
|
||||||
self.parent = MockParent()
|
self.parent = MockParent()
|
||||||
|
|
||||||
def tearDown(self): # NOQA: N803
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_text_input(self):
|
def test_text_input(self):
|
||||||
def move_func(self, r, c):
|
def move_func(self, r, c):
|
||||||
self._cursor_row = r
|
self._cursor_row = r
|
||||||
|
@ -41,48 +39,42 @@ class UIConsoleFieldTestCase(BaseTestCase):
|
||||||
'/text/field/file/path',
|
'/text/field/file/path',
|
||||||
complete=False,
|
complete=False,
|
||||||
)
|
)
|
||||||
self.assertTrue(t)
|
assert t
|
||||||
self.assertTrue(t.handle_read(33))
|
assert t.handle_read(33)
|
||||||
|
|
||||||
|
|
||||||
class UIConsoleCommandsTestCase(BaseTestCase):
|
class TestUIConsoleCommands:
|
||||||
def setUp(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_add_move_completed(self):
|
def test_add_move_completed(self):
|
||||||
completed_path = 'completed_path'
|
completed_path = 'completed_path'
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
cmd.add_arguments(parser)
|
cmd.add_arguments(parser)
|
||||||
args = parser.parse_args(['torrent', '-m', completed_path])
|
args = parser.parse_args(['torrent', '-m', completed_path])
|
||||||
self.assertEqual(args.move_completed_path, completed_path)
|
assert args.move_completed_path == completed_path
|
||||||
args = parser.parse_args(['torrent', '--move-path', completed_path])
|
args = parser.parse_args(['torrent', '--move-path', completed_path])
|
||||||
self.assertEqual(args.move_completed_path, completed_path)
|
assert args.move_completed_path == completed_path
|
||||||
|
|
||||||
def test_config_json_eval(self):
|
def test_config_json_eval(self):
|
||||||
self.assertEqual(json_eval('/downloads'), '/downloads')
|
assert json_eval('/downloads') == '/downloads'
|
||||||
self.assertEqual(json_eval('/dir/with space'), '/dir/with space')
|
assert json_eval('/dir/with space') == '/dir/with space'
|
||||||
self.assertEqual(json_eval('c:\\\\downloads'), 'c:\\\\downloads')
|
assert json_eval('c:\\\\downloads') == 'c:\\\\downloads'
|
||||||
self.assertEqual(json_eval('c:/downloads'), 'c:/downloads')
|
assert json_eval('c:/downloads') == 'c:/downloads'
|
||||||
# Ensure newlines are split and only first setting is used.
|
# Ensure newlines are split and only first setting is used.
|
||||||
self.assertEqual(json_eval('setting\nwithneline'), 'setting')
|
assert json_eval('setting\nwithneline') == 'setting'
|
||||||
# Allow both parentheses and square brackets.
|
# Allow both parentheses and square brackets.
|
||||||
self.assertEqual(json_eval('(8000, 8001)'), [8000, 8001])
|
assert json_eval('(8000, 8001)') == [8000, 8001]
|
||||||
self.assertEqual(json_eval('[8000, 8001]'), [8000, 8001])
|
assert json_eval('[8000, 8001]') == [8000, 8001]
|
||||||
self.assertEqual(json_eval('["abc", "def"]'), ['abc', 'def'])
|
assert json_eval('["abc", "def"]') == ['abc', 'def']
|
||||||
self.assertEqual(json_eval('{"foo": "bar"}'), {'foo': 'bar'})
|
assert json_eval('{"foo": "bar"}') == {'foo': 'bar'}
|
||||||
self.assertEqual(json_eval('{"number": 1234}'), {'number': 1234})
|
assert json_eval('{"number": 1234}') == {'number': 1234}
|
||||||
# Hex string for peer_tos.
|
# Hex string for peer_tos.
|
||||||
self.assertEqual(json_eval('0x00'), '0x00')
|
assert json_eval('0x00') == '0x00'
|
||||||
self.assertEqual(json_eval('1000'), 1000)
|
assert json_eval('1000') == 1000
|
||||||
self.assertEqual(json_eval('-6'), -6)
|
assert json_eval('-6') == -6
|
||||||
self.assertEqual(json_eval('10.5'), 10.5)
|
assert json_eval('10.5') == 10.5
|
||||||
self.assertEqual(json_eval('True'), True)
|
assert json_eval('True')
|
||||||
self.assertEqual(json_eval('false'), False)
|
assert not json_eval('false')
|
||||||
self.assertEqual(json_eval('none'), None)
|
assert json_eval('none') is None
|
||||||
# Empty values to clear config key.
|
# Empty values to clear config key.
|
||||||
self.assertEqual(json_eval('[]'), [])
|
assert json_eval('[]') == []
|
||||||
self.assertEqual(json_eval(''), '')
|
assert json_eval('') == ''
|
||||||
|
|
|
@ -12,6 +12,7 @@ from io import StringIO
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
import deluge
|
import deluge
|
||||||
|
@ -21,11 +22,11 @@ import deluge.ui.console.cmdline.commands.quit
|
||||||
import deluge.ui.console.main
|
import deluge.ui.console.main
|
||||||
import deluge.ui.web.server
|
import deluge.ui.web.server
|
||||||
from deluge.common import get_localhost_auth, windows_check
|
from deluge.common import get_localhost_auth, windows_check
|
||||||
|
from deluge.conftest import BaseTestCase
|
||||||
from deluge.ui import ui_entry
|
from deluge.ui import ui_entry
|
||||||
from deluge.ui.web.server import DelugeWeb
|
from deluge.ui.web.server import DelugeWeb
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .basetest import BaseTestCase
|
|
||||||
from .daemon_base import DaemonBase
|
from .daemon_base import DaemonBase
|
||||||
|
|
||||||
DEBUG_COMMAND = False
|
DEBUG_COMMAND = False
|
||||||
|
@ -56,11 +57,7 @@ class StringFileDescriptor:
|
||||||
|
|
||||||
|
|
||||||
class UIBaseTestCase:
|
class UIBaseTestCase:
|
||||||
def __init__(self):
|
|
||||||
self.var = {}
|
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
common.set_tmp_config_dir()
|
|
||||||
common.setup_test_logger(level='info', prefix=self.id())
|
common.setup_test_logger(level='info', prefix=self.id())
|
||||||
return component.start()
|
return component.start()
|
||||||
|
|
||||||
|
@ -76,24 +73,14 @@ class UIBaseTestCase:
|
||||||
class UIWithDaemonBaseTestCase(UIBaseTestCase, DaemonBase):
|
class UIWithDaemonBaseTestCase(UIBaseTestCase, DaemonBase):
|
||||||
"""Subclass for test that require a deluged daemon"""
|
"""Subclass for test that require a deluged daemon"""
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
UIBaseTestCase.__init__(self)
|
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
d = self.common_set_up()
|
d = self.common_set_up()
|
||||||
common.setup_test_logger(level='info', prefix=self.id())
|
common.setup_test_logger(level='info', prefix=self.id())
|
||||||
d.addCallback(self.start_core)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
d = UIBaseTestCase.tear_down(self)
|
|
||||||
d.addCallback(self.terminate_core)
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
class DelugeEntryTestCase(BaseTestCase):
|
class TestDelugeEntry(BaseTestCase):
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
common.set_tmp_config_dir()
|
|
||||||
return component.start()
|
return component.start()
|
||||||
|
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
|
@ -109,10 +96,11 @@ class DelugeEntryTestCase(BaseTestCase):
|
||||||
self.patch(argparse._sys, 'stdout', fd)
|
self.patch(argparse._sys, 'stdout', fd)
|
||||||
|
|
||||||
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
||||||
self.assertRaises(SystemExit, ui_entry.start_ui)
|
with pytest.raises(SystemExit):
|
||||||
self.assertTrue('usage: deluge' in fd.out.getvalue())
|
ui_entry.start_ui()
|
||||||
self.assertTrue('UI Options:' in fd.out.getvalue())
|
assert 'usage: deluge' in fd.out.getvalue()
|
||||||
self.assertTrue('* console' in fd.out.getvalue())
|
assert 'UI Options:' in fd.out.getvalue()
|
||||||
|
assert '* console' in fd.out.getvalue()
|
||||||
|
|
||||||
def test_start_default(self):
|
def test_start_default(self):
|
||||||
self.patch(sys, 'argv', ['./deluge'])
|
self.patch(sys, 'argv', ['./deluge'])
|
||||||
|
@ -147,17 +135,12 @@ class DelugeEntryTestCase(BaseTestCase):
|
||||||
# Just test that no exception is raised
|
# Just test that no exception is raised
|
||||||
ui_entry.start_ui()
|
ui_entry.start_ui()
|
||||||
|
|
||||||
self.assertEqual(_level[0], 'info')
|
assert _level[0] == 'info'
|
||||||
|
|
||||||
|
|
||||||
class GtkUIBaseTestCase(UIBaseTestCase):
|
class GtkUIBaseTestCase(UIBaseTestCase):
|
||||||
"""Implement all GtkUI tests here"""
|
"""Implement all GtkUI tests here"""
|
||||||
|
|
||||||
if windows_check():
|
|
||||||
skip = (
|
|
||||||
'Gtk tests on Windows have some issue with the mutex already being created'
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_start_gtk3ui(self):
|
def test_start_gtk3ui(self):
|
||||||
self.patch(sys, 'argv', self.var['sys_arg_cmd'])
|
self.patch(sys, 'argv', self.var['sys_arg_cmd'])
|
||||||
|
|
||||||
|
@ -168,38 +151,27 @@ class GtkUIBaseTestCase(UIBaseTestCase):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
class GtkUIDelugeScriptEntryTestCase(BaseTestCase, GtkUIBaseTestCase):
|
class TestGtkUIDelugeScriptEntry(BaseTestCase, GtkUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
GtkUIBaseTestCase.__init__(self)
|
request.cls.var = {
|
||||||
|
'cmd_name': 'deluge gtk',
|
||||||
self.var['cmd_name'] = 'deluge gtk'
|
'start_cmd': ui_entry.start_ui,
|
||||||
self.var['start_cmd'] = ui_entry.start_ui
|
'sys_arg_cmd': ['./deluge', 'gtk'],
|
||||||
self.var['sys_arg_cmd'] = ['./deluge', 'gtk']
|
}
|
||||||
|
|
||||||
def set_up(self):
|
|
||||||
return GtkUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return GtkUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
class GtkUIScriptEntryTestCase(BaseTestCase, GtkUIBaseTestCase):
|
class TestGtkUIScriptEntry(BaseTestCase, GtkUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
GtkUIBaseTestCase.__init__(self)
|
|
||||||
from deluge.ui import gtk3
|
from deluge.ui import gtk3
|
||||||
|
|
||||||
self.var['cmd_name'] = 'deluge-gtk'
|
request.cls.var = {
|
||||||
self.var['start_cmd'] = gtk3.start
|
'cmd_name': 'deluge-gtk',
|
||||||
self.var['sys_arg_cmd'] = ['./deluge-gtk']
|
'start_cmd': gtk3.start,
|
||||||
|
'sys_arg_cmd': ['./deluge-gtk'],
|
||||||
def set_up(self):
|
}
|
||||||
return GtkUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return GtkUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
class DelugeWebMock(DelugeWeb):
|
class DelugeWebMock(DelugeWeb):
|
||||||
|
@ -237,41 +209,31 @@ class WebUIBaseTestCase(UIBaseTestCase):
|
||||||
|
|
||||||
self.patch(deluge.ui.web.server, 'DelugeWeb', DelugeWebMock)
|
self.patch(deluge.ui.web.server, 'DelugeWeb', DelugeWebMock)
|
||||||
self.exec_command()
|
self.exec_command()
|
||||||
self.assertEqual(_level[0], 'info')
|
assert _level[0] == 'info'
|
||||||
|
|
||||||
|
|
||||||
class WebUIScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
|
class TestWebUIScriptEntry(BaseTestCase, WebUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
WebUIBaseTestCase.__init__(self)
|
request.cls.var = {
|
||||||
self.var['cmd_name'] = 'deluge-web'
|
'cmd_name': 'deluge-web',
|
||||||
self.var['start_cmd'] = deluge.ui.web.start
|
'start_cmd': deluge.ui.web.start,
|
||||||
self.var['sys_arg_cmd'] = ['./deluge-web']
|
'sys_arg_cmd': ['./deluge-web'],
|
||||||
|
}
|
||||||
if not windows_check():
|
if not windows_check():
|
||||||
self.var['sys_arg_cmd'].append('--do-not-daemonize')
|
request.cls.var['sys_arg_cmd'].append('--do-not-daemonize')
|
||||||
|
|
||||||
def set_up(self):
|
|
||||||
return WebUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return WebUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
class WebUIDelugeScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
|
class TestWebUIDelugeScriptEntry(BaseTestCase, WebUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
WebUIBaseTestCase.__init__(self)
|
request.cls.var = {
|
||||||
self.var['cmd_name'] = 'deluge web'
|
'cmd_name': 'deluge web',
|
||||||
self.var['start_cmd'] = ui_entry.start_ui
|
'start_cmd': ui_entry.start_ui,
|
||||||
self.var['sys_arg_cmd'] = ['./deluge', 'web']
|
'sys_arg_cmd': ['./deluge', 'web'],
|
||||||
|
}
|
||||||
if not windows_check():
|
if not windows_check():
|
||||||
self.var['sys_arg_cmd'].append('--do-not-daemonize')
|
request.cls.var['sys_arg_cmd'].append('--do-not-daemonize')
|
||||||
|
|
||||||
def set_up(self):
|
|
||||||
return WebUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return WebUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleUIBaseTestCase(UIBaseTestCase):
|
class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
|
@ -282,7 +244,7 @@ class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
||||||
self.exec_command()
|
self.exec_command()
|
||||||
|
|
||||||
def test_start_console_with_log_level(self):
|
def test_start_console_with_log_level(self, request):
|
||||||
_level = []
|
_level = []
|
||||||
|
|
||||||
def setup_logger(
|
def setup_logger(
|
||||||
|
@ -305,7 +267,7 @@ class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
# Just test that no exception is raised
|
# Just test that no exception is raised
|
||||||
self.exec_command()
|
self.exec_command()
|
||||||
|
|
||||||
self.assertEqual(_level[0], 'info')
|
assert _level[0] == 'info'
|
||||||
|
|
||||||
def test_console_help(self):
|
def test_console_help(self):
|
||||||
self.patch(sys, 'argv', self.var['sys_arg_cmd'] + ['-h'])
|
self.patch(sys, 'argv', self.var['sys_arg_cmd'] + ['-h'])
|
||||||
|
@ -313,18 +275,19 @@ class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
self.patch(argparse._sys, 'stdout', fd)
|
self.patch(argparse._sys, 'stdout', fd)
|
||||||
|
|
||||||
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
||||||
self.assertRaises(SystemExit, self.exec_command)
|
with pytest.raises(SystemExit):
|
||||||
|
self.exec_command()
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue(
|
assert (
|
||||||
('usage: %s' % self.var['cmd_name']) in std_output
|
'usage: %s' % self.var['cmd_name']
|
||||||
) # Check command name
|
) in std_output # Check command name
|
||||||
self.assertTrue('Common Options:' in std_output)
|
assert 'Common Options:' in std_output
|
||||||
self.assertTrue('Console Options:' in std_output)
|
assert 'Console Options:' in std_output
|
||||||
self.assertIn(
|
assert (
|
||||||
'Console Commands:\n The following console commands are available:',
|
'Console Commands:\n The following console commands are available:'
|
||||||
std_output,
|
in std_output
|
||||||
)
|
)
|
||||||
self.assertIn('The following console commands are available:', std_output)
|
assert 'The following console commands are available:' in std_output
|
||||||
|
|
||||||
def test_console_command_info(self):
|
def test_console_command_info(self):
|
||||||
self.patch(sys, 'argv', self.var['sys_arg_cmd'] + ['info'])
|
self.patch(sys, 'argv', self.var['sys_arg_cmd'] + ['info'])
|
||||||
|
@ -340,10 +303,11 @@ class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
self.patch(argparse._sys, 'stdout', fd)
|
self.patch(argparse._sys, 'stdout', fd)
|
||||||
|
|
||||||
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
||||||
self.assertRaises(SystemExit, self.exec_command)
|
with pytest.raises(SystemExit):
|
||||||
|
self.exec_command()
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertIn('usage: info', std_output)
|
assert 'usage: info' in std_output
|
||||||
self.assertIn('Show information about the torrents', std_output)
|
assert 'Show information about the torrents' in std_output
|
||||||
|
|
||||||
def test_console_unrecognized_arguments(self):
|
def test_console_unrecognized_arguments(self):
|
||||||
self.patch(
|
self.patch(
|
||||||
|
@ -352,8 +316,9 @@ class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
fd = StringFileDescriptor(sys.stdout)
|
fd = StringFileDescriptor(sys.stdout)
|
||||||
self.patch(argparse._sys, 'stderr', fd)
|
self.patch(argparse._sys, 'stderr', fd)
|
||||||
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
with mock.patch('deluge.ui.console.main.ConsoleUI'):
|
||||||
self.assertRaises(SystemExit, self.exec_command)
|
with pytest.raises(SystemExit):
|
||||||
self.assertIn('unrecognized arguments: --ui', fd.out.getvalue())
|
self.exec_command()
|
||||||
|
assert 'unrecognized arguments: --ui' in fd.out.getvalue()
|
||||||
|
|
||||||
|
|
||||||
class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
||||||
|
@ -381,7 +346,7 @@ class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
||||||
+ command,
|
+ command,
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_console_command_add(self):
|
def test_console_command_add(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
self.patch_arg_command([f'add "{filename}"'])
|
self.patch_arg_command([f'add "{filename}"'])
|
||||||
|
@ -391,11 +356,12 @@ class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
||||||
yield self.exec_command()
|
yield self.exec_command()
|
||||||
|
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertEqual(
|
assert (
|
||||||
std_output, 'Attempting to add torrent: ' + filename + '\nTorrent added!\n'
|
std_output
|
||||||
|
== 'Attempting to add torrent: ' + filename + '\nTorrent added!\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_console_command_add_move_completed(self):
|
def test_console_command_add_move_completed(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
tmp_path = 'c:\\tmp' if windows_check() else '/tmp'
|
tmp_path = 'c:\\tmp' if windows_check() else '/tmp'
|
||||||
|
@ -414,26 +380,23 @@ class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
||||||
yield self.exec_command()
|
yield self.exec_command()
|
||||||
|
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue(
|
assert std_output.endswith(
|
||||||
std_output.endswith(
|
|
||||||
f'move_completed: True\nmove_completed_path: {tmp_path}\n'
|
f'move_completed: True\nmove_completed_path: {tmp_path}\n'
|
||||||
)
|
) or std_output.endswith(
|
||||||
or std_output.endswith(
|
|
||||||
f'move_completed_path: {tmp_path}\nmove_completed: True\n'
|
f'move_completed_path: {tmp_path}\nmove_completed: True\n'
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.ensureDeferred
|
||||||
def test_console_command_status(self):
|
async def test_console_command_status(self):
|
||||||
fd = StringFileDescriptor(sys.stdout)
|
fd = StringFileDescriptor(sys.stdout)
|
||||||
self.patch_arg_command(['status'])
|
self.patch_arg_command(['status'])
|
||||||
self.patch(sys, 'stdout', fd)
|
self.patch(sys, 'stdout', fd)
|
||||||
|
|
||||||
yield self.exec_command()
|
await self.exec_command()
|
||||||
|
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue(std_output.startswith('Total upload: '))
|
assert std_output.startswith('Total upload: ')
|
||||||
self.assertTrue(std_output.endswith(' Moving: 0\n'))
|
assert std_output.endswith(' Moving: 0\n')
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def test_console_command_config_set_download_location(self):
|
def test_console_command_config_set_download_location(self):
|
||||||
|
@ -443,63 +406,36 @@ class ConsoleUIWithDaemonBaseTestCase(UIWithDaemonBaseTestCase):
|
||||||
|
|
||||||
yield self.exec_command()
|
yield self.exec_command()
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue(
|
assert std_output.startswith('Setting "download_location" to: \'/downloads\'')
|
||||||
std_output.startswith('Setting "download_location" to: \'/downloads\'')
|
assert std_output.endswith('Configuration value successfully updated.\n')
|
||||||
)
|
|
||||||
self.assertTrue(
|
|
||||||
std_output.endswith('Configuration value successfully updated.\n')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleScriptEntryWithDaemonTestCase(
|
@pytest.mark.usefixtures('daemon', 'client')
|
||||||
BaseTestCase, ConsoleUIWithDaemonBaseTestCase
|
class TestConsoleScriptEntryWithDaemon(BaseTestCase, ConsoleUIWithDaemonBaseTestCase):
|
||||||
):
|
@pytest.fixture(autouse=True)
|
||||||
def __init__(self, testname):
|
def set_var(self, request):
|
||||||
super().__init__(testname)
|
request.cls.var = {
|
||||||
ConsoleUIWithDaemonBaseTestCase.__init__(self)
|
'cmd_name': 'deluge-console',
|
||||||
self.var['cmd_name'] = 'deluge-console'
|
'start_cmd': deluge.ui.console.start,
|
||||||
self.var['sys_arg_cmd'] = ['./deluge-console']
|
'sys_arg_cmd': ['./deluge-console'],
|
||||||
|
}
|
||||||
def set_up(self):
|
|
||||||
from deluge.ui.console.console import Console
|
|
||||||
|
|
||||||
def start_console():
|
|
||||||
return Console().start()
|
|
||||||
|
|
||||||
self.patch(deluge.ui.console, 'start', start_console)
|
|
||||||
self.var['start_cmd'] = deluge.ui.console.start
|
|
||||||
|
|
||||||
return ConsoleUIWithDaemonBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return ConsoleUIWithDaemonBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleScriptEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
class TestConsoleScriptEntry(BaseTestCase, ConsoleUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
ConsoleUIBaseTestCase.__init__(self)
|
request.cls.var = {
|
||||||
self.var['cmd_name'] = 'deluge-console'
|
'cmd_name': 'deluge-console',
|
||||||
self.var['start_cmd'] = deluge.ui.console.start
|
'start_cmd': deluge.ui.console.start,
|
||||||
self.var['sys_arg_cmd'] = ['./deluge-console']
|
'sys_arg_cmd': ['./deluge-console'],
|
||||||
|
}
|
||||||
def set_up(self):
|
|
||||||
return ConsoleUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return ConsoleUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleDelugeScriptEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
class TestConsoleDelugeScriptEntry(BaseTestCase, ConsoleUIBaseTestCase):
|
||||||
def __init__(self, testname):
|
@pytest.fixture(autouse=True)
|
||||||
super().__init__(testname)
|
def set_var(self, request):
|
||||||
ConsoleUIBaseTestCase.__init__(self)
|
request.cls.var = {
|
||||||
self.var['cmd_name'] = 'deluge console'
|
'cmd_name': 'deluge console',
|
||||||
self.var['start_cmd'] = ui_entry.start_ui
|
'start_cmd': ui_entry.start_ui,
|
||||||
self.var['sys_arg_cmd'] = ['./deluge', 'console']
|
'sys_arg_cmd': ['./deluge', 'console'],
|
||||||
|
}
|
||||||
def set_up(self):
|
|
||||||
return ConsoleUIBaseTestCase.set_up(self)
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return ConsoleUIBaseTestCase.tear_down(self)
|
|
||||||
|
|
|
@ -8,11 +8,10 @@ import sys
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
@pytest.mark.gtkui
|
||||||
class GTK3CommonTestCase(unittest.TestCase):
|
class TestGTK3Common:
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
sys.modules['gi.repository'] = mock.MagicMock()
|
sys.modules['gi.repository'] = mock.MagicMock()
|
||||||
|
|
||||||
|
@ -22,10 +21,10 @@ class GTK3CommonTestCase(unittest.TestCase):
|
||||||
def test_cmp(self):
|
def test_cmp(self):
|
||||||
from deluge.ui.gtk3.common import cmp
|
from deluge.ui.gtk3.common import cmp
|
||||||
|
|
||||||
self.assertEqual(cmp(None, None), 0)
|
assert cmp(None, None) == 0
|
||||||
self.assertEqual(cmp(1, None), 1)
|
assert cmp(1, None) == 1
|
||||||
self.assertEqual(cmp(0, None), 1)
|
assert cmp(0, None) == 1
|
||||||
self.assertEqual(cmp(None, 7), -1)
|
assert cmp(None, 7) == -1
|
||||||
self.assertEqual(cmp(None, 'bar'), -1)
|
assert cmp(None, 'bar') == -1
|
||||||
self.assertEqual(cmp('foo', None), 1)
|
assert cmp('foo', None) == 1
|
||||||
self.assertEqual(cmp('', None), 1)
|
assert cmp('', None) == 1
|
||||||
|
|
|
@ -9,14 +9,14 @@
|
||||||
import json
|
import json
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_twisted
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import defer, reactor
|
||||||
from twisted.python.failure import Failure
|
|
||||||
from twisted.web.client import Agent, FileBodyProducer
|
from twisted.web.client import Agent, FileBodyProducer
|
||||||
from twisted.web.http_headers import Headers
|
from twisted.web.http_headers import Headers
|
||||||
from twisted.web.static import File
|
from twisted.web.static import File
|
||||||
|
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.ui.client import client
|
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from .common_web import WebServerTestBase
|
from .common_web import WebServerTestBase
|
||||||
|
@ -24,20 +24,19 @@ from .common_web import WebServerTestBase
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
|
||||||
class WebAPITestCase(WebServerTestBase):
|
class TestWebAPI(WebServerTestBase):
|
||||||
def test_connect_invalid_host(self):
|
@pytest.mark.xfail(reason='This just logs an error at the moment.')
|
||||||
d = self.deluge_web.web_api.connect('id')
|
@pytest_twisted.ensureDeferred
|
||||||
d.addCallback(self.fail)
|
async def test_connect_invalid_host(self):
|
||||||
d.addErrback(self.assertIsInstance, Failure)
|
with pytest.raises(Exception):
|
||||||
return d
|
await self.deluge_web.web_api.connect('id')
|
||||||
|
|
||||||
def test_connect(self):
|
def test_connect(self, client):
|
||||||
d = self.deluge_web.web_api.connect(self.host_id)
|
d = self.deluge_web.web_api.connect(self.host_id)
|
||||||
|
|
||||||
def on_connect(result):
|
def on_connect(result):
|
||||||
self.assertEqual(type(result), tuple)
|
assert type(result) == tuple
|
||||||
self.assertTrue(len(result) > 0)
|
assert len(result) > 0
|
||||||
self.addCleanup(client.disconnect)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
d.addCallback(on_connect)
|
d.addCallback(on_connect)
|
||||||
|
@ -49,9 +48,9 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_connect(result):
|
def on_connect(result):
|
||||||
self.assertTrue(self.deluge_web.web_api.connected())
|
assert self.deluge_web.web_api.connected()
|
||||||
yield self.deluge_web.web_api.disconnect()
|
yield self.deluge_web.web_api.disconnect()
|
||||||
self.assertFalse(self.deluge_web.web_api.connected())
|
assert not self.deluge_web.web_api.connected()
|
||||||
|
|
||||||
d.addCallback(on_connect)
|
d.addCallback(on_connect)
|
||||||
d.addErrback(self.fail)
|
d.addErrback(self.fail)
|
||||||
|
@ -59,7 +58,7 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
|
|
||||||
def test_get_config(self):
|
def test_get_config(self):
|
||||||
config = self.deluge_web.web_api.get_config()
|
config = self.deluge_web.web_api.get_config()
|
||||||
self.assertEqual(self.webserver_listen_port, config['port'])
|
assert self.webserver_listen_port == config['port']
|
||||||
|
|
||||||
def test_set_config(self):
|
def test_set_config(self):
|
||||||
config = self.deluge_web.web_api.get_config()
|
config = self.deluge_web.web_api.get_config()
|
||||||
|
@ -74,9 +73,9 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
}
|
}
|
||||||
self.deluge_web.web_api.set_config(config)
|
self.deluge_web.web_api.set_config(config)
|
||||||
web_config = component.get('DelugeWeb').config.config
|
web_config = component.get('DelugeWeb').config.config
|
||||||
self.assertNotEqual(config['pwd_salt'], web_config['pwd_salt'])
|
assert config['pwd_salt'] != web_config['pwd_salt']
|
||||||
self.assertNotEqual(config['pwd_sha1'], web_config['pwd_sha1'])
|
assert config['pwd_sha1'] != web_config['pwd_sha1']
|
||||||
self.assertNotEqual(config['sessions'], web_config['sessions'])
|
assert config['sessions'] != web_config['sessions']
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_host_status(self):
|
def get_host_status(self):
|
||||||
|
@ -84,49 +83,49 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
host[3] = 'Online'
|
host[3] = 'Online'
|
||||||
host[4] = '2.0.0.dev562'
|
host[4] = '2.0.0.dev562'
|
||||||
status = yield self.deluge_web.web_api.get_host_status(self.host_id)
|
status = yield self.deluge_web.web_api.get_host_status(self.host_id)
|
||||||
self.assertEqual(status, tuple(status))
|
assert status == tuple(status)
|
||||||
|
|
||||||
def test_get_host(self):
|
def test_get_host(self):
|
||||||
self.assertFalse(self.deluge_web.web_api._get_host('invalid_id'))
|
assert not self.deluge_web.web_api._get_host('invalid_id')
|
||||||
conn = list(self.deluge_web.web_api.hostlist.get_hosts_info()[0])
|
conn = list(self.deluge_web.web_api.hostlist.get_hosts_info()[0])
|
||||||
self.assertEqual(self.deluge_web.web_api._get_host(conn[0]), conn[0:4])
|
assert self.deluge_web.web_api._get_host(conn[0]) == conn[0:4]
|
||||||
|
|
||||||
def test_add_host(self):
|
def test_add_host(self):
|
||||||
conn = ['abcdef', '10.0.0.1', 0, 'user123', 'pass123']
|
conn = ['abcdef', '10.0.0.1', 0, 'user123', 'pass123']
|
||||||
self.assertFalse(self.deluge_web.web_api._get_host(conn[0]))
|
assert not self.deluge_web.web_api._get_host(conn[0])
|
||||||
# Add valid host
|
# Add valid host
|
||||||
result, host_id = self.deluge_web.web_api.add_host(
|
result, host_id = self.deluge_web.web_api.add_host(
|
||||||
conn[1], conn[2], conn[3], conn[4]
|
conn[1], conn[2], conn[3], conn[4]
|
||||||
)
|
)
|
||||||
self.assertEqual(result, True)
|
assert result
|
||||||
conn[0] = host_id
|
conn[0] = host_id
|
||||||
self.assertEqual(self.deluge_web.web_api._get_host(conn[0]), conn[0:4])
|
assert self.deluge_web.web_api._get_host(conn[0]) == conn[0:4]
|
||||||
|
|
||||||
# Add already existing host
|
# Add already existing host
|
||||||
ret = self.deluge_web.web_api.add_host(conn[1], conn[2], conn[3], conn[4])
|
ret = self.deluge_web.web_api.add_host(conn[1], conn[2], conn[3], conn[4])
|
||||||
self.assertEqual(ret, (False, 'Host details already in hostlist'))
|
assert ret == (False, 'Host details already in hostlist')
|
||||||
|
|
||||||
# Add invalid port
|
# Add invalid port
|
||||||
conn[2] = 'bad port'
|
conn[2] = 'bad port'
|
||||||
ret = self.deluge_web.web_api.add_host(conn[1], conn[2], conn[3], conn[4])
|
ret = self.deluge_web.web_api.add_host(conn[1], conn[2], conn[3], conn[4])
|
||||||
self.assertEqual(ret, (False, 'Invalid port. Must be an integer'))
|
assert ret == (False, 'Invalid port. Must be an integer')
|
||||||
|
|
||||||
def test_remove_host(self):
|
def test_remove_host(self):
|
||||||
conn = ['connection_id', '', 0, '', '']
|
conn = ['connection_id', '', 0, '', '']
|
||||||
self.deluge_web.web_api.hostlist.config['hosts'].append(conn)
|
self.deluge_web.web_api.hostlist.config['hosts'].append(conn)
|
||||||
self.assertEqual(self.deluge_web.web_api._get_host(conn[0]), conn[0:4])
|
assert self.deluge_web.web_api._get_host(conn[0]) == conn[0:4]
|
||||||
# Remove valid host
|
# Remove valid host
|
||||||
self.assertTrue(self.deluge_web.web_api.remove_host(conn[0]))
|
assert self.deluge_web.web_api.remove_host(conn[0])
|
||||||
self.assertFalse(self.deluge_web.web_api._get_host(conn[0]))
|
assert not self.deluge_web.web_api._get_host(conn[0])
|
||||||
# Remove non-existing host
|
# Remove non-existing host
|
||||||
self.assertFalse(self.deluge_web.web_api.remove_host(conn[0]))
|
assert not self.deluge_web.web_api.remove_host(conn[0])
|
||||||
|
|
||||||
def test_get_torrent_info(self):
|
def test_get_torrent_info(self):
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
ret = self.deluge_web.web_api.get_torrent_info(filename)
|
ret = self.deluge_web.web_api.get_torrent_info(filename)
|
||||||
self.assertEqual(ret['name'], 'azcvsupdater_2.6.2.jar')
|
assert ret['name'] == 'azcvsupdater_2.6.2.jar'
|
||||||
self.assertEqual(ret['info_hash'], 'ab570cdd5a17ea1b61e970bb72047de141bce173')
|
assert ret['info_hash'] == 'ab570cdd5a17ea1b61e970bb72047de141bce173'
|
||||||
self.assertTrue('files_tree' in ret)
|
assert 'files_tree' in ret
|
||||||
|
|
||||||
def test_get_torrent_info_with_md5(self):
|
def test_get_torrent_info_with_md5(self):
|
||||||
filename = common.get_test_data_file('md5sum.torrent')
|
filename = common.get_test_data_file('md5sum.torrent')
|
||||||
|
@ -134,19 +133,19 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
# JSON dumping happens during response creation in normal usage
|
# JSON dumping happens during response creation in normal usage
|
||||||
# JSON serialization may fail if any of the dictionary items are byte arrays rather than strings
|
# JSON serialization may fail if any of the dictionary items are byte arrays rather than strings
|
||||||
ret = json.loads(json.dumps(ret))
|
ret = json.loads(json.dumps(ret))
|
||||||
self.assertEqual(ret['name'], 'test')
|
assert ret['name'] == 'test'
|
||||||
self.assertEqual(ret['info_hash'], 'f6408ba9944cf9fe01b547b28f336b3ee6ec32c5')
|
assert ret['info_hash'] == 'f6408ba9944cf9fe01b547b28f336b3ee6ec32c5'
|
||||||
self.assertTrue('files_tree' in ret)
|
assert 'files_tree' in ret
|
||||||
|
|
||||||
def test_get_magnet_info(self):
|
def test_get_magnet_info(self):
|
||||||
ret = self.deluge_web.web_api.get_magnet_info(
|
ret = self.deluge_web.web_api.get_magnet_info(
|
||||||
'magnet:?xt=urn:btih:SU5225URMTUEQLDXQWRB2EQWN6KLTYKN'
|
'magnet:?xt=urn:btih:SU5225URMTUEQLDXQWRB2EQWN6KLTYKN'
|
||||||
)
|
)
|
||||||
self.assertEqual(ret['name'], '953bad769164e8482c7785a21d12166f94b9e14d')
|
assert ret['name'] == '953bad769164e8482c7785a21d12166f94b9e14d'
|
||||||
self.assertEqual(ret['info_hash'], '953bad769164e8482c7785a21d12166f94b9e14d')
|
assert ret['info_hash'] == '953bad769164e8482c7785a21d12166f94b9e14d'
|
||||||
self.assertTrue('files_tree' in ret)
|
assert 'files_tree' in ret
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_get_torrent_files(self):
|
def test_get_torrent_files(self):
|
||||||
yield self.deluge_web.web_api.connect(self.host_id)
|
yield self.deluge_web.web_api.connect(self.host_id)
|
||||||
filename = common.get_test_data_file('test.torrent')
|
filename = common.get_test_data_file('test.torrent')
|
||||||
|
@ -157,10 +156,8 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
ret = yield self.deluge_web.web_api.get_torrent_files(
|
ret = yield self.deluge_web.web_api.get_torrent_files(
|
||||||
'ab570cdd5a17ea1b61e970bb72047de141bce173'
|
'ab570cdd5a17ea1b61e970bb72047de141bce173'
|
||||||
)
|
)
|
||||||
self.assertEqual(ret['type'], 'dir')
|
assert ret['type'] == 'dir'
|
||||||
self.assertEqual(
|
assert ret['contents'] == {
|
||||||
ret['contents'],
|
|
||||||
{
|
|
||||||
'azcvsupdater_2.6.2.jar': {
|
'azcvsupdater_2.6.2.jar': {
|
||||||
'priority': 4,
|
'priority': 4,
|
||||||
'index': 0,
|
'index': 0,
|
||||||
|
@ -170,10 +167,9 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
'type': 'file',
|
'type': 'file',
|
||||||
'size': 307949,
|
'size': 307949,
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_download_torrent_from_url(self):
|
def test_download_torrent_from_url(self):
|
||||||
filename = 'ubuntu-9.04-desktop-i386.iso.torrent'
|
filename = 'ubuntu-9.04-desktop-i386.iso.torrent'
|
||||||
self.deluge_web.top_level.putChild(
|
self.deluge_web.top_level.putChild(
|
||||||
|
@ -181,9 +177,9 @@ class WebAPITestCase(WebServerTestBase):
|
||||||
)
|
)
|
||||||
url = 'http://localhost:%d/%s' % (self.webserver_listen_port, filename)
|
url = 'http://localhost:%d/%s' % (self.webserver_listen_port, filename)
|
||||||
res = yield self.deluge_web.web_api.download_torrent_from_url(url)
|
res = yield self.deluge_web.web_api.download_torrent_from_url(url)
|
||||||
self.assertTrue(res.endswith(filename))
|
assert res.endswith(filename)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_invalid_json(self):
|
def test_invalid_json(self):
|
||||||
"""
|
"""
|
||||||
If json_api._send_response does not return server.NOT_DONE_YET
|
If json_api._send_response does not return server.NOT_DONE_YET
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from unittest.mock import patch
|
||||||
|
|
||||||
from deluge.ui.web import auth
|
from deluge.ui.web import auth
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ class MockConfig:
|
||||||
self.config[key] = value
|
self.config[key] = value
|
||||||
|
|
||||||
|
|
||||||
class WebAuthTestCase(unittest.TestCase):
|
class TestWebAuth:
|
||||||
@patch('deluge.ui.web.auth.JSONComponent.__init__', return_value=None)
|
@patch('deluge.ui.web.auth.JSONComponent.__init__', return_value=None)
|
||||||
def test_change_password(self, mock_json):
|
def test_change_password(self, mock_json):
|
||||||
config = MockConfig(
|
config = MockConfig(
|
||||||
|
@ -31,4 +30,4 @@ class WebAuthTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
webauth = auth.Auth(config)
|
webauth = auth.Auth(config)
|
||||||
self.assertTrue(webauth.change_password('deluge', 'deluge_new'))
|
assert webauth.change_password('deluge', 'deluge_new')
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
import json as json_lib
|
import json as json_lib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
import pytest_twisted
|
||||||
import twisted.web.client
|
import twisted.web.client
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import reactor
|
||||||
from twisted.web.client import Agent, FileBodyProducer
|
from twisted.web.client import Agent, FileBodyProducer
|
||||||
from twisted.web.http_headers import Headers
|
from twisted.web.http_headers import Headers
|
||||||
|
|
||||||
|
@ -21,8 +22,8 @@ from .common_web import WebServerMockBase, WebServerTestBase
|
||||||
common.disable_new_release_check()
|
common.disable_new_release_check()
|
||||||
|
|
||||||
|
|
||||||
class WebServerTestCase(WebServerTestBase, WebServerMockBase):
|
class TestWebServer(WebServerTestBase, WebServerMockBase):
|
||||||
@defer.inlineCallbacks
|
@pytest_twisted.inlineCallbacks
|
||||||
def test_get_torrent_info(self):
|
def test_get_torrent_info(self):
|
||||||
|
|
||||||
agent = Agent(reactor)
|
agent = Agent(reactor)
|
||||||
|
@ -49,9 +50,11 @@ class WebServerTestCase(WebServerTestBase, WebServerMockBase):
|
||||||
Headers(headers),
|
Headers(headers),
|
||||||
FileBodyProducer(BytesIO(input_file.encode('utf-8'))),
|
FileBodyProducer(BytesIO(input_file.encode('utf-8'))),
|
||||||
)
|
)
|
||||||
|
|
||||||
body = yield twisted.web.client.readBody(d)
|
body = yield twisted.web.client.readBody(d)
|
||||||
|
|
||||||
|
try:
|
||||||
json = json_lib.loads(body.decode())
|
json = json_lib.loads(body.decode())
|
||||||
self.assertEqual(None, json['error'])
|
except Exception:
|
||||||
self.assertEqual('torrent_filehash', json['result']['name'])
|
print('aoeu')
|
||||||
|
assert json['error'] is None
|
||||||
|
assert 'torrent_filehash' == json['result']['name']
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
#! /usr/bin/env python
|
|
||||||
#
|
|
||||||
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
|
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
|
||||||
# See LICENSE for more details.
|
|
||||||
#
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from twisted.plugin import IPlugin
|
|
||||||
from twisted.trial.itrial import IReporter
|
|
||||||
from twisted.trial.reporter import TreeReporter
|
|
||||||
from zope.interface import implements
|
|
||||||
|
|
||||||
|
|
||||||
class _Reporter:
|
|
||||||
implements(IPlugin, IReporter)
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, name, module, description, longOpt, shortOpt, klass # noqa: N803
|
|
||||||
):
|
|
||||||
self.name = name
|
|
||||||
self.module = module
|
|
||||||
self.description = description
|
|
||||||
self.longOpt = longOpt
|
|
||||||
self.shortOpt = shortOpt
|
|
||||||
self.klass = klass
|
|
||||||
|
|
||||||
|
|
||||||
deluge = _Reporter(
|
|
||||||
'Deluge reporter that suppresses Stacktrace from TODO tests',
|
|
||||||
'twisted.plugins.delugereporter',
|
|
||||||
description='Deluge Reporter',
|
|
||||||
longOpt='deluge-reporter',
|
|
||||||
shortOpt=None,
|
|
||||||
klass='DelugeReporter',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DelugeReporter(TreeReporter):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
os.environ['DELUGE_REPORTER'] = 'true'
|
|
||||||
TreeReporter.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
def addExpectedFailure(self, *args): # NOQA: N802
|
|
||||||
# super(TreeReporter, self).addExpectedFailure(*args)
|
|
||||||
self.endLine('[TODO]', self.TODO)
|
|
|
@ -612,7 +612,7 @@ class Client:
|
||||||
d.addErrback(on_authenticate_fail)
|
d.addErrback(on_authenticate_fail)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
d.addCallback(on_connected)
|
d.addCallbacks(on_connected)
|
||||||
d.addErrback(on_connect_fail)
|
d.addErrback(on_connect_fail)
|
||||||
if not skip_authentication:
|
if not skip_authentication:
|
||||||
d.addCallback(authenticate, username, password)
|
d.addCallback(authenticate, username, password)
|
||||||
|
|
|
@ -13,4 +13,4 @@ UI_PATH = __path__[0]
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
|
|
||||||
Console().start()
|
return Console().start()
|
||||||
|
|
Loading…
Add table
Reference in a new issue