blob: 8e4c57a6ceeb5ec359f13d709fb681d349b5a060 [file] [log] [blame]
Fred Drake0aaed272000-10-23 13:39:15 +00001import os
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002import sys
Fred Drakec02bc3e2001-05-21 20:23:21 +00003import time
Thomas Wouters477c8d52006-05-27 19:21:47 +00004import stat
5import socket
6import email
Thomas Woutersb2137042007-02-01 18:02:27 +00007import email.message
Thomas Wouters477c8d52006-05-27 19:21:47 +00008import re
Guido van Rossum34d19282007-08-09 01:03:29 +00009import io
R. David Murrayb7deff12011-01-30 06:21:28 +000010import tempfile
Benjamin Petersonee8712c2008-05-20 21:35:26 +000011from test import support
Thomas Wouters477c8d52006-05-27 19:21:47 +000012import unittest
R. David Murrayb7deff12011-01-30 06:21:28 +000013import textwrap
Thomas Wouters477c8d52006-05-27 19:21:47 +000014import mailbox
15import glob
Guido van Rossum75ebb292001-04-10 15:01:20 +000016try:
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 import fcntl
18except ImportError:
Guido van Rossum75ebb292001-04-10 15:01:20 +000019 pass
20
Thomas Wouters477c8d52006-05-27 19:21:47 +000021
22class TestBase(unittest.TestCase):
23
24 def _check_sample(self, msg):
25 # Inspect a mailbox.Message representation of the sample message
Ezio Melottie9615932010-01-24 19:26:24 +000026 self.assertIsInstance(msg, email.message.Message)
27 self.assertIsInstance(msg, mailbox.Message)
Guido van Rossumcc2b0162007-02-11 06:12:03 +000028 for key, value in _sample_headers.items():
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +000029 self.assertIn(value, msg.get_all(key))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000030 self.assertTrue(msg.is_multipart())
Guido van Rossume61fd5b2007-07-11 12:20:59 +000031 self.assertEqual(len(msg.get_payload()), len(_sample_payloads))
Thomas Wouters477c8d52006-05-27 19:21:47 +000032 for i, payload in enumerate(_sample_payloads):
33 part = msg.get_payload(i)
Ezio Melottie9615932010-01-24 19:26:24 +000034 self.assertIsInstance(part, email.message.Message)
35 self.assertNotIsInstance(part, mailbox.Message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +000036 self.assertEqual(part.get_payload(), payload)
Thomas Wouters477c8d52006-05-27 19:21:47 +000037
38 def _delete_recursively(self, target):
39 # Delete a file or delete a directory recursively
40 if os.path.isdir(target):
41 for path, dirs, files in os.walk(target, topdown=False):
42 for name in files:
43 os.remove(os.path.join(path, name))
44 for name in dirs:
45 os.rmdir(os.path.join(path, name))
46 os.rmdir(target)
47 elif os.path.exists(target):
48 os.remove(target)
49
50
51class TestMailbox(TestBase):
52
R. David Murrayb7deff12011-01-30 06:21:28 +000053 maxDiff = None
54
Thomas Wouters477c8d52006-05-27 19:21:47 +000055 _factory = None # Overridden by subclasses to reuse tests
56 _template = 'From: foo\n\n%s'
57
58 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000059 self._path = support.TESTFN
Guido van Rossumd8faa362007-04-27 19:54:29 +000060 self._delete_recursively(self._path)
Thomas Wouters477c8d52006-05-27 19:21:47 +000061 self._box = self._factory(self._path)
62
63 def tearDown(self):
Guido van Rossumc12a8132007-10-26 04:29:23 +000064 self._box.close()
Thomas Wouters477c8d52006-05-27 19:21:47 +000065 self._delete_recursively(self._path)
66
67 def test_add(self):
68 # Add copies of a sample message
69 keys = []
70 keys.append(self._box.add(self._template % 0))
Guido van Rossume61fd5b2007-07-11 12:20:59 +000071 self.assertEqual(len(self._box), 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +000072 keys.append(self._box.add(mailbox.Message(_sample_message)))
Guido van Rossume61fd5b2007-07-11 12:20:59 +000073 self.assertEqual(len(self._box), 2)
Thomas Wouters477c8d52006-05-27 19:21:47 +000074 keys.append(self._box.add(email.message_from_string(_sample_message)))
Guido van Rossume61fd5b2007-07-11 12:20:59 +000075 self.assertEqual(len(self._box), 3)
R. David Murrayb7deff12011-01-30 06:21:28 +000076 keys.append(self._box.add(io.BytesIO(_bytes_sample_message)))
Guido van Rossume61fd5b2007-07-11 12:20:59 +000077 self.assertEqual(len(self._box), 4)
Thomas Wouters477c8d52006-05-27 19:21:47 +000078 keys.append(self._box.add(_sample_message))
Guido van Rossume61fd5b2007-07-11 12:20:59 +000079 self.assertEqual(len(self._box), 5)
R. David Murrayb7deff12011-01-30 06:21:28 +000080 keys.append(self._box.add(_bytes_sample_message))
81 self.assertEqual(len(self._box), 6)
82 with self.assertWarns(DeprecationWarning):
83 keys.append(self._box.add(
84 io.TextIOWrapper(io.BytesIO(_bytes_sample_message))))
85 self.assertEqual(len(self._box), 7)
Guido van Rossumea834472007-07-27 05:17:50 +000086 self.assertEqual(self._box.get_string(keys[0]), self._template % 0)
R. David Murrayb7deff12011-01-30 06:21:28 +000087 for i in (1, 2, 3, 4, 5, 6):
Thomas Wouters477c8d52006-05-27 19:21:47 +000088 self._check_sample(self._box[keys[i]])
89
R. David Murrayb7deff12011-01-30 06:21:28 +000090 _nonascii_msg = textwrap.dedent("""\
91 From: foo
92 Subject: Falinaptár házhozszállítással. Már rendeltél?
93
94 0
95 """)
96
97 def test_add_invalid_8bit_bytes_header(self):
98 key = self._box.add(self._nonascii_msg.encode('latin1'))
99 self.assertEqual(len(self._box), 1)
100 self.assertEqual(self._box.get_bytes(key),
101 self._nonascii_msg.encode('latin1'))
102
103 def test_invalid_nonascii_header_as_string(self):
104 subj = self._nonascii_msg.splitlines()[1]
105 key = self._box.add(subj.encode('latin1'))
106 self.assertEqual(self._box.get_string(key),
107 'Subject: =?unknown-8bit?b?RmFsaW5hcHThciBo4Xpob3pzeuFsbO104XNz'
108 'YWwuIE3hciByZW5kZWx06Ww/?=\n\n')
109
110 def test_add_nonascii_header_raises(self):
111 with self.assertRaisesRegex(ValueError, "ASCII-only"):
112 self._box.add(self._nonascii_msg)
113
114 _non_latin_bin_msg = textwrap.dedent("""\
115 From: foo@bar.com
116 To: báz
117 Subject: Maintenant je vous présente mon collègue, le pouf célèbre
118 \tJean de Baddie
119 Mime-Version: 1.0
120 Content-Type: text/plain; charset="utf-8"
121 Content-Transfer-Encoding: 8bit
122
123 Да, они летят.
124 """).encode('utf-8')
125
126 def test_add_8bit_body(self):
127 key = self._box.add(self._non_latin_bin_msg)
128 self.assertEqual(self._box.get_bytes(key),
129 self._non_latin_bin_msg)
130 with self._box.get_file(key) as f:
131 self.assertEqual(f.read(),
132 self._non_latin_bin_msg.replace(b'\n',
133 os.linesep.encode()))
134 self.assertEqual(self._box[key].get_payload(),
135 "Да, они летят.\n")
136
137 def test_add_binary_file(self):
138 with tempfile.TemporaryFile('wb+') as f:
139 f.write(_bytes_sample_message)
140 f.seek(0)
141 key = self._box.add(f)
142 # See issue 11062
143 if not isinstance(self._box, mailbox.Babyl):
144 self.assertEqual(self._box.get_bytes(key).split(b'\n'),
145 _bytes_sample_message.split(b'\n'))
146
147 def test_add_binary_nonascii_file(self):
148 with tempfile.TemporaryFile('wb+') as f:
149 f.write(self._non_latin_bin_msg)
150 f.seek(0)
151 key = self._box.add(f)
152 # See issue 11062
153 if not isinstance(self._box, mailbox.Babyl):
154 self.assertEqual(self._box.get_bytes(key).split(b'\n'),
155 self._non_latin_bin_msg.split(b'\n'))
156
157 def test_add_text_file_warns(self):
158 with tempfile.TemporaryFile('w+') as f:
159 f.write(_sample_message)
160 f.seek(0)
161 with self.assertWarns(DeprecationWarning):
162 key = self._box.add(f)
163 # See issue 11062
164 if not isinstance(self._box, mailbox.Babyl):
165 self.assertEqual(self._box.get_bytes(key).split(b'\n'),
166 _bytes_sample_message.split(b'\n'))
167
168 def test_add_StringIO_warns(self):
169 with self.assertWarns(DeprecationWarning):
170 key = self._box.add(io.StringIO(self._template % "0"))
171 self.assertEqual(self._box.get_string(key), self._template % "0")
172
173 def test_add_nonascii_StringIO_raises(self):
174 with self.assertWarns(DeprecationWarning):
175 with self.assertRaisesRegex(ValueError, "ASCII-only"):
176 self._box.add(io.StringIO(self._nonascii_msg))
177
Thomas Wouters477c8d52006-05-27 19:21:47 +0000178 def test_remove(self):
179 # Remove messages using remove()
180 self._test_remove_or_delitem(self._box.remove)
181
182 def test_delitem(self):
183 # Remove messages using __delitem__()
184 self._test_remove_or_delitem(self._box.__delitem__)
185
186 def _test_remove_or_delitem(self, method):
187 # (Used by test_remove() and test_delitem().)
188 key0 = self._box.add(self._template % 0)
189 key1 = self._box.add(self._template % 1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000190 self.assertEqual(len(self._box), 2)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000191 method(key0)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000192 self.assertEqual(len(self._box), 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000193 self.assertRaises(KeyError, lambda: self._box[key0])
194 self.assertRaises(KeyError, lambda: method(key0))
Guido van Rossumea834472007-07-27 05:17:50 +0000195 self.assertEqual(self._box.get_string(key1), self._template % 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000196 key2 = self._box.add(self._template % 2)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000197 self.assertEqual(len(self._box), 2)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000198 method(key2)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000199 self.assertEqual(len(self._box), 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000200 self.assertRaises(KeyError, lambda: self._box[key2])
201 self.assertRaises(KeyError, lambda: method(key2))
Guido van Rossumea834472007-07-27 05:17:50 +0000202 self.assertEqual(self._box.get_string(key1), self._template % 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000203 method(key1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000204 self.assertEqual(len(self._box), 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000205 self.assertRaises(KeyError, lambda: self._box[key1])
206 self.assertRaises(KeyError, lambda: method(key1))
207
208 def test_discard(self, repetitions=10):
209 # Discard messages
210 key0 = self._box.add(self._template % 0)
211 key1 = self._box.add(self._template % 1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000212 self.assertEqual(len(self._box), 2)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000213 self._box.discard(key0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000214 self.assertEqual(len(self._box), 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000215 self.assertRaises(KeyError, lambda: self._box[key0])
216 self._box.discard(key0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000217 self.assertEqual(len(self._box), 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000218 self.assertRaises(KeyError, lambda: self._box[key0])
219
220 def test_get(self):
221 # Retrieve messages using get()
222 key0 = self._box.add(self._template % 0)
223 msg = self._box.get(key0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000224 self.assertEqual(msg['from'], 'foo')
225 self.assertEqual(msg.get_payload(), '0')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000226 self.assertIs(self._box.get('foo'), None)
227 self.assertIs(self._box.get('foo', False), False)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000228 self._box.close()
Georg Brandlfb16cf12008-05-11 21:31:44 +0000229 self._box = self._factory(self._path)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000230 key1 = self._box.add(self._template % 1)
231 msg = self._box.get(key1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000232 self.assertEqual(msg['from'], 'foo')
Georg Brandlfb16cf12008-05-11 21:31:44 +0000233 self.assertEqual(msg.get_payload(), '1')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000234
235 def test_getitem(self):
236 # Retrieve message using __getitem__()
237 key0 = self._box.add(self._template % 0)
238 msg = self._box[key0]
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000239 self.assertEqual(msg['from'], 'foo')
240 self.assertEqual(msg.get_payload(), '0')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000241 self.assertRaises(KeyError, lambda: self._box['foo'])
242 self._box.discard(key0)
243 self.assertRaises(KeyError, lambda: self._box[key0])
244
245 def test_get_message(self):
246 # Get Message representations of messages
247 key0 = self._box.add(self._template % 0)
248 key1 = self._box.add(_sample_message)
249 msg0 = self._box.get_message(key0)
Ezio Melottie9615932010-01-24 19:26:24 +0000250 self.assertIsInstance(msg0, mailbox.Message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000251 self.assertEqual(msg0['from'], 'foo')
252 self.assertEqual(msg0.get_payload(), '0')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000253 self._check_sample(self._box.get_message(key1))
254
R. David Murrayb7deff12011-01-30 06:21:28 +0000255 def test_get_bytes(self):
256 # Get bytes representations of messages
257 key0 = self._box.add(self._template % 0)
258 key1 = self._box.add(_sample_message)
259 self.assertEqual(self._box.get_bytes(key0),
260 (self._template % 0).encode('ascii'))
261 self.assertEqual(self._box.get_bytes(key1), _bytes_sample_message)
262
Thomas Wouters477c8d52006-05-27 19:21:47 +0000263 def test_get_string(self):
264 # Get string representations of messages
265 key0 = self._box.add(self._template % 0)
266 key1 = self._box.add(_sample_message)
Guido van Rossumea834472007-07-27 05:17:50 +0000267 self.assertEqual(self._box.get_string(key0), self._template % 0)
R. David Murrayb7deff12011-01-30 06:21:28 +0000268 self.assertEqual(self._box.get_string(key1).split('\n'),
269 _sample_message.split('\n'))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000270
271 def test_get_file(self):
272 # Get file representations of messages
273 key0 = self._box.add(self._template % 0)
274 key1 = self._box.add(_sample_message)
Brett Cannon653238a2010-10-30 00:13:00 +0000275 with self._box.get_file(key0) as file:
276 data0 = file.read()
277 with self._box.get_file(key1) as file:
278 data1 = file.read()
R. David Murrayb7deff12011-01-30 06:21:28 +0000279 self.assertEqual(data0.decode('ascii').replace(os.linesep, '\n'),
Guido van Rossumea834472007-07-27 05:17:50 +0000280 self._template % 0)
R. David Murrayb7deff12011-01-30 06:21:28 +0000281 self.assertEqual(data1.decode('ascii').replace(os.linesep, '\n'),
Guido van Rossumea834472007-07-27 05:17:50 +0000282 _sample_message)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000283
284 def test_iterkeys(self):
285 # Get keys using iterkeys()
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000286 self._check_iteration(self._box.keys, do_keys=True, do_values=False)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000287
288 def test_keys(self):
289 # Get keys using keys()
290 self._check_iteration(self._box.keys, do_keys=True, do_values=False)
291
292 def test_itervalues(self):
293 # Get values using itervalues()
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000294 self._check_iteration(self._box.values, do_keys=False,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295 do_values=True)
296
297 def test_iter(self):
298 # Get values using __iter__()
299 self._check_iteration(self._box.__iter__, do_keys=False,
300 do_values=True)
301
302 def test_values(self):
303 # Get values using values()
304 self._check_iteration(self._box.values, do_keys=False, do_values=True)
305
306 def test_iteritems(self):
307 # Get keys and values using iteritems()
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000308 self._check_iteration(self._box.items, do_keys=True,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309 do_values=True)
310
311 def test_items(self):
312 # Get keys and values using items()
313 self._check_iteration(self._box.items, do_keys=True, do_values=True)
314
315 def _check_iteration(self, method, do_keys, do_values, repetitions=10):
316 for value in method():
317 self.fail("Not empty")
318 keys, values = [], []
Guido van Rossum805365e2007-05-07 22:24:25 +0000319 for i in range(repetitions):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320 keys.append(self._box.add(self._template % i))
321 values.append(self._template % i)
322 if do_keys and not do_values:
323 returned_keys = list(method())
324 elif do_values and not do_keys:
325 returned_values = list(method())
326 else:
327 returned_keys, returned_values = [], []
328 for key, value in method():
329 returned_keys.append(key)
330 returned_values.append(value)
331 if do_keys:
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000332 self.assertEqual(len(keys), len(returned_keys))
333 self.assertEqual(set(keys), set(returned_keys))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000334 if do_values:
335 count = 0
336 for value in returned_values:
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000337 self.assertEqual(value['from'], 'foo')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000338 self.assertLess(int(value.get_payload()), repetitions)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000339 count += 1
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000340 self.assertEqual(len(values), count)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000341
Thomas Wouters477c8d52006-05-27 19:21:47 +0000342 def test_contains(self):
343 # Check existence of keys using __contains__()
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000344 self.assertNotIn('foo', self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000345 key0 = self._box.add(self._template % 0)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000346 self.assertIn(key0, self._box)
347 self.assertNotIn('foo', self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000348 key1 = self._box.add(self._template % 1)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000349 self.assertIn(key1, self._box)
350 self.assertIn(key0, self._box)
351 self.assertNotIn('foo', self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000352 self._box.remove(key0)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000353 self.assertNotIn(key0, self._box)
354 self.assertIn(key1, self._box)
355 self.assertNotIn('foo', self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000356 self._box.remove(key1)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000357 self.assertNotIn(key1, self._box)
358 self.assertNotIn(key0, self._box)
359 self.assertNotIn('foo', self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000360
361 def test_len(self, repetitions=10):
362 # Get message count
363 keys = []
Guido van Rossum805365e2007-05-07 22:24:25 +0000364 for i in range(repetitions):
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000365 self.assertEqual(len(self._box), i)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000366 keys.append(self._box.add(self._template % i))
Guido van Rossumea834472007-07-27 05:17:50 +0000367 self.assertEqual(len(self._box), i + 1)
Guido van Rossum805365e2007-05-07 22:24:25 +0000368 for i in range(repetitions):
Guido van Rossumea834472007-07-27 05:17:50 +0000369 self.assertEqual(len(self._box), repetitions - i)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000370 self._box.remove(keys[i])
Guido van Rossumea834472007-07-27 05:17:50 +0000371 self.assertEqual(len(self._box), repetitions - i - 1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000372
373 def test_set_item(self):
374 # Modify messages using __setitem__()
375 key0 = self._box.add(self._template % 'original 0')
Guido van Rossumea834472007-07-27 05:17:50 +0000376 self.assertEqual(self._box.get_string(key0),
377 self._template % 'original 0')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000378 key1 = self._box.add(self._template % 'original 1')
Guido van Rossumea834472007-07-27 05:17:50 +0000379 self.assertEqual(self._box.get_string(key1),
380 self._template % 'original 1')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000381 self._box[key0] = self._template % 'changed 0'
Guido van Rossumea834472007-07-27 05:17:50 +0000382 self.assertEqual(self._box.get_string(key0),
383 self._template % 'changed 0')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000384 self._box[key1] = self._template % 'changed 1'
Guido van Rossumea834472007-07-27 05:17:50 +0000385 self.assertEqual(self._box.get_string(key1),
386 self._template % 'changed 1')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000387 self._box[key0] = _sample_message
388 self._check_sample(self._box[key0])
389 self._box[key1] = self._box[key0]
390 self._check_sample(self._box[key1])
391 self._box[key0] = self._template % 'original 0'
Guido van Rossumea834472007-07-27 05:17:50 +0000392 self.assertEqual(self._box.get_string(key0),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000393 self._template % 'original 0')
394 self._check_sample(self._box[key1])
395 self.assertRaises(KeyError,
396 lambda: self._box.__setitem__('foo', 'bar'))
397 self.assertRaises(KeyError, lambda: self._box['foo'])
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000398 self.assertEqual(len(self._box), 2)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399
400 def test_clear(self, iterations=10):
401 # Remove all messages using clear()
402 keys = []
Guido van Rossum805365e2007-05-07 22:24:25 +0000403 for i in range(iterations):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404 self._box.add(self._template % i)
405 for i, key in enumerate(keys):
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000406 self.assertEqual(self._box.get_string(key), self._template % i)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000407 self._box.clear()
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000408 self.assertEqual(len(self._box), 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000409 for i, key in enumerate(keys):
410 self.assertRaises(KeyError, lambda: self._box.get_string(key))
411
412 def test_pop(self):
413 # Get and remove a message using pop()
414 key0 = self._box.add(self._template % 0)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000415 self.assertIn(key0, self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416 key1 = self._box.add(self._template % 1)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000417 self.assertIn(key1, self._box)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000418 self.assertEqual(self._box.pop(key0).get_payload(), '0')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000419 self.assertNotIn(key0, self._box)
420 self.assertIn(key1, self._box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421 key2 = self._box.add(self._template % 2)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000422 self.assertIn(key2, self._box)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000423 self.assertEqual(self._box.pop(key2).get_payload(), '2')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000424 self.assertNotIn(key2, self._box)
425 self.assertIn(key1, self._box)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000426 self.assertEqual(self._box.pop(key1).get_payload(), '1')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000427 self.assertNotIn(key1, self._box)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000428 self.assertEqual(len(self._box), 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000429
430 def test_popitem(self, iterations=10):
431 # Get and remove an arbitrary (key, message) using popitem()
432 keys = []
Guido van Rossum805365e2007-05-07 22:24:25 +0000433 for i in range(10):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434 keys.append(self._box.add(self._template % i))
435 seen = []
Guido van Rossum805365e2007-05-07 22:24:25 +0000436 for i in range(10):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000437 key, msg = self._box.popitem()
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000438 self.assertIn(key, keys)
439 self.assertNotIn(key, seen)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440 seen.append(key)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000441 self.assertEqual(int(msg.get_payload()), keys.index(key))
442 self.assertEqual(len(self._box), 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443 for key in keys:
444 self.assertRaises(KeyError, lambda: self._box[key])
445
446 def test_update(self):
447 # Modify multiple messages using update()
448 key0 = self._box.add(self._template % 'original 0')
449 key1 = self._box.add(self._template % 'original 1')
450 key2 = self._box.add(self._template % 'original 2')
451 self._box.update({key0: self._template % 'changed 0',
452 key2: _sample_message})
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000453 self.assertEqual(len(self._box), 3)
Guido van Rossumea834472007-07-27 05:17:50 +0000454 self.assertEqual(self._box.get_string(key0),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000455 self._template % 'changed 0')
Guido van Rossumea834472007-07-27 05:17:50 +0000456 self.assertEqual(self._box.get_string(key1),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457 self._template % 'original 1')
458 self._check_sample(self._box[key2])
459 self._box.update([(key2, self._template % 'changed 2'),
460 (key1, self._template % 'changed 1'),
461 (key0, self._template % 'original 0')])
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000462 self.assertEqual(len(self._box), 3)
Guido van Rossumea834472007-07-27 05:17:50 +0000463 self.assertEqual(self._box.get_string(key0),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464 self._template % 'original 0')
Guido van Rossumea834472007-07-27 05:17:50 +0000465 self.assertEqual(self._box.get_string(key1),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000466 self._template % 'changed 1')
Guido van Rossumea834472007-07-27 05:17:50 +0000467 self.assertEqual(self._box.get_string(key2),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000468 self._template % 'changed 2')
469 self.assertRaises(KeyError,
470 lambda: self._box.update({'foo': 'bar',
471 key0: self._template % "changed 0"}))
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000472 self.assertEqual(len(self._box), 3)
Guido van Rossumea834472007-07-27 05:17:50 +0000473 self.assertEqual(self._box.get_string(key0),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474 self._template % "changed 0")
Guido van Rossumea834472007-07-27 05:17:50 +0000475 self.assertEqual(self._box.get_string(key1),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000476 self._template % "changed 1")
Guido van Rossumea834472007-07-27 05:17:50 +0000477 self.assertEqual(self._box.get_string(key2),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478 self._template % "changed 2")
479
480 def test_flush(self):
481 # Write changes to disk
Christian Heimesf6cd9672008-03-26 13:45:42 +0000482 self._test_flush_or_close(self._box.flush, True)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000483
484 def test_lock_unlock(self):
485 # Lock and unlock the mailbox
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000486 self.assertFalse(os.path.exists(self._get_lock_path()))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487 self._box.lock()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000488 self.assertTrue(os.path.exists(self._get_lock_path()))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489 self._box.unlock()
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000490 self.assertFalse(os.path.exists(self._get_lock_path()))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491
492 def test_close(self):
493 # Close mailbox and flush changes to disk
Christian Heimesf6cd9672008-03-26 13:45:42 +0000494 self._test_flush_or_close(self._box.close, False)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000495
Christian Heimesf6cd9672008-03-26 13:45:42 +0000496 def _test_flush_or_close(self, method, should_call_close):
Guido van Rossum805365e2007-05-07 22:24:25 +0000497 contents = [self._template % i for i in range(3)]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498 self._box.add(contents[0])
499 self._box.add(contents[1])
500 self._box.add(contents[2])
Guido van Rossumc12a8132007-10-26 04:29:23 +0000501 oldbox = self._box
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502 method()
Christian Heimesf6cd9672008-03-26 13:45:42 +0000503 if should_call_close:
504 self._box.close()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000505 self._box = self._factory(self._path)
506 keys = self._box.keys()
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000507 self.assertEqual(len(keys), 3)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000508 for key in keys:
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000509 self.assertIn(self._box.get_string(key), contents)
Guido van Rossumc12a8132007-10-26 04:29:23 +0000510 oldbox.close()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000511
512 def test_dump_message(self):
513 # Write message representations to disk
514 for input in (email.message_from_string(_sample_message),
R. David Murrayb7deff12011-01-30 06:21:28 +0000515 _sample_message, io.BytesIO(_bytes_sample_message)):
516 output = io.BytesIO()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000517 self._box._dump_message(input, output)
R. David Murrayb7deff12011-01-30 06:21:28 +0000518 self.assertEqual(output.getvalue(),
519 _bytes_sample_message.replace(b'\n', os.linesep.encode()))
520 output = io.BytesIO()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000521 self.assertRaises(TypeError,
522 lambda: self._box._dump_message(None, output))
523
524 def _get_lock_path(self):
525 # Return the path of the dot lock file. May be overridden.
526 return self._path + '.lock'
527
528
529class TestMailboxSuperclass(TestBase):
530
531 def test_notimplemented(self):
532 # Test that all Mailbox methods raise NotImplementedException.
533 box = mailbox.Mailbox('path')
534 self.assertRaises(NotImplementedError, lambda: box.add(''))
535 self.assertRaises(NotImplementedError, lambda: box.remove(''))
536 self.assertRaises(NotImplementedError, lambda: box.__delitem__(''))
537 self.assertRaises(NotImplementedError, lambda: box.discard(''))
538 self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000539 self.assertRaises(NotImplementedError, lambda: box.keys())
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000540 self.assertRaises(NotImplementedError, lambda: box.keys())
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000541 self.assertRaises(NotImplementedError, lambda: box.values().__next__())
542 self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__())
Thomas Wouters477c8d52006-05-27 19:21:47 +0000543 self.assertRaises(NotImplementedError, lambda: box.values())
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000544 self.assertRaises(NotImplementedError, lambda: box.items().next())
Thomas Wouters477c8d52006-05-27 19:21:47 +0000545 self.assertRaises(NotImplementedError, lambda: box.items())
546 self.assertRaises(NotImplementedError, lambda: box.get(''))
547 self.assertRaises(NotImplementedError, lambda: box.__getitem__(''))
548 self.assertRaises(NotImplementedError, lambda: box.get_message(''))
549 self.assertRaises(NotImplementedError, lambda: box.get_string(''))
R. David Murrayb7deff12011-01-30 06:21:28 +0000550 self.assertRaises(NotImplementedError, lambda: box.get_bytes(''))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000551 self.assertRaises(NotImplementedError, lambda: box.get_file(''))
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000552 self.assertRaises(NotImplementedError, lambda: '' in box)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000553 self.assertRaises(NotImplementedError, lambda: box.__contains__(''))
554 self.assertRaises(NotImplementedError, lambda: box.__len__())
555 self.assertRaises(NotImplementedError, lambda: box.clear())
556 self.assertRaises(NotImplementedError, lambda: box.pop(''))
557 self.assertRaises(NotImplementedError, lambda: box.popitem())
558 self.assertRaises(NotImplementedError, lambda: box.update((('', ''),)))
559 self.assertRaises(NotImplementedError, lambda: box.flush())
560 self.assertRaises(NotImplementedError, lambda: box.lock())
561 self.assertRaises(NotImplementedError, lambda: box.unlock())
562 self.assertRaises(NotImplementedError, lambda: box.close())
563
564
565class TestMaildir(TestMailbox):
566
567 _factory = lambda self, path, factory=None: mailbox.Maildir(path, factory)
568
569 def setUp(self):
570 TestMailbox.setUp(self)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000571 if os.name in ('nt', 'os2') or sys.platform == 'cygwin':
Thomas Wouters477c8d52006-05-27 19:21:47 +0000572 self._box.colon = '!'
573
574 def test_add_MM(self):
575 # Add a MaildirMessage instance
576 msg = mailbox.MaildirMessage(self._template % 0)
577 msg.set_subdir('cur')
578 msg.set_info('foo')
579 key = self._box.add(msg)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000580 self.assertTrue(os.path.exists(os.path.join(self._path, 'cur', '%s%sfoo' %
Thomas Wouters477c8d52006-05-27 19:21:47 +0000581 (key, self._box.colon))))
582
583 def test_get_MM(self):
584 # Get a MaildirMessage instance
585 msg = mailbox.MaildirMessage(self._template % 0)
586 msg.set_subdir('cur')
587 msg.set_flags('RF')
588 key = self._box.add(msg)
589 msg_returned = self._box.get_message(key)
Ezio Melottie9615932010-01-24 19:26:24 +0000590 self.assertIsInstance(msg_returned, mailbox.MaildirMessage)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000591 self.assertEqual(msg_returned.get_subdir(), 'cur')
592 self.assertEqual(msg_returned.get_flags(), 'FR')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000593
594 def test_set_MM(self):
595 # Set with a MaildirMessage instance
596 msg0 = mailbox.MaildirMessage(self._template % 0)
597 msg0.set_flags('TP')
598 key = self._box.add(msg0)
599 msg_returned = self._box.get_message(key)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000600 self.assertEqual(msg_returned.get_subdir(), 'new')
601 self.assertEqual(msg_returned.get_flags(), 'PT')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000602 msg1 = mailbox.MaildirMessage(self._template % 1)
603 self._box[key] = msg1
604 msg_returned = self._box.get_message(key)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000605 self.assertEqual(msg_returned.get_subdir(), 'new')
606 self.assertEqual(msg_returned.get_flags(), '')
607 self.assertEqual(msg_returned.get_payload(), '1')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608 msg2 = mailbox.MaildirMessage(self._template % 2)
609 msg2.set_info('2,S')
610 self._box[key] = msg2
611 self._box[key] = self._template % 3
612 msg_returned = self._box.get_message(key)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000613 self.assertEqual(msg_returned.get_subdir(), 'new')
614 self.assertEqual(msg_returned.get_flags(), 'S')
615 self.assertEqual(msg_returned.get_payload(), '3')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000616
Christian Heimesfdab48e2008-01-20 09:06:41 +0000617 def test_consistent_factory(self):
618 # Add a message.
619 msg = mailbox.MaildirMessage(self._template % 0)
620 msg.set_subdir('cur')
621 msg.set_flags('RF')
622 key = self._box.add(msg)
623
624 # Create new mailbox with
625 class FakeMessage(mailbox.MaildirMessage):
626 pass
627 box = mailbox.Maildir(self._path, factory=FakeMessage)
Christian Heimes15ebc882008-02-04 18:48:49 +0000628 box.colon = self._box.colon
Christian Heimesfdab48e2008-01-20 09:06:41 +0000629 msg2 = box.get_message(key)
Ezio Melottie9615932010-01-24 19:26:24 +0000630 self.assertIsInstance(msg2, FakeMessage)
Christian Heimesfdab48e2008-01-20 09:06:41 +0000631
Thomas Wouters477c8d52006-05-27 19:21:47 +0000632 def test_initialize_new(self):
633 # Initialize a non-existent mailbox
634 self.tearDown()
635 self._box = mailbox.Maildir(self._path)
Georg Brandlfb16cf12008-05-11 21:31:44 +0000636 self._check_basics()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637 self._delete_recursively(self._path)
638 self._box = self._factory(self._path, factory=None)
639 self._check_basics()
640
641 def test_initialize_existing(self):
642 # Initialize an existing mailbox
643 self.tearDown()
644 for subdir in '', 'tmp', 'new', 'cur':
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000645 os.mkdir(os.path.normpath(os.path.join(self._path, subdir)))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646 self._box = mailbox.Maildir(self._path)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000647 self._check_basics()
648
649 def _check_basics(self, factory=None):
650 # (Used by test_open_new() and test_open_existing().)
651 self.assertEqual(self._box._path, os.path.abspath(self._path))
652 self.assertEqual(self._box._factory, factory)
653 for subdir in '', 'tmp', 'new', 'cur':
654 path = os.path.join(self._path, subdir)
655 mode = os.stat(path)[stat.ST_MODE]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000656 self.assertTrue(stat.S_ISDIR(mode), "Not a directory: '%s'" % path)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657
658 def test_list_folders(self):
659 # List folders
660 self._box.add_folder('one')
661 self._box.add_folder('two')
662 self._box.add_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000663 self.assertEqual(len(self._box.list_folders()), 3)
Guido van Rossumea834472007-07-27 05:17:50 +0000664 self.assertEqual(set(self._box.list_folders()),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665 set(('one', 'two', 'three')))
666
667 def test_get_folder(self):
668 # Open folders
669 self._box.add_folder('foo.bar')
670 folder0 = self._box.get_folder('foo.bar')
671 folder0.add(self._template % 'bar')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000672 self.assertTrue(os.path.isdir(os.path.join(self._path, '.foo.bar')))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000673 folder1 = self._box.get_folder('foo.bar')
Guido van Rossumea834472007-07-27 05:17:50 +0000674 self.assertEqual(folder1.get_string(folder1.keys()[0]),
675 self._template % 'bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000676
677 def test_add_and_remove_folders(self):
678 # Delete folders
679 self._box.add_folder('one')
680 self._box.add_folder('two')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000681 self.assertEqual(len(self._box.list_folders()), 2)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000682 self.assertEqual(set(self._box.list_folders()), set(('one', 'two')))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683 self._box.remove_folder('one')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000684 self.assertEqual(len(self._box.list_folders()), 1)
685 self.assertEqual(set(self._box.list_folders()), set(('two',)))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686 self._box.add_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000687 self.assertEqual(len(self._box.list_folders()), 2)
Guido van Rossumea834472007-07-27 05:17:50 +0000688 self.assertEqual(set(self._box.list_folders()), set(('two', 'three')))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689 self._box.remove_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000690 self.assertEqual(len(self._box.list_folders()), 1)
691 self.assertEqual(set(self._box.list_folders()), set(('two',)))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692 self._box.remove_folder('two')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000693 self.assertEqual(len(self._box.list_folders()), 0)
694 self.assertEqual(self._box.list_folders(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695
696 def test_clean(self):
697 # Remove old files from 'tmp'
698 foo_path = os.path.join(self._path, 'tmp', 'foo')
699 bar_path = os.path.join(self._path, 'tmp', 'bar')
Brian Curtin5acec042010-10-13 02:29:46 +0000700 with open(foo_path, 'w') as f:
701 f.write("@")
702 with open(bar_path, 'w') as f:
703 f.write("@")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000704 self._box.clean()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000705 self.assertTrue(os.path.exists(foo_path))
706 self.assertTrue(os.path.exists(bar_path))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 foo_stat = os.stat(foo_path)
708 os.utime(foo_path, (time.time() - 129600 - 2,
709 foo_stat.st_mtime))
710 self._box.clean()
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000711 self.assertFalse(os.path.exists(foo_path))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000712 self.assertTrue(os.path.exists(bar_path))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000713
714 def test_create_tmp(self, repetitions=10):
715 # Create files in tmp directory
716 hostname = socket.gethostname()
717 if '/' in hostname:
718 hostname = hostname.replace('/', r'\057')
719 if ':' in hostname:
720 hostname = hostname.replace(':', r'\072')
721 pid = os.getpid()
722 pattern = re.compile(r"(?P<time>\d+)\.M(?P<M>\d{1,6})P(?P<P>\d+)"
723 r"Q(?P<Q>\d+)\.(?P<host>[^:/]+)")
724 previous_groups = None
Guido van Rossum805365e2007-05-07 22:24:25 +0000725 for x in range(repetitions):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726 tmp_file = self._box._create_tmp()
727 head, tail = os.path.split(tmp_file.name)
728 self.assertEqual(head, os.path.abspath(os.path.join(self._path,
729 "tmp")),
730 "File in wrong location: '%s'" % head)
731 match = pattern.match(tail)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000732 self.assertIsNot(match, None, "Invalid file name: '%s'" % tail)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000733 groups = match.groups()
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000734 if previous_groups is not None:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000735 self.assertTrue(int(groups[0] >= previous_groups[0]),
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736 "Non-monotonic seconds: '%s' before '%s'" %
737 (previous_groups[0], groups[0]))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000738 self.assertTrue(int(groups[1] >= previous_groups[1]) or
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739 groups[0] != groups[1],
740 "Non-monotonic milliseconds: '%s' before '%s'" %
741 (previous_groups[1], groups[1]))
Guido van Rossumea834472007-07-27 05:17:50 +0000742 self.assertEqual(int(groups[2]), pid,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000743 "Process ID mismatch: '%s' should be '%s'" %
744 (groups[2], pid))
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000745 self.assertEqual(int(groups[3]), int(previous_groups[3]) + 1,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000746 "Non-sequential counter: '%s' before '%s'" %
747 (previous_groups[3], groups[3]))
Guido van Rossumea834472007-07-27 05:17:50 +0000748 self.assertEqual(groups[4], hostname,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749 "Host name mismatch: '%s' should be '%s'" %
750 (groups[4], hostname))
751 previous_groups = groups
R. David Murrayb7deff12011-01-30 06:21:28 +0000752 tmp_file.write(_bytes_sample_message)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000753 tmp_file.seek(0)
R. David Murrayb7deff12011-01-30 06:21:28 +0000754 self.assertEqual(tmp_file.read(), _bytes_sample_message)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755 tmp_file.close()
756 file_count = len(os.listdir(os.path.join(self._path, "tmp")))
Guido van Rossumea834472007-07-27 05:17:50 +0000757 self.assertEqual(file_count, repetitions,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758 "Wrong file count: '%s' should be '%s'" %
759 (file_count, repetitions))
760
761 def test_refresh(self):
762 # Update the table of contents
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000763 self.assertEqual(self._box._toc, {})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764 key0 = self._box.add(self._template % 0)
765 key1 = self._box.add(self._template % 1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000766 self.assertEqual(self._box._toc, {})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000767 self._box._refresh()
Guido van Rossumea834472007-07-27 05:17:50 +0000768 self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
769 key1: os.path.join('new', key1)})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000770 key2 = self._box.add(self._template % 2)
Guido van Rossumea834472007-07-27 05:17:50 +0000771 self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
772 key1: os.path.join('new', key1)})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000773 self._box._refresh()
Guido van Rossumea834472007-07-27 05:17:50 +0000774 self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
775 key1: os.path.join('new', key1),
776 key2: os.path.join('new', key2)})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777
778 def test_lookup(self):
779 # Look up message subpaths in the TOC
780 self.assertRaises(KeyError, lambda: self._box._lookup('foo'))
781 key0 = self._box.add(self._template % 0)
Guido van Rossumea834472007-07-27 05:17:50 +0000782 self.assertEqual(self._box._lookup(key0), os.path.join('new', key0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000783 os.remove(os.path.join(self._path, 'new', key0))
Guido van Rossumea834472007-07-27 05:17:50 +0000784 self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)})
Antoine Pitrou03f13442009-11-02 11:36:51 +0000785 # Be sure that the TOC is read back from disk (see issue #6896
786 # about bad mtime behaviour on some systems).
787 self._box.flush()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000788 self.assertRaises(KeyError, lambda: self._box._lookup(key0))
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000789 self.assertEqual(self._box._toc, {})
Thomas Wouters477c8d52006-05-27 19:21:47 +0000790
791 def test_lock_unlock(self):
792 # Lock and unlock the mailbox. For Maildir, this does nothing.
793 self._box.lock()
794 self._box.unlock()
795
Thomas Wouters89f507f2006-12-13 04:49:30 +0000796 def test_folder (self):
797 # Test for bug #1569790: verify that folders returned by .get_folder()
798 # use the same factory function.
799 def dummy_factory (s):
800 return None
801 box = self._factory(self._path, factory=dummy_factory)
802 folder = box.add_folder('folder1')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000803 self.assertIs(folder._factory, dummy_factory)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000804
Thomas Wouters89f507f2006-12-13 04:49:30 +0000805 folder1_alias = box.get_folder('folder1')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000806 self.assertIs(folder1_alias._factory, dummy_factory)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000807
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000808 def test_directory_in_folder (self):
809 # Test that mailboxes still work if there's a stray extra directory
810 # in a folder.
811 for i in range(10):
812 self._box.add(mailbox.Message(_sample_message))
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000813
Guido van Rossumb5a755e2007-07-18 18:15:48 +0000814 # Create a stray directory
815 os.mkdir(os.path.join(self._path, 'cur', 'stray-dir'))
816
817 # Check that looping still works with the directory present.
818 for msg in self._box:
819 pass
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000821 def test_file_permissions(self):
822 # Verify that message files are created without execute permissions
823 if not hasattr(os, "stat") or not hasattr(os, "umask"):
824 return
825 msg = mailbox.MaildirMessage(self._template % 0)
826 orig_umask = os.umask(0)
827 try:
828 key = self._box.add(msg)
829 finally:
830 os.umask(orig_umask)
831 path = os.path.join(self._path, self._box._lookup(key))
832 mode = os.stat(path).st_mode
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000833 self.assertFalse(mode & 0o111)
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000834
835 def test_folder_file_perms(self):
836 # From bug #3228, we want to verify that the file created inside a Maildir
837 # subfolder isn't marked as executable.
838 if not hasattr(os, "stat") or not hasattr(os, "umask"):
839 return
840
841 orig_umask = os.umask(0)
842 try:
843 subfolder = self._box.add_folder('subfolder')
844 finally:
845 os.umask(orig_umask)
846
847 path = os.path.join(subfolder._path, 'maildirfolder')
848 st = os.stat(path)
849 perms = st.st_mode
850 self.assertFalse((perms & 0o111)) # Execute bits should all be off.
851
Andrew M. Kuchlingfa815342009-05-03 02:52:20 +0000852 def test_reread(self):
853 # Wait for 2 seconds
854 time.sleep(2)
855
856 # Initially, the mailbox has not been read and the time is null.
857 assert getattr(self._box, '_last_read', None) is None
858
859 # Refresh mailbox; the times should now be set to something.
860 self._box._refresh()
861 assert getattr(self._box, '_last_read', None) is not None
862
863 # Try calling _refresh() again; the modification times shouldn't have
864 # changed, so the mailbox should not be re-reading. Re-reading causes
865 # the ._toc attribute to be assigned a new dictionary object, so
866 # we'll check that the ._toc attribute isn't a different object.
867 orig_toc = self._box._toc
868 def refreshed():
869 return self._box._toc is not orig_toc
870
871 time.sleep(1) # Wait 1sec to ensure time.time()'s value changes
872 self._box._refresh()
873 assert not refreshed()
874
875 # Now, write something into cur and remove it. This changes
876 # the mtime and should cause a re-read.
877 filename = os.path.join(self._path, 'cur', 'stray-file')
878 f = open(filename, 'w')
879 f.close()
880 os.unlink(filename)
881 self._box._refresh()
882 assert refreshed()
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000883
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884class _TestMboxMMDF(TestMailbox):
885
886 def tearDown(self):
Brett Cannon653238a2010-10-30 00:13:00 +0000887 super().tearDown()
Guido van Rossumc12a8132007-10-26 04:29:23 +0000888 self._box.close()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889 self._delete_recursively(self._path)
890 for lock_remnant in glob.glob(self._path + '.*'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000891 support.unlink(lock_remnant)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000892
893 def test_add_from_string(self):
894 # Add a string starting with 'From ' to the mailbox
895 key = self._box.add('From foo@bar blah\nFrom: foo\n\n0')
Guido van Rossumea834472007-07-27 05:17:50 +0000896 self.assertEqual(self._box[key].get_from(), 'foo@bar blah')
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000897 self.assertEqual(self._box[key].get_payload(), '0')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000898
R. David Murrayb7deff12011-01-30 06:21:28 +0000899 def test_add_from_bytes(self):
900 # Add a byte string starting with 'From ' to the mailbox
901 key = self._box.add(b'From foo@bar blah\nFrom: foo\n\n0')
902 self.assertEqual(self._box[key].get_from(), 'foo@bar blah')
903 self.assertEqual(self._box[key].get_payload(), '0')
904
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905 def test_add_mbox_or_mmdf_message(self):
906 # Add an mboxMessage or MMDFMessage
907 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
908 msg = class_('From foo@bar blah\nFrom: foo\n\n0')
909 key = self._box.add(msg)
910
911 def test_open_close_open(self):
912 # Open and inspect previously-created mailbox
Guido van Rossum805365e2007-05-07 22:24:25 +0000913 values = [self._template % i for i in range(3)]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000914 for value in values:
915 self._box.add(value)
916 self._box.close()
917 mtime = os.path.getmtime(self._path)
918 self._box = self._factory(self._path)
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000919 self.assertEqual(len(self._box), 3)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000920 for key in self._box.keys():
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +0000921 self.assertIn(self._box.get_string(key), values)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922 self._box.close()
Guido van Rossume61fd5b2007-07-11 12:20:59 +0000923 self.assertEqual(mtime, os.path.getmtime(self._path))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000924
925 def test_add_and_close(self):
926 # Verifying that closing a mailbox doesn't change added items
927 self._box.add(_sample_message)
Guido van Rossum805365e2007-05-07 22:24:25 +0000928 for i in range(3):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000929 self._box.add(self._template % i)
930 self._box.add(_sample_message)
931 self._box._file.flush()
932 self._box._file.seek(0)
933 contents = self._box._file.read()
934 self._box.close()
R. David Murrayb7deff12011-01-30 06:21:28 +0000935 with open(self._path, 'rb') as f:
Brian Curtin5acec042010-10-13 02:29:46 +0000936 self.assertEqual(contents, f.read())
Thomas Wouters477c8d52006-05-27 19:21:47 +0000937 self._box = self._factory(self._path)
938
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000939 def test_lock_conflict(self):
940 # Fork off a subprocess that will lock the file for 2 seconds,
941 # unlock it, and then exit.
942 if not hasattr(os, 'fork'):
943 return
944 pid = os.fork()
945 if pid == 0:
946 # In the child, lock the mailbox.
Guido van Rossum62cbc8a2007-04-09 00:41:25 +0000947 try:
948 self._box.lock()
949 time.sleep(2)
950 self._box.unlock()
951 finally:
952 os._exit(0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000953
954 # In the parent, sleep a bit to give the child time to acquire
955 # the lock.
956 time.sleep(0.5)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000957 try:
958 self.assertRaises(mailbox.ExternalClashError,
959 self._box.lock)
960 finally:
961 # Wait for child to exit. Locking should now succeed.
962 exited_pid, status = os.waitpid(pid, 0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000963
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000964 self._box.lock()
965 self._box.unlock()
966
Thomas Wouters89f507f2006-12-13 04:49:30 +0000967 def test_relock(self):
968 # Test case for bug #1575506: the mailbox class was locking the
969 # wrong file object in its flush() method.
970 msg = "Subject: sub\n\nbody\n"
971 key1 = self._box.add(msg)
972 self._box.flush()
973 self._box.close()
974
975 self._box = self._factory(self._path)
976 self._box.lock()
977 key2 = self._box.add(msg)
978 self._box.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000979 self.assertTrue(self._box._locked)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000980 self._box.close()
981
982
Thomas Wouters477c8d52006-05-27 19:21:47 +0000983class TestMbox(_TestMboxMMDF):
984
985 _factory = lambda self, path, factory=None: mailbox.mbox(path, factory)
986
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000987 def test_file_perms(self):
988 # From bug #3228, we want to verify that the mailbox file isn't executable,
989 # even if the umask is set to something that would leave executable bits set.
990 # We only run this test on platforms that support umask.
991 if hasattr(os, 'umask') and hasattr(os, 'stat'):
992 try:
993 old_umask = os.umask(0o077)
994 self._box.close()
995 os.unlink(self._path)
996 self._box = mailbox.mbox(self._path, create=True)
997 self._box.add('')
998 self._box.close()
999 finally:
1000 os.umask(old_umask)
1001
1002 st = os.stat(self._path)
1003 perms = st.st_mode
1004 self.assertFalse((perms & 0o111)) # Execute bits should all be off.
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005
1006class TestMMDF(_TestMboxMMDF):
1007
1008 _factory = lambda self, path, factory=None: mailbox.MMDF(path, factory)
1009
1010
1011class TestMH(TestMailbox):
1012
1013 _factory = lambda self, path, factory=None: mailbox.MH(path, factory)
1014
1015 def test_list_folders(self):
1016 # List folders
1017 self._box.add_folder('one')
1018 self._box.add_folder('two')
1019 self._box.add_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001020 self.assertEqual(len(self._box.list_folders()), 3)
Guido van Rossumea834472007-07-27 05:17:50 +00001021 self.assertEqual(set(self._box.list_folders()),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022 set(('one', 'two', 'three')))
1023
1024 def test_get_folder(self):
1025 # Open folders
Thomas Wouters89f507f2006-12-13 04:49:30 +00001026 def dummy_factory (s):
1027 return None
1028 self._box = self._factory(self._path, dummy_factory)
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001029
Thomas Wouters89f507f2006-12-13 04:49:30 +00001030 new_folder = self._box.add_folder('foo.bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031 folder0 = self._box.get_folder('foo.bar')
1032 folder0.add(self._template % 'bar')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001033 self.assertTrue(os.path.isdir(os.path.join(self._path, 'foo.bar')))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034 folder1 = self._box.get_folder('foo.bar')
Guido van Rossumea834472007-07-27 05:17:50 +00001035 self.assertEqual(folder1.get_string(folder1.keys()[0]),
1036 self._template % 'bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001037
Thomas Wouters89f507f2006-12-13 04:49:30 +00001038 # Test for bug #1569790: verify that folders returned by .get_folder()
1039 # use the same factory function.
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001040 self.assertIs(new_folder._factory, self._box._factory)
1041 self.assertIs(folder0._factory, self._box._factory)
Thomas Wouters89f507f2006-12-13 04:49:30 +00001042
Thomas Wouters477c8d52006-05-27 19:21:47 +00001043 def test_add_and_remove_folders(self):
1044 # Delete folders
1045 self._box.add_folder('one')
1046 self._box.add_folder('two')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001047 self.assertEqual(len(self._box.list_folders()), 2)
Guido van Rossumea834472007-07-27 05:17:50 +00001048 self.assertEqual(set(self._box.list_folders()), set(('one', 'two')))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001049 self._box.remove_folder('one')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001050 self.assertEqual(len(self._box.list_folders()), 1)
1051 self.assertEqual(set(self._box.list_folders()), set(('two',)))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001052 self._box.add_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001053 self.assertEqual(len(self._box.list_folders()), 2)
Guido van Rossumea834472007-07-27 05:17:50 +00001054 self.assertEqual(set(self._box.list_folders()), set(('two', 'three')))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001055 self._box.remove_folder('three')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001056 self.assertEqual(len(self._box.list_folders()), 1)
1057 self.assertEqual(set(self._box.list_folders()), set(('two',)))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058 self._box.remove_folder('two')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001059 self.assertEqual(len(self._box.list_folders()), 0)
1060 self.assertEqual(self._box.list_folders(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001061
1062 def test_sequences(self):
1063 # Get and set sequences
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001064 self.assertEqual(self._box.get_sequences(), {})
Thomas Wouters477c8d52006-05-27 19:21:47 +00001065 msg0 = mailbox.MHMessage(self._template % 0)
1066 msg0.add_sequence('foo')
1067 key0 = self._box.add(msg0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001068 self.assertEqual(self._box.get_sequences(), {'foo':[key0]})
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069 msg1 = mailbox.MHMessage(self._template % 1)
1070 msg1.set_sequences(['bar', 'replied', 'foo'])
1071 key1 = self._box.add(msg1)
Guido van Rossumea834472007-07-27 05:17:50 +00001072 self.assertEqual(self._box.get_sequences(),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001073 {'foo':[key0, key1], 'bar':[key1], 'replied':[key1]})
1074 msg0.set_sequences(['flagged'])
1075 self._box[key0] = msg0
Guido van Rossumea834472007-07-27 05:17:50 +00001076 self.assertEqual(self._box.get_sequences(),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001077 {'foo':[key1], 'bar':[key1], 'replied':[key1],
1078 'flagged':[key0]})
1079 self._box.remove(key1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001080 self.assertEqual(self._box.get_sequences(), {'flagged':[key0]})
Thomas Wouters477c8d52006-05-27 19:21:47 +00001081
R. David Murray548ac412009-04-02 19:44:43 +00001082 def test_issue2625(self):
1083 msg0 = mailbox.MHMessage(self._template % 0)
1084 msg0.add_sequence('foo')
1085 key0 = self._box.add(msg0)
1086 refmsg0 = self._box.get_message(key0)
1087
Benjamin Peterson21896a32010-03-21 22:03:03 +00001088 def test_issue7627(self):
1089 msg0 = mailbox.MHMessage(self._template % 0)
1090 key0 = self._box.add(msg0)
1091 self._box.lock()
1092 self._box.remove(key0)
1093 self._box.unlock()
1094
Thomas Wouters477c8d52006-05-27 19:21:47 +00001095 def test_pack(self):
1096 # Pack the contents of the mailbox
1097 msg0 = mailbox.MHMessage(self._template % 0)
1098 msg1 = mailbox.MHMessage(self._template % 1)
1099 msg2 = mailbox.MHMessage(self._template % 2)
1100 msg3 = mailbox.MHMessage(self._template % 3)
1101 msg0.set_sequences(['foo', 'unseen'])
1102 msg1.set_sequences(['foo'])
1103 msg2.set_sequences(['foo', 'flagged'])
1104 msg3.set_sequences(['foo', 'bar', 'replied'])
1105 key0 = self._box.add(msg0)
1106 key1 = self._box.add(msg1)
1107 key2 = self._box.add(msg2)
1108 key3 = self._box.add(msg3)
Guido van Rossumea834472007-07-27 05:17:50 +00001109 self.assertEqual(self._box.get_sequences(),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110 {'foo':[key0,key1,key2,key3], 'unseen':[key0],
1111 'flagged':[key2], 'bar':[key3], 'replied':[key3]})
1112 self._box.remove(key2)
Guido van Rossumea834472007-07-27 05:17:50 +00001113 self.assertEqual(self._box.get_sequences(),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001114 {'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3],
1115 'replied':[key3]})
1116 self._box.pack()
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001117 self.assertEqual(self._box.keys(), [1, 2, 3])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001118 key0 = key0
1119 key1 = key0 + 1
1120 key2 = key1 + 1
Guido van Rossumea834472007-07-27 05:17:50 +00001121 self.assertEqual(self._box.get_sequences(),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001122 {'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]})
1123
Thomas Wouters89f507f2006-12-13 04:49:30 +00001124 # Test case for packing while holding the mailbox locked.
1125 key0 = self._box.add(msg1)
1126 key1 = self._box.add(msg1)
1127 key2 = self._box.add(msg1)
1128 key3 = self._box.add(msg1)
1129
1130 self._box.remove(key0)
1131 self._box.remove(key2)
1132 self._box.lock()
1133 self._box.pack()
1134 self._box.unlock()
Guido van Rossumea834472007-07-27 05:17:50 +00001135 self.assertEqual(self._box.get_sequences(),
Thomas Wouters89f507f2006-12-13 04:49:30 +00001136 {'foo':[1, 2, 3, 4, 5],
1137 'unseen':[1], 'bar':[3], 'replied':[3]})
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001138
Thomas Wouters477c8d52006-05-27 19:21:47 +00001139 def _get_lock_path(self):
1140 return os.path.join(self._path, '.mh_sequences.lock')
1141
1142
1143class TestBabyl(TestMailbox):
1144
1145 _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)
1146
1147 def tearDown(self):
Brett Cannon653238a2010-10-30 00:13:00 +00001148 super().tearDown()
Guido van Rossumc12a8132007-10-26 04:29:23 +00001149 self._box.close()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001150 self._delete_recursively(self._path)
1151 for lock_remnant in glob.glob(self._path + '.*'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001152 support.unlink(lock_remnant)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001153
1154 def test_labels(self):
1155 # Get labels from the mailbox
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001156 self.assertEqual(self._box.get_labels(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001157 msg0 = mailbox.BabylMessage(self._template % 0)
1158 msg0.add_label('foo')
1159 key0 = self._box.add(msg0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001160 self.assertEqual(self._box.get_labels(), ['foo'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001161 msg1 = mailbox.BabylMessage(self._template % 1)
1162 msg1.set_labels(['bar', 'answered', 'foo'])
1163 key1 = self._box.add(msg1)
Guido van Rossumea834472007-07-27 05:17:50 +00001164 self.assertEqual(set(self._box.get_labels()), set(['foo', 'bar']))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001165 msg0.set_labels(['blah', 'filed'])
1166 self._box[key0] = msg0
Guido van Rossumea834472007-07-27 05:17:50 +00001167 self.assertEqual(set(self._box.get_labels()),
Thomas Wouters477c8d52006-05-27 19:21:47 +00001168 set(['foo', 'bar', 'blah']))
1169 self._box.remove(key1)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001170 self.assertEqual(set(self._box.get_labels()), set(['blah']))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171
1172
1173class TestMessage(TestBase):
1174
1175 _factory = mailbox.Message # Overridden by subclasses to reuse tests
1176
1177 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001178 self._path = support.TESTFN
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179
1180 def tearDown(self):
1181 self._delete_recursively(self._path)
1182
1183 def test_initialize_with_eMM(self):
Thomas Woutersb2137042007-02-01 18:02:27 +00001184 # Initialize based on email.message.Message instance
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185 eMM = email.message_from_string(_sample_message)
1186 msg = self._factory(eMM)
1187 self._post_initialize_hook(msg)
1188 self._check_sample(msg)
1189
1190 def test_initialize_with_string(self):
1191 # Initialize based on string
1192 msg = self._factory(_sample_message)
1193 self._post_initialize_hook(msg)
1194 self._check_sample(msg)
1195
1196 def test_initialize_with_file(self):
1197 # Initialize based on contents of file
Brian Curtin5acec042010-10-13 02:29:46 +00001198 with open(self._path, 'w+') as f:
1199 f.write(_sample_message)
1200 f.seek(0)
1201 msg = self._factory(f)
1202 self._post_initialize_hook(msg)
1203 self._check_sample(msg)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204
R. David Murrayb7deff12011-01-30 06:21:28 +00001205 def test_initialize_with_binary_file(self):
1206 # Initialize based on contents of binary file
1207 with open(self._path, 'wb+') as f:
1208 f.write(_bytes_sample_message)
1209 f.seek(0)
1210 msg = self._factory(f)
1211 self._post_initialize_hook(msg)
1212 self._check_sample(msg)
1213
Thomas Wouters477c8d52006-05-27 19:21:47 +00001214 def test_initialize_with_nothing(self):
1215 # Initialize without arguments
1216 msg = self._factory()
1217 self._post_initialize_hook(msg)
Ezio Melottie9615932010-01-24 19:26:24 +00001218 self.assertIsInstance(msg, email.message.Message)
1219 self.assertIsInstance(msg, mailbox.Message)
1220 self.assertIsInstance(msg, self._factory)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001221 self.assertEqual(msg.keys(), [])
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001222 self.assertFalse(msg.is_multipart())
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001223 self.assertEqual(msg.get_payload(), None)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001224
1225 def test_initialize_incorrectly(self):
1226 # Initialize with invalid argument
1227 self.assertRaises(TypeError, lambda: self._factory(object()))
1228
1229 def test_become_message(self):
1230 # Take on the state of another message
1231 eMM = email.message_from_string(_sample_message)
1232 msg = self._factory()
1233 msg._become_message(eMM)
1234 self._check_sample(msg)
1235
1236 def test_explain_to(self):
1237 # Copy self's format-specific data to other message formats.
1238 # This test is superficial; better ones are in TestMessageConversion.
1239 msg = self._factory()
1240 for class_ in (mailbox.Message, mailbox.MaildirMessage,
1241 mailbox.mboxMessage, mailbox.MHMessage,
1242 mailbox.BabylMessage, mailbox.MMDFMessage):
1243 other_msg = class_()
1244 msg._explain_to(other_msg)
Thomas Woutersb2137042007-02-01 18:02:27 +00001245 other_msg = email.message.Message()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001246 self.assertRaises(TypeError, lambda: msg._explain_to(other_msg))
1247
1248 def _post_initialize_hook(self, msg):
1249 # Overridden by subclasses to check extra things after initialization
1250 pass
1251
1252
1253class TestMaildirMessage(TestMessage):
1254
1255 _factory = mailbox.MaildirMessage
1256
1257 def _post_initialize_hook(self, msg):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001258 self.assertEqual(msg._subdir, 'new')
1259 self.assertEqual(msg._info, '')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260
1261 def test_subdir(self):
1262 # Use get_subdir() and set_subdir()
1263 msg = mailbox.MaildirMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001264 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001265 msg.set_subdir('cur')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001266 self.assertEqual(msg.get_subdir(), 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001267 msg.set_subdir('new')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001268 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001269 self.assertRaises(ValueError, lambda: msg.set_subdir('tmp'))
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001270 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271 msg.set_subdir('new')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001272 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273 self._check_sample(msg)
1274
1275 def test_flags(self):
1276 # Use get_flags(), set_flags(), add_flag(), remove_flag()
1277 msg = mailbox.MaildirMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001278 self.assertEqual(msg.get_flags(), '')
1279 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001280 msg.set_flags('F')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001281 self.assertEqual(msg.get_subdir(), 'new')
1282 self.assertEqual(msg.get_flags(), 'F')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001283 msg.set_flags('SDTP')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001284 self.assertEqual(msg.get_flags(), 'DPST')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001285 msg.add_flag('FT')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001286 self.assertEqual(msg.get_flags(), 'DFPST')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001287 msg.remove_flag('TDRP')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001288 self.assertEqual(msg.get_flags(), 'FS')
1289 self.assertEqual(msg.get_subdir(), 'new')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001290 self._check_sample(msg)
1291
1292 def test_date(self):
1293 # Use get_date() and set_date()
1294 msg = mailbox.MaildirMessage(_sample_message)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001295 self.assertLess(abs(msg.get_date() - time.time()), 60)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001296 msg.set_date(0.0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001297 self.assertEqual(msg.get_date(), 0.0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001298
1299 def test_info(self):
1300 # Use get_info() and set_info()
1301 msg = mailbox.MaildirMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001302 self.assertEqual(msg.get_info(), '')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001303 msg.set_info('1,foo=bar')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001304 self.assertEqual(msg.get_info(), '1,foo=bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001305 self.assertRaises(TypeError, lambda: msg.set_info(None))
1306 self._check_sample(msg)
1307
1308 def test_info_and_flags(self):
1309 # Test interaction of info and flag methods
1310 msg = mailbox.MaildirMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001311 self.assertEqual(msg.get_info(), '')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001312 msg.set_flags('SF')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001313 self.assertEqual(msg.get_flags(), 'FS')
1314 self.assertEqual(msg.get_info(), '2,FS')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315 msg.set_info('1,')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001316 self.assertEqual(msg.get_flags(), '')
1317 self.assertEqual(msg.get_info(), '1,')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001318 msg.remove_flag('RPT')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001319 self.assertEqual(msg.get_flags(), '')
1320 self.assertEqual(msg.get_info(), '1,')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321 msg.add_flag('D')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001322 self.assertEqual(msg.get_flags(), 'D')
1323 self.assertEqual(msg.get_info(), '2,D')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001324 self._check_sample(msg)
1325
1326
1327class _TestMboxMMDFMessage(TestMessage):
1328
1329 _factory = mailbox._mboxMMDFMessage
1330
1331 def _post_initialize_hook(self, msg):
1332 self._check_from(msg)
1333
1334 def test_initialize_with_unixfrom(self):
1335 # Initialize with a message that already has a _unixfrom attribute
1336 msg = mailbox.Message(_sample_message)
1337 msg.set_unixfrom('From foo@bar blah')
1338 msg = mailbox.mboxMessage(msg)
Guido van Rossumea834472007-07-27 05:17:50 +00001339 self.assertEqual(msg.get_from(), 'foo@bar blah', msg.get_from())
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340
1341 def test_from(self):
1342 # Get and set "From " line
1343 msg = mailbox.mboxMessage(_sample_message)
1344 self._check_from(msg)
1345 msg.set_from('foo bar')
Guido van Rossumea834472007-07-27 05:17:50 +00001346 self.assertEqual(msg.get_from(), 'foo bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001347 msg.set_from('foo@bar', True)
1348 self._check_from(msg, 'foo@bar')
1349 msg.set_from('blah@temp', time.localtime())
1350 self._check_from(msg, 'blah@temp')
1351
1352 def test_flags(self):
1353 # Use get_flags(), set_flags(), add_flag(), remove_flag()
1354 msg = mailbox.mboxMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001355 self.assertEqual(msg.get_flags(), '')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001356 msg.set_flags('F')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001357 self.assertEqual(msg.get_flags(), 'F')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001358 msg.set_flags('XODR')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001359 self.assertEqual(msg.get_flags(), 'RODX')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360 msg.add_flag('FA')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001361 self.assertEqual(msg.get_flags(), 'RODFAX')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362 msg.remove_flag('FDXA')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001363 self.assertEqual(msg.get_flags(), 'RO')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001364 self._check_sample(msg)
1365
1366 def _check_from(self, msg, sender=None):
1367 # Check contents of "From " line
1368 if sender is None:
1369 sender = "MAILER-DAEMON"
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001370 self.assertTrue(re.match(sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:"
Thomas Wouters477c8d52006-05-27 19:21:47 +00001371 r"\d{2} \d{4}", msg.get_from()) is not None)
1372
1373
1374class TestMboxMessage(_TestMboxMMDFMessage):
1375
1376 _factory = mailbox.mboxMessage
1377
1378
1379class TestMHMessage(TestMessage):
1380
1381 _factory = mailbox.MHMessage
1382
1383 def _post_initialize_hook(self, msg):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001384 self.assertEqual(msg._sequences, [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001385
1386 def test_sequences(self):
1387 # Get, set, join, and leave sequences
1388 msg = mailbox.MHMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001389 self.assertEqual(msg.get_sequences(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390 msg.set_sequences(['foobar'])
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001391 self.assertEqual(msg.get_sequences(), ['foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392 msg.set_sequences([])
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001393 self.assertEqual(msg.get_sequences(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001394 msg.add_sequence('unseen')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001395 self.assertEqual(msg.get_sequences(), ['unseen'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001396 msg.add_sequence('flagged')
Guido van Rossumea834472007-07-27 05:17:50 +00001397 self.assertEqual(msg.get_sequences(), ['unseen', 'flagged'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398 msg.add_sequence('flagged')
Guido van Rossumea834472007-07-27 05:17:50 +00001399 self.assertEqual(msg.get_sequences(), ['unseen', 'flagged'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400 msg.remove_sequence('unseen')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001401 self.assertEqual(msg.get_sequences(), ['flagged'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402 msg.add_sequence('foobar')
Guido van Rossumea834472007-07-27 05:17:50 +00001403 self.assertEqual(msg.get_sequences(), ['flagged', 'foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404 msg.remove_sequence('replied')
Guido van Rossumea834472007-07-27 05:17:50 +00001405 self.assertEqual(msg.get_sequences(), ['flagged', 'foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001406 msg.set_sequences(['foobar', 'replied'])
Guido van Rossumea834472007-07-27 05:17:50 +00001407 self.assertEqual(msg.get_sequences(), ['foobar', 'replied'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001408
1409
1410class TestBabylMessage(TestMessage):
1411
1412 _factory = mailbox.BabylMessage
1413
1414 def _post_initialize_hook(self, msg):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001415 self.assertEqual(msg._labels, [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416
1417 def test_labels(self):
1418 # Get, set, join, and leave labels
1419 msg = mailbox.BabylMessage(_sample_message)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001420 self.assertEqual(msg.get_labels(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001421 msg.set_labels(['foobar'])
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001422 self.assertEqual(msg.get_labels(), ['foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423 msg.set_labels([])
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001424 self.assertEqual(msg.get_labels(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001425 msg.add_label('filed')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001426 self.assertEqual(msg.get_labels(), ['filed'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427 msg.add_label('resent')
Guido van Rossumea834472007-07-27 05:17:50 +00001428 self.assertEqual(msg.get_labels(), ['filed', 'resent'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429 msg.add_label('resent')
Guido van Rossumea834472007-07-27 05:17:50 +00001430 self.assertEqual(msg.get_labels(), ['filed', 'resent'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431 msg.remove_label('filed')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001432 self.assertEqual(msg.get_labels(), ['resent'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001433 msg.add_label('foobar')
Guido van Rossumea834472007-07-27 05:17:50 +00001434 self.assertEqual(msg.get_labels(), ['resent', 'foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435 msg.remove_label('unseen')
Guido van Rossumea834472007-07-27 05:17:50 +00001436 self.assertEqual(msg.get_labels(), ['resent', 'foobar'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437 msg.set_labels(['foobar', 'answered'])
Guido van Rossumea834472007-07-27 05:17:50 +00001438 self.assertEqual(msg.get_labels(), ['foobar', 'answered'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001439
1440 def test_visible(self):
1441 # Get, set, and update visible headers
1442 msg = mailbox.BabylMessage(_sample_message)
1443 visible = msg.get_visible()
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001444 self.assertEqual(visible.keys(), [])
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001445 self.assertIs(visible.get_payload(), None)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001446 visible['User-Agent'] = 'FooBar 1.0'
1447 visible['X-Whatever'] = 'Blah'
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001448 self.assertEqual(msg.get_visible().keys(), [])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449 msg.set_visible(visible)
1450 visible = msg.get_visible()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001451 self.assertTrue(visible.keys() == ['User-Agent', 'X-Whatever'])
1452 self.assertTrue(visible['User-Agent'] == 'FooBar 1.0')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001453 self.assertEqual(visible['X-Whatever'], 'Blah')
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001454 self.assertIs(visible.get_payload(), None)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455 msg.update_visible()
Guido van Rossumea834472007-07-27 05:17:50 +00001456 self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever'])
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001457 self.assertIs(visible.get_payload(), None)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458 visible = msg.get_visible()
Guido van Rossumea834472007-07-27 05:17:50 +00001459 self.assertEqual(visible.keys(), ['User-Agent', 'Date', 'From', 'To',
1460 'Subject'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001461 for header in ('User-Agent', 'Date', 'From', 'To', 'Subject'):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001462 self.assertEqual(visible[header], msg[header])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001463
1464
1465class TestMMDFMessage(_TestMboxMMDFMessage):
1466
1467 _factory = mailbox.MMDFMessage
1468
1469
1470class TestMessageConversion(TestBase):
1471
1472 def test_plain_to_x(self):
1473 # Convert Message to all formats
1474 for class_ in (mailbox.Message, mailbox.MaildirMessage,
1475 mailbox.mboxMessage, mailbox.MHMessage,
1476 mailbox.BabylMessage, mailbox.MMDFMessage):
1477 msg_plain = mailbox.Message(_sample_message)
1478 msg = class_(msg_plain)
1479 self._check_sample(msg)
1480
1481 def test_x_to_plain(self):
1482 # Convert all formats to Message
1483 for class_ in (mailbox.Message, mailbox.MaildirMessage,
1484 mailbox.mboxMessage, mailbox.MHMessage,
1485 mailbox.BabylMessage, mailbox.MMDFMessage):
1486 msg = class_(_sample_message)
1487 msg_plain = mailbox.Message(msg)
1488 self._check_sample(msg_plain)
1489
R. David Murrayb7deff12011-01-30 06:21:28 +00001490 def test_x_from_bytes(self):
1491 # Convert all formats to Message
1492 for class_ in (mailbox.Message, mailbox.MaildirMessage,
1493 mailbox.mboxMessage, mailbox.MHMessage,
1494 mailbox.BabylMessage, mailbox.MMDFMessage):
1495 msg = class_(_bytes_sample_message)
1496 self._check_sample(msg)
1497
Thomas Wouters477c8d52006-05-27 19:21:47 +00001498 def test_x_to_invalid(self):
1499 # Convert all formats to an invalid format
1500 for class_ in (mailbox.Message, mailbox.MaildirMessage,
1501 mailbox.mboxMessage, mailbox.MHMessage,
1502 mailbox.BabylMessage, mailbox.MMDFMessage):
1503 self.assertRaises(TypeError, lambda: class_(False))
1504
1505 def test_maildir_to_maildir(self):
1506 # Convert MaildirMessage to MaildirMessage
1507 msg_maildir = mailbox.MaildirMessage(_sample_message)
1508 msg_maildir.set_flags('DFPRST')
1509 msg_maildir.set_subdir('cur')
1510 date = msg_maildir.get_date()
1511 msg = mailbox.MaildirMessage(msg_maildir)
1512 self._check_sample(msg)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001513 self.assertEqual(msg.get_flags(), 'DFPRST')
1514 self.assertEqual(msg.get_subdir(), 'cur')
1515 self.assertEqual(msg.get_date(), date)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516
1517 def test_maildir_to_mboxmmdf(self):
1518 # Convert MaildirMessage to mboxmessage and MMDFMessage
1519 pairs = (('D', ''), ('F', 'F'), ('P', ''), ('R', 'A'), ('S', 'R'),
1520 ('T', 'D'), ('DFPRST', 'RDFA'))
1521 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1522 msg_maildir = mailbox.MaildirMessage(_sample_message)
1523 msg_maildir.set_date(0.0)
1524 for setting, result in pairs:
1525 msg_maildir.set_flags(setting)
1526 msg = class_(msg_maildir)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001527 self.assertEqual(msg.get_flags(), result)
Guido van Rossumea834472007-07-27 05:17:50 +00001528 self.assertEqual(msg.get_from(), 'MAILER-DAEMON %s' %
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529 time.asctime(time.gmtime(0.0)))
1530 msg_maildir.set_subdir('cur')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001531 self.assertEqual(class_(msg_maildir).get_flags(), 'RODFA')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001532
1533 def test_maildir_to_mh(self):
1534 # Convert MaildirMessage to MHMessage
1535 msg_maildir = mailbox.MaildirMessage(_sample_message)
1536 pairs = (('D', ['unseen']), ('F', ['unseen', 'flagged']),
1537 ('P', ['unseen']), ('R', ['unseen', 'replied']), ('S', []),
1538 ('T', ['unseen']), ('DFPRST', ['replied', 'flagged']))
1539 for setting, result in pairs:
1540 msg_maildir.set_flags(setting)
Guido van Rossumea834472007-07-27 05:17:50 +00001541 self.assertEqual(mailbox.MHMessage(msg_maildir).get_sequences(),
1542 result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543
1544 def test_maildir_to_babyl(self):
1545 # Convert MaildirMessage to Babyl
1546 msg_maildir = mailbox.MaildirMessage(_sample_message)
1547 pairs = (('D', ['unseen']), ('F', ['unseen']),
1548 ('P', ['unseen', 'forwarded']), ('R', ['unseen', 'answered']),
1549 ('S', []), ('T', ['unseen', 'deleted']),
1550 ('DFPRST', ['deleted', 'answered', 'forwarded']))
1551 for setting, result in pairs:
1552 msg_maildir.set_flags(setting)
Guido van Rossumea834472007-07-27 05:17:50 +00001553 self.assertEqual(mailbox.BabylMessage(msg_maildir).get_labels(),
1554 result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555
1556 def test_mboxmmdf_to_maildir(self):
1557 # Convert mboxMessage and MMDFMessage to MaildirMessage
1558 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1559 msg_mboxMMDF = class_(_sample_message)
1560 msg_mboxMMDF.set_from('foo@bar', time.gmtime(0.0))
1561 pairs = (('R', 'S'), ('O', ''), ('D', 'T'), ('F', 'F'), ('A', 'R'),
1562 ('RODFA', 'FRST'))
1563 for setting, result in pairs:
1564 msg_mboxMMDF.set_flags(setting)
1565 msg = mailbox.MaildirMessage(msg_mboxMMDF)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001566 self.assertEqual(msg.get_flags(), result)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001567 self.assertEqual(msg.get_date(), 0.0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568 msg_mboxMMDF.set_flags('O')
Guido van Rossumea834472007-07-27 05:17:50 +00001569 self.assertEqual(mailbox.MaildirMessage(msg_mboxMMDF).get_subdir(),
1570 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571
1572 def test_mboxmmdf_to_mboxmmdf(self):
1573 # Convert mboxMessage and MMDFMessage to mboxMessage and MMDFMessage
1574 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1575 msg_mboxMMDF = class_(_sample_message)
1576 msg_mboxMMDF.set_flags('RODFA')
1577 msg_mboxMMDF.set_from('foo@bar')
1578 for class2_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1579 msg2 = class2_(msg_mboxMMDF)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001580 self.assertEqual(msg2.get_flags(), 'RODFA')
1581 self.assertEqual(msg2.get_from(), 'foo@bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582
1583 def test_mboxmmdf_to_mh(self):
1584 # Convert mboxMessage and MMDFMessage to MHMessage
1585 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1586 msg_mboxMMDF = class_(_sample_message)
1587 pairs = (('R', []), ('O', ['unseen']), ('D', ['unseen']),
1588 ('F', ['unseen', 'flagged']),
1589 ('A', ['unseen', 'replied']),
1590 ('RODFA', ['replied', 'flagged']))
1591 for setting, result in pairs:
1592 msg_mboxMMDF.set_flags(setting)
Guido van Rossumea834472007-07-27 05:17:50 +00001593 self.assertEqual(mailbox.MHMessage(msg_mboxMMDF).get_sequences(),
1594 result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001595
1596 def test_mboxmmdf_to_babyl(self):
1597 # Convert mboxMessage and MMDFMessage to BabylMessage
1598 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1599 msg = class_(_sample_message)
1600 pairs = (('R', []), ('O', ['unseen']),
1601 ('D', ['unseen', 'deleted']), ('F', ['unseen']),
1602 ('A', ['unseen', 'answered']),
1603 ('RODFA', ['deleted', 'answered']))
1604 for setting, result in pairs:
1605 msg.set_flags(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001606 self.assertEqual(mailbox.BabylMessage(msg).get_labels(), result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001607
1608 def test_mh_to_maildir(self):
1609 # Convert MHMessage to MaildirMessage
1610 pairs = (('unseen', ''), ('replied', 'RS'), ('flagged', 'FS'))
1611 for setting, result in pairs:
1612 msg = mailbox.MHMessage(_sample_message)
1613 msg.add_sequence(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001614 self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), result)
1615 self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616 msg = mailbox.MHMessage(_sample_message)
1617 msg.add_sequence('unseen')
1618 msg.add_sequence('replied')
1619 msg.add_sequence('flagged')
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001620 self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), 'FR')
1621 self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001622
1623 def test_mh_to_mboxmmdf(self):
1624 # Convert MHMessage to mboxMessage and MMDFMessage
1625 pairs = (('unseen', 'O'), ('replied', 'ROA'), ('flagged', 'ROF'))
1626 for setting, result in pairs:
1627 msg = mailbox.MHMessage(_sample_message)
1628 msg.add_sequence(setting)
1629 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001630 self.assertEqual(class_(msg).get_flags(), result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001631 msg = mailbox.MHMessage(_sample_message)
1632 msg.add_sequence('unseen')
1633 msg.add_sequence('replied')
1634 msg.add_sequence('flagged')
1635 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001636 self.assertEqual(class_(msg).get_flags(), 'OFA')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001637
1638 def test_mh_to_mh(self):
1639 # Convert MHMessage to MHMessage
1640 msg = mailbox.MHMessage(_sample_message)
1641 msg.add_sequence('unseen')
1642 msg.add_sequence('replied')
1643 msg.add_sequence('flagged')
Guido van Rossumea834472007-07-27 05:17:50 +00001644 self.assertEqual(mailbox.MHMessage(msg).get_sequences(),
1645 ['unseen', 'replied', 'flagged'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001646
1647 def test_mh_to_babyl(self):
1648 # Convert MHMessage to BabylMessage
1649 pairs = (('unseen', ['unseen']), ('replied', ['answered']),
1650 ('flagged', []))
1651 for setting, result in pairs:
1652 msg = mailbox.MHMessage(_sample_message)
1653 msg.add_sequence(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001654 self.assertEqual(mailbox.BabylMessage(msg).get_labels(), result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655 msg = mailbox.MHMessage(_sample_message)
1656 msg.add_sequence('unseen')
1657 msg.add_sequence('replied')
1658 msg.add_sequence('flagged')
Guido van Rossumea834472007-07-27 05:17:50 +00001659 self.assertEqual(mailbox.BabylMessage(msg).get_labels(),
1660 ['unseen', 'answered'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001661
1662 def test_babyl_to_maildir(self):
1663 # Convert BabylMessage to MaildirMessage
1664 pairs = (('unseen', ''), ('deleted', 'ST'), ('filed', 'S'),
1665 ('answered', 'RS'), ('forwarded', 'PS'), ('edited', 'S'),
1666 ('resent', 'PS'))
1667 for setting, result in pairs:
1668 msg = mailbox.BabylMessage(_sample_message)
1669 msg.add_label(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001670 self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), result)
1671 self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672 msg = mailbox.BabylMessage(_sample_message)
1673 for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
1674 'edited', 'resent'):
1675 msg.add_label(label)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001676 self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), 'PRT')
1677 self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678
1679 def test_babyl_to_mboxmmdf(self):
1680 # Convert BabylMessage to mboxMessage and MMDFMessage
1681 pairs = (('unseen', 'O'), ('deleted', 'ROD'), ('filed', 'RO'),
1682 ('answered', 'ROA'), ('forwarded', 'RO'), ('edited', 'RO'),
1683 ('resent', 'RO'))
1684 for setting, result in pairs:
1685 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
1686 msg = mailbox.BabylMessage(_sample_message)
1687 msg.add_label(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001688 self.assertEqual(class_(msg).get_flags(), result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001689 msg = mailbox.BabylMessage(_sample_message)
1690 for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
1691 'edited', 'resent'):
1692 msg.add_label(label)
1693 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001694 self.assertEqual(class_(msg).get_flags(), 'ODA')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695
1696 def test_babyl_to_mh(self):
1697 # Convert BabylMessage to MHMessage
1698 pairs = (('unseen', ['unseen']), ('deleted', []), ('filed', []),
1699 ('answered', ['replied']), ('forwarded', []), ('edited', []),
1700 ('resent', []))
1701 for setting, result in pairs:
1702 msg = mailbox.BabylMessage(_sample_message)
1703 msg.add_label(setting)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001704 self.assertEqual(mailbox.MHMessage(msg).get_sequences(), result)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705 msg = mailbox.BabylMessage(_sample_message)
1706 for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
1707 'edited', 'resent'):
1708 msg.add_label(label)
Guido van Rossumea834472007-07-27 05:17:50 +00001709 self.assertEqual(mailbox.MHMessage(msg).get_sequences(),
1710 ['unseen', 'replied'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001711
1712 def test_babyl_to_babyl(self):
1713 # Convert BabylMessage to BabylMessage
1714 msg = mailbox.BabylMessage(_sample_message)
1715 msg.update_visible()
1716 for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded',
1717 'edited', 'resent'):
1718 msg.add_label(label)
1719 msg2 = mailbox.BabylMessage(msg)
Guido van Rossumea834472007-07-27 05:17:50 +00001720 self.assertEqual(msg2.get_labels(), ['unseen', 'deleted', 'filed',
1721 'answered', 'forwarded', 'edited',
1722 'resent'])
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001723 self.assertEqual(msg.get_visible().keys(), msg2.get_visible().keys())
Thomas Wouters477c8d52006-05-27 19:21:47 +00001724 for key in msg.get_visible().keys():
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001725 self.assertEqual(msg.get_visible()[key], msg2.get_visible()[key])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726
1727
1728class TestProxyFileBase(TestBase):
1729
1730 def _test_read(self, proxy):
1731 # Read by byte
1732 proxy.seek(0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001733 self.assertEqual(proxy.read(), b'bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001734 proxy.seek(1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001735 self.assertEqual(proxy.read(), b'ar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736 proxy.seek(0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001737 self.assertEqual(proxy.read(2), b'ba')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001738 proxy.seek(1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001739 self.assertEqual(proxy.read(-1), b'ar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740 proxy.seek(2)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001741 self.assertEqual(proxy.read(1000), b'r')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001742
1743 def _test_readline(self, proxy):
1744 # Read by line
Guido van Rossum98297ee2007-11-06 21:34:58 +00001745 linesep = os.linesep.encode()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746 proxy.seek(0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001747 self.assertEqual(proxy.readline(), b'foo' + linesep)
1748 self.assertEqual(proxy.readline(), b'bar' + linesep)
1749 self.assertEqual(proxy.readline(), b'fred' + linesep)
1750 self.assertEqual(proxy.readline(), b'bob')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751 proxy.seek(2)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001752 self.assertEqual(proxy.readline(), b'o' + linesep)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753 proxy.seek(6 + 2 * len(os.linesep))
Guido van Rossum98297ee2007-11-06 21:34:58 +00001754 self.assertEqual(proxy.readline(), b'fred' + linesep)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755 proxy.seek(6 + 2 * len(os.linesep))
Guido van Rossum98297ee2007-11-06 21:34:58 +00001756 self.assertEqual(proxy.readline(2), b'fr')
1757 self.assertEqual(proxy.readline(-10), b'ed' + linesep)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758
1759 def _test_readlines(self, proxy):
1760 # Read multiple lines
Guido van Rossum98297ee2007-11-06 21:34:58 +00001761 linesep = os.linesep.encode()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001762 proxy.seek(0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001763 self.assertEqual(proxy.readlines(), [b'foo' + linesep,
1764 b'bar' + linesep,
1765 b'fred' + linesep, b'bob'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766 proxy.seek(0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001767 self.assertEqual(proxy.readlines(2), [b'foo' + linesep])
1768 proxy.seek(3 + len(linesep))
1769 self.assertEqual(proxy.readlines(4 + len(linesep)),
1770 [b'bar' + linesep, b'fred' + linesep])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001771 proxy.seek(3)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001772 self.assertEqual(proxy.readlines(1000), [linesep, b'bar' + linesep,
1773 b'fred' + linesep, b'bob'])
Thomas Wouters477c8d52006-05-27 19:21:47 +00001774
1775 def _test_iteration(self, proxy):
1776 # Iterate by line
Guido van Rossum98297ee2007-11-06 21:34:58 +00001777 linesep = os.linesep.encode()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778 proxy.seek(0)
1779 iterator = iter(proxy)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001780 self.assertEqual(next(iterator), b'foo' + linesep)
1781 self.assertEqual(next(iterator), b'bar' + linesep)
1782 self.assertEqual(next(iterator), b'fred' + linesep)
1783 self.assertEqual(next(iterator), b'bob')
Georg Brandla18af4e2007-04-21 15:47:16 +00001784 self.assertRaises(StopIteration, next, iterator)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001785
1786 def _test_seek_and_tell(self, proxy):
1787 # Seek and use tell to check position
Guido van Rossum98297ee2007-11-06 21:34:58 +00001788 linesep = os.linesep.encode()
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789 proxy.seek(3)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001790 self.assertEqual(proxy.tell(), 3)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001791 self.assertEqual(proxy.read(len(linesep)), linesep)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001792 proxy.seek(2, 1)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001793 self.assertEqual(proxy.read(1 + len(linesep)), b'r' + linesep)
1794 proxy.seek(-3 - len(linesep), 2)
1795 self.assertEqual(proxy.read(3), b'bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796 proxy.seek(2, 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001797 self.assertEqual(proxy.read(), b'o' + linesep + b'bar' + linesep)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798 proxy.seek(100)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001799 self.assertFalse(proxy.read())
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800
1801 def _test_close(self, proxy):
1802 # Close a file
1803 proxy.close()
1804 self.assertRaises(AttributeError, lambda: proxy.close())
1805
1806
1807class TestProxyFile(TestProxyFileBase):
1808
1809 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001810 self._path = support.TESTFN
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811 self._file = open(self._path, 'wb+')
1812
1813 def tearDown(self):
1814 self._file.close()
1815 self._delete_recursively(self._path)
1816
1817 def test_initialize(self):
1818 # Initialize and check position
Neal Norwitz9a923102007-08-30 06:20:05 +00001819 self._file.write(b'foo')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001820 pos = self._file.tell()
1821 proxy0 = mailbox._ProxyFile(self._file)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001822 self.assertEqual(proxy0.tell(), pos)
1823 self.assertEqual(self._file.tell(), pos)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824 proxy1 = mailbox._ProxyFile(self._file, 0)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001825 self.assertEqual(proxy1.tell(), 0)
1826 self.assertEqual(self._file.tell(), pos)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827
1828 def test_read(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001829 self._file.write(b'bar')
Thomas Wouters477c8d52006-05-27 19:21:47 +00001830 self._test_read(mailbox._ProxyFile(self._file))
1831
1832 def test_readline(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001833 self._file.write(bytes('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
1834 os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001835 self._test_readline(mailbox._ProxyFile(self._file))
1836
1837 def test_readlines(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001838 self._file.write(bytes('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
1839 os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001840 self._test_readlines(mailbox._ProxyFile(self._file))
1841
1842 def test_iteration(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001843 self._file.write(bytes('foo%sbar%sfred%sbob' % (os.linesep, os.linesep,
1844 os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001845 self._test_iteration(mailbox._ProxyFile(self._file))
1846
1847 def test_seek_and_tell(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001848 self._file.write(bytes('foo%sbar%s' % (os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849 self._test_seek_and_tell(mailbox._ProxyFile(self._file))
1850
1851 def test_close(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001852 self._file.write(bytes('foo%sbar%s' % (os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001853 self._test_close(mailbox._ProxyFile(self._file))
1854
1855
1856class TestPartialFile(TestProxyFileBase):
1857
1858 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001859 self._path = support.TESTFN
Thomas Wouters477c8d52006-05-27 19:21:47 +00001860 self._file = open(self._path, 'wb+')
1861
1862 def tearDown(self):
1863 self._file.close()
1864 self._delete_recursively(self._path)
1865
1866 def test_initialize(self):
1867 # Initialize and check position
Neal Norwitz9a923102007-08-30 06:20:05 +00001868 self._file.write(bytes('foo' + os.linesep + 'bar', 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001869 pos = self._file.tell()
1870 proxy = mailbox._PartialFile(self._file, 2, 5)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001871 self.assertEqual(proxy.tell(), 0)
1872 self.assertEqual(self._file.tell(), pos)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001873
1874 def test_read(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001875 self._file.write(bytes('***bar***', 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876 self._test_read(mailbox._PartialFile(self._file, 3, 6))
1877
1878 def test_readline(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001879 self._file.write(bytes('!!!!!foo%sbar%sfred%sbob!!!!!' %
1880 (os.linesep, os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001881 self._test_readline(mailbox._PartialFile(self._file, 5,
1882 18 + 3 * len(os.linesep)))
1883
1884 def test_readlines(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001885 self._file.write(bytes('foo%sbar%sfred%sbob?????' %
1886 (os.linesep, os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887 self._test_readlines(mailbox._PartialFile(self._file, 0,
1888 13 + 3 * len(os.linesep)))
1889
1890 def test_iteration(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001891 self._file.write(bytes('____foo%sbar%sfred%sbob####' %
1892 (os.linesep, os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001893 self._test_iteration(mailbox._PartialFile(self._file, 4,
1894 17 + 3 * len(os.linesep)))
1895
1896 def test_seek_and_tell(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001897 self._file.write(bytes('(((foo%sbar%s$$$' % (os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001898 self._test_seek_and_tell(mailbox._PartialFile(self._file, 3,
1899 9 + 2 * len(os.linesep)))
1900
1901 def test_close(self):
Neal Norwitz9a923102007-08-30 06:20:05 +00001902 self._file.write(bytes('&foo%sbar%s^' % (os.linesep, os.linesep), 'ascii'))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001903 self._test_close(mailbox._PartialFile(self._file, 1,
1904 6 + 3 * len(os.linesep)))
1905
1906
1907## Start: tests from the original module (for backward compatibility).
1908
Skip Montanaro5253da12004-07-24 19:56:03 +00001909FROM_ = "From some.body@dummy.domain Sat Jul 24 13:43:35 2004\n"
Fred Drakec02bc3e2001-05-21 20:23:21 +00001910DUMMY_MESSAGE = """\
1911From: some.body@dummy.domain
1912To: me@my.domain
Skip Montanaro5253da12004-07-24 19:56:03 +00001913Subject: Simple Test
Fred Drakec02bc3e2001-05-21 20:23:21 +00001914
1915This is a dummy message.
1916"""
1917
Fred Drakec02bc3e2001-05-21 20:23:21 +00001918class MaildirTestCase(unittest.TestCase):
1919
1920 def setUp(self):
1921 # create a new maildir mailbox to work with:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001922 self._dir = support.TESTFN
Fred Drakec02bc3e2001-05-21 20:23:21 +00001923 os.mkdir(self._dir)
1924 os.mkdir(os.path.join(self._dir, "cur"))
1925 os.mkdir(os.path.join(self._dir, "tmp"))
1926 os.mkdir(os.path.join(self._dir, "new"))
1927 self._counter = 1
1928 self._msgfiles = []
1929
1930 def tearDown(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001931 list(map(os.unlink, self._msgfiles))
Fred Drakec02bc3e2001-05-21 20:23:21 +00001932 os.rmdir(os.path.join(self._dir, "cur"))
1933 os.rmdir(os.path.join(self._dir, "tmp"))
1934 os.rmdir(os.path.join(self._dir, "new"))
1935 os.rmdir(self._dir)
1936
Skip Montanaro5253da12004-07-24 19:56:03 +00001937 def createMessage(self, dir, mbox=False):
Jack Jansen97df7b62001-06-19 20:20:05 +00001938 t = int(time.time() % 1000000)
Fred Drakec02bc3e2001-05-21 20:23:21 +00001939 pid = self._counter
1940 self._counter += 1
Skip Montanaro7a98be22007-08-16 14:35:24 +00001941 filename = ".".join((str(t), str(pid), "myhostname", "mydomain"))
Fred Drakec02bc3e2001-05-21 20:23:21 +00001942 tmpname = os.path.join(self._dir, "tmp", filename)
1943 newname = os.path.join(self._dir, dir, filename)
Brian Curtin5acec042010-10-13 02:29:46 +00001944 with open(tmpname, "w") as fp:
1945 self._msgfiles.append(tmpname)
1946 if mbox:
1947 fp.write(FROM_)
1948 fp.write(DUMMY_MESSAGE)
Tim Peters6626c1f2001-05-22 16:29:01 +00001949 if hasattr(os, "link"):
1950 os.link(tmpname, newname)
1951 else:
Brian Curtin5acec042010-10-13 02:29:46 +00001952 with open(newname, "w") as fp:
1953 fp.write(DUMMY_MESSAGE)
Fred Drakec02bc3e2001-05-21 20:23:21 +00001954 self._msgfiles.append(newname)
Skip Montanaro5253da12004-07-24 19:56:03 +00001955 return tmpname
Fred Drakec02bc3e2001-05-21 20:23:21 +00001956
1957 def test_empty_maildir(self):
1958 """Test an empty maildir mailbox"""
1959 # Test for regression on bug #117490:
1960 # Make sure the boxes attribute actually gets set.
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001961 self.mbox = mailbox.Maildir(support.TESTFN)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001962 #self.assertTrue(hasattr(self.mbox, "boxes"))
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001963 #self.assertEqual(len(self.mbox.boxes), 0)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001964 self.assertIs(self.mbox.next(), None)
1965 self.assertIs(self.mbox.next(), None)
Fred Drakec02bc3e2001-05-21 20:23:21 +00001966
1967 def test_nonempty_maildir_cur(self):
1968 self.createMessage("cur")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001969 self.mbox = mailbox.Maildir(support.TESTFN)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001970 #self.assertEqual(len(self.mbox.boxes), 1)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001971 self.assertIsNot(self.mbox.next(), None)
1972 self.assertIs(self.mbox.next(), None)
1973 self.assertIs(self.mbox.next(), None)
Fred Drakec02bc3e2001-05-21 20:23:21 +00001974
1975 def test_nonempty_maildir_new(self):
1976 self.createMessage("new")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001977 self.mbox = mailbox.Maildir(support.TESTFN)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001978 #self.assertEqual(len(self.mbox.boxes), 1)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001979 self.assertIsNot(self.mbox.next(), None)
1980 self.assertIs(self.mbox.next(), None)
1981 self.assertIs(self.mbox.next(), None)
Fred Drakec02bc3e2001-05-21 20:23:21 +00001982
1983 def test_nonempty_maildir_both(self):
1984 self.createMessage("cur")
1985 self.createMessage("new")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001986 self.mbox = mailbox.Maildir(support.TESTFN)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001987 #self.assertEqual(len(self.mbox.boxes), 2)
Alexandre Vassalottib27a1d22009-07-22 23:27:17 +00001988 self.assertIsNot(self.mbox.next(), None)
1989 self.assertIsNot(self.mbox.next(), None)
1990 self.assertIs(self.mbox.next(), None)
1991 self.assertIs(self.mbox.next(), None)
Fred Drake0aaed272000-10-23 13:39:15 +00001992
Georg Brandledb978f2008-05-11 08:59:40 +00001993## End: tests from the original module (for backward compatibility).
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994
1995
1996_sample_message = """\
1997Return-Path: <gkj@gregorykjohnson.com>
1998X-Original-To: gkj+person@localhost
1999Delivered-To: gkj+person@localhost
2000Received: from localhost (localhost [127.0.0.1])
2001 by andy.gregorykjohnson.com (Postfix) with ESMTP id 356ED9DD17
2002 for <gkj+person@localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)
2003Delivered-To: gkj@sundance.gregorykjohnson.com
2004Received: from localhost [127.0.0.1]
2005 by localhost with POP3 (fetchmail-6.2.5)
2006 for gkj+person@localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)
2007Received: from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228])
2008 by sundance.gregorykjohnson.com (Postfix) with ESMTP id 5B056316746
2009 for <gkj@gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)
2010Received: by andy.gregorykjohnson.com (Postfix, from userid 1000)
2011 id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)
2012Date: Wed, 13 Jul 2005 17:23:11 -0400
2013From: "Gregory K. Johnson" <gkj@gregorykjohnson.com>
2014To: gkj@gregorykjohnson.com
2015Subject: Sample message
2016Message-ID: <20050713212311.GC4701@andy.gregorykjohnson.com>
2017Mime-Version: 1.0
2018Content-Type: multipart/mixed; boundary="NMuMz9nt05w80d4+"
2019Content-Disposition: inline
2020User-Agent: Mutt/1.5.9i
2021
2022
2023--NMuMz9nt05w80d4+
2024Content-Type: text/plain; charset=us-ascii
2025Content-Disposition: inline
2026
2027This is a sample message.
2028
2029--
2030Gregory K. Johnson
2031
2032--NMuMz9nt05w80d4+
2033Content-Type: application/octet-stream
2034Content-Disposition: attachment; filename="text.gz"
2035Content-Transfer-Encoding: base64
2036
2037H4sICM2D1UIAA3RleHQAC8nILFYAokSFktSKEoW0zJxUPa7wzJIMhZLyfIWczLzUYj0uAHTs
20383FYlAAAA
2039
2040--NMuMz9nt05w80d4+--
2041"""
2042
R. David Murrayb7deff12011-01-30 06:21:28 +00002043_bytes_sample_message = _sample_message.encode('ascii')
2044
Thomas Wouters477c8d52006-05-27 19:21:47 +00002045_sample_headers = {
2046 "Return-Path":"<gkj@gregorykjohnson.com>",
2047 "X-Original-To":"gkj+person@localhost",
2048 "Delivered-To":"gkj+person@localhost",
2049 "Received":"""from localhost (localhost [127.0.0.1])
2050 by andy.gregorykjohnson.com (Postfix) with ESMTP id 356ED9DD17
2051 for <gkj+person@localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""",
2052 "Delivered-To":"gkj@sundance.gregorykjohnson.com",
2053 "Received":"""from localhost [127.0.0.1]
2054 by localhost with POP3 (fetchmail-6.2.5)
2055 for gkj+person@localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""",
2056 "Received":"""from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228])
2057 by sundance.gregorykjohnson.com (Postfix) with ESMTP id 5B056316746
2058 for <gkj@gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""",
2059 "Received":"""by andy.gregorykjohnson.com (Postfix, from userid 1000)
2060 id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""",
2061 "Date":"Wed, 13 Jul 2005 17:23:11 -0400",
2062 "From":""""Gregory K. Johnson" <gkj@gregorykjohnson.com>""",
2063 "To":"gkj@gregorykjohnson.com",
2064 "Subject":"Sample message",
2065 "Mime-Version":"1.0",
2066 "Content-Type":"""multipart/mixed; boundary="NMuMz9nt05w80d4+\"""",
2067 "Content-Disposition":"inline",
2068 "User-Agent": "Mutt/1.5.9i" }
2069
2070_sample_payloads = ("""This is a sample message.
2071
2072--
2073Gregory K. Johnson
2074""",
2075"""H4sICM2D1UIAA3RleHQAC8nILFYAokSFktSKEoW0zJxUPa7wzJIMhZLyfIWczLzUYj0uAHTs
20763FYlAAAA
2077""")
Fred Drake0aaed272000-10-23 13:39:15 +00002078
Fred Drakec02bc3e2001-05-21 20:23:21 +00002079
Fred Drake2e2be372001-09-20 21:33:42 +00002080def test_main():
Thomas Wouters477c8d52006-05-27 19:21:47 +00002081 tests = (TestMailboxSuperclass, TestMaildir, TestMbox, TestMMDF, TestMH,
2082 TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage,
2083 TestMHMessage, TestBabylMessage, TestMMDFMessage,
2084 TestMessageConversion, TestProxyFile, TestPartialFile,
2085 MaildirTestCase)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002086 support.run_unittest(*tests)
2087 support.reap_children()
Fred Drake2e2be372001-09-20 21:33:42 +00002088
2089
Thomas Wouters477c8d52006-05-27 19:21:47 +00002090if __name__ == '__main__':
Fred Drake2e2be372001-09-20 21:33:42 +00002091 test_main()