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