tests: add delete remote folder helper function

We need to clean out the remote folders before we invoke the test suite.
Implement a helper function that does this, and improve the test output
(less verbose) and the setup.py --help-commands (more verbose). Document
that it is possible to run a single test only. (although it is not
guaranteed that a test does not rely on the output of previous tests).

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2012-02-17 10:12:53 +01:00
parent bf44d30b46
commit 79ddb0be71
3 changed files with 73 additions and 9 deletions

View File

@ -29,7 +29,10 @@ from test.OLItest import TextTestRunner, TestLoader, OLITestLib
class TestCommand(Command): class TestCommand(Command):
"""runs the OLI testsuite""" """runs the OLI testsuite"""
description = "Runs the test suite" description = """Runs the test suite. In order to execute only a single
test, you could also issue e.g. 'python -m unittest
test.tests.test_01_basic.TestBasicFunctions.test_01_olistartup' on the
command line."""
user_options = [] user_options = []
def initialize_options(self): def initialize_options(self):

View File

@ -13,9 +13,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import imaplib
import unittest import unittest
import logging import logging
import os import os
import re
import sys import sys
import shutil import shutil
import subprocess import subprocess
@ -50,6 +52,7 @@ class OLITestLib():
directory at a time. OLITestLib is not suited for running directory at a time. OLITestLib is not suited for running
several tests in parallel. The user is responsible for several tests in parallel. The user is responsible for
cleaning that up herself.""" cleaning that up herself."""
assert cls.cred_file != None
# creating temporary dir for testing in same dir as credentials.conf # creating temporary dir for testing in same dir as credentials.conf
cls.testdir = os.path.abspath( cls.testdir = os.path.abspath(
tempfile.mkdtemp(prefix='tmp_%s_'%suffix, tempfile.mkdtemp(prefix='tmp_%s_'%suffix,
@ -63,6 +66,7 @@ class OLITestLib():
The returned config can be manipulated and then saved with The returned config can be manipulated and then saved with
write_config_file()""" write_config_file()"""
#TODO, only do first time and cache then for subsequent calls?
assert cls.cred_file != None assert cls.cred_file != None
assert cls.testdir != None assert cls.testdir != None
config = SafeConfigParser() config = SafeConfigParser()
@ -112,6 +116,51 @@ class OLITestLib():
return (e.returncode, e.output) return (e.returncode, e.output)
return (0, output) return (0, output)
@classmethod
def delete_remote_testfolders(cls, reponame=None):
"""Delete all INBOX.OLITEST* folders on the remote IMAP repository
reponame: All on `reponame` or all IMAP-type repositories if None"""
config = cls.get_default_config()
if reponame:
sections = ['Repository {}'.format(reponame)]
else:
sections = [r for r in config.sections() \
if r.startswith('Repository')]
sections = filter(lambda s: \
config.get(s, 'Type', None).lower() == 'imap',
sections)
for sec in sections:
# Connect to each IMAP repo and delete all folders
# matching the folderfilter setting. We only allow basic
# settings and no fancy password getting here...
# 1) connect and get dir listing
host = config.get(sec, 'remotehost')
user = config.get(sec, 'remoteuser')
passwd = config.get(sec, 'remotepass')
imapobj = imaplib.IMAP4(host)
imapobj.login(user, passwd)
res_t, data = imapobj.list()
assert res_t == 'OK'
dirs = []
for d in data:
m = re.search(r''' # Find last quote
"((?: # Non-tripple quoted can contain...
[^"] | # a non-quote
\\" # a backslashded quote
)*)" # closing quote
[^"]*$ # followed by no more quotes
''', d, flags=re.VERBOSE)
folder = m.group(1)
folder = folder.replace(r'\"', '"') # remove quoting
dirs.append(folder)
# 2) filter out those not starting with INBOX.OLItest and del...
dirs = [d for d in dirs if d.startswith('INBOX.OLItest')]
for folder in dirs:
res_t, data = imapobj.delete(folder)
assert res_t == 'OK'
imapobj.logout()
@classmethod @classmethod
def create_maildir(cls, folder): def create_maildir(cls, folder):
"""Create empty maildir 'folder' in our test maildir """Create empty maildir 'folder' in our test maildir

View File

@ -19,6 +19,12 @@ import logging
import os, sys import os, sys
from test.OLItest import OLITestLib from test.OLItest import OLITestLib
# Things need to be setup first, usually setup.py initializes everything.
# but if e.g. called from command line, we take care of default values here:
if not OLITestLib.cred_file:
OLITestLib(cred_file='./test/credentials.conf', cmd='./offlineimap.py')
def setUpModule(): def setUpModule():
logging.info("Set Up test module %s" % __name__) logging.info("Set Up test module %s" % __name__)
tdir = OLITestLib.create_test_dir(suffix=__name__) tdir = OLITestLib.create_test_dir(suffix=__name__)
@ -52,13 +58,16 @@ class TestBasicFunctions(unittest.TestCase):
def test_01_olistartup(self): def test_01_olistartup(self):
"""Tests if OLI can be invoked without exceptions """Tests if OLI can be invoked without exceptions
It syncs all "OLItest* (specified in the default config) to our Cleans existing remote tet folders. Then syncs all "OLItest*
local Maildir at keeps it there.""" (specified in the default config) to our local Maildir. The
result should be 0 folders and 0 mails."""
OLITestLib.delete_remote_testfolders()
code, res = OLITestLib.run_OLI() code, res = OLITestLib.run_OLI()
self.assertEqual(res, "") self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
logging.warn("%d boxes and %d mails" % (boxes, mails)) self.assertTrue((boxes, mails)==(0,0), msg="Expected 0 folders and 0"
"mails, but sync led to {} folders and {} mails".format(
boxes, mails))
def test_02_createdir(self): def test_02_createdir(self):
"""Create local OLItest 1 & OLItest "1" maildir, sync """Create local OLItest 1 & OLItest "1" maildir, sync
@ -71,7 +80,9 @@ class TestBasicFunctions(unittest.TestCase):
#logging.warn("%s %s "% (code, res)) #logging.warn("%s %s "% (code, res))
self.assertEqual(res, "") self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
logging.warn("%d boxes and %d mails" % (boxes, mails)) self.assertTrue((boxes, mails)==(2,0), msg="Expected 2 folders and 0"
"mails, but sync led to {} folders and {} mails".format(
boxes, mails))
def test_03_nametransmismatch(self): def test_03_nametransmismatch(self):
"""Create mismatching remote and local nametrans rules """Create mismatching remote and local nametrans rules
@ -87,6 +98,7 @@ class TestBasicFunctions(unittest.TestCase):
#logging.warn("%s %s "% (code, res)) #logging.warn("%s %s "% (code, res))
# We expect an INFINITE FOLDER CREATION WARNING HERE.... # We expect an INFINITE FOLDER CREATION WARNING HERE....
mismatch = "ERROR: INFINITE FOLDER CREATION DETECTED!" in res mismatch = "ERROR: INFINITE FOLDER CREATION DETECTED!" in res
self.assertEqual(mismatch, True, "Mismatching nametrans rules did NOT" self.assertEqual(mismatch, True, msg="Mismatching nametrans rules did "
"trigger an 'infinite folder generation' error.") "NOT trigger an 'infinite folder generation' error. Output was:\n"
boxes, mails = OLITestLib.count_maildir_mails('') "{}".format(res))