summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CrypterPluginTester.py81
-rw-r--r--tests/HosterPluginTester.py152
-rwxr-xr-xtests/clonedigger.sh2
-rw-r--r--tests/config/db.version1
-rw-r--r--tests/config/plugin.conf138
-rw-r--r--tests/config/pyload.conf.org75
-rw-r--r--tests/config/pyload.db.orgbin0 -> 13312 bytes
-rw-r--r--tests/crypterlinks.txt5
-rw-r--r--tests/helper/BenchmarkTest.py66
-rw-r--r--tests/helper/PluginTester.py151
-rw-r--r--tests/helper/Stubs.py130
-rw-r--r--tests/helper/__init__.py0
-rwxr-xr-xtests/hosterlinks.txt50
-rwxr-xr-xtests/nosetests.sh5
-rwxr-xr-xtests/plugin_tests.sh7
-rwxr-xr-xtests/pyflakes.sh5
-rwxr-xr-xtests/quit_pyload.sh7
-rwxr-xr-xtests/run_pyload.sh17
-rwxr-xr-xtests/sloccount.sh2
-rw-r--r--tests/test_api.py24
-rw-r--r--tests/test_backends.py (renamed from tests/test_json.py)25
-rw-r--r--tests/test_configparser.py48
-rw-r--r--tests/test_database.py194
-rw-r--r--tests/test_filemanager.py214
-rw-r--r--tests/test_interactionManager.py58
-rw-r--r--tests/test_syntax.py43
26 files changed, 1480 insertions, 20 deletions
diff --git a/tests/CrypterPluginTester.py b/tests/CrypterPluginTester.py
new file mode 100644
index 000000000..67e5ddebc
--- /dev/null
+++ b/tests/CrypterPluginTester.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+
+from os.path import dirname, join
+from nose.tools import nottest
+
+from logging import log, DEBUG
+
+from helper.Stubs import Core
+from helper.PluginTester import PluginTester
+
+from module.plugins.Base import Fail
+from module.utils import accumulate, to_int
+
+class CrypterPluginTester(PluginTester):
+ @nottest
+ def test_plugin(self, name, url, flag):
+
+ print "%s: %s" % (name, url.encode("utf8"))
+ log(DEBUG, "%s: %s", name, url.encode("utf8"))
+
+ plugin = self.core.pluginManager.getPluginClass(name)
+ p = plugin(self.core, None, "")
+ self.thread.plugin = p
+
+ try:
+ result = p._decrypt([url])
+
+ if to_int(flag):
+ assert to_int(flag) == len(result)
+
+ except Exception, e:
+ if isinstance(e, Fail) and flag == "fail":
+ pass
+ else:
+ raise
+
+
+# setup methods
+
+c = Core()
+
+f = open(join(dirname(__file__), "crypterlinks.txt"))
+links = [x.strip() for x in f.readlines()]
+urls = []
+flags = {}
+
+for l in links:
+ if not l or l.startswith("#"): continue
+ if l.startswith("http"):
+ if "||" in l:
+ l, flag = l.split("||")
+ flags[l] = flag
+
+ urls.append(l)
+
+h, crypter = c.pluginManager.parseUrls(urls)
+plugins = accumulate(crypter)
+for plugin, urls in plugins.iteritems():
+
+ def meta_class(plugin):
+ class _testerClass(CrypterPluginTester):
+ pass
+ _testerClass.__name__ = plugin
+ return _testerClass
+
+ _testerClass = meta_class(plugin)
+
+ for i, url in enumerate(urls):
+ def meta(plugin, url, flag, sig):
+ def _test(self):
+ self.test_plugin(plugin, url, flag)
+
+ _test.func_name = sig
+ return _test
+
+ sig = "test_LINK%d" % i
+ setattr(_testerClass, sig, meta(plugin, url, flags.get(url, None), sig))
+ print url
+
+ locals()[plugin] = _testerClass
+ del _testerClass
diff --git a/tests/HosterPluginTester.py b/tests/HosterPluginTester.py
new file mode 100644
index 000000000..627494a3f
--- /dev/null
+++ b/tests/HosterPluginTester.py
@@ -0,0 +1,152 @@
+# -*- coding: utf-8 -*-
+
+from os.path import dirname
+from logging import log, DEBUG
+from hashlib import md5
+from time import time
+from shutil import move
+import codecs
+
+from nose.tools import nottest
+
+from helper.Stubs import Core
+from helper.PluginTester import PluginTester
+
+from module.datatypes.PyFile import PyFile
+from module.plugins.Base import Fail
+from module.utils import accumulate
+from module.utils.fs import save_join, join, exists, listdir, remove, stat
+
+DL_DIR = join("Downloads", "tmp")
+
+class HosterPluginTester(PluginTester):
+ files = {}
+
+ def setUp(self):
+ PluginTester.setUp(self)
+ for f in self.files:
+ if exists(save_join(DL_DIR, f)): remove(save_join(DL_DIR, f))
+
+ # folder for reports
+ report = join("tmp", self.__class__.__name__)
+ if exists(report):
+ for f in listdir(report):
+ remove(join(report, f))
+
+
+ @nottest
+ def test_plugin(self, name, url, flag):
+ # Print to stdout to see whats going on
+ print "%s: %s, %s" % (name, url.encode("utf8"), flag)
+ log(DEBUG, "%s: %s, %s", name, url.encode("utf8"), flag)
+
+ # url and plugin should be only important thing
+ pyfile = PyFile(self.core, -1, url, url, 0, 0, "", name, 0, 0)
+ pyfile.initPlugin()
+
+ self.thread.pyfile = pyfile
+ self.thread.plugin = pyfile.plugin
+
+ try:
+ a = time()
+ pyfile.plugin.preprocessing(self.thread)
+
+ log(DEBUG, "downloading took %ds" % (time() - a))
+ log(DEBUG, "size %d kb" % (pyfile.size / 1024))
+
+ if flag == "offline":
+ raise Exception("No offline Exception raised.")
+
+ if pyfile.name not in self.files:
+ raise Exception("Filename %s not recognized." % pyfile.name)
+
+ if not exists(save_join(DL_DIR, pyfile.name)):
+ raise Exception("File %s does not exists." % pyfile.name)
+
+ hash = md5()
+ f = open(save_join(DL_DIR, pyfile.name), "rb")
+ while True:
+ buf = f.read(4096)
+ if not buf: break
+ hash.update(buf)
+ f.close()
+
+ if hash.hexdigest() != self.files[pyfile.name]:
+ log(DEBUG, "Hash is %s" % hash.hexdigest())
+
+ size = stat(f.name).st_size
+ if size < 1024 * 1024 * 10: # 10MB
+ # Copy for debug report
+ log(DEBUG, "Downloaded file copied to report")
+ move(f.name, join("tmp", plugin, f.name))
+
+ raise Exception("Hash does not match.")
+
+
+
+ except Exception, e:
+ if isinstance(e, Fail) and flag == "fail":
+ pass
+ elif isinstance(e, Fail) and flag == "offline" and e.message == "offline":
+ pass
+ else:
+ raise
+
+
+# setup methods
+
+c = Core()
+
+# decode everything as unicode
+f = codecs.open(join(dirname(__file__), "hosterlinks.txt"), "r", "utf_8")
+links = [x.strip() for x in f.readlines()]
+urls = []
+flags = {}
+
+for l in links:
+ if not l or l.startswith("#"): continue
+ if l.startswith("http"):
+ if "||" in l:
+ l, flag = l.split("||")
+ flags[l] = str(flag.strip())
+ urls.append(l)
+
+ elif len(l.rsplit(" ", 1)) == 2:
+ name, hash = l.rsplit(" ", 1)
+ HosterPluginTester.files[name] = str(hash)
+
+hoster, c = c.pluginManager.parseUrls(urls)
+
+plugins = accumulate(hoster)
+for plugin, urls in plugins.iteritems():
+ # closure functions to retain local scope
+ def meta_class(plugin):
+ class _testerClass(HosterPluginTester):
+ pass
+ _testerClass.__name__ = plugin
+ return _testerClass
+
+ _testerClass = meta_class(plugin)
+
+ for i, url in enumerate(urls):
+ def meta(__plugin, url, flag, sig):
+ def _test(self):
+ self.test_plugin(__plugin, url, flag)
+
+ _test.func_name = sig
+ return _test
+
+ tmp_flag = flags.get(url, None)
+ if flags.get(url, None):
+ sig = "test_LINK%d_%s" % (i, tmp_flag)
+ else:
+ sig = "test_LINK%d" % i
+
+ # set test method
+ setattr(_testerClass, sig, meta(plugin, url, tmp_flag, sig))
+
+
+ #register class
+ locals()[plugin] = _testerClass
+ # remove from locals, or tested twice
+ del _testerClass
diff --git a/tests/clonedigger.sh b/tests/clonedigger.sh
new file mode 100755
index 000000000..93c1cb323
--- /dev/null
+++ b/tests/clonedigger.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+clonedigger -o cpd.xml --cpd-output --fast --ignore-dir=lib --ignore-dir=remote module
diff --git a/tests/config/db.version b/tests/config/db.version
new file mode 100644
index 000000000..bf0d87ab1
--- /dev/null
+++ b/tests/config/db.version
@@ -0,0 +1 @@
+4 \ No newline at end of file
diff --git a/tests/config/plugin.conf b/tests/config/plugin.conf
new file mode 100644
index 000000000..5e7ee3858
--- /dev/null
+++ b/tests/config/plugin.conf
@@ -0,0 +1,138 @@
+version: 2
+
+[MultiuploadCom]
+preferedHoster = multiupload
+ignoredHoster =
+
+[SerienjunkiesOrg]
+preferredHoster = RapidshareCom,UploadedTo,NetloadIn,FilefactoryCom,FreakshareNet,FilebaseTo,MegauploadCom,HotfileCom,DepositfilesCom,EasyshareCom,KickloadCom
+changeName = True
+
+[EmbeduploadCom]
+preferedHoster = embedupload
+ignoredHoster =
+
+[MultiloadCz]
+usedHoster =
+ignoredHoster =
+
+[WiiReloadedOrg]
+changeName = True
+
+[Xdcc]
+nick = pyload
+ident = pyloadident
+realname = pyloadreal
+
+[UlozTo]
+reuseCaptcha = True
+captchaUser =
+captchaNb =
+
+[YoutubeCom]
+quality = hd
+fmt = 0
+.mp4 = True
+.flv = True
+.webm = False
+.3gp = False
+
+[RapidshareCom]
+server = None
+
+[VeehdCom]
+filename_spaces = False
+replacement_char = _
+
+[RealdebridCom]
+https = False
+
+[ClickAndLoad]
+activated = True
+extern = False
+
+[ExtractArchive]
+activated = True
+fullpath = True
+overwrite = True
+passwordfile = unrar_passwords.txt
+deletearchive = False
+subfolder = False
+destination =
+queue = True
+renice = 0
+
+[CaptchaTrader]
+activated = True
+username =
+force = False
+passkey =
+
+[MergeFiles]
+activated = False
+
+[IRCInterface]
+activated = False
+host = Enter your server here!
+port = 6667
+ident = pyload-irc
+realname = pyload-irc
+nick = pyLoad-IRC
+owner = Enter your nick here!
+info_file = False
+info_pack = True
+captcha = True
+
+[Ev0InFetcher]
+activated = False
+interval = 10
+queue = False
+shows =
+quality = xvid
+hoster = NetloadIn,RapidshareCom,MegauploadCom,HotfileCom
+
+[EasybytezCom]
+activated = False
+includeHoster =
+excludeHoster =
+
+[XMPPInterface]
+activated = False
+jid = user@exmaple-jabber-server.org
+pw =
+tls = False
+owners = me@icq-gateway.org;some@msn-gateway.org
+info_file = False
+info_pack = True
+captcha = True
+
+[RehostTo]
+activated = False
+
+[MultiHoster]
+activated = True
+
+[MultiHome]
+activated = False
+interfaces = None
+
+[MultishareCz]
+activated = False
+includeHoster =
+excludeHoster = rapidshare.com|uloz.to
+
+[HotFolder]
+activated = False
+folder = container
+watch_file = False
+keep = True
+file = links.txt
+
+[ExternalScripts]
+activated = True
+
+[UpdateManager]
+activated = True
+interval = 360
+debug = False
+
diff --git a/tests/config/pyload.conf.org b/tests/config/pyload.conf.org
new file mode 100644
index 000000000..7fb1c8c87
--- /dev/null
+++ b/tests/config/pyload.conf.org
@@ -0,0 +1,75 @@
+version: 2
+
+[remote]
+nolocalauth = False
+activated = True
+port = 7227
+listenaddr = 127.0.0.1
+
+[log]
+log_size = 100
+log_folder = Logs
+file_log = False
+log_count = 5
+log_rotate = True
+
+[permission]
+group = users
+change_dl = False
+change_file = False
+user = user
+file = 0644
+change_group = False
+folder = 0755
+change_user = False
+
+[general]
+language = en
+download_folder = Downloads
+checksum = False
+folder_per_package = True
+debug_mode = True
+min_free_space = 200
+renice = 0
+
+[ssl]
+cert = ssl.crt
+activated = False
+key = ssl.key
+
+[webinterface]
+template = default
+activated = True
+prefix =
+server = builtin
+host = 127.0.0.1
+https = False
+port = 8001
+
+[proxy]
+username =
+proxy = False
+address = localhost
+password =
+type = http
+port = 7070
+
+[reconnect]
+endTime = 0:00
+activated = False
+method = ./reconnect.sh
+startTime = 0:00
+
+[download]
+max_downloads = 3
+limit_speed = False
+interface =
+skip_existing = False
+max_speed = -1
+ipv6 = False
+chunks = 3
+
+[downloadTime]
+start = 0:00
+end = 0:00
+
diff --git a/tests/config/pyload.db.org b/tests/config/pyload.db.org
new file mode 100644
index 000000000..d340531c5
--- /dev/null
+++ b/tests/config/pyload.db.org
Binary files differ
diff --git a/tests/crypterlinks.txt b/tests/crypterlinks.txt
new file mode 100644
index 000000000..4ff651888
--- /dev/null
+++ b/tests/crypterlinks.txt
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+
+# Crypter links, append ||fail or ||#N to mark error or number of expected results (single links+packages)
+
+http://www.filesonic.com/folder/19906605||2
diff --git a/tests/helper/BenchmarkTest.py b/tests/helper/BenchmarkTest.py
new file mode 100644
index 000000000..d28c52959
--- /dev/null
+++ b/tests/helper/BenchmarkTest.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+from time import time
+
+
+class BenchmarkTest:
+
+ bench = []
+ results = {}
+
+ @classmethod
+ def timestamp(cls, name, a):
+ t = time()
+ r = cls.results.get(name, [])
+ r.append((t-a) * 1000)
+ cls.results[name] = r
+
+ @classmethod
+ def benchmark(cls, n=1):
+
+ print "Benchmarking %s" % cls.__name__
+ print
+
+ for i in range(n):
+ cls.collect_results()
+
+ if "setUpClass" in cls.results:
+ cls.bench.insert(0, "setUpClass")
+
+ if "tearDownClass" in cls.results:
+ cls.bench.append("tearDownClass")
+
+ length = str(max([len(k) for k in cls.bench]) + 1)
+ total = 0
+
+ for k in cls.bench:
+ v = cls.results[k]
+
+ if len(v) > 1:
+ print ("%" + length +"s: %s | average: %.2f ms") % (k, ", ".join(["%.2f" % x for x in v]), sum(v)/len(v))
+ total += sum(v)/len(v)
+ else:
+ print ("%" + length +"s: %.2f ms") % (k, v[0])
+ total += v[0]
+
+ print "\ntotal: %.2f ms" % total
+
+
+ @classmethod
+ def collect_results(cls):
+ if hasattr(cls, "setUpClass"):
+ a = time()
+ cls.setUpClass()
+ cls.timestamp("setUpClass", a)
+
+ obj = cls()
+
+ for f in cls.bench:
+ a = time()
+ getattr(obj, "test_" + f)()
+ cls.timestamp(f, a)
+
+ if hasattr(cls, "tearDownClass"):
+ a = time()
+ cls.tearDownClass()
+ cls.timestamp("tearDownClass", a) \ No newline at end of file
diff --git a/tests/helper/PluginTester.py b/tests/helper/PluginTester.py
new file mode 100644
index 000000000..ef61385be
--- /dev/null
+++ b/tests/helper/PluginTester.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+
+from unittest import TestCase
+from os import makedirs, remove
+from os.path import exists, join, expanduser
+from shutil import move
+from sys import exc_clear, exc_info
+from logging import log, DEBUG
+from time import sleep, time
+from random import randint
+from glob import glob
+
+from pycurl import LOW_SPEED_TIME, FORM_FILE
+from json import loads
+
+from Stubs import Thread, Core, noop
+
+from module.network.RequestFactory import getRequest, getURL
+from module.plugins.Hoster import Hoster, Abort, Fail
+
+def _wait(self):
+ """ waits the time previously set """
+ self.waiting = True
+
+ waittime = self.pyfile.waitUntil - time()
+ log(DEBUG, "waiting %ss" % waittime)
+
+ if self.wantReconnect and waittime > 300:
+ raise Fail("Would wait for reconnect %ss" % waittime)
+ elif waittime > 300:
+ raise Fail("Would wait %ss" % waittime)
+
+ while self.pyfile.waitUntil > time():
+ sleep(1)
+ if self.pyfile.abort: raise Abort
+
+ self.waiting = False
+ self.pyfile.setStatus("starting")
+
+Hoster.wait = _wait
+
+
+def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype='jpg',
+ result_type='textual'):
+ img = self.load(url, get=get, post=post, cookies=cookies)
+
+ id = ("%.2f" % time())[-6:].replace(".", "")
+ temp_file = open(join("tmp", "tmpCaptcha_%s_%s.%s" % (self.__name__, id, imgtype)), "wb")
+ temp_file.write(img)
+ temp_file.close()
+
+ Ocr = self.core.pluginManager.loadClass("captcha", self.__name__)
+
+ if Ocr:
+ log(DEBUG, "Using tesseract for captcha")
+ sleep(randint(3000, 5000) / 1000.0)
+ if self.pyfile.abort: raise Abort
+
+ ocr = Ocr()
+ result = ocr.get_captcha(temp_file.name)
+ else:
+ log(DEBUG, "Using ct for captcha")
+ # put username and passkey into two lines in ct.conf
+ conf = join(expanduser("~"), "ct.conf")
+ if not exists(conf): raise Exception("CaptchaTrader config %s not found." % conf)
+ f = open(conf, "rb")
+ req = getRequest()
+
+ #raise timeout threshold
+ req.c.setopt(LOW_SPEED_TIME, 80)
+
+ try:
+ json = req.load("http://captchatrader.com/api/submit",
+ post={"api_key": "9f65e7f381c3af2b076ea680ae96b0b7",
+ "username": f.readline().strip(),
+ "password": f.readline().strip(),
+ "value": (FORM_FILE, temp_file.name),
+ "type": "file"}, multipart=True)
+ finally:
+ f.close()
+ req.close()
+
+ response = loads(json)
+ log(DEBUG, str(response))
+ result = response[1]
+
+ self.cTask = response[0]
+
+ return result
+
+Hoster.decryptCaptcha = decryptCaptcha
+
+
+def respond(ticket, value):
+ conf = join(expanduser("~"), "ct.conf")
+ f = open(conf, "rb")
+ try:
+ getURL("http://captchatrader.com/api/respond",
+ post={"is_correct": value,
+ "username": f.readline().strip(),
+ "password": f.readline().strip(),
+ "ticket": ticket})
+ except Exception, e :
+ print "CT Exception:", e
+ log(DEBUG, str(e))
+ finally:
+ f.close()
+
+
+
+def invalidCaptcha(self):
+ log(DEBUG, "Captcha invalid")
+ if self.cTask:
+ respond(self.cTask, 0)
+
+Hoster.invalidCaptcha = invalidCaptcha
+
+def correctCaptcha(self):
+ log(DEBUG, "Captcha correct")
+ if self.cTask:
+ respond(self.cTask, 1)
+
+Hoster.correctCaptcha = correctCaptcha
+
+Hoster.checkForSameFiles = noop
+
+class PluginTester(TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.core = Core()
+ name = "%s.%s" % (cls.__module__, cls.__name__)
+ for f in glob(join(name, "debug_*")):
+ remove(f)
+
+ # Copy debug report to attachment dir for jenkins
+ @classmethod
+ def tearDownClass(cls):
+ name = "%s.%s" % (cls.__module__, cls.__name__)
+ if not exists(name): makedirs(name)
+ for f in glob("debug_*"):
+ move(f, join(name, f))
+
+ def setUp(self):
+ self.thread = Thread(self.core)
+ exc_clear()
+
+ def tearDown(self):
+ exc = exc_info()
+ if exc != (None, None, None):
+ debug = self.thread.writeDebugReport()
+ log(DEBUG, debug)
diff --git a/tests/helper/Stubs.py b/tests/helper/Stubs.py
new file mode 100644
index 000000000..5c44cfb58
--- /dev/null
+++ b/tests/helper/Stubs.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+import sys
+from os.path import abspath, dirname, join
+from time import strftime
+from traceback import format_exc
+
+sys.path.append(abspath(join(dirname(__file__), "..", "..", "module", "lib")))
+sys.path.append(abspath(join(dirname(__file__), "..", "..")))
+
+import __builtin__
+
+from module.datatypes.PyPackage import PyPackage
+from module.threads.BaseThread import BaseThread
+from module.config.ConfigParser import ConfigParser
+from module.network.RequestFactory import RequestFactory
+from module.PluginManager import PluginManager
+from module.common.JsEngine import JsEngine
+
+from logging import log, DEBUG, INFO, WARN, ERROR
+
+
+# Do nothing
+def noop(*args, **kwargs):
+ pass
+
+ConfigParser.save = noop
+
+class LogStub:
+ def debug(self, *args):
+ log(DEBUG, *args)
+
+ def info(self, *args):
+ log(INFO, *args)
+
+ def error(self, *args):
+ log(ERROR, *args)
+
+ def warning(self, *args):
+ log(WARN, *args)
+
+
+class NoLog:
+ def debug(self, *args):
+ pass
+
+ def info(self, *args):
+ pass
+
+ def error(self, *args):
+ log(ERROR, *args)
+
+ def warning(self, *args):
+ log(WARN, *args)
+
+
+class Core:
+ def __init__(self):
+ self.log = NoLog()
+
+ self.api = self.core = self
+ self.threadManager = self
+ self.debug = True
+ self.captcha = True
+ self.config = ConfigParser()
+ self.pluginManager = PluginManager(self)
+ self.requestFactory = RequestFactory(self)
+ __builtin__.pyreq = self.requestFactory
+ self.accountManager = AccountManager()
+ self.addonManager = AddonManager()
+ self.eventManager = self.interActionManager = NoopClass()
+ self.js = JsEngine()
+ self.cache = {}
+ self.packageCache = {}
+
+ self.log = LogStub()
+
+ def getServerVersion(self):
+ return "TEST_RUNNER on %s" % strftime("%d %h %Y")
+
+ def path(self, path):
+ return path
+
+ def updateLink(self, *args):
+ pass
+
+ def updatePackage(self, *args):
+ pass
+
+ def processingIds(self, *args):
+ return []
+
+ def getPackage(self, id):
+ return PyPackage(self, 0, "tmp", "tmp", "", "", 0, 0)
+
+ def print_exc(self):
+ log(ERROR, format_exc())
+
+
+class NoopClass:
+ def __getattr__(self, item):
+ return noop
+
+class AddonManager(NoopClass):
+ def activePlugins(self):
+ return []
+
+class AccountManager:
+
+ def getAccountForPlugin(self, name):
+ return None
+
+class Thread(BaseThread):
+ def __init__(self, core):
+ BaseThread.__init__(self, core)
+ self.plugin = None
+
+
+ def writeDebugReport(self):
+ if hasattr(self, "pyfile"):
+ dump = BaseThread.writeDebugReport(self, self.plugin.__name__, pyfile=self.pyfile)
+ else:
+ dump = BaseThread.writeDebugReport(self, self.plugin.__name__, plugin=self.plugin)
+
+ return dump
+
+__builtin__._ = lambda x: x
+__builtin__.pypath = abspath(join(dirname(__file__), "..", ".."))
+__builtin__.addonManager = AddonManager()
+__builtin__.pyreq = None
diff --git a/tests/helper/__init__.py b/tests/helper/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/helper/__init__.py
diff --git a/tests/hosterlinks.txt b/tests/hosterlinks.txt
new file mode 100755
index 000000000..70dcc44f6
--- /dev/null
+++ b/tests/hosterlinks.txt
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# Valid files, with md5 hash
+# Please only use files around 5-15 MB and with explicit permission for redistribution
+
+http://download.pyload.org/random.bin
+random.bin d76505d0869f9f928a17d42d66326307
+Mořská želva ( Зелёная черепаха .&+ 綠蠵龜 _@- Đồi mồi dứa ).tar 932212256dc0b0a1e71c0944eef633a4
+Mořská_želva_(_Зелёная_черепаха_.&+_綠蠵龜__@-_Đồi_mồi_dứa_).tar 932212256dc0b0a1e71c0944eef633a4
+
+# Hoster links, append ||offline or ||fail to mark your expectation
+
+http://netload.in/datei9XirAJZs79/random.bin.htm
+http://rapidshare.com/files/445996776/random.bin
+http://hotfile.com/dl/101569859/2e01f04/random.bin.html
+http://www.megaupload.com/?d=1JZLOP3B
+http://www.shragle.com/files/f899389b/random.bin
+http://www10.zippyshare.com/v/76557688/file.html
+http://yourfiles.to/?d=312EC6E911
+http://depositfiles.com/files/k8la98953
+http://uploading.com/files/3896f5a1/random.bin/
+
+
+http://ul.to/file/o41isx||offline
+http://www.4shared.com/file/-O5CBhQV/random.html||offline
+http://www.4shared.com/file/-O5CBhQV/random.html||offline
+http://www.fileserve.com/file/MxjZXjX||offline
+http://www.share-online.biz/download.php?id=PTCOX1GL6XAH||offline
+http://dl.free.fr/d4aL5dyXY||offline
+http://files.mail.ru/32EW66||offline
+http://www.shragle.com/files/f899389b/random.bin||offline
+
+
+# Hoster links with fancy unicode filenames:
+http://vs3iaw.1fichier.com/fr/
+http://www.4shared.com/file/rQltf2Fr/Mosk_elva___Зелная_черепаха___.html
+http://bezvadata.cz/stahnout/99273_morska-zelva-.-d-i-m-i-d-a-.tar
+http://www.crocko.com/A524453DA89841B4BFC4FB9125D6F186/
+http://czshare.com/2483034/zelva
+http://www.easybytez.com/etvhltkg0d05
+http://www.filejungle.com/f/qX5fxT/
+http://fp.io/43798f2b/
+http://www.filesonic.com/file/yU2cU6s
+http://www.fshare.vn/file/A7H8LSTP7Z/
+http://ifile.it/muwgivz
+http://letitbit.net/download/67793.60a7d3745791db7271a6e6c92cfe/Mořská_želva_(_Зелёная_черепаха_.___綠蠵龜___-_Đồi_mồi_dứa_).tar.html
+http://www.mediafire.com/file/n09th58z1x5r585
+http://www.quickshare.cz/stahnout-soubor/676150:morska-zelva----_-oi-moi-dua-tar_6MB
+http://www.uloz.to/12553820/morska-zelva-oi-moi-dua-tar
+http://www.wupload.com/file/2642593407/ \ No newline at end of file
diff --git a/tests/nosetests.sh b/tests/nosetests.sh
new file mode 100755
index 000000000..c68861b90
--- /dev/null
+++ b/tests/nosetests.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+NS=nosetests
+which nosetests2 > /dev/null && NS=nosetests2
+$NS tests/ --with-coverage --with-xunit --cover-package=module --cover-erase
+coverage xml
diff --git a/tests/plugin_tests.sh b/tests/plugin_tests.sh
new file mode 100755
index 000000000..be06c0dc5
--- /dev/null
+++ b/tests/plugin_tests.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+NS=nosetests
+which nosetests2 > /dev/null && NS=nosetests2
+# must be executed within tests dir
+cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+$NS HosterPluginTester.py CrypterPluginTester.py -s --with-xunit --with-coverage --cover-erase --cover-package=module.plugins --with-id
+coverage xml
diff --git a/tests/pyflakes.sh b/tests/pyflakes.sh
new file mode 100755
index 000000000..0c7e03891
--- /dev/null
+++ b/tests/pyflakes.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+find -name '*.py' |egrep -v '^.(/tests/|/module/lib)'|xargs pyflakes > pyflakes.log || :
+# Filter warnings and strip ./ from path
+cat pyflakes.log | awk -F\: '{printf "%s:%s: [E]%s\n", $1, $2, $3}' | grep -i -E -v "'_'|pypath|webinterface|pyreq|hookmanager" > pyflakes.txt
+sed -i 's/^.\///g' pyflakes.txt
diff --git a/tests/quit_pyload.sh b/tests/quit_pyload.sh
new file mode 100755
index 000000000..e466bcb31
--- /dev/null
+++ b/tests/quit_pyload.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+PYTHON=python
+which python2 > /dev/null && PYTHON=python2
+$PYTHON pyLoadCore.py --configdir=tests/config --quit
+if [ -d userplugins ]; then
+ rm -r userplugins
+fi \ No newline at end of file
diff --git a/tests/run_pyload.sh b/tests/run_pyload.sh
new file mode 100755
index 000000000..66498cd10
--- /dev/null
+++ b/tests/run_pyload.sh
@@ -0,0 +1,17 @@
+#/usr/bin/env bash
+cp tests/config/pyload.db.org tests/config/pyload.db
+cp tests/config/pyload.conf.org tests/config/pyload.conf
+
+PYTHON=python
+which python2 > /dev/null && PYTHON=python2
+
+touch pyload.out
+$PYTHON pyLoadCore.py -d --configdir=tests/config > pyload.out 2> pyload.err &
+
+for i in {1..30}; do
+ grep 8001 pyload.out > /dev/null && echo "pyLoad started" && break
+ sleep 1
+done
+
+echo "pyLoad start script finished"
+
diff --git a/tests/sloccount.sh b/tests/sloccount.sh
new file mode 100755
index 000000000..0dab4164e
--- /dev/null
+++ b/tests/sloccount.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+sloccount --duplicates --wide --details module > sloccount.sc
diff --git a/tests/test_api.py b/tests/test_api.py
index f8901f731..0171b46bb 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -1,20 +1,18 @@
-# -*- coding: utf-8 -*-
-from module.common import APIExerciser
-from nose.tools import nottest
+from unittest import TestCase
+from pyLoadCore import Core
+from module.common.APIExerciser import APIExerciser
-class TestApi:
+class TestApi(TestCase):
- def __init__(self):
- self.api = APIExerciser.APIExerciser(None, True, "TestUser", "pwhere")
+ @classmethod
+ def setUpClass(cls):
+ cls.core = Core()
+ cls.core.start(False, False, True)
- def test_login(self):
- assert self.api.api.login("crapp", "wrong pw") is False
-
- #takes really long, only test when needed
- @nottest
def test_random(self):
+ api = APIExerciser(self.core)
- for i in range(0, 100):
- self.api.testAPI()
+ for i in range(2000):
+ api.testAPI()
diff --git a/tests/test_json.py b/tests/test_backends.py
index ff56e8f5a..71ccedd2f 100644
--- a/tests/test_json.py
+++ b/tests/test_backends.py
@@ -1,14 +1,30 @@
# -*- coding: utf-8 -*-
+
from urllib import urlencode
from urllib2 import urlopen, HTTPError
from json import loads
from logging import log
+from module.common import APIExerciser
+
url = "http://localhost:8001/api/%s"
-class TestJson:
+class TestBackends():
+
+ def setUp(self):
+ u = urlopen(url % "login", data=urlencode({"username": "TestUser", "password": "sometestpw"}))
+ self.key = loads(u.read())
+ assert self.key is not False
+
+ def test_random(self):
+ api = APIExerciser.APIExerciser(None, True, "TestUser", "sometestpw")
+
+ assert api.api.login("crapp", "wrong pw") is False
+
+ for i in range(0, 1000):
+ api.testAPI()
def call(self, name, post=None):
if not post: post = {}
@@ -16,11 +32,6 @@ class TestJson:
u = urlopen(url % name, data=urlencode(post))
return loads(u.read())
- def setUp(self):
- u = urlopen(url % "login", data=urlencode({"username": "TestUser", "password": "pwhere"}))
- self.key = loads(u.read())
- assert self.key is not False
-
def test_wronglogin(self):
u = urlopen(url % "login", data=urlencode({"username": "crap", "password": "wrongpw"}))
assert loads(u.read()) is False
@@ -45,4 +56,4 @@ class TestJson:
except HTTPError, e:
assert e.code == 404
else:
- assert False \ No newline at end of file
+ assert False
diff --git a/tests/test_configparser.py b/tests/test_configparser.py
new file mode 100644
index 000000000..d797c7912
--- /dev/null
+++ b/tests/test_configparser.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+from collections import defaultdict
+from helper.Stubs import Core
+
+from module.database import DatabaseBackend
+from module.config.ConfigParser import ConfigParser
+
+# TODO
+class TestConfigParser():
+
+ @classmethod
+ def setUpClass(cls):
+ cls.db = DatabaseBackend(Core())
+ cls.db.manager = cls.db.core
+ cls.db.manager.statusMsg = defaultdict(lambda: "statusmsg")
+ cls.config = ConfigParser()
+ cls.db.setup()
+ cls.db.clearAllConfigs()
+
+
+ def test_db(self):
+
+ self.db.saveConfig("plugin", "some value", 0)
+ self.db.saveConfig("plugin", "some other value", 1)
+
+ assert self.db.loadConfig("plugin", 0) == "some value"
+ assert self.db.loadConfig("plugin", 1) == "some other value"
+
+ d = self.db.loadAllConfigs()
+ assert d[0]["plugin"] == "some value"
+
+ self.db.deleteConfig("plugin")
+
+ assert not self.db.loadAllConfigs()
+
+
+ def test_dict(self):
+
+ assert self.config["general"]["language"]
+ self.config["general"]["language"] = "de"
+ assert self.config["general"]["language"] == "de"
+
+ def test_config(self):
+ pass
+
+ def test_userconfig(self):
+ pass \ No newline at end of file
diff --git a/tests/test_database.py b/tests/test_database.py
new file mode 100644
index 000000000..b7408e213
--- /dev/null
+++ b/tests/test_database.py
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+
+from collections import defaultdict
+
+from helper.Stubs import Core
+from helper.BenchmarkTest import BenchmarkTest
+
+from module.database import DatabaseBackend
+
+# disable asyncronous queries
+DatabaseBackend.async = DatabaseBackend.queue
+
+from random import choice
+
+class TestDatabase(BenchmarkTest):
+ bench = ["insert", "insert_links", "insert_many", "get_packages",
+ "get_files", "get_files_queued", "get_package_childs", "get_package_files",
+ "get_package_data", "get_file_data", "find_files", "collector", "purge"]
+ pids = None
+ fids = None
+ owner = 123
+ pstatus = 0
+
+ @classmethod
+ def setUpClass(cls):
+ cls.pids = [-1]
+ cls.fids = []
+
+ cls.db = DatabaseBackend(Core())
+ cls.db.manager = cls.db.core
+ cls.db.manager.statusMsg = defaultdict(lambda: "statusmsg")
+
+ cls.db.setup()
+ cls.db.purgeAll()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.db.purgeAll()
+ cls.db.shutdown()
+
+ # benchmarker ignore setup
+ def setUp(self):
+ self.db.purgeAll()
+ self.pids = [-1]
+ self.fids = []
+
+ self.test_insert(20)
+ self.test_insert_many()
+ self.fids = self.db.getAllFiles().keys()
+
+
+ def test_insert(self, n=200):
+ for i in range(n):
+ pid = self.db.addPackage("name", "folder", choice(self.pids), "password", "site", "comment", self.pstatus,
+ self.owner)
+ self.pids.append(pid)
+
+ def test_insert_links(self):
+ for i in range(10000):
+ fid = self.db.addLink("url %s" % i, "name", "plugin", choice(self.pids), self.owner)
+ self.fids.append(fid)
+
+ def test_insert_many(self):
+ for pid in self.pids:
+ self.db.addLinks([("url %s" % i, "plugin") for i in range(50)], pid, self.owner)
+
+ def test_get_packages(self):
+ packs = self.db.getAllPackages()
+ n = len(packs)
+ assert n == len(self.pids) - 1
+
+ print "Fetched %d packages" % n
+ self.assert_pack(choice(packs.values()))
+
+ def test_get_files(self):
+ files = self.db.getAllFiles()
+ n = len(files)
+ assert n >= len(self.pids)
+
+ print "Fetched %d files" % n
+ self.assert_file(choice(files.values()))
+
+ def test_get_files_queued(self):
+ files = self.db.getAllFiles(unfinished=True)
+ print "Fetched %d files queued" % len(files)
+
+ def test_delete(self):
+ pid = choice(self.pids)
+ self.db.deletePackage(pid)
+ self.pids.remove(pid)
+
+ def test_get_package_childs(self):
+ pid = choice(self.pids)
+ packs = self.db.getAllPackages(root=pid)
+
+ print "Package %d has %d packages" % (pid, len(packs))
+ self.assert_pack(choice(packs.values()))
+
+ def test_get_package_files(self):
+ pid = choice(self.pids)
+ files = self.db.getAllFiles(package=pid)
+
+ print "Package %d has %d files" % (pid, len(files))
+ self.assert_file(choice(files.values()))
+
+ def test_get_package_data(self, stats=False):
+ pid = choice(self.pids)
+ p = self.db.getPackageInfo(pid, stats)
+ self.assert_pack(p)
+ # test again with stat
+ if not stats:
+ self.test_get_package_data(True)
+
+ def test_get_file_data(self):
+ fid = choice(self.fids)
+ f = self.db.getFileInfo(fid)
+ self.assert_file(f)
+
+ def test_find_files(self):
+ files = self.db.getAllFiles(search="1")
+ print "Found %s files" % len(files)
+ f = choice(files.values())
+
+ assert "1" in f.name
+
+ def test_collector(self):
+ self.db.saveCollector(0, "data")
+ assert self.db.retrieveCollector(0) == "data"
+ self.db.deleteCollector(0)
+
+ def test_purge(self):
+ self.db.purgeLinks()
+
+
+ def test_user_context(self):
+ self.db.purgeAll()
+
+ p1 = self.db.addPackage("name", "folder", 0, "password", "site", "comment", self.pstatus, 0)
+ self.db.addLink("url", "name", "plugin", p1, 0)
+ p2 = self.db.addPackage("name", "folder", 0, "password", "site", "comment", self.pstatus, 1)
+ self.db.addLink("url", "name", "plugin", p2, 1)
+
+ assert len(self.db.getAllPackages(owner=0)) == 1 == len(self.db.getAllFiles(owner=0))
+ assert len(self.db.getAllPackages(root=0, owner=0)) == 1 == len(self.db.getAllFiles(package=p1, owner=0))
+ assert len(self.db.getAllPackages(owner=1)) == 1 == len(self.db.getAllFiles(owner=1))
+ assert len(self.db.getAllPackages(root=0, owner=1)) == 1 == len(self.db.getAllFiles(package=p2, owner=1))
+ assert len(self.db.getAllPackages()) == 2 == len(self.db.getAllFiles())
+
+ self.db.deletePackage(p1, 1)
+ assert len(self.db.getAllPackages(owner=0)) == 1 == len(self.db.getAllFiles(owner=0))
+ self.db.deletePackage(p1, 0)
+ assert len(self.db.getAllPackages(owner=1)) == 1 == len(self.db.getAllFiles(owner=1))
+ self.db.deletePackage(p2)
+
+ assert len(self.db.getAllPackages()) == 0
+
+ def test_count(self):
+ self.db.purgeAll()
+
+ assert self.db.filecount() == 0
+ assert self.db.queuecount() == 0
+ assert self.db.proccesscount() == 0
+
+ def assert_file(self, f):
+ try:
+ assert f is not None
+ self.assert_int(f, ("fid", "status", "size", "media", "fileorder", "added", "package", "owner"))
+ assert f.status in range(5)
+ assert f.owner == self.owner
+ assert f.media in range(1024)
+ assert f.package in self.pids
+ assert f.added > 10 ** 6 # date is usually big integer
+ except:
+ print f
+ raise
+
+ def assert_pack(self, p):
+ try:
+ assert p is not None
+ self.assert_int(p, ("pid", "root", "added", "status", "packageorder", "owner"))
+ assert p.pid in self.pids
+ assert p.owner == self.owner
+ assert p.status in range(5)
+ assert p.root in self.pids
+ assert p.added > 10 ** 6
+ except:
+ print p
+ raise
+
+ def assert_int(self, obj, list):
+ for attr in list: assert type(getattr(obj, attr)) == int
+
+if __name__ == "__main__":
+ TestDatabase.benchmark() \ No newline at end of file
diff --git a/tests/test_filemanager.py b/tests/test_filemanager.py
new file mode 100644
index 000000000..f5bdd9df3
--- /dev/null
+++ b/tests/test_filemanager.py
@@ -0,0 +1,214 @@
+# -*- coding: utf-8 -*-
+
+from random import choice
+
+from helper.Stubs import Core
+from helper.BenchmarkTest import BenchmarkTest
+
+from module.database import DatabaseBackend
+# disable asyncronous queries
+DatabaseBackend.async = DatabaseBackend.queue
+
+from module.FileManager import FileManager
+
+class TestFileManager(BenchmarkTest):
+ bench = ["add_packages", "add_files", "get_files_root", "get",
+ "get_package_content", "get_package_tree",
+ "order_package", "order_files", "move"]
+
+ pids = [-1]
+ count = 100
+
+ @classmethod
+ def setUpClass(cls):
+ c = Core()
+ # db needs seperate initialisation
+ cls.db = c.db = DatabaseBackend(c)
+ cls.db.setup()
+ cls.db.purgeAll()
+
+ cls.m = cls.db.manager = FileManager(c)
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.db.purgeAll()
+ cls.db.shutdown()
+
+
+ # benchmarker ignore setup
+ def setUp(self):
+ self.db.purgeAll()
+ self.pids = [-1]
+
+ self.count = 20
+ self.test_add_packages()
+ self.test_add_files()
+
+ def test_add_packages(self):
+ for i in range(100):
+ pid = self.m.addPackage("name", "folder", choice(self.pids), "", "", "", False)
+ self.pids.append(pid)
+
+ if -1 in self.pids:
+ self.pids.remove(-1)
+
+ def test_add_files(self):
+ for pid in self.pids:
+ self.m.addLinks([("plugin %d" % i, "url %s" % i) for i in range(self.count)], pid)
+
+ count = self.m.getQueueCount()
+ files = self.count * len(self.pids)
+ # in test runner files get added twice
+ assert count == files or count == files * 2
+
+ def test_get(self):
+ info = self.m.getPackageInfo(choice(self.pids))
+ assert info.stats.linkstotal == self.count
+
+ fid = choice(info.fids)
+ f = self.m.getFile(fid)
+ assert f.fid in self.m.files
+
+ f.name = "new name"
+ f.sync()
+ finfo = self.m.getFileInfo(fid)
+ assert finfo is not None
+ assert finfo.name == "new name"
+
+ p = self.m.getPackage(choice(self.pids))
+ assert p is not None
+ assert p.pid in self.m.packages
+ p.sync()
+
+ p.delete()
+
+ self.m.getTree(-1, True, False)
+
+
+ def test_get_files_root(self):
+ view = self.m.getTree(-1, True, False)
+
+ for pid in self.pids:
+ assert pid in view.packages
+
+ assert len(view.packages) == len(self.pids)
+
+ p = choice(view.packages.values())
+ assert len(p.fids) == self.count
+ assert p.stats.linkstotal == self.count
+
+
+ def test_get_package_content(self):
+ view = self.m.getTree(choice(self.pids), False, False)
+ p = view.root
+
+ assert len(view.packages) == len(p.pids)
+ for pid in p.pids: assert pid in view.packages
+
+ def test_get_package_tree(self):
+ view = self.m.getTree(choice(self.pids), True, False)
+ for pid in view.root.pids: assert pid in view.packages
+ for fid in view.root.fids: assert fid in view.files
+
+ def test_delete(self):
+ self.m.deleteFile(self.count * 5)
+ self.m.deletePackage(choice(self.pids))
+
+ def test_order_package(self):
+ parent = self.m.addPackage("order", "", -1, "", "", "", False)
+ self.m.addLinks([("url", "plugin") for i in range(100)], parent)
+
+ pids = [self.m.addPackage("c", "", parent, "", "", "", False) for i in range(5)]
+ v = self.m.getTree(parent, False, False)
+ self.assert_ordered(pids, 0, 5, v.root.pids, v.packages, True)
+
+ pid = v.packages.keys()[0]
+ self.assert_pack_ordered(parent, pid, 3)
+ self.assert_pack_ordered(parent, pid, 0)
+ self.assert_pack_ordered(parent, pid, 0)
+ self.assert_pack_ordered(parent, pid, 4)
+ pid = v.packages.keys()[2]
+ self.assert_pack_ordered(parent, pid, 4)
+ self.assert_pack_ordered(parent, pid, 3)
+ self.assert_pack_ordered(parent, pid, 2)
+
+
+ def test_order_files(self):
+ parent = self.m.addPackage("order", "", -1, "", "", "", False)
+ self.m.addLinks([("url", "plugin") for i in range(100)], parent)
+ v = self.m.getTree(parent, False, False)
+
+ fids = v.root.fids[10:20]
+ v = self.assert_files_ordered(parent, fids, 0)
+
+ fids = v.root.fids[20:30]
+
+ self.m.orderFiles(fids, parent, 99)
+ v = self.m.getTree(parent, False, False)
+ assert fids[-1] == v.root.fids[-1]
+ assert fids[0] == v.root.fids[90]
+ self.assert_ordered(fids, 90, 100, v.root.fids, v.files)
+
+ fids = v.root.fids[80:]
+ v = self.assert_files_ordered(parent, fids, 20)
+
+ self.m.orderFiles(fids, parent, 80)
+ v = self.m.getTree(parent, False, False)
+ self.assert_ordered(fids, 61, 81, v.root.fids, v.files)
+
+ fids = v.root.fids[50:51]
+ self.m.orderFiles(fids, parent, 99)
+ v = self.m.getTree(parent, False, False)
+ self.assert_ordered(fids, 99, 100, v.root.fids, v.files)
+
+ fids = v.root.fids[50:51]
+ v = self.assert_files_ordered(parent, fids, 0)
+
+
+ def assert_files_ordered(self, parent, fids, pos):
+ fs = [self.m.getFile(choice(fids)) for i in range(5)]
+ self.m.orderFiles(fids, parent, pos)
+ v = self.m.getTree(parent, False, False)
+ self.assert_ordered(fids, pos, pos+len(fids), v.root.fids, v.files)
+
+ return v
+
+ def assert_pack_ordered(self, parent, pid, pos):
+ self.m.orderPackage(pid, pos)
+ v = self.m.getTree(parent, False, False)
+ self.assert_ordered([pid], pos, pos+1, v.root.pids, v.packages, True)
+
+ # assert that ordering is total, complete with no gaps
+ def assert_ordered(self, part, start, end, data, dict, pack=False):
+ assert data[start:end] == part
+ if pack:
+ assert sorted([p.packageorder for p in dict.values()]) == range(len(dict))
+ assert [dict[pid].packageorder for pid in part] == range(start, end)
+ else:
+ assert sorted([f.fileorder for f in dict.values()]) == range(len(dict))
+ assert [dict[fid].fileorder for fid in part] == range(start, end)
+
+
+ def test_move(self):
+
+ pid = self.pids[-1]
+ pid2 = self.pids[1]
+
+ self.m.movePackage(pid, -1)
+ v = self.m.getTree(-1, False, False)
+
+ assert v.root.pids[-1] == pid
+ assert sorted([p.packageorder for p in v.packages.values()]) == range(len(v.packages))
+
+ v = self.m.getTree(pid, False, False)
+ fids = v.root.fids[10:20]
+ self.m.moveFiles(fids, pid2)
+ v = self.m.getTree(pid2, False, False)
+
+ assert sorted([f.fileorder for f in v.files.values()]) == range(len(v.files))
+ assert len(v.files) == self.count + len(fids)
+
+
+
+if __name__ == "__main__":
+ TestFileManager.benchmark() \ No newline at end of file
diff --git a/tests/test_interactionManager.py b/tests/test_interactionManager.py
new file mode 100644
index 000000000..920d84b9d
--- /dev/null
+++ b/tests/test_interactionManager.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+
+from unittest import TestCase
+from helper.Stubs import Core
+
+from module.Api import Input, Output
+from module.interaction.InteractionManager import InteractionManager
+
+class TestInteractionManager(TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.core = Core()
+
+ def setUp(self):
+ self.im = InteractionManager(self.core)
+
+
+ def test_notifications(self):
+
+ n = self.im.createNotification("test", "notify")
+ assert self.im.getNotifications() == [n]
+
+ for i in range(10):
+ self.im.createNotification("title", "test")
+
+ assert len(self.im.getNotifications()) == 11
+
+
+ def test_captcha(self):
+ assert self.im.getTask() is None
+
+ t = self.im.newCaptchaTask("1", "", "")
+ assert t.output == Output.Captcha
+ self.im.handleTask(t)
+ assert t is self.im.getTask()
+
+ t2 = self.im.newCaptchaTask("2", "", "")
+ self.im.handleTask(t2)
+
+ assert self.im.getTask(Output.Query) is None
+ assert self.im.getTask() is t
+
+ self.im.removeTask(t)
+ assert self.im.getTask() is t2
+
+ self.im.getTaskByID(t2.iid)
+ assert self.im.getTask() is None
+
+
+ def test_query(self):
+ assert self.im.getTask() is None
+ t = self.im.newQueryTask(Input.Text, None, "text")
+ assert t.description == "text"
+ self.im.handleTask(t)
+
+ assert self.im.getTask(Output.Query) is t
+ assert self.im.getTask(Output.Captcha) is None \ No newline at end of file
diff --git a/tests/test_syntax.py b/tests/test_syntax.py
new file mode 100644
index 000000000..a4cc53ee5
--- /dev/null
+++ b/tests/test_syntax.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+
+from os import walk
+from os.path import abspath, dirname, join
+
+from unittest import TestCase
+
+PATH = abspath(join(dirname(abspath(__file__)), "..", ""))
+
+# needed to register globals
+from helper import Stubs
+
+class TestSyntax(TestCase):
+ pass
+
+
+for path, dirs, files in walk(join(PATH, "module")):
+
+ for f in files:
+ if not f.endswith(".py") or f.startswith("__"): continue
+ fpath = join(path, f)
+ pack = fpath.replace(PATH, "")[1:-3] #replace / and .py
+ imp = pack.replace("/", ".")
+ packages = imp.split(".")
+ #__import__(imp)
+
+ # to much sideeffect when importing
+ if "web" in packages or "lib" in packages: continue
+ if "ThriftTest" in packages: continue
+
+ # currying
+ def meta(imp, sig):
+ def _test(self=None):
+ __import__(imp)
+
+ _test.func_name = sig
+ return _test
+
+ # generate test methods
+ sig = "test_%s_%s" % (packages[-2], packages[-1])
+
+
+ setattr(TestSyntax, sig, meta(imp, sig)) \ No newline at end of file