tests: Add "create email test"

This is the first test that actually creates a (local) email and
syncs. We check the result of the sync operation, to see if the
server has actually been assigning a proper UID to the email and
bail out if not.

This test therefore excercises our ability to properly detect the
new UID of an APPENDED email. Obviously we still need some
IMAP<->IMAP tests too, but since this is the same codepath being
used for APPENDs in that case, it could also help to detect
instabilities there.

In order to get this test in, the OLITestLib got a few new helper
functions:
- delete_maildir
- create_mail
- get_maildir_uids

The test passes here. I invoke it via:

python -m unittest test.tests.test_01_basic.TestBasicFunctions.test_04_createmail

or run python setup.py test, to run the whole suite.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2012-02-24 09:39:39 +01:00
parent 0e6b4ae798
commit 2800a71a28
2 changed files with 77 additions and 1 deletions

View File

@ -22,12 +22,15 @@ import sys
import shutil
import subprocess
import tempfile
import random
random.seed()
try:
from configparser import SafeConfigParser
except ImportError: # python 2
from ConfigParser import SafeConfigParser
from . import default_conf
class OLITestLib():
cred_file = None
testdir = None
@ -179,6 +182,36 @@ class OLITestLib():
if e.errno != 17: # 'already exists' is ok.
raise
@classmethod
def delete_maildir(cls, folder):
"""Delete maildir 'folder' in our test maildir
Does not fail if not existing"""
assert cls.testdir != None
maildir = os.path.join(cls.testdir, 'mail', folder)
shutil.rmtree(maildir, ignore_errors=True)
@classmethod
def create_mail(cls, folder, mailfile=None, content=None):
"""Create a mail in maildir 'folder'/new
Use default mailfilename if not given.
Use some default content if not given"""
assert cls.testdir != None
while True: # Loop till we found a unique filename
mailfile = '{}:2,'.format(random.randint(0,999999999))
mailfilepath = os.path.join(cls.testdir, 'mail',
folder, 'new', mailfile)
if not os.path.isfile(mailfilepath):
break
with open(mailfilepath,"wb") as mailf:
mailf.write(b'''From: test <test@offlineimap.org>
Subject: Boo
Date: 1 Jan 1980
To: test@offlineimap.org
Content here.''')
@classmethod
def count_maildir_mails(cls, folder):
"""Returns the number of mails in maildir 'folder'
@ -196,3 +229,22 @@ class OLITestLib():
if dirpath.endswith(('/cur', '/new')):
mails += len(files)
return boxes, mails
# find UID in a maildir filename
re_uidmatch = re.compile(',U=(\d+)')
@classmethod
def get_maildir_uids(cls, folder):
"""Returns a list of maildir mail uids, 'None' if no valid uid"""
assert cls.testdir != None
mailfilepath = os.path.join(cls.testdir, 'mail', folder)
assert os.path.isdir(mailfilepath)
ret = []
for dirpath, dirs, files in os.walk(mailfilepath):
if not dirpath.endswith((os.path.sep + 'new', os.path.sep + 'cur')):
continue # only /new /cur are interesting
for file in files:
m = cls.re_uidmatch.search(file)
uid = m.group(1) if m else None
ret.append(uid)
return ret

View File

@ -31,6 +31,7 @@ def setUpModule():
def tearDownModule():
logging.info("Tear Down test module")
# comment out next line to keep testdir after test runs. TODO: make nicer
OLITestLib.delete_test_dir()
#Stuff that can be used
@ -80,7 +81,7 @@ class TestBasicFunctions(unittest.TestCase):
#logging.warn("%s %s "% (code, res))
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails)==(2,0), msg="Expected 2 folders and 0"
self.assertTrue((boxes, mails)==(2,0), msg="Expected 2 folders and 0 "
"mails, but sync led to {} folders and {} mails".format(
boxes, mails))
@ -101,4 +102,27 @@ class TestBasicFunctions(unittest.TestCase):
self.assertEqual(mismatch, True, msg="Mismatching nametrans rules did "
"NOT trigger an 'infinite folder generation' error. Output was:\n"
"{}".format(res))
# Write out default config file again
OLITestLib.write_config_file()
def test_04_createmail(self):
"""Create mail in OLItest 1, sync, wipe folder sync
Currently, this will mean the folder will be recreated
locally. At some point when remote folder deletion is
implemented, this behavior will change."""
OLITestLib.delete_remote_testfolders()
OLITestLib.create_maildir('INBOX.OLItest')
OLITestLib.create_mail('INBOX.OLItest')
code, res = OLITestLib.run_OLI()
#logging.warn("%s %s "% (code, res))
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails)==(1,1), msg="Expected 1 folders and 1 "
"mails, but sync led to {} folders and {} mails".format(
boxes, mails))
# The local Mail should have been assigned a proper UID now, check!
uids = OLITestLib.get_maildir_uids('INBOX.OLItest')
self.assertFalse (None in uids, msg = "All mails should have been "+ \
"assigned the IMAP's UID number, but {} messages had no valid ID "\
.format(len([None for x in uids if x==None])))