diff --git a/.travis.yml b/.travis.yml index a9e03d2de..1d5b49103 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,8 @@ script: env: - TOX_ENV=pydef + - TOX_ENV=trial + - TOX_ENV=todo # - TOX_ENV=plugins - TOX_ENV=flake8 - TOX_ENV=flake8-complexity diff --git a/deluge/plugins/Stats/deluge/plugins/stats/tests/test_stats.py b/deluge/plugins/Stats/deluge/plugins/stats/tests/test_stats.py index 888a54338..147ee78bb 100644 --- a/deluge/plugins/Stats/deluge/plugins/stats/tests/test_stats.py +++ b/deluge/plugins/Stats/deluge/plugins/stats/tests/test_stats.py @@ -1,3 +1,4 @@ +import pytest import twisted.internet.defer as defer from twisted.trial import unittest @@ -31,13 +32,19 @@ class StatsTestCase(unittest.TestCase): component._ComponentRegistry.components = {} return component.shutdown().addCallback(on_shutdown) + @pytest.mark.todo def test_client_totals(self): + StatsTestCase.test_client_totals.im_func.todo = "To be fixed" + def callback(args): print_totals(args) d = client.stats.get_totals() d.addCallback(callback) + @pytest.mark.todo def test_session_totals(self): + StatsTestCase.test_session_totals.im_func.todo = "To be fixed" + def callback(args): print_totals(args) d = client.stats.get_session_totals() diff --git a/deluge/tests/common.py b/deluge/tests/common.py index bc7558e79..d3bd6ccb2 100644 --- a/deluge/tests/common.py +++ b/deluge/tests/common.py @@ -13,6 +13,11 @@ import deluge.log deluge.log.setup_logger("none") +def disable_new_release_check(): + import deluge.core.preferencesmanager + 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) diff --git a/deluge/tests/test_component.py b/deluge/tests/test_component.py index bdfd0a0e0..b281188b9 100644 --- a/deluge/tests/test_component.py +++ b/deluge/tests/test_component.py @@ -5,7 +5,7 @@ import deluge.component as component from .basetest import BaseTestCase -class TestComponent(component.Component): +class ComponentTester(component.Component): def __init__(self, name, depend=None): component.Component.__init__(self, name, depend=depend) self.start_count = 0 @@ -18,7 +18,7 @@ class TestComponent(component.Component): self.stop_count += 1 -class TestComponentDelayStart(TestComponent): +class ComponentTesterDelayStart(ComponentTester): def start(self): def do_sleep(): import time @@ -30,7 +30,7 @@ class TestComponentDelayStart(TestComponent): return d.addCallback(on_done) -class TestComponentUpdate(component.Component): +class ComponentTesterUpdate(component.Component): def __init__(self, name): component.Component.__init__(self, name) self.counter = 0 @@ -44,7 +44,7 @@ class TestComponentUpdate(component.Component): self.stop_count += 1 -class TestComponentShutdown(component.Component): +class ComponentTesterShutdown(component.Component): def __init__(self, name): component.Component.__init__(self, name) self.shutdowned = False @@ -66,7 +66,7 @@ class ComponentTestClass(BaseTestCase): self.assertEquals(c._component_state, "Started") self.assertEquals(c.start_count, 1) - c = TestComponent("test_start_c1") + c = ComponentTester("test_start_c1") d = component.start(["test_start_c1"]) d.addCallback(on_start, c) return d @@ -85,19 +85,19 @@ class ComponentTestClass(BaseTestCase): self.assertEquals(c2.start_count, 1) return component.stop(["test_start_depends_c1"]).addCallback(on_stop, c1, c2) - c1 = TestComponent("test_start_depends_c1") - c2 = TestComponent("test_start_depends_c2", depend=["test_start_depends_c1"]) + c1 = ComponentTester("test_start_depends_c1") + c2 = ComponentTester("test_start_depends_c2", depend=["test_start_depends_c1"]) d = component.start(["test_start_depends_c2"]) d.addCallback(on_start, c1, c2) return d def start_with_depends(self): - c1 = TestComponentDelayStart("test_start_all_c1") - c2 = TestComponent("test_start_all_c2", depend=["test_start_all_c4"]) - c3 = TestComponentDelayStart("test_start_all_c3", depend=["test_start_all_c5", "test_start_all_c1"]) - c4 = TestComponent("test_start_all_c4", depend=["test_start_all_c3"]) - c5 = TestComponent("test_start_all_c5") + c1 = ComponentTesterDelayStart("test_start_all_c1") + c2 = ComponentTester("test_start_all_c2", depend=["test_start_all_c4"]) + c3 = ComponentTesterDelayStart("test_start_all_c3", depend=["test_start_all_c5", "test_start_all_c1"]) + c4 = ComponentTester("test_start_all_c4", depend=["test_start_all_c3"]) + c5 = ComponentTester("test_start_all_c5") d = component.start() return (d, c1, c2, c3, c4, c5) @@ -118,10 +118,10 @@ class ComponentTestClass(BaseTestCase): return ret[0] def test_register_exception(self): - TestComponent("test_register_exception_c1") + ComponentTester("test_register_exception_c1") self.assertRaises( component.ComponentAlreadyRegistered, - TestComponent, + ComponentTester, "test_register_exception_c1") def test_stop_component(self): @@ -134,7 +134,7 @@ class ComponentTestClass(BaseTestCase): self.assertEquals(c._component_state, "Started") return component.stop(["test_stop_component_c1"]).addCallback(on_stop, c) - c = TestComponentUpdate("test_stop_component_c1") + c = ComponentTesterUpdate("test_stop_component_c1") d = component.start(["test_stop_component_c1"]) d.addCallback(on_start, c) return d @@ -162,7 +162,7 @@ class ComponentTestClass(BaseTestCase): self.assertNotEqual(c1.counter, counter) return component.stop() - c1 = TestComponentUpdate("test_update_c1") + c1 = ComponentTesterUpdate("test_update_c1") cnt = int(c1.counter) d = component.start(["test_update_c1"]) @@ -182,7 +182,7 @@ class ComponentTestClass(BaseTestCase): d.addCallback(on_pause, c1, counter) return d - c1 = TestComponentUpdate("test_pause_c1") + c1 = ComponentTesterUpdate("test_pause_c1") cnt = int(c1.counter) d = component.start(["test_pause_c1"]) @@ -200,7 +200,7 @@ class ComponentTestClass(BaseTestCase): d.addCallback(on_shutdown, c1) return d - c1 = TestComponentShutdown("test_shutdown_c1") + c1 = ComponentTesterShutdown("test_shutdown_c1") d = component.start(["test_shutdown_c1"]) d.addCallback(on_start, c1) return d diff --git a/deluge/tests/test_core.py b/deluge/tests/test_core.py index 16ccabddf..a96d21272 100644 --- a/deluge/tests/test_core.py +++ b/deluge/tests/test_core.py @@ -1,7 +1,7 @@ import os -import warnings from hashlib import sha1 as sha +import pytest from twisted.internet import reactor from twisted.internet.error import CannotListenError from twisted.python.failure import Failure @@ -19,13 +19,12 @@ from deluge.ui.web.common import compress from . import common from .basetest import BaseTestCase -warnings.filterwarnings("ignore", category=RuntimeWarning) -warnings.resetwarnings() +common.disable_new_release_check() rpath = common.rpath -class TestCookieResource(Resource): +class CookieResource(Resource): def render(self, request): if request.getCookie("password") != "deluge": @@ -36,7 +35,7 @@ class TestCookieResource(Resource): return open(rpath("ubuntu-9.04-desktop-i386.iso.torrent")).read() -class TestPartialDownload(Resource): +class PartialDownload(Resource): def render(self, request): data = open(rpath("ubuntu-9.04-desktop-i386.iso.torrent")).read() @@ -47,7 +46,7 @@ class TestPartialDownload(Resource): return data -class TestRedirectResource(Resource): +class RedirectResource(Resource): def render(self, request): request.redirect("/ubuntu-9.04-desktop-i386.iso.torrent") @@ -60,9 +59,9 @@ class TopLevelResource(Resource): def __init__(self): Resource.__init__(self) - self.putChild("cookie", TestCookieResource()) - self.putChild("partial", TestPartialDownload()) - self.putChild("redirect", TestRedirectResource()) + self.putChild("cookie", CookieResource()) + self.putChild("partial", PartialDownload()) + self.putChild("redirect", RedirectResource()) self.putChild("ubuntu-9.04-desktop-i386.iso.torrent", File(common.rpath("ubuntu-9.04-desktop-i386.iso.torrent"))) @@ -196,6 +195,7 @@ class CoreTestCase(BaseTestCase): self.assertTrue(space >= 0) self.assertEquals(self.core.get_free_space("/someinvalidpath"), -1) + @pytest.mark.slow def test_test_listen_port(self): d = self.core.test_listen_port() diff --git a/deluge/tests/test_httpdownloader.py b/deluge/tests/test_httpdownloader.py index e2e71b55b..a9e4818c9 100644 --- a/deluge/tests/test_httpdownloader.py +++ b/deluge/tests/test_httpdownloader.py @@ -1,5 +1,4 @@ import tempfile -import warnings from email.utils import formatdate from twisted.internet import reactor @@ -22,10 +21,6 @@ except ImportError: from twisted.web.error import Resource -warnings.filterwarnings("ignore", category=RuntimeWarning) -warnings.resetwarnings() - - rpath = common.rpath temp_dir = tempfile.mkdtemp() @@ -34,13 +29,13 @@ def fname(name): return "%s/%s" % (temp_dir, name) -class TestRedirectResource(Resource): +class RedirectResource(Resource): def render(self, request): request.redirect("http://localhost:51242/") -class TestRenameResource(Resource): +class RenameResource(Resource): def render(self, request): filename = request.args.get("filename", ["renamed_file"])[0] @@ -50,7 +45,7 @@ class TestRenameResource(Resource): return "This file should be called " + filename -class TestCookieResource(Resource): +class CookieResource(Resource): def render(self, request): request.setHeader("Content-Type", "text/plain") @@ -63,7 +58,7 @@ class TestCookieResource(Resource): return request.getCookie("password") -class TestGzipResource(Resource): +class GzipResource(Resource): def render(self, request): message = request.args.get("msg", ["EFFICIENCY!"])[0] @@ -77,10 +72,10 @@ class TopLevelResource(Resource): def __init__(self): Resource.__init__(self) - self.putChild("cookie", TestCookieResource()) - self.putChild("gzip", TestGzipResource()) - self.putChild("redirect", TestRedirectResource()) - self.putChild("rename", TestRenameResource()) + self.putChild("cookie", CookieResource()) + self.putChild("gzip", GzipResource()) + self.putChild("redirect", RedirectResource()) + self.putChild("rename", RenameResource()) def getChild(self, path, request): # NOQA if path == "": @@ -97,7 +92,7 @@ class TopLevelResource(Resource): class DownloadFileTestCase(unittest.TestCase): def setUp(self): # NOQA - setup_logger("warning", "log_file") + setup_logger("warning", fname("log_file")) self.website = Site(TopLevelResource()) self.listen_port = 51242 tries = 10 diff --git a/deluge/tests/test_log.py b/deluge/tests/test_log.py index 78e64040d..feda208fa 100644 --- a/deluge/tests/test_log.py +++ b/deluge/tests/test_log.py @@ -16,8 +16,6 @@ class LogTestCase(unittest.TestCase): def test_old_log_deprecation_warning(self): import warnings from deluge.log import LOG - warnings.filterwarnings("ignore", category=DeprecationWarning, - module="deluge.tests.test_log") d = defer.Deferred() d.addCallback(LOG.debug, "foo") self.assertFailure(d, DeprecationWarning) diff --git a/deluge/tests/twisted/plugins/delugereporter.py b/deluge/tests/twisted/plugins/delugereporter.py new file mode 100644 index 000000000..952fc7366 --- /dev/null +++ b/deluge/tests/twisted/plugins/delugereporter.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python + +from twisted.plugin import IPlugin +from twisted.trial.itrial import IReporter +from twisted.trial.reporter import TreeReporter +from zope.interface import implements + + +class _Reporter(object): + implements(IPlugin, IReporter) + + def __init__(self, name, module, description, longOpt, shortOpt, klass): # NOQA + 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): + TreeReporter.__init__(self, *args, **kwargs) + + def addExpectedFailure(self, *args): # NOQA + # super(TreeReporter, self).addExpectedFailure(*args) + self.endLine('[TODO]', self.TODO) diff --git a/setup.cfg b/setup.cfg index d01c4672c..8818ae079 100644 --- a/setup.cfg +++ b/setup.cfg @@ -18,5 +18,5 @@ frameworks = CoreFoundation, Foundation, AppKit known_standard_library=unicodedata line_length=120 skip=gtkui.py -known_third_party=pygtk,gtk,gobject,gtk.gdk,pango,cairo,pangocairo +known_third_party=pygtk,gtk,gobject,gtk.gdk,pango,cairo,pangocairo,twisted order_by_type=true diff --git a/tox.ini b/tox.ini index 17a0cb807..fe98758a9 100644 --- a/tox.ini +++ b/tox.ini @@ -10,11 +10,11 @@ ignore = E133 exclude = .tox,.git,dist,build [tox] -envlist = py27, py26, flake8, isort, docs +envlist = py27, flake8, isort, docs minversion=1.8 [testenv] -setenv = PYTHONPATH = {env:PYTHONPATH}:{env:PWD} +setenv = PYTHONPATH = {env:PWD}: sitepackages = True deps = twisted @@ -34,20 +34,10 @@ pep8maxlinelength = 120 whitelist_externals= {[testenv]whitelist_externals} commands = py.test deluge -[testenv:testcoverage] -install_command = pip install {opts} {packages} -deps = - {[testenv]deps} - pytest-cov - coverage -whitelist_externals = - {[testenv]whitelist_externals} - coverage -commands = - coverage run --branch --source=deluge -m py.test deluge/tests/ - coverage report - # For creating html report - # coverage html -d docs/build/htmlcoverage + +############## +# Unit tests +############## [testenv:pydef] commands = @@ -79,6 +69,11 @@ commands = {[testenv:pydef]commands} basepython = python2.7 commands = {[testenv:pydef]commands} + +########################### +# Code style verification +########################### + [testenv:isort] deps = {[testenv]deps} @@ -110,6 +105,44 @@ deps = mccabe commands = flake8 --exit-zero --max-complexity 15 deluge + +###################### +# Unit Test coverage +###################### + +[testcoveragebase] +#install_command = pip install {opts} {packages} +deps = + {[testenv]deps} + pytest-cov + coverage +whitelist_externals = + {[testenv]whitelist_externals} + coverage +commands = + coverage run --branch --source=deluge -m py.test "not (todo or gtkui)" deluge/tests/ + +[testenv:testcoverage] +deps = {[testcoveragebase]deps} +setenv = {[testenv]setenv} +whitelist_externals = {[testcoveragebase]whitelist_externals} +commands = + {[testcoveragebase]commands} + coverage report + +[testenv:testcoverage-html] +deps = {[testcoveragebase]deps} +setenv = {[testenv]setenv} +whitelist_externals = {[testcoveragebase]whitelist_externals} +commands = + {[testcoveragebase]commands} + coverage html -d docs/build/htmlcoverage + + +###################### +# Docs generation +###################### + # We do not have all dependencies on RTD and travis so we exclude the # site packages (sitepackages=False) when building docs so that local # tests have a similar environment.