mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-12 20:44:50 +00:00
Added .travis.yml (for travis-ci) and tox.ini files
Targets: * Runs the unit-tests for python 2.7 * Tests unit-test coverage * Try to build docs * Code style checks: * flake8 * isort Codes changes: * Fixed tests for httpdownloader (using tmp dir) * Implemented a couple of tests for Stats plugin but they fail to run on travis Issues: * Can't get py26 to work because of installing libtorrent through apt and the option system_site_packages fails for 2.6.
This commit is contained in:
parent
8dc9a0773c
commit
66f2739be7
35
.travis.yml
Normal file
35
.travis.yml
Normal file
@ -0,0 +1,35 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
# - "2.6"
|
||||
- "2.7"
|
||||
|
||||
# command to install dependencies
|
||||
install:
|
||||
- pip install tox
|
||||
- lsb_release -a
|
||||
- sudo add-apt-repository ppa:deluge-team/ppa -y
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install python-libtorrent
|
||||
|
||||
script:
|
||||
- tox
|
||||
|
||||
env:
|
||||
- TOX_ENV=pydef
|
||||
- TOX_ENV=plugins
|
||||
- TOX_ENV=flake8
|
||||
- TOX_ENV=flake8-complexity
|
||||
- TOX_ENV=isort
|
||||
- TOX_ENV=docs
|
||||
- TOX_ENV=testcoverage
|
||||
|
||||
virtualenv:
|
||||
system_site_packages: true
|
||||
|
||||
before_script:
|
||||
- export PYTHONPATH=$PYTHONPATH:$PWD
|
||||
- python -c "import libtorrent as lt; print lt.version"
|
||||
|
||||
script:
|
||||
- tox -e $TOX_ENV
|
@ -30,6 +30,7 @@ try:
|
||||
import dbus
|
||||
bus = dbus.SessionBus()
|
||||
dbus_fileman = bus.get_object("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1")
|
||||
|
||||
except:
|
||||
dbus_fileman = None
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
while true; do
|
||||
python test.py
|
||||
sleep 2
|
||||
done;
|
@ -1,22 +0,0 @@
|
||||
from __future__ import print_function
|
||||
|
||||
from deluge.common import fsize
|
||||
from deluge.ui.client import sclient
|
||||
|
||||
sclient.set_core_uri()
|
||||
|
||||
|
||||
def print_totals(totals):
|
||||
for name, value in totals.iteritems():
|
||||
print(name, fsize(value))
|
||||
|
||||
print("overhead:")
|
||||
print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"]))
|
||||
print("down:", fsize(totals["total_download"] - totals["total_payload_download"]))
|
||||
|
||||
|
||||
print("==totals==")
|
||||
print_totals(sclient.stats_get_totals())
|
||||
|
||||
print("==session totals==")
|
||||
print_totals(sclient.stats_get_session_totals())
|
@ -0,0 +1,44 @@
|
||||
import twisted.internet.defer as defer
|
||||
from twisted.trial import unittest
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import fsize
|
||||
from deluge.tests import common as tests_common
|
||||
from deluge.ui.client import client
|
||||
|
||||
|
||||
def print_totals(totals):
|
||||
for name, value in totals.iteritems():
|
||||
print(name, fsize(value))
|
||||
|
||||
print("overhead:")
|
||||
print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"]))
|
||||
print("down:", fsize(totals["total_download"] - totals["total_payload_download"]))
|
||||
|
||||
|
||||
class StatsTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self): # NOQA
|
||||
defer.setDebugging(True)
|
||||
tests_common.set_tmp_config_dir()
|
||||
client.start_classic_mode()
|
||||
client.core.enable_plugin("Stats")
|
||||
|
||||
def tearDown(self): # NOQA
|
||||
client.stop_classic_mode()
|
||||
|
||||
def on_shutdown(result):
|
||||
component._ComponentRegistry.components = {}
|
||||
return component.shutdown().addCallback(on_shutdown)
|
||||
|
||||
def test_client_totals(self):
|
||||
def callback(args):
|
||||
print_totals(args)
|
||||
d = client.stats.get_totals()
|
||||
d.addCallback(callback)
|
||||
|
||||
def test_session_totals(self):
|
||||
def callback(args):
|
||||
print_totals(args)
|
||||
d = client.stats.get_session_totals()
|
||||
d.addCallback(callback)
|
@ -2,10 +2,11 @@ from twisted.internet import defer
|
||||
from twisted.internet.error import CannotListenError
|
||||
from twisted.trial import unittest
|
||||
|
||||
import deluge.tests.common as common
|
||||
from deluge import error
|
||||
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
|
||||
from deluge.ui.client import Client, client, DaemonSSLProxy
|
||||
from deluge.ui.client import client, Client, DaemonSSLProxy
|
||||
|
||||
from . import common
|
||||
|
||||
|
||||
class NoVersionSendingDaemonSSLProxy(DaemonSSLProxy):
|
||||
|
@ -7,7 +7,8 @@ from twisted.trial import unittest
|
||||
|
||||
import deluge.config
|
||||
from deluge.config import Config
|
||||
from deluge.tests.common import set_tmp_config_dir
|
||||
|
||||
from .common import set_tmp_config_dir
|
||||
|
||||
DEFAULTS = {"string": "foobar", "int": 1, "float": 0.435, "bool": True, "unicode": u"foobar"}
|
||||
|
||||
|
@ -13,11 +13,12 @@ from twisted.web.static import File
|
||||
|
||||
import deluge.component as component
|
||||
import deluge.error
|
||||
import deluge.tests.common as common
|
||||
from deluge.core.core import Core
|
||||
from deluge.core.rpcserver import RPCServer
|
||||
from deluge.ui.web.common import compress
|
||||
|
||||
from . import common
|
||||
|
||||
warnings.filterwarnings("ignore", category=RuntimeWarning)
|
||||
warnings.resetwarnings()
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import tempfile
|
||||
import warnings
|
||||
from email.utils import formatdate
|
||||
|
||||
@ -8,11 +9,12 @@ from twisted.trial import unittest
|
||||
from twisted.web.http import NOT_MODIFIED
|
||||
from twisted.web.server import Site
|
||||
|
||||
import deluge.tests.common as common
|
||||
from deluge.httpdownloader import download_file
|
||||
from deluge.log import setup_logger
|
||||
from deluge.ui.web.common import compress
|
||||
|
||||
from . import common
|
||||
|
||||
try:
|
||||
from twisted.web.resource import Resource
|
||||
except ImportError:
|
||||
@ -25,6 +27,11 @@ warnings.resetwarnings()
|
||||
|
||||
|
||||
rpath = common.rpath
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
|
||||
|
||||
def fname(name):
|
||||
return "%s/%s" % (temp_dir, name)
|
||||
|
||||
|
||||
class TestRedirectResource(Resource):
|
||||
@ -132,13 +139,13 @@ class DownloadFileTestCase(unittest.TestCase):
|
||||
return filename
|
||||
|
||||
def test_download(self):
|
||||
d = download_file("http://localhost:%d/" % self.listen_port, "index.html")
|
||||
d.addCallback(self.assertEqual, "index.html")
|
||||
d = download_file("http://localhost:%d/" % self.listen_port, fname("index.html"))
|
||||
d.addCallback(self.assertEqual, fname("index.html"))
|
||||
return d
|
||||
|
||||
def test_download_without_required_cookies(self):
|
||||
url = "http://localhost:%d/cookie" % self.listen_port
|
||||
d = download_file(url, "none")
|
||||
d = download_file(url, fname("none"))
|
||||
d.addCallback(self.fail)
|
||||
d.addErrback(self.assertIsInstance, Failure)
|
||||
return d
|
||||
@ -146,68 +153,68 @@ class DownloadFileTestCase(unittest.TestCase):
|
||||
def test_download_with_required_cookies(self):
|
||||
url = "http://localhost:%d/cookie" % self.listen_port
|
||||
cookie = {"cookie": "password=deluge"}
|
||||
d = download_file(url, "monster", headers=cookie)
|
||||
d.addCallback(self.assertEqual, "monster")
|
||||
d = download_file(url, fname("monster"), headers=cookie)
|
||||
d.addCallback(self.assertEqual, fname("monster"))
|
||||
d.addCallback(self.assertContains, "COOKIE MONSTER!")
|
||||
return d
|
||||
|
||||
def test_download_with_rename(self):
|
||||
url = "http://localhost:%d/rename?filename=renamed" % self.listen_port
|
||||
d = download_file(url, "original")
|
||||
d.addCallback(self.assertEqual, "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
|
||||
|
||||
def test_download_with_rename_exists(self):
|
||||
open('renamed', 'w').close()
|
||||
open(fname('renamed'), 'w').close()
|
||||
url = "http://localhost:%d/rename?filename=renamed" % self.listen_port
|
||||
d = download_file(url, "original")
|
||||
d.addCallback(self.assertEqual, "renamed-1")
|
||||
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
|
||||
|
||||
def test_download_with_rename_sanitised(self):
|
||||
url = "http://localhost:%d/rename?filename=/etc/passwd" % self.listen_port
|
||||
d = download_file(url, "original")
|
||||
d.addCallback(self.assertEqual, "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
|
||||
|
||||
def test_download_with_rename_prevented(self):
|
||||
url = "http://localhost:%d/rename?filename=spam" % self.listen_port
|
||||
d = download_file(url, "forced", force_filename=True)
|
||||
d.addCallback(self.assertEqual, "forced")
|
||||
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
|
||||
|
||||
def test_download_with_gzip_encoding(self):
|
||||
url = "http://localhost:%d/gzip?msg=success" % self.listen_port
|
||||
d = download_file(url, "gzip_encoded")
|
||||
d = download_file(url, fname("gzip_encoded"))
|
||||
d.addCallback(self.assertContains, "success")
|
||||
return d
|
||||
|
||||
def test_download_with_gzip_encoding_disabled(self):
|
||||
url = "http://localhost:%d/gzip?msg=fail" % self.listen_port
|
||||
d = download_file(url, "gzip_encoded", allow_compression=False)
|
||||
d = download_file(url, fname("gzip_encoded"), allow_compression=False)
|
||||
d.addCallback(self.failIfContains, "fail")
|
||||
return d
|
||||
|
||||
def test_page_redirect(self):
|
||||
url = 'http://localhost:%d/redirect' % self.listen_port
|
||||
d = download_file(url, "none")
|
||||
d = download_file(url, fname("none"))
|
||||
d.addCallback(self.fail)
|
||||
d.addErrback(self.assertIsInstance, Failure)
|
||||
return d
|
||||
|
||||
def test_page_not_found(self):
|
||||
d = download_file("http://localhost:%d/page/not/found" % self.listen_port, "none")
|
||||
d = download_file("http://localhost:%d/page/not/found" % self.listen_port, fname("none"))
|
||||
d.addCallback(self.fail)
|
||||
d.addErrback(self.assertIsInstance, Failure)
|
||||
return d
|
||||
|
||||
def test_page_not_modified(self):
|
||||
headers = {'If-Modified-Since': formatdate(usegmt=True)}
|
||||
d = download_file("http://localhost:%d/" % self.listen_port, "index.html", headers=headers)
|
||||
d = download_file("http://localhost:%d/" % self.listen_port, fname("index.html"), headers=headers)
|
||||
d.addCallback(self.fail)
|
||||
d.addErrback(self.assertIsInstance, Failure)
|
||||
return d
|
||||
|
@ -7,12 +7,13 @@ 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.core.core import Core
|
||||
from deluge.core.rpcserver import RPCServer
|
||||
from deluge.core.torrent import Torrent
|
||||
|
||||
from . import common
|
||||
|
||||
config_setup = False
|
||||
core = None
|
||||
rpcserver = None
|
||||
|
@ -3,9 +3,10 @@ import os
|
||||
from twisted.trial import unittest
|
||||
|
||||
import deluge.ui.tracker_icons
|
||||
from deluge.tests.common import set_tmp_config_dir
|
||||
from deluge.ui.tracker_icons import TrackerIcon, TrackerIcons
|
||||
|
||||
from .common import set_tmp_config_dir
|
||||
|
||||
set_tmp_config_dir()
|
||||
icons = TrackerIcons()
|
||||
|
||||
|
@ -29,7 +29,7 @@ from deluge import component, httpdownloader
|
||||
from deluge.common import is_magnet
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.ui import common as uicommon
|
||||
from deluge.ui.client import Client, client
|
||||
from deluge.ui.client import client, Client
|
||||
from deluge.ui.coreconfig import CoreConfig
|
||||
from deluge.ui.sessionproxy import SessionProxy
|
||||
from deluge.ui.web.common import _, compress
|
||||
|
@ -14,6 +14,7 @@ import os
|
||||
import sys
|
||||
from datetime import date
|
||||
|
||||
import mock
|
||||
import pkg_resources
|
||||
|
||||
try:
|
||||
@ -22,6 +23,7 @@ except ImportError:
|
||||
get_version = None
|
||||
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
on_travis = os.environ.get('TRAVIS', None) == 'true'
|
||||
|
||||
# If your extensions are in another directory, add it here. If the directory
|
||||
# is relative to the documentation root, use os.path.abspath to make it
|
||||
@ -55,7 +57,7 @@ MOCK_MODULES = ['deluge.ui.languages', 'deluge.ui.countries', 'deluge.ui.gtkui.g
|
||||
'twisted.web', 'twisted.web.client', 'twisted.web.error',
|
||||
'win32gui', 'win32api', 'win32con', '_winreg']
|
||||
|
||||
if on_rtd:
|
||||
if on_rtd or on_travis:
|
||||
MOCK_MODULES += ['libtorrent', 'pygtk', "gtk", "gobject", "gtk.gdk", "pango", "cairo", "pangocairo"]
|
||||
|
||||
for mod_name in MOCK_MODULES:
|
||||
@ -67,7 +69,7 @@ for mod_name in MOCK_MODULES:
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinxcontrib.napoleon']
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinxcontrib.napoleon', 'sphinx.ext.coverage']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
@ -14,10 +14,6 @@ includes = glib, gio, cairo, pango, pangocairo, atk, gobject, gtk.keysyms,
|
||||
zope.interface, mako.cache, email.mime, libtorrent, gtkosx_application
|
||||
frameworks = CoreFoundation, Foundation, AppKit
|
||||
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
builtins = _,__request__
|
||||
|
||||
[isort]
|
||||
known_standard_library=unicodedata
|
||||
line_length=120
|
||||
|
22
setup.py
22
setup.py
@ -18,6 +18,7 @@ from distutils.command.build import build as _build
|
||||
from distutils.command.clean import clean as _clean
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
import msgfmt
|
||||
from version import get_version
|
||||
@ -35,6 +36,23 @@ def windows_check():
|
||||
desktop_data = 'deluge/ui/data/share/applications/deluge.desktop'
|
||||
|
||||
|
||||
class PyTest(TestCommand):
|
||||
|
||||
def initialize_options(self):
|
||||
TestCommand.initialize_options(self)
|
||||
self.pytest_args = []
|
||||
|
||||
def finalize_options(self):
|
||||
TestCommand.finalize_options(self)
|
||||
self.test_args = []
|
||||
self.test_suite = True
|
||||
|
||||
def run_tests(self):
|
||||
import pytest
|
||||
errcode = pytest.main(self.test_args)
|
||||
sys.exit(errcode)
|
||||
|
||||
|
||||
class BuildTranslations(cmd.Command):
|
||||
description = 'Compile .po files into .mo files & create .desktop file'
|
||||
|
||||
@ -269,7 +287,8 @@ cmdclass = {
|
||||
'build_docs': BuildDocs,
|
||||
'clean_plugins': CleanPlugins,
|
||||
'clean': Clean,
|
||||
'egg_info_plugins': EggInfoPlugins
|
||||
'egg_info_plugins': EggInfoPlugins,
|
||||
'test': PyTest,
|
||||
}
|
||||
|
||||
# Data files to be installed to the system
|
||||
@ -333,6 +352,7 @@ setup(
|
||||
url="http://deluge-torrent.org",
|
||||
license="GPLv3",
|
||||
cmdclass=cmdclass,
|
||||
tests_require=['pytest'],
|
||||
data_files=_data_files,
|
||||
package_data={"deluge": ["ui/gtkui/glade/*.glade",
|
||||
"ui/gtkui/glade/*.ui",
|
||||
|
141
tox.ini
Normal file
141
tox.ini
Normal file
@ -0,0 +1,141 @@
|
||||
# Tox (http://tox.testrun.org/) is a tool for running tests
|
||||
# in multiple virtualenvs. This configuration file will run the
|
||||
# test suite on all supported python versions. To use it, "pip install tox"
|
||||
# and then run "tox" from this directory.
|
||||
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
builtins = _,__request__
|
||||
exclude = .tox, .git, dist, build
|
||||
ignore = E123,E133,E226,E241,E242
|
||||
|
||||
[tox]
|
||||
envlist = py27, py26, flake8, isort, docs
|
||||
|
||||
[testenv]
|
||||
commands = {envpython} setup.py test
|
||||
sitepackages=True
|
||||
deps =
|
||||
twisted
|
||||
service_identity
|
||||
mako
|
||||
chardet
|
||||
pyopenssl
|
||||
pyxdg
|
||||
pytest
|
||||
whitelist_externals=
|
||||
py.test
|
||||
setenv =
|
||||
PYTHONPATH = {env:PYTHONPATH}:{env:PWD}
|
||||
|
||||
[pytest]
|
||||
python_functions=test_
|
||||
norecursedirs=.tox .git dist build
|
||||
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
|
||||
|
||||
[testenv:pydef]
|
||||
commands=
|
||||
python -c "import libtorrent as lt; print lt.version"
|
||||
py.test deluge/tests
|
||||
|
||||
[testenv:plugins]
|
||||
commands=
|
||||
py.test deluge/plugins
|
||||
|
||||
[testenv:py26]
|
||||
basepython=python2.6
|
||||
commands=
|
||||
{[testenv:pydef]commands}
|
||||
|
||||
[testenv:py27]
|
||||
basepython=python2.7
|
||||
commands=
|
||||
{[testenv:pydef]commands}
|
||||
|
||||
[testenv:isort]
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
isort
|
||||
whitelist_externals=
|
||||
{[testenv]whitelist_externals}
|
||||
isort
|
||||
commands=
|
||||
python -c "import subprocess, sys; output = subprocess.check_output('isort --recursive --diff --stdout deluge docs/ *.py', shell=True); print output; sys.exit(len(output) != 0)"
|
||||
|
||||
[testenv:flake8]
|
||||
setenv =
|
||||
{[testenv]setenv}
|
||||
whitelist_externals=
|
||||
{[testenv]whitelist_externals}
|
||||
flake8
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
flake8
|
||||
pep8-naming
|
||||
commands=
|
||||
flake8 deluge
|
||||
|
||||
[testenv:flake8-complexity]
|
||||
setenv =
|
||||
{[testenv]setenv}
|
||||
whitelist_externals=
|
||||
{[testenv]whitelist_externals}
|
||||
flake8
|
||||
sh
|
||||
deps =
|
||||
{[testenv:flake8]deps}
|
||||
mccabe
|
||||
commands=
|
||||
sh -c "flake8 --max-complexity 10 deluge || true"
|
||||
|
||||
[testenv:docscoverage]
|
||||
changedir=docs
|
||||
install_command=pip install {opts} {packages}
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
sphinx
|
||||
sphinxcontrib-napoleon
|
||||
coverage
|
||||
pytest-cov
|
||||
whitelist_externals=
|
||||
{[testenv]whitelist_externals}
|
||||
mkdir
|
||||
sphinx-build
|
||||
commands=
|
||||
mkdir -p build/doccoverage
|
||||
sphinx-build -W -b coverage -d build/doctrees source build/doccoverage
|
||||
py.test --doctest-glob='*.rst'
|
||||
|
||||
[testenv:docs]
|
||||
changedir=docs
|
||||
install_command=pip install {opts} --allow-external PIL --allow-unverified PIL {packages}
|
||||
whitelist_externals=
|
||||
{[testenv]whitelist_externals}
|
||||
sphinx-build
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
sphinx
|
||||
sphinxcontrib-napoleon
|
||||
PIL
|
||||
commands=
|
||||
python -c "import sphinxcontrib.napoleon"
|
||||
sphinx-build -E -W -b html -d build/doctrees source build/html
|
Loading…
x
Reference in New Issue
Block a user