Merge pull request #13 from thekix/master

Updated test code
This commit is contained in:
Rodolfo García Peñas (kix) 2020-10-25 19:39:06 +01:00 committed by GitHub
commit 5e7b006540
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 84 additions and 87 deletions

View File

@ -24,7 +24,8 @@ from threading import Event
from offlineimap import folder, imaputil, imapserver, OfflineImapError from offlineimap import folder, imaputil, imapserver, OfflineImapError
from offlineimap.repository.Base import BaseRepository from offlineimap.repository.Base import BaseRepository
from offlineimap.threadutil import ExitNotifyThread from offlineimap.threadutil import ExitNotifyThread
from offlineimap.utils.distro import get_os_sslcertfile, get_os_sslcertfile_searchpath from offlineimap.utils.distro_utils import get_os_sslcertfile, \
get_os_sslcertfile_searchpath
class IMAPRepository(BaseRepository): class IMAPRepository(BaseRepository):
@ -246,7 +247,6 @@ class IMAPRepository(BaseRepository):
the above behaviour, so any explicitely-requested configuration the above behaviour, so any explicitely-requested configuration
that doesn't result in an existing file will give an exception. that doesn't result in an existing file will give an exception.
""" """
xforms = [os.path.expanduser, os.path.expandvars, os.path.abspath] xforms = [os.path.expanduser, os.path.expandvars, os.path.abspath]
cacertfile = self.getconf_xform('sslcacertfile', xforms, None) cacertfile = self.getconf_xform('sslcacertfile', xforms, None)
# Can't use above cacertfile because of abspath. # Can't use above cacertfile because of abspath.

View File

@ -5,29 +5,33 @@
import platform import platform
import os import os
# Each dictionary value is either string or some iterable. # linux_distribution deprecated in Python 3.7
# try:
from platform import linux_distribution
except ImportError:
from distro import linux_distribution
# For the former we will just return the value, for an iterable # For the former we will just return the value, for an iterable
# we will walk through the values and will return the first # we will walk through the values and will return the first
# one that corresponds to the existing file. # one that corresponds to the existing file.
__DEF_OS_LOCATIONS = { __DEF_OS_LOCATIONS = {
'freebsd': '/usr/local/share/certs/ca-root-nss.crt', 'freebsd': ['/usr/local/share/certs/ca-root-nss.crt'],
'openbsd': '/etc/ssl/cert.pem', 'openbsd': ['/etc/ssl/cert.pem'],
'dragonfly': '/etc/ssl/cert.pem', 'dragonfly': ['/etc/ssl/cert.pem'],
'darwin': [ 'darwin': [
# MacPorts, port curl-ca-bundle # MacPorts, port curl-ca-bundle
'/opt/local/share/curl/curl-ca-bundle.crt', '/opt/local/share/curl/curl-ca-bundle.crt',
# homebrew, package openssl # homebrew, package openssl
'/usr/local/etc/openssl/cert.pem', '/usr/local/etc/openssl/cert.pem',
], ],
'linux-ubuntu': '/etc/ssl/certs/ca-certificates.crt', 'linux-ubuntu': ['/etc/ssl/certs/ca-certificates.crt'],
'linux-debian': '/etc/ssl/certs/ca-certificates.crt', 'linux-debian': ['/etc/ssl/certs/ca-certificates.crt'],
'linux-gentoo': '/etc/ssl/certs/ca-certificates.crt', 'linux-gentoo': ['/etc/ssl/certs/ca-certificates.crt'],
'linux-fedora': '/etc/pki/tls/certs/ca-bundle.crt', 'linux-fedora': ['/etc/pki/tls/certs/ca-bundle.crt'],
'linux-redhat': '/etc/pki/tls/certs/ca-bundle.crt', 'linux-redhat': ['/etc/pki/tls/certs/ca-bundle.crt'],
'linux-suse': '/etc/ssl/ca-bundle.pem', 'linux-suse': ['/etc/ssl/ca-bundle.pem'],
'linux-opensuse': '/etc/ssl/ca-bundle.pem', 'linux-opensuse': ['/etc/ssl/ca-bundle.pem'],
'linux-arch': '/etc/ssl/certs/ca-certificates.crt', 'linux-arch': ['/etc/ssl/certs/ca-certificates.crt'],
} }
@ -42,16 +46,16 @@ def get_os_name():
proper name capitalisation. proper name capitalisation.
""" """
OS = platform.system().lower() os_name = platform.system().lower()
if OS.startswith('linux'): if os_name.startswith('linux'):
DISTRO = platform.linux_distribution()[0] distro_name = linux_distribution()[0]
if DISTRO: if distro_name:
OS = OS + "-%s" % DISTRO.split()[0].lower() os_name = os_name + "-%s" % distro_name.split()[0].lower()
if os.path.exists('/etc/arch-release'): if os.path.exists('/etc/arch-release'):
OS = "linux-arch" os_name = "linux-arch"
return OS return os_name
def get_os_sslcertfile_searchpath(): def get_os_sslcertfile_searchpath():
@ -65,14 +69,13 @@ def get_os_sslcertfile_searchpath():
at all. at all.
""" """
OS = get_os_name() os_name = get_os_name()
l = None location = None
if OS in __DEF_OS_LOCATIONS: if os_name in __DEF_OS_LOCATIONS:
l = __DEF_OS_LOCATIONS[OS] location = __DEF_OS_LOCATIONS[os_name]
if not hasattr(l, '__iter__'):
l = (l,) return location
return l
def get_os_sslcertfile(): def get_os_sslcertfile():
@ -85,12 +88,12 @@ def get_os_sslcertfile():
correspond to non-existing filesystem objects. correspond to non-existing filesystem objects.
""" """
l = get_os_sslcertfile_searchpath() location = get_os_sslcertfile_searchpath()
if l is None: if location is None:
return None return None
for f in l: for f in location:
assert (type(f) == type("")) assert isinstance(f, str)
if os.path.exists(f) and (os.path.isfile(f) or os.path.islink(f)): if os.path.exists(f) and (os.path.isfile(f) or os.path.islink(f)):
return f return f

View File

@ -2,3 +2,4 @@
gssapi[kerberos] gssapi[kerberos]
portalocker[cygwin] portalocker[cygwin]
rfc6555 rfc6555
distro

View File

@ -21,12 +21,12 @@
# 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 os
from distutils.core import setup, Command from distutils.core import setup, Command
import offlineimap import offlineimap
import logging import logging
from test.OLItest import TextTestRunner, TestLoader, OLITestLib 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. In order to execute only a single description = """Runs the test suite. In order to execute only a single
@ -46,23 +46,20 @@ class TestCommand(Command):
# set credentials and OfflineImap command to be executed: # set credentials and OfflineImap command to be executed:
OLITestLib(cred_file='./test/credentials.conf', cmd='./offlineimap.py') OLITestLib(cred_file='./test/credentials.conf', cmd='./offlineimap.py')
suite = TestLoader().discover('./test/tests') suite = TestLoader().discover('./test/tests')
#TODO: failfast does not seem to exist in python2.6? TextTestRunner(verbosity=2, failfast=True).run(suite)
TextTestRunner(verbosity=2,failfast=True).run(suite)
setup(name = "offlineimap", setup(name="offlineimap",
version = offlineimap.__version__, version=offlineimap.__version__,
description = offlineimap.__description__, description=offlineimap.__description__,
long_description = offlineimap.__description__, long_description=offlineimap.__description__,
author = offlineimap.__author__, author=offlineimap.__author__,
author_email = offlineimap.__author_email__, author_email=offlineimap.__author_email__,
url = offlineimap.__homepage__, url=offlineimap.__homepage__,
packages = ['offlineimap', 'offlineimap.folder', packages=['offlineimap', 'offlineimap.folder',
'offlineimap.repository', 'offlineimap.ui', 'offlineimap.repository', 'offlineimap.ui',
'offlineimap.utils'], 'offlineimap.utils'],
scripts = ['bin/offlineimap'], scripts=['bin/offlineimap'],
license = offlineimap.__copyright__ + \ license=offlineimap.__copyright__ + ", Licensed under the GPL version 2",
", Licensed under the GPL version 2", cmdclass={'test': TestCommand}
cmdclass = { 'test': TestCommand} )
)

View File

@ -19,7 +19,7 @@ import shutil
import subprocess import subprocess
import tempfile import tempfile
import random import random
import offlineimap.virtual_imaplib2 as imaplib import imaplib2 as imaplib
from offlineimap.CustomConfig import CustomConfigParser from offlineimap.CustomConfig import CustomConfigParser
from . import default_conf from . import default_conf
@ -147,7 +147,7 @@ class OLITestLib:
continue continue
if isinstance(d, tuple): if isinstance(d, tuple):
# literal (unquoted) # literal (unquoted)
folder = b'"%s"' % d[1].replace('"', '\\"') folder = '"%s"' % d[1].replace('"', '\\"')
else: else:
m = re.search(br''' m = re.search(br'''
[ ] # space [ ] # space
@ -156,13 +156,15 @@ class OLITestLib:
([^"]|\\")* # a non-quote or a backslashded quote ([^"]|\\")* # a non-quote or a backslashded quote
(?P=quote))$ # ending quote (?P=quote))$ # ending quote
''', d, flags=re.VERBOSE) ''', d, flags=re.VERBOSE)
folder = bytearray(m.group('dir')) folder = m.group('dir').decode('utf-8')
if not m.group('quote'): if not m.group('quote'):
folder = '"%s"' % folder folder = '"%s"' % folder
# folder = folder.replace(br'\"', b'"') # remove quoting # folder = folder.replace(br'\"', b'"') # remove quoting
dirs.append(folder) dirs.append(folder)
# 2) filter out those not starting with INBOX.OLItest and del... # 2) filter out those not starting with INBOX.OLItest and del...
dirs = [d for d in dirs if d.startswith(b'"INBOX.OLItest') or d.startswith(b'"INBOX/OLItest')] dirs = [d for d in dirs
if d.startswith('"INBOX.OLItest')
or d.startswith('"INBOX/OLItest')]
for folder in dirs: for folder in dirs:
res_t, data = imapobj.delete(folder) res_t, data = imapobj.delete(folder)
assert res_t == 'OK', "Folder deletion of {0} failed with error" \ assert res_t == 'OK', "Folder deletion of {0} failed with error" \

View File

@ -10,9 +10,9 @@ How to run the tests
folder structure. So don't use a real used account here... folder structure. So don't use a real used account here...
- go to the top level dir (one above this one) and execute: - go to the top level dir (one above this one) and execute:
'python setup.py test' 'python3 setup.py test'
System requirements System requirements
=================== ===================
This test suite depend on python>=2.7 to run out of the box. If you want to run this with python 2.6 you will need to install the backport from http://pypi.python.org/pypi/unittest2 instead. This test suite depend on python 3 to run out of the box.

View File

@ -40,7 +40,7 @@ class TestOfflineimapGlobals(unittest.TestCase):
def test_nonexistent_key(self): def test_nonexistent_key(self):
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
pass raise AttributeError
def test_double_init(self): def test_double_init(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):

View File

@ -58,39 +58,39 @@ class TestInternalFunctions(unittest.TestCase):
def test_01_imapsplit(self): def test_01_imapsplit(self):
"""Test imaputil.imapsplit()""" """Test imaputil.imapsplit()"""
res = imaputil.imapsplit(b'(\\HasNoChildren) "." "INBOX.Sent"') res = imaputil.imapsplit('(\\HasNoChildren) "." "INBOX.Sent"')
self.assertEqual(res, [b'(\\HasNoChildren)', b'"."', b'"INBOX.Sent"']) self.assertEqual(res, ['(\\HasNoChildren)', '"."', '"INBOX.Sent"'])
res = imaputil.imapsplit(b'"mo\\" o" sdfsdf') res = imaputil.imapsplit('"mo\\" o" sdfsdf')
self.assertEqual(res, [b'"mo\\" o"', b'sdfsdf']) self.assertEqual(res, ['"mo\\" o"', 'sdfsdf'])
def test_02_flagsplit(self): def test_02_flagsplit(self):
"""Test imaputil.flagsplit()""" """Test imaputil.flagsplit()"""
res = imaputil.flagsplit(b'(\\Draft \\Deleted)') res = imaputil.flagsplit('(\\Draft \\Deleted)')
self.assertEqual(res, [b'\\Draft', b'\\Deleted']) self.assertEqual(res, ['\\Draft', '\\Deleted'])
res = imaputil.flagsplit(b'(FLAGS (\\Seen Old) UID 4807)') res = imaputil.flagsplit('(FLAGS (\\Seen Old) UID 4807)')
self.assertEqual(res, [b'FLAGS', b'(\\Seen Old)', b'UID', b'4807']) self.assertEqual(res, ['FLAGS', '(\\Seen Old)', 'UID', '4807'])
def test_04_flags2hash(self): def test_04_flags2hash(self):
"""Test imaputil.flags2hash()""" """Test imaputil.flags2hash()"""
res = imaputil.flags2hash(b'(FLAGS (\\Seen Old) UID 4807)') res = imaputil.flags2hash('(FLAGS (\\Seen Old) UID 4807)')
self.assertEqual(res, {b'FLAGS': b'(\\Seen Old)', b'UID': b'4807'}) self.assertEqual(res, {'FLAGS': '(\\Seen Old)', 'UID': '4807'})
def test_05_flagsimap2maildir(self): def test_05_flagsimap2maildir(self):
"""Test imaputil.flagsimap2maildir()""" """Test imaputil.flagsimap2maildir()"""
res = imaputil.flagsimap2maildir(b'(\\Draft \\Deleted)') res = imaputil.flagsimap2maildir('(\\Draft \\Deleted)')
self.assertEqual(res, set(b'DT')) self.assertEqual(res, set('DT'))
def test_06_flagsmaildir2imap(self): def test_06_flagsmaildir2imap(self):
"""Test imaputil.flagsmaildir2imap()""" """Test imaputil.flagsmaildir2imap()"""
res = imaputil.flagsmaildir2imap(set(b'DR')) res = imaputil.flagsmaildir2imap(set('DR'))
self.assertEqual(res, b'(\\Answered \\Draft)') self.assertEqual(res, '(\\Answered \\Draft)')
# test all possible flags # test all possible flags
res = imaputil.flagsmaildir2imap(set(b'SRFTD')) res = imaputil.flagsmaildir2imap(set('SRFTD'))
self.assertEqual(res, b'(\\Answered \\Deleted \\Draft \\Flagged \\Seen)') self.assertEqual(res, '(\\Answered \\Deleted \\Draft \\Flagged \\Seen)')
def test_07_uid_sequence(self): def test_07_uid_sequence(self):
"""Test imaputil.uid_sequence()""" """Test imaputil.uid_sequence()"""
res = imaputil.uid_sequence([1, 2, 3, 4, 5, 10, 12, 13]) res = imaputil.uid_sequence([1, 2, 3, 4, 5, 10, 12, 13])
self.assertEqual(res, b'1:5,10,12:13') self.assertEqual(res, '1:5,10,12:13')

View File

@ -53,8 +53,7 @@ class TestBasicFunctions(unittest.TestCase):
Cleans existing remote test folders. Then syncs all "OLItest* Cleans existing remote test folders. Then syncs all "OLItest*
(specified in the default config) to our local Maildir. The (specified in the default config) to our local Maildir. The
result should be 0 folders and 0 mails.""" result should be 0 folders and 0 mails."""
code, res = OLITestLib.run_OLI() OLITestLib.run_OLI()
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails) == (0, 0), self.assertTrue((boxes, mails) == (0, 0),
msg="Expected 0 folders and 0 " msg="Expected 0 folders and 0 "
@ -65,8 +64,7 @@ class TestBasicFunctions(unittest.TestCase):
"""Create local 'OLItest 1', sync""" """Create local 'OLItest 1', sync"""
OLITestLib.delete_maildir('') # Delete all local maildir folders OLITestLib.delete_maildir('') # Delete all local maildir folders
OLITestLib.create_maildir('INBOX.OLItest 1') OLITestLib.create_maildir('INBOX.OLItest 1')
code, res = OLITestLib.run_OLI() OLITestLib.run_OLI()
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails) == (1, 0), self.assertTrue((boxes, mails) == (1, 0),
msg="Expected 1 folders and 0 " msg="Expected 1 folders and 0 "
@ -80,10 +78,9 @@ class TestBasicFunctions(unittest.TestCase):
one is included here as a small challenge.""" one is included here as a small challenge."""
OLITestLib.delete_maildir('') # Delete all local maildir folders OLITestLib.delete_maildir('') # Delete all local maildir folders
OLITestLib.create_maildir('INBOX.OLItest "1"') OLITestLib.create_maildir('INBOX.OLItest "1"')
code, res = OLITestLib.run_OLI() code, res = OLITestLib.run_OLI()
if 'unallowed folder' in res: if 'unallowed folder' in res:
raise unittest.SkipTest("remote server doesn't handle quote") raise unittest.SkipTest("remote server doesn't handle quote")
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails) == (1, 0), self.assertTrue((boxes, mails) == (1, 0),
msg="Expected 1 folders and 0 " msg="Expected 1 folders and 0 "
@ -153,12 +150,9 @@ class TestBasicFunctions(unittest.TestCase):
OLITestLib.delete_remote_testfolders() OLITestLib.delete_remote_testfolders()
OLITestLib.delete_maildir('') OLITestLib.delete_maildir('')
OLITestLib.create_maildir('INBOX.OLItest') OLITestLib.create_maildir('INBOX.OLItest')
code, res = OLITestLib.run_OLI() OLITestLib.run_OLI()
# logging.warn("%s %s "% (code, res))
self.assertEqual(res, "")
OLITestLib.delete_maildir('INBOX.OLItest') OLITestLib.delete_maildir('INBOX.OLItest')
code, res = OLITestLib.run_OLI() OLITestLib.run_OLI()
self.assertEqual(res, "")
boxes, mails = OLITestLib.count_maildir_mails('') boxes, mails = OLITestLib.count_maildir_mails('')
self.assertTrue((boxes, mails) == (0, 0), self.assertTrue((boxes, mails) == (0, 0),
msg="Expected 0 folders and 0 " msg="Expected 0 folders and 0 "