1# Copyright (C) 2002-2004 Python Software Foundation
2#
3# A torture test of the email package.  This should not be run as part of the
4# standard Python test suite since it requires several meg of email messages
5# collected in the wild.  These source messages are not checked into the
6# Python distro, but are available as part of the standalone email package at
7# http://sf.net/projects/mimelib
8
9import sys
10import os
11import unittest
12from io import StringIO
13
14from test.test_email import TestEmailBase
15from test.support import run_unittest
16
17import email
18from email import __file__ as testfile
19from email.iterators import _structure
20
21def openfile(filename):
22    from os.path import join, dirname, abspath
23    path = abspath(join(dirname(testfile), os.pardir, 'moredata', filename))
24    return open(path, 'r')
25
26# Prevent this test from running in the Python distro
27try:
28    openfile('crispin-torture.txt')
29except OSError:
30    raise unittest.SkipTest
31
32
33
34class TortureBase(TestEmailBase):
35    def _msgobj(self, filename):
36        fp = openfile(filename)
37        try:
38            msg = email.message_from_file(fp)
39        finally:
40            fp.close()
41        return msg
42
43
44
45class TestCrispinTorture(TortureBase):
46    # Mark Crispin's torture test from the SquirrelMail project
47    def test_mondo_message(self):
48        eq = self.assertEqual
49        neq = self.ndiffAssertEqual
50        msg = self._msgobj('crispin-torture.txt')
51        payload = msg.get_payload()
52        eq(type(payload), list)
53        eq(len(payload), 12)
54        eq(msg.preamble, None)
55        eq(msg.epilogue, '\n')
56        # Probably the best way to verify the message is parsed correctly is to
57        # dump its structure and compare it against the known structure.
58        fp = StringIO()
59        _structure(msg, fp=fp)
60        neq(fp.getvalue(), """\
61multipart/mixed
62    text/plain
63    message/rfc822
64        multipart/alternative
65            text/plain
66            multipart/mixed
67                text/richtext
68            application/andrew-inset
69    message/rfc822
70        audio/basic
71    audio/basic
72    image/pbm
73    message/rfc822
74        multipart/mixed
75            multipart/mixed
76                text/plain
77                audio/x-sun
78            multipart/mixed
79                image/gif
80                image/gif
81                application/x-be2
82                application/atomicmail
83            audio/x-sun
84    message/rfc822
85        multipart/mixed
86            text/plain
87            image/pgm
88            text/plain
89    message/rfc822
90        multipart/mixed
91            text/plain
92            image/pbm
93    message/rfc822
94        application/postscript
95    image/gif
96    message/rfc822
97        multipart/mixed
98            audio/basic
99            audio/basic
100    message/rfc822
101        multipart/mixed
102            application/postscript
103            text/plain
104            message/rfc822
105                multipart/mixed
106                    text/plain
107                    multipart/parallel
108                        image/gif
109                        audio/basic
110                    application/atomicmail
111                    message/rfc822
112                        audio/x-sun
113""")
114
115def _testclasses():
116    mod = sys.modules[__name__]
117    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
118
119
120def suite():
121    suite = unittest.TestSuite()
122    for testclass in _testclasses():
123        suite.addTest(unittest.makeSuite(testclass))
124    return suite
125
126
127def test_main():
128    for testclass in _testclasses():
129        run_unittest(testclass)
130
131
132if __name__ == '__main__':
133    unittest.main(defaultTest='suite')
134