#! /usr/bin/env python
############################################################################
# Copyright (C) 2002 Paul Rodger <paul@paulrodger.com>
# (C) 2006,2007 Nikolaus Schulz <microschulz@web.de>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################
# $Id: test_archivemail.py 231 2007-11-07 00:57:44Z nikosch $
"""
Unit-test archivemail using 'PyUnit'.
TODO: add tests for:
* procmail locks already existing
* archiving maildir-format mailboxes
* archiving MH-format mailboxes
* preservation of status information from maildir to mbox
* a 3rd party process changing the mbox file being read
"""
import sys
def check_python_version():
"""Abort if we are running on python < v2.3"""
too_old_error = "This test script requires python version 2.3 or later. " + \
"Your version of python is:\n%s" % sys.version
try:
version = sys.version_info # we might not even have this function! :)
if (version[0] < 2) or (version[0] == 2 and version[1] < 3):
print too_old_error
sys.exit(1)
except AttributeError:
print too_old_error
sys.exit(1)
# define & run this early because 'unittest' requires Python >= 2.1
check_python_version()
import copy
import fcntl
import filecmp
import os
import re
import shutil
import stat
import tempfile
import time
import unittest
try:
import archivemail
except ImportError:
print "The archivemail script needs to be called 'archivemail.py'"
print "and should be in the current directory in order to be imported"
print "and tested. Sorry."
if os.path.isfile("archivemail"):
print "Try renaming it from 'archivemail' to 'archivemail.py'."
sys.exit(1)
class TestCaseInTempdir(unittest.TestCase):
"""Base class for testcases that need to create temporary files.
All testcases that create temporary files should be derived from this
class, not directly from unittest.TestCase.
TestCaseInTempdir provides these methods:
setUp() Creates a safe temporary directory and sets tempfile.tempdir.
tearDown() Recursively removes the temporary directory and unsets
tempfile.tempdir.
Overriding methods should call the ones above."""
temproot = None
def setUp(self):
if not self.temproot:
assert(not tempfile.tempdir)
self.temproot = tempfile.tempdir = \
tempfile.mkdtemp(prefix="test-archivemail")
def tearDown(self):
assert(tempfile.tempdir == self.temproot)
if self.temproot:
shutil.rmtree(self.temproot)
tempfile.tempdir = self.temproot = None
############ Mbox Class testing ##############
class TestMboxIsEmpty(TestCaseInTempdir):
def setUp(self):
super(TestMboxIsEmpty, self).setUp()
self.empty_name = make_mbox(messages=0)
self.not_empty_name = make_mbox(messages=1)
def testEmpty(self):
"""is_empty() should be true for an empty mbox"""
mbox = archivemail.Mbox(self.empty_name)
assert(mbox.is_empty())
def testNotEmpty(self):
"""is_empty() should be false for a non-empty mbox"""
mbox = archivemail.Mbox(self.not_empty_name)
assert(not mbox.is_empty())
class TestMboxLeaveEmpty(TestCaseInTempdir):
def setUp(self):
super(TestMboxLeaveEmpty, self).setUp()
self.mbox_name = make_mbox()
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.mbox = archivemail.Mbox(self.mbox_name)
def testLeaveEmpty(self):
"""leave_empty should leave a zero-length file"""
self.mbox.leave_empty()
assert(os.path.isfile(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(new_mode, self.mbox_mode)
class TestMboxProcmailLock(TestCaseInTempdir):
def setUp(self):
super(TestMboxProcmailLock, self).setUp()
self.mbox_name = make_mbox()
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.mbox = archivemail.Mbox(self.mbox_name)
def testProcmailLock(self):
"""procmail_lock/unlock should create/delete a lockfile"""
lock = self.mbox_name + ".lock"
self.mbox.procmail_lock()
assert(os.path.isfile(lock))
self.mbox.procmail_unlock()
assert(not os.path.isfile(lock))
class TestMboxRemove(TestCaseInTempdir):
def setUp(self):
super(TestMboxRemove, self).setUp()
self.mbox_name = make_mbox()
self.mbox = archivemail.Mbox(self.mbox_name)
def testMboxRemove(self):
"""remove() should delete a mbox mailbox"""
assert(os.path.exists(self.mbox_name))
self.mbox.remove()
assert(not os.path.exists(self.mbox_name))
class TestMboxExclusiveLock(TestCaseInTempdir):
def setUp(self):
super(TestMboxExclusiveLock, self).setUp()
self.mbox_name = make_mbox()
self.mbox = archivemail.Mbox(self.mbox_name)
def testExclusiveLock(self):
"""exclusive_lock/unlock should create/delete an advisory lock"""
# We're using flock(2) locks; these aren't completely portable, and on
# some systems (e.g. Solaris) they may be emulated with fcntl(2) locks,
# which have pretty different semantics. We could test real flock
# locks within this process, but that doesn't work for fcntl locks.
#
# The following code snippet heavily lends from the Python 2.5 mailbox
# unittest.
# BEGIN robbery:
# Fork off a subprocess that will lock the file for 2 seconds,
# unlock it, and then exit.
pid = os.fork()
if pid == 0:
# In the child, lock the mailbox.
self.mbox.exclusive_lock()
time.sleep(2)
self.mbox.exclusive_unlock()
os._exit(0)
# In the parent, sleep a bit to give the child time to acquire
# the lock.
time.sleep(0.5)
# The parent's file self.mbox.mbox_file shares flock locks with the
# duplicated FD in the child; reopen it so we get a different file
# table entry.
file = open(self.mbox_name, "r+")
lock_nb = fcntl.LOCK_EX | fcntl.LOCK_NB
fd = file.fileno()
try:
self.assertRaises(IOError, fcntl.flock, fd, lock_nb)
finally:
# Wait for child to exit. Locking should now succeed.
exited_pid, status = os.waitpid(pid, 0)
fcntl.flock(fd, lock_nb)
fcntl.flock(fd, fcntl.LOCK_UN)
# END robbery
class TestMboxNext(TestCaseInTempdir):
def setUp(self):
super(TestMboxNext, self).setUp()
self.not_empty_name = make_mbox(messages=18)
self.empty_name = make_mbox(messages=0)
def testNextEmpty(self):
"""mbox.next() should return None on an empty mailbox"""
mbox = archivemail.Mbox(self.empty_name)
msg = mbox.next()
self.assertEqual(msg, None)
def testNextNotEmpty(self):
"""mbox.next() should a message on a populated mailbox"""
mbox = archivemail.Mbox(self.not_empty_name)
for count in range(18):
msg = mbox.next()
assert(msg)
msg = mbox.next()
self.assertEqual(msg, None)
class TestMboxWrite(TestCaseInTempdir):
def setUp(self):
super(TestMboxWrite, self).setUp()
self.mbox_read = make_mbox(messages=3)
self.mbox_write = make_mbox(messages=0)
def testWrite(self):
"""mbox.write() should append messages to a mbox mailbox"""
read = archivemail.Mbox(self.mbox_read)
write = archivemail.Mbox(self.mbox_write, mode="w")
for count in range(3):
msg = read.next()
write.write(msg)
read.close()
write.close()
assert(filecmp.cmp(self.mbox_read, self.mbox_write, shallow=0))
def testWriteNone(self):
"""calling mbox.write() with no message should raise AssertionError"""
read = archivemail.Mbox(self.mbox_read)
write = archivemail.Mbox(self.mbox_write, mode="w")
self.assertRaises(AssertionError, write.write, None)
########## options class testing #################
class TestOptionDefaults(unittest.TestCase):
def testVerbose(self):
"""verbose should be off by default"""
self.assertEqual(archivemail.options.verbose, 0)
def testDaysOldMax(self):
"""default archival time should be 180 days"""
self.assertEqual(archivemail.options.days_old_max, 180)
def testQuiet(self):
"""quiet should be off by default"""
self.assertEqual(archivemail.options.quiet, 0)
def testDeleteOldMail(self):
"""we should not delete old mail by default"""
self.assertEqual(archivemail.options.delete_old_mail, 0)
def testNoCompress(self):
"""no-compression should be off by default"""
self.assertEqual(archivemail.options.no_compress, 0)
def testIncludeFlagged(self):
"""we should not archive flagged messages by default"""
self.assertEqual(archivemail.options.include_flagged, 0)
def testPreserveUnread(self):
"""we should not preserve unread messages by default"""
self.assertEqual(archivemail.options.preserve_unread, 0)
########## archivemail.is_older_than_days() unit testing #################
class TestIsTooOld(unittest.TestCase):
def testVeryOld(self):
"""with max_days=360, should be true for these dates > 1 year"""
for years in range(1, 10):
time_msg = time.time() - (years * 365 * 24 * 60 * 60)
assert(archivemail.is_older_than_days(time_message=time_msg,
max_days=360))
def testOld(self):
"""with max_days=14, should be true for these dates > 14 days"""
for days in range(14, 360):
time_msg = time.time() - (days * 24 * 60 * 60)
assert(archivemail.is_older_than_days(time_message=time_msg,
max_days=14))
def testJustOld(self):
"""with max_days=1, should be true for these dates >= 1 day"""
for minutes in range(0, 61):
time_msg = time.time() - (25 * 60 * 60) + (minutes * 60)
assert(archivemail.is_older_than_days(time_message=time_msg,
max_days=1))
def testNotOld(self):
"""with max_days=9, should be false for these dates < 9 days"""
for days in range(0, 9):
time_msg = time.time() - (days * 24 * 60 * 60)
assert(not archivemail.is_older_than_days(time_message=time_msg,
max_days=9))
def testJustNotOld(self):
"""with max_days=1, should be false for these hours <= 1 day"""
for minutes in range(0, 60):
time_msg = time.time() - (23 * 60 * 60) - (minutes * 60)
assert(not archivemail.is_older_than_days(time_message=time_msg,
max_days=1))
def testFuture(self):
"""with max_days=1, should be false for times in the future"""
for minutes in range(0, 60):
time_msg = time.time() + (minutes * 60)
assert(not archivemail.is_older_than_days(time_message=time_msg,
max_days=1))
########## archivemail.parse_imap_url() unit testing #################
class TestParseIMAPUrl(unittest.TestCase):
def setUp(self):
archivemail.options.quiet = 1
archivemail.options.verbose = 0
archivemail.options.pwfile = None
urls_withoutpass = [
('imaps://user@example.org@imap.example.org/upperbox/lowerbox',
('user', None, 'example.org@imap.example.org',
'upperbox/lowerbox')),
('imaps://"user@example.org"@imap.example.org/upperbox/lowerbox',
('user@example.org', None, 'imap.example.org',
'upperbox/lowerbox')),
('imaps://user@example.org"@imap.example.org/upperbox/lowerbox',
('user', None, 'example.org"@imap.example.org',
'upperbox/lowerbox')),
('imaps://"user@example.org@imap.example.org/upperbox/lowerbox',
('"user', None, 'example.org@imap.example.org',
'upperbox/lowerbox')),
('imaps://"us\\"er@example.org"@imap.example.org/upperbox/lowerbox',
('us"er@example.org', None, 'imap.example.org',
'upperbox/lowerbox')),
('imaps://user\\@example.org@imap.example.org/upperbox/lowerbox',
('user\\', None, 'example.org@imap.example.org',
'upperbox/lowerbox'))
]
urls_withpass = [
('imaps://user@example.org:passwd@imap.example.org/upperbox/lowerbox',
('user@example.org', 'passwd', 'imap.example.org',
'upperbox/lowerbox'),
('user', None, 'example.org:passwd@imap.example.org',
'upperbox/lowerbox')),
('imaps://"user@example.org:passwd@imap.example.org/upperbox/lowerbox',
('"user@example.org', "passwd", 'imap.example.org',
'upperbox/lowerbox'),
('"user', None, 'example.org:passwd@imap.example.org',
'upperbox/lowerbox')),
('imaps://u\\ser\\@example.org:"p@sswd"@imap.example.org/upperbox/lowerbox',
('u\\ser\\@example.org', 'p@sswd', 'imap.example.org',
'upperbox/lowerbox'),
('u\\ser\\', None, 'example.org:"p@sswd"@imap.example.org',
'upperbox/lowerbox'))
]
# These are invalid when the password's not stripped.
urls_onlywithpass = [
('imaps://"user@example.org":passwd@imap.example.org/upperbox/lowerbox',
('user@example.org', "passwd", 'imap.example.org',
'upperbox/lowerbox'))
]
def testUrlsWithoutPwfile(self):
"""Parse test urls with --pwfile option unset. This parses a password in
the URL, if present."""
archivemail.options.pwfile = None
for mbstr in self.urls_withpass + self.urls_withoutpass:
url = mbstr[0][mbstr[0].find('://')+3:]
result = archivemail.parse_imap_url(url)
self.assertEqual(result, mbstr[1])
def testUrlsWithPwfile(self):
"""Parse test urls with --pwfile set. In this case the ':' character
loses its meaning as a delimiter."""
archivemail.options.pwfile = "whocares.txt"
for mbstr in self.urls_withpass:
url = mbstr[0][mbstr[0].find('://')+3:]
result = archivemail.parse_imap_url(url)
self.assertEqual(result, mbstr[2])
for mbstr in self.urls_onlywithpass:
url = mbstr[0][mbstr[0].find('://')+3:]
self.assertRaises(archivemail.UnexpectedError,
archivemail.parse_imap_url, url)
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.verbose = 0
archivemail.options.pwfile = None
########## acceptance testing ###########
class TestArchiveMbox(TestCaseInTempdir):
"""archiving should work based on the date of messages given"""
old_mbox = None
new_mbox = None
copy_name = None
mbox_name = None
def setUp(self):
archivemail.options.quiet = 1
super(TestArchiveMbox, self).setUp()
def testOld(self):
"""archiving an old mailbox"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def testOldFromInBody(self):
"""archiving an old mailbox with 'From ' in the body"""
body = """This is a message with ^From at the start of a line
From is on this line
This is after the ^From line"""
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181), body=body)
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
archivemail.archive(self.mbox_name)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
def testDateSystem(self):
"""test that the --date option works as expected"""
test_headers = (
{
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2000',
'Date' : None,
},
{
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : None,
'Delivery-date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : None,
'Resent-Date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
)
for headers in test_headers:
for option in ('--date=2000-07-29', '-D2000-07-29',
'--date="29 Jul 2000"', '--date="29 July 2000"'):
self.setUp()
self.mbox_name = make_mbox(messages=3, headers=headers)
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
run = "./archivemail.py -q %s %s" % (option, self.mbox_name)
self.assertEqual(os.system(run), 0)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
for option in ('--date=2000-07-27', '-D2000-07-27',
'--date="27 Jul 2000"', '--date="27 July 2000"'):
self.setUp()
self.mbox_name = make_mbox(messages=3, headers=headers)
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
run = "./archivemail.py -q %s %s" % (option, self.mbox_name)
self.assertEqual(os.system(run), 0)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testMixed(self):
"""archiving a mixed mailbox"""
for execute in ("package", "system"):
self.setUp()
self.new_mbox = make_mbox(messages=3, hours_old=(24 * 179))
self.old_mbox = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_name = tempfile.mkstemp()[1]
shutil.copyfile(self.new_mbox, self.mbox_name)
append_file(self.old_mbox, self.mbox_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.new_mbox, self.mbox_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.old_mbox, shallow=0))
self.tearDown()
def testNew(self):
"""archiving a new mailbox"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testOldExisting(self):
"""archiving an old mailbox with an existing archive"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
archive_name = self.mbox_name + "_archive"
shutil.copyfile(self.mbox_name, self.copy_name)
shutil.copyfile(self.mbox_name, archive_name) # archive has 3 msgs
append_file(self.mbox_name, self.copy_name) # copy now has 6 msgs
self.assertEqual(os.system("gzip %s" % archive_name), 0)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def testOldWeirdHeaders(self):
"""archiving old mailboxes with weird headers"""
weird_headers = (
{ # we should archive because of the date on the 'From_' line
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2000',
'Date' : 'Friskhdfkjkh, 28 Jul 2002 1line noise6:11:36 +1000',
},
{ # we should archive because of the date on the 'From_' line
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2000',
'Date' : None,
},
{ # we should archive because of the date in 'Delivery-date'
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : 'Frcorruptioni, 28 Jul 20line noise00 16:6 +1000',
'Delivery-date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{ # we should archive because of the date in 'Delivery-date'
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : None,
'Delivery-date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{ # we should archive because of the date in 'Resent-Date'
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : 'Frcorruptioni, 28 Jul 20line noise00 16:6 +1000',
'Resent-Date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{ # we should archive because of the date in 'Resent-Date'
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2030',
'Date' : None,
'Resent-Date' : 'Fri, 28 Jul 2000 16:11:36 +1000',
},
{ # completely blank dates were crashing < version 0.4.7
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2000',
'Date' : '',
},
{ # completely blank dates were crashing < version 0.4.7
'From_' : 'sender@dummy.domain Fri Jul 28 16:11:36 2000',
'Date' : '',
'Resent-Date' : '',
},
)
for headers in weird_headers:
self.setUp()
self.mbox_name = make_mbox(messages=3, headers=headers)
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
archivemail.archive(self.mbox_name)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
super(TestArchiveMbox, self).tearDown()
class TestArchiveMboxTimestamp(TestCaseInTempdir):
"""original mbox timestamps should always be preserved"""
def setUp(self):
super(TestArchiveMboxTimestamp, self).setUp()
archivemail.options.quiet = 1
def testNew(self):
"""mbox timestamps should not change after no archival"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
self.mtime = os.path.getmtime(self.mbox_name) - 66
self.atime = os.path.getatime(self.mbox_name) - 88
os.utime(self.mbox_name, (self.atime, self.mtime))
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
new_atime = os.path.getatime(self.mbox_name)
new_mtime = os.path.getmtime(self.mbox_name)
self.assertEqual(self.mtime, new_mtime)
self.assertEqual(self.atime, new_atime)
self.tearDown()
def testMixed(self):
"""mbox timestamps should not change after semi-archival"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mtime = os.path.getmtime(self.mbox_name) - 66
self.atime = os.path.getatime(self.mbox_name) - 88
os.utime(self.mbox_name, (self.atime, self.mtime))
archive_name = self.mbox_name + "_archive.gz"
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
new_atime = os.path.getatime(self.mbox_name)
new_mtime = os.path.getmtime(self.mbox_name)
self.assertEqual(self.mtime, new_mtime)
self.assertEqual(self.atime, new_atime)
self.tearDown()
def testOld(self):
"""mbox timestamps should not change after archival"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mtime = os.path.getmtime(self.mbox_name) - 66
self.atime = os.path.getatime(self.mbox_name) - 88
os.utime(self.mbox_name, (self.atime, self.mtime))
archive_name = self.mbox_name + "_archive.gz"
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
new_atime = os.path.getatime(self.mbox_name)
new_mtime = os.path.getmtime(self.mbox_name)
self.assertEqual(self.mtime, new_mtime)
self.assertEqual(self.atime, new_atime)
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
super(TestArchiveMboxTimestamp, self).tearDown()
class TestArchiveMboxPreserveStatus(TestCaseInTempdir):
"""make sure the 'preserve_unread' option works"""
def setUp(self):
super(TestArchiveMboxPreserveStatus, self).setUp()
archivemail.options.quiet = 1
archivemail.options.preserve_unread = 1
def testOldRead(self):
"""archiving an old read mailbox should create an archive"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181), \
headers={"Status":"RO"})
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --preserve-unread --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -u --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def testOldUnread(self):
"""archiving an unread mailbox should not create an archive"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --preserve-unread --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -u --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.preserve_unread = 0
super(TestArchiveMboxPreserveStatus, self).tearDown()
class TestArchiveMboxSuffix(TestCaseInTempdir):
"""make sure the 'suffix' option works"""
def setUp(self):
super(TestArchiveMboxSuffix, self).setUp()
archivemail.options.quiet = 1
def testSuffix(self):
"""archiving with specified --suffix arguments"""
for suffix in ("_static_", "_%B_%Y", "-%Y-%m-%d"):
for execute in ("system_long", "system_short", "package"):
self.setUp()
days_old_max = 180
self.mbox_name = make_mbox(messages=3,
hours_old=(24 * (days_old_max+1)))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "system_long":
run = "./archivemail.py --quiet --suffix='%s' %s" % \
(suffix, self.mbox_name)
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py --quiet -s'%s' %s" % \
(suffix, self.mbox_name)
self.assertEqual(os.system(run), 0)
elif execute == "package":
archivemail.options.archive_suffix = suffix
archivemail.archive(self.mbox_name)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
parsed_suffix_time = time.time() - days_old_max*24*60*60
parsed_suffix = time.strftime(suffix,
time.localtime(parsed_suffix_time))
archive_name = self.mbox_name + parsed_suffix + ".gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = re.sub("\.gz$", "", archive_name)
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
os.remove(archive_name)
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.archive_suffix = "_archive"
super(TestArchiveMboxSuffix, self).tearDown()
class TestArchiveDryRun(TestCaseInTempdir):
"""make sure the 'dry-run' option works"""
def setUp(self):
super(TestArchiveDryRun, self).setUp()
archivemail.options.quiet = 1
archivemail.options.dry_run = 1
def testOld(self):
"""archiving an old mailbox with the 'dry-run' option"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --dry-run --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -n --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def tearDown(self):
archivemail.options.dry_run = 0
archivemail.options.quiet = 0
super(TestArchiveDryRun, self).tearDown()
class TestArchiveDays(TestCaseInTempdir):
"""make sure the 'days' option works"""
def setUp(self):
super(TestArchiveDays, self).setUp()
archivemail.options.quiet = 1
def testOld(self):
"""specifying the 'days' option on an older mailbox"""
for execute in ("package", "system", "system_long"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 12))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.days_old_max = 11
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py -d11 --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
elif execute == "system_long":
run = "./archivemail.py --days=11 --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def testNew(self):
"""specifying the 'days' option on a newer mailbox"""
for execute in ("package", "system", "system_long"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 10))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.days_old_max = 11
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py -d11 --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
elif execute == "system_long":
run = "./archivemail.py --days=11 --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def tearDown(self):
archivemail.options.days_old_max = 180
archivemail.options.quiet = 0
super(TestArchiveDays, self).tearDown()
class TestArchiveDelete(TestCaseInTempdir):
"""make sure the 'delete' option works"""
old_mbox = None
new_mbox = None
copy_name = None
mbox_name = None
def setUp(self):
super(TestArchiveDelete, self).setUp()
archivemail.options.quiet = 1
archivemail.options.delete_old_mail = 1
def testNew(self):
"""archiving a new mailbox with the 'delete' option"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --delete --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testMixed(self):
"""archiving a mixed mailbox with the 'delete' option"""
for execute in ("package", "system"):
self.setUp()
self.new_mbox = make_mbox(messages=3, hours_old=(24 * 179))
self.old_mbox = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_name = tempfile.mkstemp()[1]
shutil.copyfile(self.new_mbox, self.mbox_name)
append_file(self.old_mbox, self.mbox_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --delete --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.new_mbox, self.mbox_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testOld(self):
"""archiving an old mailbox with the 'delete' option"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --delete --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def tearDown(self):
archivemail.options.delete_old_mail = 0
archivemail.options.quiet = 0
super(TestArchiveDelete, self).tearDown()
class TestArchiveCopy(TestCaseInTempdir):
"""make sure the 'copy' option works"""
old_mbox = None
new_mbox = None
mbox_backup_name = None
mbox_name = None
def setUp(self):
super(TestArchiveCopy, self).setUp()
archivemail.options.quiet = 1
archivemail.options.copy_old_mail = 1
def testNew(self):
"""archiving a new mailbox with the 'copy' option"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
self.mbox_backup_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.mbox_backup_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --copy --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
# mbox must not have changed:
assert(filecmp.cmp(self.mbox_name, self.mbox_backup_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
# There is no archive.
assert(not os.path.exists(archive_name))
self.tearDown()
def testMixed(self):
"""archiving a mixed mailbox with the 'copy' option"""
for execute in ("package", "system"):
self.setUp()
self.new_mbox = make_mbox(messages=3, hours_old=(24 * 179))
self.old_mbox = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_name = tempfile.mkstemp()[1]
shutil.copyfile(self.new_mbox, self.mbox_name)
append_file(self.old_mbox, self.mbox_name)
self.mbox_backup_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.mbox_backup_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --copy --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
# mbox must not have changed:
assert(filecmp.cmp(self.mbox_backup_name, self.mbox_name, shallow=0))
# archive has the old messages.
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.old_mbox, shallow=0))
self.tearDown()
def testOld(self):
"""archiving an old mailbox with the 'copy' option"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_backup_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.mbox_backup_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --copy --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
# mbox must not have changed:
assert(filecmp.cmp(self.mbox_backup_name, self.mbox_name, shallow=0))
# archive has the old messages.
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.mbox_name, shallow=0))
self.tearDown()
def tearDown(self):
archivemail.options.copy_old_mail = 0
archivemail.options.quiet = 0
super(TestArchiveCopy, self).tearDown()
class TestArchiveMboxFlagged(TestCaseInTempdir):
"""make sure the 'include_flagged' option works"""
def setUp(self):
super(TestArchiveMboxFlagged, self).setUp()
archivemail.options.quiet = 1
def testOld(self):
"""by default, old flagged messages should not be archived"""
for execute in ("system", "package"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181), \
headers={"X-Status":"F"})
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.include_flagged = 0
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testIncludeFlaggedNew(self):
"""new flagged messages should not be archived with include_flagged"""
for execute in ("system", "package"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179), \
headers={"X-Status":"F"})
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.include_flagged = 1
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --include-flagged --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def testIncludeFlaggedOld(self):
"""old flagged messages should be archived with include_flagged"""
for execute in ("system", "package"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181), \
headers={"X-Status":"F"})
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.include_flagged = 1
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --include-flagged --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def tearDown(self):
archivemail.options.include_flagged = 0
archivemail.options.quiet = 0
super(TestArchiveMboxFlagged, self).tearDown()
class TestArchiveMboxOutputDir(TestCaseInTempdir):
"""make sure that the 'output-dir' option works"""
def setUp(self):
super(TestArchiveMboxOutputDir, self).setUp()
archivemail.options.quiet = 1
def testOld(self):
"""archiving an old mailbox with a sepecified output dir"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
self.dir_name = tempfile.mkdtemp()
if execute == "package":
archivemail.options.output_dir = self.dir_name
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --output-dir=%s --quiet %s" % \
(self.dir_name, self.mbox_name)
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -o%s --quiet %s" % \
(self.dir_name, self.mbox_name)
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.dir_name + "/" + \
os.path.basename(self.mbox_name) + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = re.sub(".gz$", "", archive_name)
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.output_dir = None
super(TestArchiveMboxOutputDir, self).tearDown()
class TestArchiveMboxUncompressed(TestCaseInTempdir):
"""make sure that the 'no_compress' option works"""
mbox_name = None
new_mbox = None
old_mbox = None
copy_name = None
def setUp(self):
archivemail.options.quiet = 1
archivemail.options.no_compress = 1
super(TestArchiveMboxUncompressed, self).setUp()
def testOld(self):
"""archiving an old mailbox uncompressed"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --no-compress --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
assert(not os.path.exists(archive_name + ".gz"))
self.tearDown()
def testNew(self):
"""archiving a new mailbox uncompressed"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 179))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --no-compress --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive"
assert(not os.path.exists(archive_name))
assert(not os.path.exists(archive_name + ".gz"))
self.tearDown()
def testMixed(self):
"""archiving a mixed mailbox uncompressed"""
for execute in ("package", "system"):
self.setUp()
self.new_mbox = make_mbox(messages=3, hours_old=(24 * 179))
self.old_mbox = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_name = tempfile.mkstemp()[1]
shutil.copyfile(self.new_mbox, self.mbox_name)
append_file(self.old_mbox, self.mbox_name)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --no-compress --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.new_mbox, self.mbox_name, shallow=0))
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.old_mbox, shallow=0))
assert(not os.path.exists(archive_name + ".gz"))
self.tearDown()
def testOldExists(self):
"""archiving an old mailbox uncopressed with an existing archive"""
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=3, hours_old=(24 * 181))
self.mbox_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.copy_name = tempfile.mkstemp()[1]
archive_name = self.mbox_name + "_archive"
shutil.copyfile(self.mbox_name, self.copy_name)
shutil.copyfile(self.mbox_name, archive_name) # archive has 3 msgs
append_file(self.mbox_name, self.copy_name) # copy now has 6 msgs
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --no-compress --quiet %s" % \
self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(self.mbox_mode, new_mode)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
assert(not os.path.exists(archive_name + ".gz"))
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.no_compress = 0
super(TestArchiveMboxUncompressed, self).tearDown()
class TestArchiveSize(TestCaseInTempdir):
"""check that the 'size' argument works"""
def setUp(self):
super(TestArchiveSize, self).setUp()
archivemail.options.quiet = 1
def testSmaller(self):
"""giving a size argument smaller than the message"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=1, hours_old=(24 * 181))
size_arg = os.path.getsize(self.mbox_name) - 1
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.min_size = size_arg
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --size=%d --quiet %s" % \
(size_arg, self.mbox_name)
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -S%d --quiet %s" % \
(size_arg, self.mbox_name)
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
self.assertEqual(os.path.getsize(self.mbox_name), 0)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(archive_name))
self.assertEqual(os.system("gzip -d %s" % archive_name), 0)
archive_name = self.mbox_name + "_archive"
assert(os.path.exists(archive_name))
assert(filecmp.cmp(archive_name, self.copy_name, shallow=0))
self.tearDown()
def testBigger(self):
"""giving a size argument bigger than the message"""
for execute in ("package", "system_long", "system_short"):
self.setUp()
self.mbox_name = make_mbox(messages=1, hours_old=(24 * 181))
size_arg = os.path.getsize(self.mbox_name) + 1
self.copy_name = tempfile.mkstemp()[1]
shutil.copyfile(self.mbox_name, self.copy_name)
if execute == "package":
archivemail.options.min_size = size_arg
archivemail.archive(self.mbox_name)
elif execute == "system_long":
run = "./archivemail.py --size=%d --quiet %s" % \
(size_arg, self.mbox_name)
self.assertEqual(os.system(run), 0)
elif execute == "system_short":
run = "./archivemail.py -S%d --quiet %s" % \
(size_arg, self.mbox_name)
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
assert(os.path.exists(self.mbox_name))
assert(filecmp.cmp(self.mbox_name, self.copy_name, shallow=0))
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
archivemail.options.min_size = None
super(TestArchiveSize, self).tearDown()
class TestArchiveMboxMode(TestCaseInTempdir):
"""file mode (permissions) of the original mbox should be preserved"""
def setUp(self):
super(TestArchiveMboxMode, self).setUp()
archivemail.options.quiet = 1
def testOld(self):
"""after archiving, the original mbox mode should be preserved"""
for mode in (0666, 0664, 0660, 0640, 0600):
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=1, hours_old=(24 * 181))
os.chmod(self.mbox_name, mode)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
archive_name = self.mbox_name + "_archive.gz"
assert(os.path.exists(self.mbox_name))
assert(os.path.exists(archive_name))
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(mode, stat.S_IMODE(new_mode))
archive_mode = os.stat(archive_name)[stat.ST_MODE]
self.assertEqual(0600, stat.S_IMODE(archive_mode))
self.tearDown()
def testNew(self):
"""after no archiving, the original mbox mode should be preserved"""
for mode in (0666, 0664, 0660, 0640, 0600):
for execute in ("package", "system"):
self.setUp()
self.mbox_name = make_mbox(messages=1, hours_old=(24 * 179))
os.chmod(self.mbox_name, mode)
if execute == "package":
archivemail.archive(self.mbox_name)
elif execute == "system":
run = "./archivemail.py --quiet %s" % self.mbox_name
self.assertEqual(os.system(run), 0)
else:
sys.exit(1)
archive_name = self.mbox_name + "_archive.gz"
assert(not os.path.exists(archive_name))
assert(os.path.exists(self.mbox_name))
new_mode = os.stat(self.mbox_name)[stat.ST_MODE]
self.assertEqual(mode, stat.S_IMODE(new_mode))
os.remove(self.mbox_name)
self.tearDown()
def tearDown(self):
archivemail.options.quiet = 0
super(TestArchiveMboxMode, self).tearDown()
########## helper routines ############
def make_message(body=None, default_headers={}, hours_old=None):
headers = copy.copy(default_headers)
if not headers:
headers = {}
if not headers.has_key('Date'):
time_message = time.time() - (60 * 60 * hours_old)
headers['Date'] = time.asctime(time.localtime(time_message))
if not headers.has_key('From'):
headers['From'] = "sender@dummy.domain"
if not headers.has_key('To'):
headers['To'] = "receipient@dummy.domain"
if not headers.has_key('Subject'):
headers['Subject'] = "This is the subject"
if not headers.has_key('From_'):
headers['From_'] = "%s %s" % (headers['From'], headers['Date'])
if not body:
body = "This is the message body"
msg = ""
if headers.has_key('From_'):
msg = msg + ("From %s\n" % headers['From_'])
del headers['From_']
for key in headers.keys():
if headers[key] is not None:
msg = msg + ("%s: %s\n" % (key, headers[key]))
msg = msg + "\n\n" + body + "\n\n"
return msg
def append_file(source, dest):
"""appends the file named 'source' to the file named 'dest'"""
assert(os.path.isfile(source))
assert(os.path.isfile(dest))
read = open(source, "r")
write = open(dest, "a+")
write.writelines(read.readlines())
read.close()
write.close()
def make_mbox(body=None, headers=None, hours_old=0, messages=1):
assert(tempfile.tempdir)
fd, name = tempfile.mkstemp()
file = os.fdopen(fd, "w")
for count in range(messages):
msg = make_message(body=body, default_headers=headers,
hours_old=hours_old)
file.write(msg)
file.close()
return name
if __name__ == "__main__":
unittest.main()
|