summaryrefslogtreecommitdiff
path: root/src/leap/mail/imap/tests
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2015-08-31 14:21:50 -0400
committerKali Kaneko <kali@leap.se>2015-08-31 14:21:50 -0400
commit974511645819ef2559fb0c064fdea4bcc926e6d8 (patch)
treeedecfd6c6a3b9bdadaea45de150990a40acaca96 /src/leap/mail/imap/tests
parent67b738c2f5922dbc5cf105e9617ce6d1d5e4e8e3 (diff)
parent43c920f38d1c114e9044d2da15d4a05d5faab79d (diff)
Merge tag '0.4.0rc2' into debian/0.4.0rc2
Tag leap.mail version 0.4.0rc2
Diffstat (limited to 'src/leap/mail/imap/tests')
-rw-r--r--src/leap/mail/imap/tests/__init__.py20
-rwxr-xr-xsrc/leap/mail/imap/tests/regressions_mime_struct (renamed from src/leap/mail/imap/tests/regressions)20
l---------[-rw-r--r--]src/leap/mail/imap/tests/rfc822.message87
l---------[-rw-r--r--]src/leap/mail/imap/tests/rfc822.multi-minimal.message17
l---------src/leap/mail/imap/tests/rfc822.multi-nested.message1
l---------[-rw-r--r--]src/leap/mail/imap/tests/rfc822.multi-signed.message239
l---------[-rw-r--r--]src/leap/mail/imap/tests/rfc822.multi.message97
l---------[-rw-r--r--]src/leap/mail/imap/tests/rfc822.plain.message67
-rwxr-xr-xsrc/leap/mail/imap/tests/stress_tests_imap.zsh (renamed from src/leap/mail/imap/tests/leap_tests_imap.zsh)0
-rw-r--r--src/leap/mail/imap/tests/test_imap.py676
-rw-r--r--src/leap/mail/imap/tests/test_imap_store_fetch.py71
-rw-r--r--src/leap/mail/imap/tests/utils.py227
-rw-r--r--src/leap/mail/imap/tests/walktree.py4
13 files changed, 403 insertions, 1123 deletions
diff --git a/src/leap/mail/imap/tests/__init__.py b/src/leap/mail/imap/tests/__init__.py
index f3d5ca6..5cf60ed 100644
--- a/src/leap/mail/imap/tests/__init__.py
+++ b/src/leap/mail/imap/tests/__init__.py
@@ -1,4 +1,4 @@
-#-*- encoding: utf-8 -*-
+# -*- encoding: utf-8 -*-
"""
leap/email/imap/tests/__init__.py
----------------------------------
@@ -10,13 +10,6 @@ code, using twisted.trial, for testing leap_mx.
@copyright: © 2013 Kali Kaneko, see COPYLEFT file
"""
-__all__ = ['test_imap']
-
-
-def run():
- """xxx fill me in"""
- pass
-
import os
import u1db
@@ -25,11 +18,18 @@ from leap.common.testing.basetest import BaseLeapTest
from leap.soledad.client import Soledad
from leap.soledad.common.document import SoledadDocument
+__all__ = ['test_imap']
+
-#-----------------------------------------------------------------------------
+def run():
+ """xxx fill me in"""
+ pass
+
+# -----------------------------------------------------------------------------
# Some tests inherit from BaseSoledadTest in order to have a working Soledad
# instance in each test.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
+
class BaseSoledadIMAPTest(BaseLeapTest):
"""
diff --git a/src/leap/mail/imap/tests/regressions b/src/leap/mail/imap/tests/regressions_mime_struct
index efe3f46..0332664 100755
--- a/src/leap/mail/imap/tests/regressions
+++ b/src/leap/mail/imap/tests/regressions_mime_struct
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# regressions
+# regression_mime_struct
# Copyright (C) 2014 LEAP
# Copyright (c) Twisted Matrix Laboratories.
#
@@ -18,7 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-Simple Regression Tests using IMAP4 client.
+Simple Regression Tests for checking MIME struct handling using IMAP4 client.
Iterates trough all mails under a given folder and tries to APPEND them to
the server being tested. After FETCHING the pushed message, it compares
@@ -40,7 +40,9 @@ from twisted.protocols import basic
from twisted.python import log
-REGRESSIONS_FOLDER = "regressions_test"
+REGRESSIONS_FOLDER = os.environ.get(
+ "REGRESSIONS_FOLDER", "regressions_test")
+print "[+] Using regressions folder:", REGRESSIONS_FOLDER
parser = Parser()
@@ -263,7 +265,7 @@ def cbSelectMbox(result, proto):
if result["EXISTS"] != 0:
# Flag as deleted, expunge, and do an examine again.
- #print "There is mail here, will delete..."
+ print "There is mail here, will delete..."
return cbDeleteAndExpungeTestFolder(proto)
else:
@@ -276,11 +278,15 @@ def ebSelectMbox(failure, proto, folder):
Creates the folder.
"""
- print failure.getTraceback()
+ log.err(failure)
log.msg("Folder %r does not exist. Creating..." % (folder,))
return proto.create(folder).addCallback(cbAuthentication, proto)
+def ebExpunge(failure):
+ log.err(failure)
+
+
def cbDeleteAndExpungeTestFolder(proto):
"""
Callback invoked fom cbExamineMbox when the number of messages in the
@@ -292,7 +298,9 @@ def cbDeleteAndExpungeTestFolder(proto):
).addCallback(
lambda r: proto.expunge()
).addCallback(
- cbExpunge, proto)
+ cbExpunge, proto
+ ).addErrback(
+ ebExpunge)
def cbExpunge(result, proto):
diff --git a/src/leap/mail/imap/tests/rfc822.message b/src/leap/mail/imap/tests/rfc822.message
index ee97ab9..b19cc28 100644..120000
--- a/src/leap/mail/imap/tests/rfc822.message
+++ b/src/leap/mail/imap/tests/rfc822.message
@@ -1,86 +1 @@
-Return-Path: <twisted-commits-admin@twistedmatrix.com>
-Delivered-To: exarkun@meson.dyndns.org
-Received: from localhost [127.0.0.1]
- by localhost with POP3 (fetchmail-6.2.1)
- for exarkun@localhost (single-drop); Thu, 20 Mar 2003 14:50:20 -0500 (EST)
-Received: from pyramid.twistedmatrix.com (adsl-64-123-27-105.dsl.austtx.swbell.net [64.123.27.105])
- by intarweb.us (Postfix) with ESMTP id 4A4A513EA4
- for <exarkun@meson.dyndns.org>; Thu, 20 Mar 2003 14:49:27 -0500 (EST)
-Received: from localhost ([127.0.0.1] helo=pyramid.twistedmatrix.com)
- by pyramid.twistedmatrix.com with esmtp (Exim 3.35 #1 (Debian))
- id 18w648-0007Vl-00; Thu, 20 Mar 2003 13:51:04 -0600
-Received: from acapnotic by pyramid.twistedmatrix.com with local (Exim 3.35 #1 (Debian))
- id 18w63j-0007VK-00
- for <twisted-commits@twistedmatrix.com>; Thu, 20 Mar 2003 13:50:39 -0600
-To: twisted-commits@twistedmatrix.com
-From: etrepum CVS <etrepum@twistedmatrix.com>
-Reply-To: twisted-python@twistedmatrix.com
-X-Mailer: CVSToys
-Message-Id: <E18w63j-0007VK-00@pyramid.twistedmatrix.com>
-Subject: [Twisted-commits] rebuild now works on python versions from 2.2.0 and up.
-Sender: twisted-commits-admin@twistedmatrix.com
-Errors-To: twisted-commits-admin@twistedmatrix.com
-X-BeenThere: twisted-commits@twistedmatrix.com
-X-Mailman-Version: 2.0.11
-Precedence: bulk
-List-Help: <mailto:twisted-commits-request@twistedmatrix.com?subject=help>
-List-Post: <mailto:twisted-commits@twistedmatrix.com>
-List-Subscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
- <mailto:twisted-commits-request@twistedmatrix.com?subject=subscribe>
-List-Id: <twisted-commits.twistedmatrix.com>
-List-Unsubscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
- <mailto:twisted-commits-request@twistedmatrix.com?subject=unsubscribe>
-List-Archive: <http://twistedmatrix.com/pipermail/twisted-commits/>
-Date: Thu, 20 Mar 2003 13:50:39 -0600
-
-Modified files:
-Twisted/twisted/python/rebuild.py 1.19 1.20
-
-Log message:
-rebuild now works on python versions from 2.2.0 and up.
-
-
-ViewCVS links:
-http://twistedmatrix.com/users/jh.twistd/viewcvs/cgi/viewcvs.cgi/twisted/python/rebuild.py.diff?r1=text&tr1=1.19&r2=text&tr2=1.20&cvsroot=Twisted
-
-Index: Twisted/twisted/python/rebuild.py
-diff -u Twisted/twisted/python/rebuild.py:1.19 Twisted/twisted/python/rebuild.py:1.20
---- Twisted/twisted/python/rebuild.py:1.19 Fri Jan 17 13:50:49 2003
-+++ Twisted/twisted/python/rebuild.py Thu Mar 20 11:50:08 2003
-@@ -206,15 +206,27 @@
- clazz.__dict__.clear()
- clazz.__getattr__ = __getattr__
- clazz.__module__ = module.__name__
-+ if newclasses:
-+ import gc
-+ if (2, 2, 0) <= sys.version_info[:3] < (2, 2, 2):
-+ hasBrokenRebuild = 1
-+ gc_objects = gc.get_objects()
-+ else:
-+ hasBrokenRebuild = 0
- for nclass in newclasses:
- ga = getattr(module, nclass.__name__)
- if ga is nclass:
- log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qual(nclass))
- else:
-- import gc
-- for r in gc.get_referrers(nclass):
-- if isinstance(r, nclass):
-+ if hasBrokenRebuild:
-+ for r in gc_objects:
-+ if not getattr(r, '__class__', None) is nclass:
-+ continue
- r.__class__ = ga
-+ else:
-+ for r in gc.get_referrers(nclass):
-+ if getattr(r, '__class__', None) is nclass:
-+ r.__class__ = ga
- if doLog:
- log.msg('')
- log.msg(' (fixing %s): ' % str(module.__name__))
-
-
-_______________________________________________
-Twisted-commits mailing list
-Twisted-commits@twistedmatrix.com
-http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits
+../../tests/rfc822.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/rfc822.multi-minimal.message b/src/leap/mail/imap/tests/rfc822.multi-minimal.message
index 582297c..e0aa678 100644..120000
--- a/src/leap/mail/imap/tests/rfc822.multi-minimal.message
+++ b/src/leap/mail/imap/tests/rfc822.multi-minimal.message
@@ -1,16 +1 @@
-Content-Type: multipart/mixed; boundary="===============6203542367371144092=="
-MIME-Version: 1.0
-Subject: [TEST] 010 - Inceptos cum lorem risus congue
-From: testmailbitmaskspam@gmail.com
-To: test_c5@dev.bitmask.net
-
---===============6203542367371144092==
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-
-Howdy from python!
-The subject: [TEST] 010 - Inceptos cum lorem risus congue
-Current date & time: Wed Jan 8 16:36:21 2014
-Trying to attach: []
---===============6203542367371144092==--
+../../tests/rfc822.multi-minimal.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/rfc822.multi-nested.message b/src/leap/mail/imap/tests/rfc822.multi-nested.message
new file mode 120000
index 0000000..306d0de
--- /dev/null
+++ b/src/leap/mail/imap/tests/rfc822.multi-nested.message
@@ -0,0 +1 @@
+../../tests/rfc822.multi-nested.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/rfc822.multi-signed.message b/src/leap/mail/imap/tests/rfc822.multi-signed.message
index 9907c2d..4172244 100644..120000
--- a/src/leap/mail/imap/tests/rfc822.multi-signed.message
+++ b/src/leap/mail/imap/tests/rfc822.multi-signed.message
@@ -1,238 +1 @@
-Date: Mon, 6 Jan 2014 04:40:47 -0400
-From: Kali Kaneko <kali@leap.se>
-To: penguin@example.com
-Subject: signed message
-Message-ID: <20140106084047.GA21317@samsara.lan>
-MIME-Version: 1.0
-Content-Type: multipart/signed; micalg=pgp-sha1;
- protocol="application/pgp-signature"; boundary="z9ECzHErBrwFF8sy"
-Content-Disposition: inline
-User-Agent: Mutt/1.5.21 (2012-12-30)
-
-
---z9ECzHErBrwFF8sy
-Content-Type: multipart/mixed; boundary="z0eOaCaDLjvTGF2l"
-Content-Disposition: inline
-
-
---z0eOaCaDLjvTGF2l
-Content-Type: text/plain; charset=utf-8
-Content-Disposition: inline
-Content-Transfer-Encoding: quoted-printable
-
-This is an example of a signed message,
-with attachments.
-
-
---=20
-Nihil sine chao! =E2=88=B4
-
---z0eOaCaDLjvTGF2l
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename="attach.txt"
-
-this is attachment in plain text.
-
---z0eOaCaDLjvTGF2l
-Content-Type: application/octet-stream
-Content-Disposition: attachment; filename="hack.ico"
-Content-Transfer-Encoding: base64
-
-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
-AAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8Af39/AL+/vwA/Pz8A39/fAF9fXwCfn58A
-Hx8fAO/v7wAvLy8Ab29vAI+PjwAPDw8A0NDQALCwsABQUFAA9/f3ABcXFwDn5+cAJycnAMjI
-yABHR0cAqKioAGdnZwCXl5cAd3d3AIeHhwAHBwcA2NjYALi4uABXV1cANTU1ADo6OgD7+/sA
-CwsLAPPz8wATExMA6+vrABsbGwDj4+MAIyMjANTU1AArKysAzMzMAMTExABLS0sAtLS0AKys
-rABbW1sApKSkAGNjYwCbm5sAa2trAJOTkwBzc3MAi4uLAHt7ewCDg4MAAwMDANzc3AAyMjIA
-vLy8AFNTUwD9/f0ABQUFAPn5+QAJCQkADQ0NAPHx8QDt7e0AFRUVAOnp6QAZGRkA5eXlAB0d
-HQDh4eEAISEhACUlJQDa2toAKSkpANbW1gDS0tIAysrKADw8PADGxsYAwsLCAEVFRQBJSUkA
-urq6ALa2tgCysrIArq6uAFlZWQCqqqoAXV1dAKampgBlZWUAoqKiAJ2dnQBtbW0AmZmZAHFx
-cQCVlZUAeXl5AH19fQCJiYkAhYWFAAEBAQACAgIABAQEAP7+/gAGBgYA/Pz8AAgICAD6+voA
-CgoKAPj4+AAMDAwA9vb2APT09AASEhIA8vLyABQUFADu7u4AFhYWAOzs7AAYGBgA6urqAOjo
-6AAeHh4AICAgAOTk5AAiIiIA4uLiACQkJADg4OAAJiYmAN7e3gDd3d0AKCgoANvb2wAqKioA
-2dnZACwsLADX19cALi4uANXV1QAxMTEA09PTADMzMwDR0dEANDQ0AM3NzQA5OTkAy8vLADs7
-OwDJyckAPT09AMfHxwBAQEAAxcXFAMPDwwDBwcEAwMDAAL6+vgBKSkoAvb29ALu7uwC5ubkA
-UVFRALe3twBSUlIAtbW1AFRUVACzs7MAVlZWAFhYWABaWloAra2tAFxcXACrq6sAXl5eAKmp
-qQCnp6cAZGRkAKOjowChoaEAaGhoAKCgoACenp4AnJycAG5ubgCampoAcHBwAJiYmABycnIA
-lpaWAJSUlAB2dnYAkpKSAHh4eACQkJAAenp6AI6OjgB8fHwAjIyMAIiIiACCgoIAhISEAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAC1WlpaWlpaWlpaWlpaWlpaWlpaHjAHr6taWlpaWlpaWlpa
-WlpaWlpaq68HMB5aWlpap6KlWzBaA6KoWlpaWlq1WgEBAQEBAQEBAQEBAQEBAQEBAQGXNkUB
-AQEBAQEBAQEBAQEBAQEBAQFFNpcBAQEBASg4EI6HPa5lfgEBAQEBWloBAQEBAQEBAQEBAQEB
-AQEBAQEBlzZFAQEBAQEBAQEBAQEBAQEBAQEBRTaXAQEBETpEAAAAAAAAAH/FbwEBAVpaAQEB
-AQEBAQEBAQEBAQEBAQEBAZc2RQEBAQEBAQEBAQEBAQEBAQEBAUU2lwEBhFQAAAAAAAAAAAAA
-ALJCAQFaWgEBAQEBAQEBAQEBAQEBAQEBAQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNpcBeJoA
-AAAAAAAAAAAAAAAAMQEBWloBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAQEBAQEBAQEBAQEBAQEB
-AQEBRTZSATUAAAAAAAAAAAAAAAAAAABnAVpaAQEBAQEBAQEBAQEBAQEBAQEBAZc2RQEBAQEB
-AQEBAQEBAQEBAQEBAUU2Tx1wAAAAAAAAAAAAAAAAAAAAgkaoWgEBAQEBAQEBAQEBAQEBAQEB
-AQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNgVrAAAAAAAAAAAAAAAAAAAAAABioloBAQEBAQEB
-AQEBAQEBAQEBAQEBlzZFAQEBAQEBAQEBAQEBAQEBAQEBRWcqngAAAAAAAAAAAAAAAAAAAAAA
-tANaAQEBAQEBAQEBAQEBAQEBAQEBAZc2RQEBAQEBAQEBAQEBAQEBAQEBAUXDpIcAAAAAAAAA
-AAAAAAAAAAAAAJRaWgEBAQEBAQEBAQEBAQEBAQEBAQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFF
-wa9HAAAAAAAAAAAAAAAAAAAAAABOMFoBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAQEBAQEBAQEB
-AQEBAQEBAQEBRWVZggAAAAAAAAAAAAAAAAAAAAAAjltaAQEBAQEBAQEBAQEBAQEBAQEBAZc2
-RQEBAQEBAQEBAQEBAQEBAQEBAUXFmZYAAAAAAAAAAAAAAAAAAAAAAKqlWgEBAQEBAQEBAQEB
-AQEBAQEBAQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNorHAAAAAAAAAAAAAAAAAAAAAABloloB
-AQEBAQEBAQEBAQEBAQEBAQEBlzZFAQEBAQEBAQEBAQEBAQEBAQEBRTY8UwAAAAAAAAAAAAAA
-AAAAAAASEz5aAQEBAQEBAQEBAQEBAQEBAQEBAZc2RQEBAQEBAQEBAQEBAQEBAQEBAUU2lQFd
-AAAAAAAAAAAAAAAAAAAA0AFaWgEBAQEBAQEBAQEBAQEBAQEBAQGXNkUBAQEBAQEBAQEBAQEB
-AQEBAQFFNpcBhoUAAAAAAAAAAAAAAAAAVxEBWloBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAQEB
-AQEBAQEBAQEBAQEBAQEBRTaXAQGXTQAAAAAAAAAAAAAAnCgBAVpaAQEBAQEBAQEBAQEBAQEB
-AQEBAZc2RQEBAQEBAQEBAQEBAQEBAQEBAUU2lwEBASiwAAAAAAAAAAAcwncBAQFaWgEBAQEB
-AQEBAQEBAQEBAQEBAQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNpcBAQEBASy8khINgiFojQEB
-AQEBWjCVl5eXl5eXl5dSUpeXl5eXl5eTHsWdlZeXl5eXl5eXl5eXl5eXl5eVncUek5eXl1I8
-ipsvs6iVBU9Sl5eXlTAHNjY2NjY2Zb1ivbtiY2c2NjY2NsVlxjY2NjY2NjY2NjY2NjY2NjY2
-NsZlxTY2NjY2xr8yFxcXusHGNjY2NjYHW3hFRUURAY8HC7Jh0ahFb3pFRRGdxkp4RUVFRUVF
-RUVFRUVFRUVFRXhKxp0RRUVFIkKhDLkxwMiXInNFRUV4W1oBAQEBCcclAAAAAAAAnK0BAQEB
-lzZFAQEBAQEBAQEBAQEBAQEBAQEBRTaXAQEBAQ4ucAAAAAAAdAaNAQEBAVpaAQEBpYMAAAAA
-AAAAAAAAGHUBAZc2RQEBAQEBAQEBAQEBAQEBAQEBAUU2lwEBAWtwAAAAAAAAAAAADboBAQFa
-WgEBHnIAAAAAAAAAAAAAAACxcwGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNpcBAcQAAAAAAAAA
-AAAAAABtwQEBWloBiCcAAAAAAAAAAAAAAAAAAM0BUjZFAQEBAQEBAQEBAQEBAQEBAQEBRTaX
-AbsAAAAAAAAAAAAAAAAAAHCiAVpaAQYAAAAAAAAAAAAAAAAAAAAck082RQEBAQEBAQEBAQEB
-AQEBAQEBAUU2UUVLAAAAAAAAAAAAAAAAAAAAIQEePkoNAAAAAAAAAAAAAAAAAAAAAMCLxkUB
-AQEBAQEBAQEBAQEBAQEBAQFFNgViAAAAAAAAAAAAAAAAAAAAAACppKK9AAAAAAAAAAAAAAAA
-AAAAAACQnxlFAQEBAQEBAQEBAQEBAQEBAQEBRcZPrAAAAAAAAAAAAAAAAAAAAAAAZqOjCwAA
-AAAAAAAAAAAAAAAAAAAAQ7i/RQEBAQEBAQEBAQEBAQEBAQEBAUUZVSsAAAAAAAAAAAAAAAAA
-AAAAAFRZpT8AAAAAAAAAAAAAAAAAAAAAAADKvkUBAQEBAQEBAQEBAQEBAQEBAQFFZVpJAAAA
-AAAAAAAAAAAAAAAAAAAUXKU/AAAAAAAAAAAAAAAAAAAAAAAAyr5FAQEBAQEBAQEBAQEBAQEB
-AQEBRWVaSQAAAAAAAAAAAAAAAAAAAAAAFFyjCwAAAAAAAAAAAAAAAAAAAAAAdl40RQEBAQEB
-AQEBAQEBAQEBAQEBAUUZVSsAAAAAAAAAAAAAAAAAAAAAAKCoVrcAAAAAAAAAAAAAAAAAAAAA
-ACCZxUUBAQEBAQEBAQEBAQEBAQEBAQFFxo1fAAAAAAAAAAAAAAAAAAAAAABpVqh+fQAAAAAA
-AAAAAAAAAAAAAADRijZFAQEBAQEBAQEBAQEBAQEBAQEBRTaKXAAAAAAAAAAAAAAAAAAAAAA7
-LANaAWgAAAAAAAAAAAAAAAAAAABJSJE2RQEBAQEBAQEBAQEBAQEBAQEBAUU2KgEKAAAAAAAA
-AAAAAAAAAAAAHwGrWgF8kAAAAAAAAAAAAAAAAAAAZQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFF
-NpcBHm0AAAAAAAAAAAAAAAAAEk8BWloBAZVLAAAAAAAAAAAAAAAANwEBlzZFAQEBAQEBAQEB
-AQEBAQEBAQEBRTaXAQHFAAAAAAAAAAAAAAAAQx4BAVpaAQEBj1QAAAAAAAAAAAByGQEBAZc2
-RQEBAQEBAQEBAQEBAQEBAQEBAUU2lwEBARcSAAAAAAAAAAAAjJkBAQFaWgEBAQFxuphuAAAA
-ABK8jwEBAQGXNkUBAQEBAQEBAQEBAQEBAQEBAQFFNpcBAQEBSMlLAAAAAG0rDEUBAQEBWlt4
-RUVFeAFFLWU6DC8FcXNFRUURncZKeEVFRUVFRUVFRUVFRUVFRUV4SsadEUVFRXUBhC8MOmWi
-JgF3RUVFeFsHNjY2NjY2Z7+9Yru+wzY2NjY2NsVlxjY2NjY2NsU0vr6/wzY2NjY2NsZlxTY2
-NjY2NmUytbO3Yhk2NjY2NjYHMJWXl5eXl5eXl5eXl5eXl5eXl5MexZ2Vl5eXHQWdXgwMYKKK
-T5eXl5WdxR6Tl5eXKgWVrWfOvquPipWXl5eVMFoBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAQEB
-AYE5kHYAAEMpvJEBAQEBRTaXAQEBAXFiBEcAAG4Spi8BAQEBAVpaAQEBAQEBAQEBAQEBAQEB
-AQEBAZc2RQEBAcF7AAAAAAAAAABBaUIBAUU2lwEBAZsgAAAAAAAAAAAAFooBAQFaWgEBAQEB
-AQEBAQEBAQEBAQEBAQGXNkUBAQsAAAAAAAAAAAAAAACxcwFFNpcBAQ92AAAAAAAAAAAAAABN
-UQEBWloBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAcwAAAAAAAAAAAAAAAAAABgBejaXAZd5AAAA
-AAAAAAAAAAAAAImAAVpaAQEBAQEBAQEBAQEBAQEBAQEBAZc2c1JDAAAAAAAAAAAAAAAAAAAA
-W3E2KgGeAAAAAAAAAAAAAAAAAAAAMwGrWgEBAQEBAQEBAQEBAQEBAQEBAQGXNm9kAAAAAAAA
-AAAAAAAAAAAAAAQJZ4ukAAAAAAAAAAAAAAAAAAAAAHKVpVoBAQEBAQEBAQEBAQEBAQEBAQEB
-l8OGKQAAAAAAAAAAAAAAAAAAAAAcor+LNQAAAAAAAAAAAAAAAAAAAAAAaqJaAQEBAQEBAQEB
-AQEBAQEBAQEBAZdjHmwAAAAAAAAAAAAAAAAAAAAAAM8ymT0AAAAAAAAAAAAAAAAAAAAAAFg+
-WgEBAQEBAQEBAQEBAQEBAQEBAQGXvWUAAAAAAAAAAAAAAAAAAAAAAABhuFmCAAAAAAAAAAAA
-AAAAAAAAAACOW1oBAQEBAQEBAQEBAQEBAQEBAQEBl7vOAAAAAAAAAAAAAAAAAAAAAAAAtGCv
-RwAAAAAAAAAAAAAAAAAAAAAATjBaAQEBAQEBAQEBAQEBAQEBAQEBAZcHYgAAAAAAAAAAAAAA
-AAAAAAAAAAu4pIcAAAAAAAAAAAAAAAAAAAAAAD1aWgEBAQEBAQEBAQEBAQEBAQEBAQGXNBUj
-AAAAAAAAAAAAAAAAAAAAAAAyvSpXAAAAAAAAAAAAAAAAAAAAAAAYpFoBAQEBAQEBAQEBAQEB
-AQEBAQEBl2ckVAAAAAAAAAAAAAAAAAAAAACDiMMFzAAAAAAAAAAAAAAAAAAAAAAAr6NaAQEB
-AQEBAQEBAQEBAQEBAQEBAZc2b7sAAAAAAAAAAAAAAAAAAAAAaW82HRMlAAAAAAAAAAAAAAAA
-AAAAlECpWgEBAQEBAQEBAQEBAQEBAQEBAQGXNngBBAAAAAAAAAAAAAAAAAAAKUZ3NpcBzwAA
-AAAAAAAAAAAAAAAAAA8BWloBAQEBAQEBAQEBAQEBAQEBAQEBlzZFAZGCAAAAAAAAAAAAAAAA
-dC0BRTaXAXGwAAAAAAAAAAAAAAAAAAIBAVpaAQEBAQEBAQEBAQEBAQEBAQEBAZc2RQEBlY4A
-AAAAAAAAAAAACD4BAUU2lwEBd7YAAAAAAAAAAAAAbmtvAQFaWgEBAQEBAQEBAQEBAQEBAQEB
-AQGXNkUBAQEJyw0AAAAAAAB0M0wBAQFFNpcBAQEBF1AAAAAAAAAAVD4BAQEBWloBAQEBAQEB
-AQEBAQEBAQEBAQEBlzZFAQEBAQETB7ymprxliwEBAQEBRTaXAQEBAQF1qxqsV7QbVXEBAQEB
-AVq1WlpaWlpaWlpaWlpaWlpaWlpaHjAHr6taWlpaPqKkPj6kLadaWlpaq68HMB5aWlpaqaNW
-pz4DLaQeWlpaWlq1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
-
---z0eOaCaDLjvTGF2l--
-
---z9ECzHErBrwFF8sy
-Content-Type: application/pgp-signature
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.15 (GNU/Linux)
-
-iQIcBAEBAgAGBQJSymwPAAoJECNji/csWTvBhtcP/2AKF0uk6ljrfMWhNBSFwDqv
-kYng3slREnF/pxnIGOpR2GAxPBPjRipZOuUU8QL+pXBwk5kWzb9RYpr26xMYWRtl
-vXdVbob5NolNEYrqTkkQ1kejERQGFyescsUJDcEDXJl024czKWbxHTYYN4vlYJMK
-PZ5mPSdADFn970PnVXfNix3Rjvv7SFQGammDBGjQzyROkoiDKPZcomp6dzm6zEXC
-w8i42WfHU8GkyVVNvXZI52Xw3LUXiXsJ58B1V1O5U42facepG6S+S0DC/PWptqPw
-sAM9/YGkvBNWrsJA/BavXPRLE1gVpu+hZZEsOqRvs244k7JTrVo54xDbdeOT2nTr
-BDk4e88vmCVKGgE9MZjDbjgOHDZhmsxNQm4DBGRH2huF0noUc/8Sm4KhSO49S2mN
-QjIT5QrPerQNiP5QtShHZRJX7ElXYZWX1SG/c9jQjfd0W1XK/cGtwClICe+lpprt
-mLC2607yalbRhCxV9bQlVUnd2tY3NY4UgIKgCEiEwb1hf/k9jQDvpk16VuNWSZQJ
-jFeg9F2WdNjQMp79cyvnayyhjS9o/K2LbSIgJi7KdlQcVZ/2DQfbMjCwByR7P9g8
-gcAKh8V7E6IpAu1mnvs4FDagipppK6hOTRj2s/I3xZzneprSK1WaVro/8LAWZe9X
-sSdfcAhT7Tno7PB/Acoh
-=+okv
------END PGP SIGNATURE-----
-
---z9ECzHErBrwFF8sy--
+../../tests/rfc822.multi-signed.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/rfc822.multi.message b/src/leap/mail/imap/tests/rfc822.multi.message
index 30f74e5..62057d2 100644..120000
--- a/src/leap/mail/imap/tests/rfc822.multi.message
+++ b/src/leap/mail/imap/tests/rfc822.multi.message
@@ -1,96 +1 @@
-Date: Fri, 19 May 2000 09:55:48 -0400 (EDT)
-From: Doug Sauder <doug@penguin.example.com>
-To: Joe Blow <blow@example.com>
-Subject: Test message from PINE
-Message-ID: <Pine.LNX.4.21.0005190951410.8452-102000@penguin.example.com>
-MIME-Version: 1.0
-Content-Type: MULTIPART/MIXED; BOUNDARY="-1463757054-952513540-958744548=:8452"
-
- This message is in MIME format. The first part should be readable text,
- while the remaining parts are likely unreadable without MIME-aware tools.
- Send mail to mime@docserver.cac.washington.edu for more info.
-
----1463757054-952513540-958744548=:8452
-Content-Type: TEXT/PLAIN; charset=US-ASCII
-
-This is a test message from PINE MUA.
-
-
----1463757054-952513540-958744548=:8452
-Content-Type: APPLICATION/octet-stream; name="redball.png"
-Content-Transfer-Encoding: BASE64
-Content-ID: <Pine.LNX.4.21.0005190955480.8452@penguin.example.com>
-Content-Description: A PNG graphic file
-Content-Disposition: attachment; filename="redball.png"
-
-iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAADAFBMVEX///8A
-AAABAAALAAAVAAAaAAAXAAARAAAKAAADAAAcAAAyAABEAABNAABIAAA9AAAj
-AAAWAAAmAABhAAB7AACGAACHAAB9AAB0AABgAAA5AAAUAAAGAAAnAABLAABv
-AACQAAClAAC7AAC/AACrAAChAACMAABzAABbAAAuAAAIAABMAAB3AACZAAC0
-GRnKODjVPT3bKSndBQW4AACoAAB5AAAxAAAYAAAEAABFAACaAAC7JCTRYWHf
-hITmf3/mVlbqHx/SAAC5AACjAABdAABCAAAoAAAJAABnAAC6Dw/QVFTek5Pl
-rKzpmZntZWXvJSXXAADBAACxAACcAABtAABTAAA2AAAbAAAFAABKAACBAADL
-ICDdZ2fonJzrpqbtiorvUVHvFBTRAADDAAC2AAB4AABeAABAAAAiAABXAACS
-AADCAADaGxvoVVXseHjveHjvV1fvJibhAADOAAC3AACnAACVAABHAAArAAAP
-AACdAADFAADhBQXrKCjvPDzvNTXvGxvjAADQAADJAAC1AACXAACEAABsAABP
-AAASAAACAABiAADpAADvAgLnAADYAADLAAC6AACwAABwAAATAAAkAABYAADI
-AADTAADNAACzAACDAABuAAAeAAB+AADAAACkAACNAAB/AABpAABQAAAwAACR
-AACpAAC8AACqAACbAABlAABJAAAqAAAOAAA0AACsAACvAACtAACmAACJAAB6
-AABrAABaAAA+AAApAABqAACCAACfAACeAACWAACPAAB8AAAZAAAHAABVAACO
-AACKAAA4AAAQAAA/AAByAACAAABcAAA3AAAsAABmAABDAABWAAAgAAAzAAA8
-AAA6AAAfAAAMAAAdAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8
-LtlFAAAAAXRSTlMAQObYZgAAABZ0RVh0U29mdHdhcmUAZ2lmMnBuZyAyLjAu
-MT1evmgAAAIISURBVHicY2CAg/8QwIABmJhZWFnZ2Dk4MaU5uLh5eHn5+LkF
-BDlQJf8zC/EIi4iKiUtI8koJScsgyf5nlpWTV1BUUlZRVVPX4NFk1UJIyghp
-6+jq6RsYGhmbKJgK85mZW8Dk/rNaSlhZ29ja2Ts4Ojkr6Li4urFDNf53N/Ow
-8vTy9vH18w8IDAoWDQkNC4+ASP5ni4wKio6JjYtPSExKTnFWSE1LF4A69n9G
-ZlZ2Tm5efkFhUXFySWlZlEd5RSVY7j+TkGRVdU1tXX1DY1Ozcktpa1t7h2Yn
-OAj+d7l1tyo79vT29SdNSJ44SbFVdHIo9xSIHNPUaWqTpifNSJrZnK00S0U1
-a/acUG5piNz/uXLzVJ2qm6dXz584S2WB1cJFi5cshZr539xVftnyFKUVTi2T
-VjqvyhJLXb1m7TqoHPt6F/HW0g0bN63crGqVtWXrtu07BJihcsw71+zanRW8
-Z89eq337RQ/Ip60xO3gIElX/LbikDm8T36KwbNmRo7O3zpHkPSZwHBqL//8f
-lz1x2OOkyKJTi7aqbzutfUZI2gIuF8F2lr/D5dw2+fZdwpl8YVOlI+CJ4/9/
-joOyYed5QzMvhGqnm2V0WiClm///D0lfXHtJ6vLlK9w7rx7vQk5SQJbFtSms
-1y9evXid7QZacgOxmSxktNzdtSwwU+J/VICaCPFIYU3XAJhIOtjf5sfyAAAA
-JXRFWHRDb21tZW50AGNsaXAyZ2lmIHYuMC42IGJ5IFl2ZXMgUGlndWV0NnM7
-vAAAAABJRU5ErkJggg==
----1463757054-952513540-958744548=:8452
-Content-Type: APPLICATION/octet-stream; name="blueball.png"
-Content-Transfer-Encoding: BASE64
-Content-ID: <Pine.LNX.4.21.0005190955481.8452@penguin.example.com>
-Content-Description: A PNG graphic file
-Content-Disposition: attachment; filename="blueball.png"
-
-iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAMAAAC6CgRnAAADAFBMVEX///8A
-AAgAABAAABgAAAAACCkAEEIAEEoACDEAEFIIIXMIKXsIKYQIIWsAGFoACDkI
-IWMQOZwYQqUYQq0YQrUQOaUQMZQAGFIQMYwpUrU5Y8Y5Y84pWs4YSs4YQs4Y
-Qr1Ca8Z7nNacvd6Mtd5jlOcxa94hUt4YStYYQsYQMaUAACHO5+/n7++cxu9S
-hO8pWucQOa1Ke86tzt6lzu9ajO8QMZxahNat1ufO7++Mve9Ke+8YOaUYSsaM
-vee15++Uve8AAClajOdzpe9rnO8IKYwxY+8pWu8IIXsAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADB
-Mg1VAAAAAXRSTlMAQObYZgAAABZ0RVh0U29mdHdhcmUAZ2lmMnBuZyAyLjAu
-MT1evmgAAAGISURBVHicddJtV5swGAbgEk6AJhBSk4bMCUynBSLaqovbrG/b
-fPn/vyh70lbsscebL5xznTsh5BmNhgQoRChwo50EOIohUYLDj4zHhKYQkrEo
-Qdvock4ne0IKMVUpKZLQDeqSTIsv+18PyqqWUw2IBsRM7307PPp+fDJrWtnp
-LDJvewYxnewfnvanZ+fzpmwXijC8KbqEa3Fx2ff91Y95U9XCUpaDeQwiMpHX
-P/v+1++bWVPWQoGFawtjury9vru/f/C1Vi7ezT0WWpQHf/7+u/G71aLThK/M
-jRxmT6KdzZ9fGk9yatMsTgZLl3XVgFRAC6spj/13enssqJVtWVa3NdBSacL8
-+VZmYqKmdd1CSYoOiMOSGwtzlqqlFFIuOqv0a1ZEZrUkWICLLFW266y1KvWE
-1zV/iDAH1EopnVLCiygZCIomH3NCKX0lnI+B1iuuzCGTxwXjnDO4d7NpbX42
-YJJHkBwmAm2TxwAZg40J3+Xtbv1rgOAZwG0NxW62p+lT+Yi747sD/wEUVMzY
-mWkOvwAAACV0RVh0Q29tbWVudABjbGlwMmdpZiB2LjAuNiBieSBZdmVzIFBp
-Z3VldDZzO7wAAAAASUVORK5CYII=
----1463757054-952513540-958744548=:8452--
+../../tests/rfc822.multi.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/rfc822.plain.message b/src/leap/mail/imap/tests/rfc822.plain.message
index fc627c3..5bab0e8 100644..120000
--- a/src/leap/mail/imap/tests/rfc822.plain.message
+++ b/src/leap/mail/imap/tests/rfc822.plain.message
@@ -1,66 +1 @@
-From pyar-bounces@python.org.ar Wed Jan 8 14:46:02 2014
-Return-Path: <pyar-bounces@python.org.ar>
-X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on spamd2.riseup.net
-X-Spam-Level: **
-X-Spam-Pyzor: Reported 0 times.
-X-Spam-Status: No, score=2.1 required=8.0 tests=AM_TRUNCATED,CK_419SIZE,
- CK_NAIVER_NO_DNS,CK_NAIVE_NO_DNS,ENV_FROM_DIFF0,HAS_REPLY_TO,LINK_NR_TOP,
- NO_REAL_NAME,RDNS_NONE,RISEUP_SPEAR_C shortcircuit=no autolearn=disabled
- version=3.3.2
-Delivered-To: kali@leap.se
-Received: from mx1.riseup.net (mx1-pn.riseup.net [10.0.1.33])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (Client CN "*.riseup.net", Issuer "Gandi Standard SSL CA" (not verified))
- by vireo.riseup.net (Postfix) with ESMTPS id 6C39A8F
- for <kali@leap.se>; Wed, 8 Jan 2014 18:46:02 +0000 (UTC)
-Received: from pyar.usla.org.ar (unknown [190.228.30.157])
- by mx1.riseup.net (Postfix) with ESMTP id F244C533F4
- for <kali@leap.se>; Wed, 8 Jan 2014 10:46:01 -0800 (PST)
-Received: from [127.0.0.1] (localhost [127.0.0.1])
- by pyar.usla.org.ar (Postfix) with ESMTP id CC51D26A4F
- for <kali@leap.se>; Wed, 8 Jan 2014 15:46:00 -0300 (ART)
-MIME-Version: 1.0
-Content-Type: text/plain; charset="iso-8859-1"
-Content-Transfer-Encoding: quoted-printable
-From: pyar-request@python.org.ar
-To: kali@leap.se
-Subject: confirm 0e47e4342e4d42508e8c283175b05b3377148ac2
-Reply-To: pyar-request@python.org.ar
-Auto-Submitted: auto-replied
-Message-ID: <mailman.245.1389206759.1579.pyar@python.org.ar>
-Date: Wed, 08 Jan 2014 15:45:59 -0300
-Precedence: bulk
-X-BeenThere: pyar@python.org.ar
-X-Mailman-Version: 2.1.15
-List-Id: Python Argentina <pyar.python.org.ar>
-X-List-Administrivia: yes
-Errors-To: pyar-bounces@python.org.ar
-Sender: "pyar" <pyar-bounces@python.org.ar>
-X-Virus-Scanned: clamav-milter 0.97.8 at mx1
-X-Virus-Status: Clean
-
-Mailing list subscription confirmation notice for mailing list pyar
-
-We have received a request de kaliyuga@riseup.net for subscription of
-your email address, "kaliyuga@riseup.net", to the pyar@python.org.ar
-mailing list. To confirm that you want to be added to this mailing
-list, simply reply to this message, keeping the Subject: header
-intact. Or visit this web page:
-
- http://listas.python.org.ar/confirm/pyar/0e47e4342e4d42508e8c283175b05b=
-3377148ac2
-
-
-Or include the following line -- and only the following line -- in a
-message to pyar-request@python.org.ar:
-
- confirm 0e47e4342e4d42508e8c283175b05b3377148ac2
-
-Note that simply sending a `reply' to this message should work from
-most mail readers, since that usually leaves the Subject: line in the
-right form (additional "Re:" text in the Subject: is okay).
-
-If you do not wish to be subscribed to this list, please simply
-disregard this message. If you think you are being maliciously
-subscribed to the list, or have any other questions, send them to
-pyar-owner@python.org.ar.
+../../tests/rfc822.plain.message \ No newline at end of file
diff --git a/src/leap/mail/imap/tests/leap_tests_imap.zsh b/src/leap/mail/imap/tests/stress_tests_imap.zsh
index 544faca..544faca 100755
--- a/src/leap/mail/imap/tests/leap_tests_imap.zsh
+++ b/src/leap/mail/imap/tests/stress_tests_imap.zsh
diff --git a/src/leap/mail/imap/tests/test_imap.py b/src/leap/mail/imap/tests/test_imap.py
index 631a2c1..62c3c41 100644
--- a/src/leap/mail/imap/tests/test_imap.py
+++ b/src/leap/mail/imap/tests/test_imap.py
@@ -17,7 +17,7 @@
"""
Test case for leap.email.imap.server
TestCases taken from twisted tests and modified to make them work
-against SoledadBackedAccount.
+against our implementation of the IMAPAccount.
@authors: Kali Kaneko, <kali@leap.se>
XXX add authors from the original twisted tests.
@@ -25,31 +25,20 @@ XXX add authors from the original twisted tests.
@license: GPLv3, see included LICENSE file
"""
# XXX review license of the original tests!!!
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
import os
+import string
import types
from twisted.mail import imap4
from twisted.internet import defer
-from twisted.trial import unittest
from twisted.python import util
from twisted.python import failure
from twisted import cred
-
-# import u1db
-
-from leap.mail.imap.mailbox import SoledadMailbox
-from leap.mail.imap.memorystore import MemoryStore
-from leap.mail.imap.messages import MessageCollection
-from leap.mail.imap.server import LeapIMAPServer
+from leap.mail.imap.mailbox import IMAPMailbox
+from leap.mail.imap.messages import CaseInsensitiveDict
from leap.mail.imap.tests.utils import IMAP4HelperMixin
@@ -73,7 +62,6 @@ def sortNest(l):
class TestRealm:
-
"""
A minimal auth realm for testing purposes only
"""
@@ -82,153 +70,21 @@ class TestRealm:
def requestAvatar(self, avatarId, mind, *interfaces):
return imap4.IAccount, self.theAccount, lambda: None
-
#
# TestCases
#
-class MessageCollectionTestCase(IMAP4HelperMixin, unittest.TestCase):
-
- """
- Tests for the MessageCollection class
- """
- count = 0
-
- def setUp(self):
- """
- setUp method for each test
- We override mixin method since we are only testing
- MessageCollection interface in this particular TestCase
- """
- super(MessageCollectionTestCase, self).setUp()
- memstore = MemoryStore()
- self.messages = MessageCollection("testmbox%s" % (self.count,),
- self._soledad, memstore=memstore)
- MessageCollectionTestCase.count += 1
-
- def tearDown(self):
- """
- tearDown method for each test
- """
- del self.messages
-
- def testEmptyMessage(self):
- """
- Test empty message and collection
- """
- em = self.messages._get_empty_doc()
- self.assertEqual(
- em,
- {
- "chash": '',
- "deleted": False,
- "flags": [],
- "mbox": "inbox",
- "seen": False,
- "multi": False,
- "size": 0,
- "type": "flags",
- "uid": 1,
- })
- self.assertEqual(self.messages.count(), 0)
-
- def testMultipleAdd(self):
- """
- Add multiple messages
- """
- mc = self.messages
- self.assertEqual(self.messages.count(), 0)
-
- def add_first():
- d = defer.gatherResults([
- mc.add_msg('Stuff 1', subject="test1"),
- mc.add_msg('Stuff 2', subject="test2"),
- mc.add_msg('Stuff 3', subject="test3"),
- mc.add_msg('Stuff 4', subject="test4")])
- return d
-
- def add_second(result):
- d = defer.gatherResults([
- mc.add_msg('Stuff 5', subject="test5"),
- mc.add_msg('Stuff 6', subject="test6"),
- mc.add_msg('Stuff 7', subject="test7")])
- return d
-
- def check_second(result):
- return self.assertEqual(mc.count(), 7)
-
- d1 = add_first()
- d1.addCallback(add_second)
- d1.addCallback(check_second)
-
- def testRecentCount(self):
- """
- Test the recent count
- """
- mc = self.messages
- countrecent = mc.count_recent
- eq = self.assertEqual
-
- self.assertEqual(countrecent(), 0)
-
- d = mc.add_msg('Stuff', subject="test1")
- # For the semantics defined in the RFC, we auto-add the
- # recent flag by default.
-
- def add2(_):
- return mc.add_msg('Stuff', subject="test2",
- flags=('\\Deleted',))
-
- def add3(_):
- return mc.add_msg('Stuff', subject="test3",
- flags=('\\Recent',))
-
- def add4(_):
- return mc.add_msg('Stuff', subject="test4",
- flags=('\\Deleted', '\\Recent'))
-
- d.addCallback(lambda r: eq(countrecent(), 1))
- d.addCallback(add2)
- d.addCallback(lambda r: eq(countrecent(), 2))
- d.addCallback(add3)
- d.addCallback(lambda r: eq(countrecent(), 3))
- d.addCallback(add4)
- d.addCallback(lambda r: eq(countrecent(), 4))
-
- def testFilterByMailbox(self):
- """
- Test that queries filter by selected mailbox
- """
- mc = self.messages
- self.assertEqual(self.messages.count(), 0)
-
- def add_1():
- d1 = mc.add_msg('msg 1', subject="test1")
- d2 = mc.add_msg('msg 2', subject="test2")
- d3 = mc.add_msg('msg 3', subject="test3")
- d = defer.gatherResults([d1, d2, d3])
- return d
-
- add_1().addCallback(lambda ignored: self.assertEqual(
- mc.count(), 3))
-
- # XXX this has to be redone to fit memstore ------------#
- #newmsg = mc._get_empty_doc()
- #newmsg['mailbox'] = "mailbox/foo"
- #mc._soledad.create_doc(newmsg)
- #self.assertEqual(mc.count(), 3)
- #self.assertEqual(
- #len(mc._soledad.get_from_index(mc.TYPE_IDX, "flags")), 4)
+# DEBUG ---
+# from twisted.internet.base import DelayedCall
+# DelayedCall.debug = True
-class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
- # TODO this currently will use a memory-only store.
- # create a different one for testing soledad sync.
+class LEAPIMAP4ServerTestCase(IMAP4HelperMixin):
"""
- Tests for the generic behavior of the LeapIMAP4Server
+ Tests for the generic behavior of the LEAPIMAP4Server
which, right now, it's just implemented in this test file as
- LeapIMAPServer. We will move the implementation, together with
+ LEAPIMAPServer. We will move the implementation, together with
authentication bits, to leap.mail.imap.server so it can be instantiated
from the tac file.
@@ -248,6 +104,7 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
"""
succeed = ('testbox', 'test/box', 'test/', 'test/box/box', 'foobox')
fail = ('testbox', 'test/box')
+ acc = self.server.theAccount
def cb():
self.result.append(1)
@@ -259,46 +116,54 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
return self.client.login(TEST_USER, TEST_PASSWD)
def create():
+ create_deferreds = []
for name in succeed + fail:
d = self.client.create(name)
d.addCallback(strip(cb)).addErrback(eb)
- d.addCallbacks(self._cbStopClient, self._ebGeneral)
+ create_deferreds.append(d)
+ dd = defer.gatherResults(create_deferreds)
+ dd.addCallbacks(self._cbStopClient, self._ebGeneral)
+ return dd
self.result = []
- d1 = self.connected.addCallback(strip(login)).addCallback(
- strip(create))
+ d1 = self.connected.addCallback(strip(login))
+ d1.addCallback(strip(create))
d2 = self.loopback()
- d = defer.gatherResults([d1, d2])
+ d = defer.gatherResults([d1, d2], consumeErrors=True)
+ d.addCallback(lambda _: acc.account.list_all_mailbox_names())
return d.addCallback(self._cbTestCreate, succeed, fail)
- def _cbTestCreate(self, ignored, succeed, fail):
+ def _cbTestCreate(self, mailboxes, succeed, fail):
self.assertEqual(self.result, [1] * len(succeed) + [0] * len(fail))
- mboxes = list(LeapIMAPServer.theAccount.mailboxes)
- answers = ([u'INBOX', u'foobox', 'test', u'test/box',
- u'test/box/box', 'testbox'])
- self.assertEqual(mboxes, [a for a in answers])
+ answers = ([u'INBOX', u'testbox', u'test/box', u'test',
+ u'test/box/box', 'foobox'])
+ self.assertEqual(sorted(mailboxes), sorted([a for a in answers]))
def testDelete(self):
"""
Test whether we can delete mailboxes
"""
- LeapIMAPServer.theAccount.addMailbox('delete/me')
+ def add_mailbox():
+ return self.server.theAccount.addMailbox('test-delete/me')
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
def delete():
- return self.client.delete('delete/me')
+ return self.client.delete('test-delete/me')
- d1 = self.connected.addCallback(strip(login))
+ acc = self.server.theAccount.account
+
+ d1 = self.connected.addCallback(add_mailbox)
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(delete), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
- d.addCallback(
- lambda _: self.assertEqual(
- LeapIMAPServer.theAccount.mailboxes, ['INBOX']))
+ d.addCallback(lambda _: acc.list_all_mailbox_names())
+ d.addCallback(lambda mboxes: self.assertEqual(
+ mboxes, ['INBOX']))
return d
def testIllegalInboxDelete(self):
@@ -357,24 +222,34 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
Try deleting a mailbox with sub-folders, and \NoSelect flag set.
An exception is expected.
"""
- LeapIMAPServer.theAccount.addMailbox('delete')
- to_delete = LeapIMAPServer.theAccount.getMailbox('delete')
- to_delete.setFlags((r'\Noselect',))
- to_delete.getFlags()
- LeapIMAPServer.theAccount.addMailbox('delete/me')
+ acc = self.server.theAccount
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
- def delete():
+ def create_mailboxes():
+ d1 = acc.addMailbox('delete')
+ d2 = acc.addMailbox('delete/me')
+ d = defer.gatherResults([d1, d2])
+ return d
+
+ def get_noselect_mailbox(mboxes):
+ mbox = mboxes[0]
+ return mbox.setFlags((r'\Noselect',))
+
+ def delete_mbox(ignored):
return self.client.delete('delete')
def deleteFailed(failure):
self.failure = failure
self.failure = None
+
d1 = self.connected.addCallback(strip(login))
- d1.addCallback(strip(delete)).addErrback(deleteFailed)
+ d1.addCallback(strip(create_mailboxes))
+ d1.addCallback(get_noselect_mailbox)
+
+ d1.addCallback(delete_mbox).addErrback(deleteFailed)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
@@ -386,11 +261,15 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
self.assertEqual(str(self.failure.value), expected))
return d
+ # FIXME --- this test sometimes FAILS (timing issue).
+ # Some of the deferreds used in the rename op is not waiting for the
+ # operations properly
def testRename(self):
"""
Test whether we can rename a mailbox
"""
- LeapIMAPServer.theAccount.addMailbox('oldmbox')
+ def create_mbox():
+ return self.server.theAccount.addMailbox('oldmbox')
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -398,15 +277,16 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def rename():
return self.client.rename('oldmbox', 'newname')
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(create_mbox))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(rename), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
d.addCallback(lambda _:
- self.assertEqual(
- LeapIMAPServer.theAccount.mailboxes,
- ['INBOX', 'newname']))
+ self.server.theAccount.account.list_all_mailbox_names())
+ d.addCallback(lambda mboxes:
+ self.assertItemsEqual(mboxes, ['INBOX', 'newname']))
return d
def testIllegalInboxRename(self):
@@ -440,8 +320,12 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
"""
Try to rename hierarchical mailboxes
"""
- LeapIMAPServer.theAccount.create('oldmbox/m1')
- LeapIMAPServer.theAccount.create('oldmbox/m2')
+ acc = self.server.theAccount
+
+ def add_mailboxes():
+ return defer.gatherResults([
+ acc.addMailbox('oldmbox/m1'),
+ acc.addMailbox('oldmbox/m2')])
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -449,45 +333,65 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def rename():
return self.client.rename('oldmbox', 'newname')
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(add_mailboxes))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(rename), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
+ d.addCallback(lambda _: acc.account.list_all_mailbox_names())
return d.addCallback(self._cbTestHierarchicalRename)
- def _cbTestHierarchicalRename(self, ignored):
- mboxes = LeapIMAPServer.theAccount.mailboxes
- expected = ['INBOX', 'newname', 'newname/m1', 'newname/m2']
- self.assertEqual(mboxes, [s for s in expected])
+ def _cbTestHierarchicalRename(self, mailboxes):
+ expected = ['INBOX', 'newname/m1', 'newname/m2']
+ self.assertEqual(sorted(mailboxes), sorted([s for s in expected]))
def testSubscribe(self):
"""
Test whether we can mark a mailbox as subscribed to
"""
+ acc = self.server.theAccount
+
+ def add_mailbox():
+ return acc.addMailbox('this/mbox')
+
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
def subscribe():
return self.client.subscribe('this/mbox')
- d1 = self.connected.addCallback(strip(login))
+ def get_subscriptions(ignored):
+ return self.server.theAccount.getSubscriptions()
+
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(subscribe), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(
- LeapIMAPServer.theAccount.subscriptions,
- ['this/mbox']))
+ d.addCallback(get_subscriptions)
+ d.addCallback(lambda subscriptions:
+ self.assertEqual(subscriptions,
+ ['this/mbox']))
return d
def testUnsubscribe(self):
"""
Test whether we can unsubscribe from a set of mailboxes
"""
- LeapIMAPServer.theAccount.subscribe('this/mbox')
- LeapIMAPServer.theAccount.subscribe('that/mbox')
+ acc = self.server.theAccount
+
+ def add_mailboxes():
+ return defer.gatherResults([
+ acc.addMailbox('this/mbox'),
+ acc.addMailbox('that/mbox')])
+
+ def dc1():
+ return acc.subscribe('this/mbox')
+
+ def dc2():
+ return acc.subscribe('that/mbox')
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -495,24 +399,35 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def unsubscribe():
return self.client.unsubscribe('this/mbox')
- d1 = self.connected.addCallback(strip(login))
+ def get_subscriptions(ignored):
+ return acc.getSubscriptions()
+
+ d1 = self.connected.addCallback(strip(add_mailboxes))
+ d1.addCallback(strip(login))
+ d1.addCallback(strip(dc1))
+ d1.addCallback(strip(dc2))
d1.addCallbacks(strip(unsubscribe), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
- d.addCallback(lambda _:
- self.assertEqual(
- LeapIMAPServer.theAccount.subscriptions,
- ['that/mbox']))
+ d.addCallback(get_subscriptions)
+ d.addCallback(lambda subscriptions:
+ self.assertEqual(subscriptions,
+ ['that/mbox']))
return d
def testSelect(self):
"""
Try to select a mailbox
"""
- self.server.theAccount.addMailbox('TESTMAILBOX-SELECT', creation_ts=42)
+ mbox_name = "TESTMAILBOXSELECT"
self.selectedArgs = None
+ acc = self.server.theAccount
+
+ def add_mailbox():
+ return acc.addMailbox(mbox_name, creation_ts=42)
+
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -520,29 +435,26 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def selected(args):
self.selectedArgs = args
self._cbStopClient(None)
- d = self.client.select('TESTMAILBOX-SELECT')
+ d = self.client.select(mbox_name)
d.addCallback(selected)
return d
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallback(strip(select))
- d1.addErrback(self._ebGeneral)
+ # d1.addErrback(self._ebGeneral)
d2 = self.loopback()
- return defer.gatherResults([d1, d2]).addCallback(self._cbTestSelect)
+
+ d = defer.gatherResults([d1, d2])
+ d.addCallback(self._cbTestSelect)
+ return d
def _cbTestSelect(self, ignored):
- mbox = LeapIMAPServer.theAccount.getMailbox('TESTMAILBOX-SELECT')
- self.assertEqual(self.server.mbox.messages.mbox, mbox.messages.mbox)
- # XXX UIDVALIDITY should be "42" if the creation_ts is passed along
- # to the memory store. However, the current state of the account
- # implementation is incomplete and we're writing to soledad store
- # directly there. We should handle the UIDVALIDITY timestamping
- # mechanism in a separate test suite.
+ self.assertTrue(self.selectedArgs is not None)
self.assertEqual(self.selectedArgs, {
- 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 0,
- # 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 42,
+ 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 42,
'FLAGS': ('\\Seen', '\\Answered', '\\Flagged',
'\\Deleted', '\\Draft', '\\Recent', 'List'),
'READ-WRITE': True
@@ -560,13 +472,16 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
caps.update(c)
self.server.transport.loseConnection()
return self.client.getCapabilities().addCallback(gotCaps)
- d1 = self.connected.addCallback(
+
+ d1 = self.connected
+ d1.addCallback(
strip(getCaps)).addErrback(self._ebGeneral)
+
d = defer.gatherResults([self.loopback(), d1])
expected = {'IMAP4rev1': None, 'NAMESPACE': None, 'LITERAL+': None,
'IDLE': None}
-
- return d.addCallback(lambda _: self.assertEqual(expected, caps))
+ d.addCallback(lambda _: self.assertEqual(expected, caps))
+ return d
def testCapabilityWithAuth(self):
caps = {}
@@ -587,7 +502,8 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
'IDLE': None, 'LITERAL+': None,
'AUTH': ['CRAM-MD5']}
- return d.addCallback(lambda _: self.assertEqual(expCap, caps))
+ d.addCallback(lambda _: self.assertEqual(expCap, caps))
+ return d
#
# authentication
@@ -635,7 +551,6 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
return d.addCallback(self._cbTestLogin)
def _cbTestLogin(self, ignored):
- self.assertEqual(self.server.account, LeapIMAPServer.theAccount)
self.assertEqual(self.server.state, 'auth')
def testFailedLogin(self):
@@ -673,7 +588,6 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
return d.addCallback(self._cbTestLoginRequiringQuoting)
def _cbTestLoginRequiringQuoting(self, ignored):
- self.assertEqual(self.server.account, LeapIMAPServer.theAccount)
self.assertEqual(self.server.state, 'auth')
#
@@ -720,11 +634,13 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
for details.
"""
# TODO implement the IMAP4ClientExamineTests testcase.
-
- self.server.theAccount.addMailbox('test-mailbox-e',
- creation_ts=42)
+ mbox_name = "test_mailbox_e"
+ acc = self.server.theAccount
self.examinedArgs = None
+ def add_mailbox():
+ return acc.addMailbox(mbox_name, creation_ts=42)
+
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -732,11 +648,12 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def examined(args):
self.examinedArgs = args
self._cbStopClient(None)
- d = self.client.examine('test-mailbox-e')
+ d = self.client.examine(mbox_name)
d.addCallback(examined)
return d
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallback(strip(examine))
d1.addErrback(self._ebGeneral)
d2 = self.loopback()
@@ -744,28 +661,24 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
return d.addCallback(self._cbTestExamine)
def _cbTestExamine(self, ignored):
- mbox = self.server.theAccount.getMailbox('test-mailbox-e')
- self.assertEqual(self.server.mbox.messages.mbox, mbox.messages.mbox)
-
- # XXX UIDVALIDITY should be "42" if the creation_ts is passed along
- # to the memory store. However, the current state of the account
- # implementation is incomplete and we're writing to soledad store
- # directly there. We should handle the UIDVALIDITY timestamping
- # mechanism in a separate test suite.
self.assertEqual(self.examinedArgs, {
- 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 0,
- # 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 42,
+ 'EXISTS': 0, 'RECENT': 0, 'UIDVALIDITY': 42,
'FLAGS': ('\\Seen', '\\Answered', '\\Flagged',
'\\Deleted', '\\Draft', '\\Recent', 'List'),
'READ-WRITE': False})
- def _listSetup(self, f):
- LeapIMAPServer.theAccount.addMailbox('root/subthingl',
- creation_ts=42)
- LeapIMAPServer.theAccount.addMailbox('root/another-thing',
- creation_ts=42)
- LeapIMAPServer.theAccount.addMailbox('non-root/subthing',
- creation_ts=42)
+ def _listSetup(self, f, f2=None):
+
+ acc = self.server.theAccount
+
+ def dc1():
+ return acc.addMailbox('root_subthing', creation_ts=42)
+
+ def dc2():
+ return acc.addMailbox('root_another_thing', creation_ts=42)
+
+ def dc3():
+ return acc.addMailbox('non_root_subthing', creation_ts=42)
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -775,6 +688,13 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
self.listed = None
d1 = self.connected.addCallback(strip(login))
+ d1.addCallback(strip(dc1))
+ d1.addCallback(strip(dc2))
+ d1.addCallback(strip(dc3))
+
+ if f2 is not None:
+ d1.addCallback(f2)
+
d1.addCallbacks(strip(f), self._ebGeneral)
d1.addCallbacks(listed, self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
@@ -787,12 +707,13 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
"""
def list():
return self.client.list('root', '%')
+
d = self._listSetup(list)
d.addCallback(lambda listed: self.assertEqual(
sortNest(listed),
sortNest([
- (SoledadMailbox.INIT_FLAGS, "/", "root/subthingl"),
- (SoledadMailbox.INIT_FLAGS, "/", "root/another-thing")
+ (IMAPMailbox.init_flags, "/", "root_subthing"),
+ (IMAPMailbox.init_flags, "/", "root_another_thing")
])
))
return d
@@ -801,20 +722,29 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
"""
Test LSub command
"""
- LeapIMAPServer.theAccount.subscribe('root/subthingl2')
+ acc = self.server.theAccount
+
+ def subs_mailbox():
+ # why not client.subscribe instead?
+ return acc.subscribe('root_subthing')
def lsub():
return self.client.lsub('root', '%')
- d = self._listSetup(lsub)
+
+ d = self._listSetup(lsub, strip(subs_mailbox))
d.addCallback(self.assertEqual,
- [(SoledadMailbox.INIT_FLAGS, "/", "root/subthingl2")])
+ [(IMAPMailbox.init_flags, "/", "root_subthing")])
return d
def testStatus(self):
"""
Test Status command
"""
- LeapIMAPServer.theAccount.addMailbox('root/subthings')
+ acc = self.server.theAccount
+
+ def add_mailbox():
+ return acc.addMailbox('root_subthings')
+
# XXX FIXME ---- should populate this a little bit,
# with unseen etc...
@@ -823,13 +753,15 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def status():
return self.client.status(
- 'root/subthings', 'MESSAGES', 'UIDNEXT', 'UNSEEN')
+ 'root_subthings', 'MESSAGES', 'UIDNEXT', 'UNSEEN')
def statused(result):
self.statused = result
self.statused = None
- d1 = self.connected.addCallback(strip(login))
+
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(status), self._ebGeneral)
d1.addCallbacks(statused, self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
@@ -886,56 +818,86 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
"""
infile = util.sibpath(__file__, 'rfc822.message')
message = open(infile)
- LeapIMAPServer.theAccount.addMailbox('root/subthing')
+ acc = self.server.theAccount
+ mailbox_name = "appendmbox/subthing"
+
+ def add_mailbox():
+ return acc.addMailbox(mailbox_name)
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
def append():
return self.client.append(
- 'root/subthing',
- message,
+ mailbox_name, message,
('\\SEEN', '\\DELETED'),
'Tue, 17 Jun 2003 11:22:16 -0600 (MDT)',
)
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(append), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
+
+ d.addCallback(lambda _: acc.getMailbox(mailbox_name))
+ d.addCallback(lambda mb: mb.fetch(imap4.MessageSet(start=1), True))
return d.addCallback(self._cbTestFullAppend, infile)
- def _cbTestFullAppend(self, ignored, infile):
- mb = LeapIMAPServer.theAccount.getMailbox('root/subthing')
- self.assertEqual(1, len(mb.messages))
+ def _cbTestFullAppend(self, fetched, infile):
+ fetched = list(fetched)
+ self.assertTrue(len(fetched) == 1)
+ self.assertTrue(len(fetched[0]) == 2)
+ uid, msg = fetched[0]
+ parsed = self.parser.parse(open(infile))
+ expected_body = parsed.get_payload()
+ expected_headers = CaseInsensitiveDict(parsed.items())
- msg = mb.messages.get_msg_by_uid(1)
- self.assertEqual(
- set(('\\Recent', '\\SEEN', '\\DELETED')),
- set(msg.getFlags()))
+ def assert_flags(flags):
+ self.assertEqual(
+ set(('\\SEEN', '\\DELETED')),
+ set(flags))
- self.assertEqual(
- 'Tue, 17 Jun 2003 11:22:16 -0600 (MDT)',
- msg.getInternalDate())
+ def assert_date(date):
+ self.assertEqual(
+ 'Tue, 17 Jun 2003 11:22:16 -0600 (MDT)',
+ date)
- parsed = self.parser.parse(open(infile))
- body = parsed.get_payload()
- headers = dict(parsed.items())
- self.assertEqual(
- body,
- msg.getBodyFile().read())
- gotheaders = msg.getHeaders(True)
+ def assert_body(body):
+ gotbody = body.read()
+ self.assertEqual(expected_body, gotbody)
+
+ def assert_headers(headers):
+ self.assertItemsEqual(map(string.lower, expected_headers), headers)
+
+ d = defer.maybeDeferred(msg.getFlags)
+ d.addCallback(assert_flags)
- self.assertItemsEqual(
- headers, gotheaders)
+ d.addCallback(lambda _: defer.maybeDeferred(msg.getInternalDate))
+ d.addCallback(assert_date)
+
+ d.addCallback(
+ lambda _: defer.maybeDeferred(
+ msg.getBodyFile, self._soledad))
+ d.addCallback(assert_body)
+
+ d.addCallback(lambda _: defer.maybeDeferred(msg.getHeaders, True))
+ d.addCallback(assert_headers)
+
+ return d
def testPartialAppend(self):
"""
Test partially appending a message to the mailbox
"""
+ # TODO this test sometimes will fail because of the notify_just_mdoc
infile = util.sibpath(__file__, 'rfc822.message')
- LeapIMAPServer.theAccount.addMailbox('PARTIAL/SUBTHING')
+
+ acc = self.server.theAccount
+
+ def add_mailbox():
+ return acc.addMailbox('PARTIAL/SUBTHING')
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -950,33 +912,47 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
(), self.client._IMAP4Client__cbContinueAppend, message
)
)
- d1 = self.connected.addCallback(strip(login))
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
d1.addCallbacks(strip(append), self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
+
+ d.addCallback(lambda _: acc.getMailbox("PARTIAL/SUBTHING"))
+ d.addCallback(lambda mb: mb.fetch(imap4.MessageSet(start=1), True))
return d.addCallback(
self._cbTestPartialAppend, infile)
- def _cbTestPartialAppend(self, ignored, infile):
- mb = LeapIMAPServer.theAccount.getMailbox('PARTIAL/SUBTHING')
- self.assertEqual(1, len(mb.messages))
- msg = mb.messages.get_msg_by_uid(1)
- self.assertEqual(
- set(('\\SEEN', '\\Recent')),
- set(msg.getFlags())
- )
+ def _cbTestPartialAppend(self, fetched, infile):
+ fetched = list(fetched)
+ self.assertTrue(len(fetched) == 1)
+ self.assertTrue(len(fetched[0]) == 2)
+ uid, msg = fetched[0]
parsed = self.parser.parse(open(infile))
- body = parsed.get_payload()
- self.assertEqual(
- body,
- msg.getBodyFile().read())
+ expected_body = parsed.get_payload()
+
+ def assert_flags(flags):
+ self.assertEqual(
+ set((['\\SEEN'])), set(flags))
+
+ def assert_body(body):
+ gotbody = body.read()
+ self.assertEqual(expected_body, gotbody)
+
+ d = defer.maybeDeferred(msg.getFlags)
+ d.addCallback(assert_flags)
+
+ d.addCallback(lambda _: defer.maybeDeferred(msg.getBodyFile))
+ d.addCallback(assert_body)
+ return d
def testCheck(self):
"""
Test check command
"""
- LeapIMAPServer.theAccount.addMailbox('root/subthing')
+ def add_mailbox():
+ return self.server.theAccount.addMailbox('root/subthing')
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
@@ -987,89 +963,51 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
def check():
return self.client.check()
- d = self.connected.addCallback(strip(login))
+ d = self.connected.addCallbacks(
+ strip(add_mailbox), self._ebGeneral)
+ d.addCallbacks(lambda _: login(), self._ebGeneral)
d.addCallbacks(strip(select), self._ebGeneral)
d.addCallbacks(strip(check), self._ebGeneral)
d.addCallbacks(self._cbStopClient, self._ebGeneral)
- return self.loopback()
-
- # Okay, that was fun
-
- def testClose(self):
- """
- Test closing the mailbox. We expect to get deleted all messages flagged
- as such.
- """
- name = 'mailbox-close'
- self.server.theAccount.addMailbox(name)
-
- m = LeapIMAPServer.theAccount.getMailbox(name)
-
- def login():
- return self.client.login(TEST_USER, TEST_PASSWD)
-
- def select():
- return self.client.select(name)
-
- def add_messages():
- d1 = m.messages.add_msg(
- 'test 1', subject="Message 1",
- flags=('\\Deleted', 'AnotherFlag'))
- d2 = m.messages.add_msg(
- 'test 2', subject="Message 2",
- flags=('AnotherFlag',))
- d3 = m.messages.add_msg(
- 'test 3', subject="Message 3",
- flags=('\\Deleted',))
- d = defer.gatherResults([d1, d2, d3])
- return d
-
- def close():
- return self.client.close()
-
- d = self.connected.addCallback(strip(login))
- d.addCallbacks(strip(select), self._ebGeneral)
- d.addCallbacks(strip(add_messages), self._ebGeneral)
- d.addCallbacks(strip(close), self._ebGeneral)
- d.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
- return defer.gatherResults([d, d2]).addCallback(self._cbTestClose, m)
-
- def _cbTestClose(self, ignored, m):
- self.assertEqual(len(m.messages), 1)
- msg = m.messages.get_msg_by_uid(2)
- self.assertTrue(msg is not None)
+ return defer.gatherResults([d, d2])
- self.assertEqual(
- dict(msg.hdoc.content)['subject'],
- 'Message 2')
- self.failUnless(m.closed)
+ # Okay, that was much fun indeed
def testExpunge(self):
"""
Test expunge command
"""
- name = 'mailbox-expunge'
- self.server.theAccount.addMailbox(name)
- m = LeapIMAPServer.theAccount.getMailbox(name)
+ acc = self.server.theAccount
+ mailbox_name = 'mailboxexpunge'
+
+ def add_mailbox():
+ return acc.addMailbox(mailbox_name)
def login():
return self.client.login(TEST_USER, TEST_PASSWD)
def select():
- return self.client.select('mailbox-expunge')
+ return self.client.select(mailbox_name)
+
+ def save_mailbox(mailbox):
+ self.mailbox = mailbox
+
+ def get_mailbox():
+ d = acc.getMailbox(mailbox_name)
+ d.addCallback(save_mailbox)
+ return d
def add_messages():
- d1 = m.messages.add_msg(
- 'test 1', subject="Message 1",
- flags=('\\Deleted', 'AnotherFlag'))
- d2 = m.messages.add_msg(
- 'test 2', subject="Message 2",
- flags=('AnotherFlag',))
- d3 = m.messages.add_msg(
- 'test 3', subject="Message 3",
- flags=('\\Deleted',))
- d = defer.gatherResults([d1, d2, d3])
+ d = self.mailbox.addMessage(
+ 'test 1', flags=('\\Deleted', 'AnotherFlag'),
+ notify_just_mdoc=False)
+ d.addCallback(lambda _: self.mailbox.addMessage(
+ 'test 2', flags=('AnotherFlag',),
+ notify_just_mdoc=False))
+ d.addCallback(lambda _: self.mailbox.addMessage(
+ 'test 3', flags=('\\Deleted',),
+ notify_just_mdoc=False))
return d
def expunge():
@@ -1080,47 +1018,41 @@ class LeapIMAP4ServerTestCase(IMAP4HelperMixin, unittest.TestCase):
self.results = results
self.results = None
- d1 = self.connected.addCallback(strip(login))
- d1.addCallbacks(strip(select), self._ebGeneral)
+ d1 = self.connected.addCallback(strip(add_mailbox))
+ d1.addCallback(strip(login))
+ d1.addCallback(strip(get_mailbox))
d1.addCallbacks(strip(add_messages), self._ebGeneral)
+ d1.addCallbacks(strip(select), self._ebGeneral)
d1.addCallbacks(strip(expunge), self._ebGeneral)
d1.addCallbacks(expunged, self._ebGeneral)
d1.addCallbacks(self._cbStopClient, self._ebGeneral)
d2 = self.loopback()
d = defer.gatherResults([d1, d2])
- return d.addCallback(self._cbTestExpunge, m)
+ d.addCallback(lambda _: self.mailbox.getMessageCount())
+ return d.addCallback(self._cbTestExpunge)
- def _cbTestExpunge(self, ignored, m):
+ def _cbTestExpunge(self, count):
# we only left 1 mssage with no deleted flag
- self.assertEqual(len(m.messages), 1)
- msg = m.messages.get_msg_by_uid(2)
-
- msg = list(m.messages)[0]
- self.assertTrue(msg is not None)
-
- self.assertEqual(
- msg.hdoc.content['subject'],
- 'Message 2')
-
+ self.assertEqual(count, 1)
# the uids of the deleted messages
self.assertItemsEqual(self.results, [1, 3])
-class AccountTestCase(IMAP4HelperMixin, unittest.TestCase):
+class AccountTestCase(IMAP4HelperMixin):
"""
Test the Account.
"""
def _create_empty_mailbox(self):
- LeapIMAPServer.theAccount.addMailbox('')
+ return self.server.theAccount.addMailbox('')
def _create_one_mailbox(self):
- LeapIMAPServer.theAccount.addMailbox('one')
+ return self.server.theAccount.addMailbox('one')
def test_illegalMailboxCreate(self):
self.assertRaises(AssertionError, self._create_empty_mailbox)
-class IMAP4ServerSearchTestCase(IMAP4HelperMixin, unittest.TestCase):
+class IMAP4ServerSearchTestCase(IMAP4HelperMixin):
"""
Tests for the behavior of the search_* functions in L{imap5.IMAP4Server}.
"""
diff --git a/src/leap/mail/imap/tests/test_imap_store_fetch.py b/src/leap/mail/imap/tests/test_imap_store_fetch.py
deleted file mode 100644
index 6da8581..0000000
--- a/src/leap/mail/imap/tests/test_imap_store_fetch.py
+++ /dev/null
@@ -1,71 +0,0 @@
-from twisted.protocols import loopback
-from twisted.python import util
-
-from leap.mail.imap.tests.utils import IMAP4HelperMixin
-
-TEST_USER = "testuser@leap.se"
-TEST_PASSWD = "1234"
-
-
-class StoreAndFetchTestCase(IMAP4HelperMixin):
- """
- Several tests to check that the internal storage representation
- is able to render the message structures as we expect them.
- """
-
- def setUp(self):
- IMAP4HelperMixin.setUp(self)
- self.received_messages = self.received_uid = None
- self.result = None
-
- def addListener(self, x):
- pass
-
- def removeListener(self, x):
- pass
-
- def _addSignedMessage(self, _):
- self.server.state = 'select'
- infile = util.sibpath(__file__, 'rfc822.multi-signed.message')
- raw = open(infile).read()
- MBOX_NAME = "multipart/SIGNED"
-
- self.server.theAccount.addMailbox(MBOX_NAME)
- mbox = self.server.theAccount.getMailbox(MBOX_NAME)
- self.server.mbox = mbox
- # return a deferred that will fire with UID
- return self.server.mbox.messages.add_msg(raw)
-
- def _fetchWork(self, uids):
-
- def result(R):
- self.result = R
-
- self.connected.addCallback(
- self._addSignedMessage).addCallback(
- lambda uid: self.function(
- uids, uid=uid) # do NOT use seq numbers!
- ).addCallback(result).addCallback(
- self._cbStopClient).addErrback(self._ebGeneral)
-
- d = loopback.loopbackTCP(self.server, self.client, noisy=False)
- d.addCallback(lambda x: self.assertEqual(self.result, self.expected))
- return d
-
- def testMultiBody(self):
- """
- Test that a multipart signed message is retrieved the same
- as we stored it.
- """
- self.function = self.client.fetchBody
- messages = '1'
-
- # XXX review. This probably should give everything?
-
- self.expected = {1: {
- 'RFC822.TEXT': 'This is an example of a signed message,\n'
- 'with attachments.\n\n\n--=20\n'
- 'Nihil sine chao! =E2=88=B4\n',
- 'UID': '1'}}
- # print "test multi: fetch uid", messages
- return self._fetchWork(messages)
diff --git a/src/leap/mail/imap/tests/utils.py b/src/leap/mail/imap/tests/utils.py
index 0932bd4..a34538b 100644
--- a/src/leap/mail/imap/tests/utils.py
+++ b/src/leap/mail/imap/tests/utils.py
@@ -1,30 +1,44 @@
-import os
-import tempfile
-import shutil
-
+# -*- coding: utf-8 -*-
+# utils.py
+# Copyright (C) 2014, 2015 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Common utilities for testing Soledad IMAP Server.
+"""
from email import parser
from mock import Mock
from twisted.mail import imap4
from twisted.internet import defer
from twisted.protocols import loopback
+from twisted.python import log
-from leap.common.testing.basetest import BaseLeapTest
-from leap.mail.imap.account import SoledadBackedAccount
-from leap.mail.imap.memorystore import MemoryStore
-from leap.mail.imap.server import LeapIMAPServer
-from leap.soledad.client import Soledad
+from leap.mail.adaptors import soledad as soledad_adaptor
+from leap.mail.imap.account import IMAPAccount
+from leap.mail.imap.server import LEAPIMAPServer
+from leap.mail.tests.common import SoledadTestMixin
TEST_USER = "testuser@leap.se"
TEST_PASSWD = "1234"
+
#
# Simple IMAP4 Client for testing
#
-
class SimpleClient(imap4.IMAP4Client):
-
"""
A Simple IMAP4 Client to test our
Soledad-LEAPServer
@@ -51,161 +65,59 @@ class SimpleClient(imap4.IMAP4Client):
self.transport.loseConnection()
-def initialize_soledad(email, gnupg_home, tempdir):
- """
- Initializes soledad by hand
-
- :param email: ID for the user
- :param gnupg_home: path to home used by gnupg
- :param tempdir: path to temporal dir
- :rtype: Soledad instance
- """
-
- uuid = "foobar-uuid"
- passphrase = u"verysecretpassphrase"
- secret_path = os.path.join(tempdir, "secret.gpg")
- local_db_path = os.path.join(tempdir, "soledad.u1db")
- server_url = "http://provider"
- cert_file = ""
-
- class MockSharedDB(object):
-
- get_doc = Mock(return_value=None)
- put_doc = Mock()
- lock = Mock(return_value=('atoken', 300))
- unlock = Mock(return_value=True)
-
- def __call__(self):
- return self
-
- Soledad._shared_db = MockSharedDB()
-
- _soledad = Soledad(
- uuid,
- passphrase,
- secret_path,
- local_db_path,
- server_url,
- cert_file)
-
- return _soledad
-
-
-# XXX this is not properly a mixin, since helper already inherits from
-# uniittest.Testcase
-class IMAP4HelperMixin(BaseLeapTest):
+class IMAP4HelperMixin(SoledadTestMixin):
"""
MixIn containing several utilities to be shared across
different TestCases
"""
-
serverCTX = None
clientCTX = None
- # setUpClass cannot be a classmethod in trial, see:
- # https://twistedmatrix.com/trac/ticket/1870
-
def setUp(self):
- """
- Setup method for each test.
-
- Initializes and run a LEAP IMAP4 Server,
- but passing the same Soledad instance (it's costly to initialize),
- so we have to be sure to restore state across tests.
- """
- self.old_path = os.environ['PATH']
- self.old_home = os.environ['HOME']
- self.tempdir = tempfile.mkdtemp(prefix="leap_tests-")
- self.home = self.tempdir
- bin_tdir = os.path.join(
- self.tempdir,
- 'bin')
- os.environ["PATH"] = bin_tdir
- os.environ["HOME"] = self.tempdir
-
- # Soledad: config info
- self.gnupg_home = "%s/gnupg" % self.tempdir
- self.email = 'leap@leap.se'
-
- # initialize soledad by hand so we can control keys
- self._soledad = initialize_soledad(
- self.email,
- self.gnupg_home,
- self.tempdir)
- UUID = 'deadbeef',
- USERID = TEST_USER
- memstore = MemoryStore()
-
- ###########
- d = defer.Deferred()
- self.server = LeapIMAPServer(
- uuid=UUID, userid=USERID,
- contextFactory=self.serverCTX,
- # XXX do we really need this??
- soledad=self._soledad)
+ soledad_adaptor.cleanup_deferred_locks()
- self.client = SimpleClient(d, contextFactory=self.clientCTX)
- self.connected = d
-
- # XXX REVIEW-ME.
- # We're adding theAccount here to server
- # but it was also passed to initialization
- # as it was passed to realm.
- # I THINK we ONLY need to do it at one place now.
-
- theAccount = SoledadBackedAccount(
- USERID,
- soledad=self._soledad,
- memstore=memstore)
- LeapIMAPServer.theAccount = theAccount
-
- # in case we get something from previous tests...
- for mb in self.server.theAccount.mailboxes:
- self.server.theAccount.delete(mb)
+ UUID = 'deadbeef',
+ USERID = TEST_USER
- # email parser
- self.parser = parser.Parser()
+ def setup_server(account):
+ self.server = LEAPIMAPServer(
+ uuid=UUID, userid=USERID,
+ contextFactory=self.serverCTX,
+ soledad=self._soledad)
+ self.server.theAccount = account
+
+ d_server_ready = defer.Deferred()
+ self.client = SimpleClient(
+ d_server_ready, contextFactory=self.clientCTX)
+ self.connected = d_server_ready
+
+ def setup_account(_):
+ self.parser = parser.Parser()
+
+ # XXX this should be fixed in soledad.
+ # Soledad sync makes trial block forever. The sync it's mocked to
+ # fix this problem. _mock_soledad_get_from_index can be used from
+ # the tests to provide documents.
+ # TODO see here, possibly related?
+ # -- http://www.pythoneye.com/83_20424875/
+ self._soledad.sync = Mock()
+
+ d = defer.Deferred()
+ self.acc = IMAPAccount(USERID, self._soledad, d=d)
+ return d
+
+ d = super(IMAP4HelperMixin, self).setUp()
+ d.addCallback(setup_account)
+ d.addCallback(setup_server)
+ return d
def tearDown(self):
- """
- tearDown method called after each test.
-
- Deletes all documents in the Index, and deletes
- instances of server and client.
- """
- try:
- self._soledad.close()
- os.environ["PATH"] = self.old_path
- os.environ["HOME"] = self.old_home
- # safety check
- assert 'leap_tests-' in self.tempdir
- shutil.rmtree(self.tempdir)
- except Exception:
- print "ERROR WHILE CLOSING SOLEDAD"
-
- def populateMessages(self):
- """
- Populates soledad instance with several simple messages
- """
- # XXX we should encapsulate this thru SoledadBackedAccount
- # instead.
-
- # XXX we also should put this in a mailbox!
-
- self._soledad.messages.add_msg('', subject="test1")
- self._soledad.messages.add_msg('', subject="test2")
- self._soledad.messages.add_msg('', subject="test3")
- # XXX should change Flags too
- self._soledad.messages.add_msg('', subject="test4")
-
- def delete_all_docs(self):
- """
- Deletes all the docs in the testing instance of the
- SoledadBackedAccount.
- """
- self.server.theAccount.deleteAllMessages(
- iknowhatiamdoing=True)
+ SoledadTestMixin.tearDown(self)
+ del self._soledad
+ del self.client
+ del self.server
+ del self.connected
def _cbStopClient(self, ignore):
self.client.transport.loseConnection()
@@ -213,13 +125,8 @@ class IMAP4HelperMixin(BaseLeapTest):
def _ebGeneral(self, failure):
self.client.transport.loseConnection()
self.server.transport.loseConnection()
- # can we do something similar?
- # I guess this was ok with trial, but not in noseland...
- # log.err(failure, "Problem with %r" % (self.function,))
- raise failure.value
- # failure.trap(Exception)
+ if hasattr(self, 'function'):
+ log.err(failure, "Problem with %r" % (self.function,))
def loopback(self):
return loopback.loopbackAsync(self.server, self.client)
-
-
diff --git a/src/leap/mail/imap/tests/walktree.py b/src/leap/mail/imap/tests/walktree.py
index 695f487..f259a55 100644
--- a/src/leap/mail/imap/tests/walktree.py
+++ b/src/leap/mail/imap/tests/walktree.py
@@ -1,4 +1,4 @@
-#t -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
# walktree.py
# Copyright (C) 2013 LEAP
#
@@ -19,6 +19,7 @@ Tests for the walktree module.
"""
import os
import sys
+import pprint
from email import parser
from leap.mail import walk as W
@@ -118,7 +119,6 @@ if DEBUG and DO_CHECK:
print "Structure: OK"
-import pprint
print
print "RAW DOCS"
pprint.pprint(raw_docs)