[Tests] Various fixes for unit tests and tox

* Added custom trial reporter for TODO with test example in test_torrentmanager.py
* Set Stats plugin tests as todo
* Disable new_release_check when running unit tests
* Added pytest.mark.slow to test_core.test_test_listen_port
* Get rid of unit test warnings (Caused by bad names in test classes)
* Removed warnings.filterwarnings in test files.
* Added separate tox target for generating test coverage HTML report.
This commit is contained in:
bendikro 2014-10-04 00:14:20 +02:00 committed by Calum Lind
parent 178c417fb0
commit 8334bf9477
10 changed files with 135 additions and 60 deletions

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

65
tox.ini
View File

@ -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.