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 cStringIO import StringIO
13from types import ListType
14
15from email.test.test_email import TestEmailBase
16from test.test_support import TestSkipped, run_unittest
17
18import email
19from email import __file__ as testfile
20from email.iterators import _structure
21
22def openfile(filename):
23    from os.path import join, dirname, abspath
24    path = abspath(join(dirname(testfile), os.pardir, 'moredata', filename))
25    return open(path, 'r')
26
27# Prevent this test from running in the Python distro
28try:
29    openfile('crispin-torture.txt')
30except IOError:
31    raise TestSkipped
32
33
34
35class TortureBase(TestEmailBase):
36    def _msgobj(self, filename):
37        fp = openfile(filename)
38        try:
39            msg = email.message_from_file(fp)
40        finally:
41            fp.close()
42        return msg
43
44
45
46class TestCrispinTorture(TortureBase):
47    # Mark Crispin's torture test from the SquirrelMail project
48    def test_mondo_message(self):
49        eq = self.assertEqual
50        neq = self.ndiffAssertEqual
51        msg = self._msgobj('crispin-torture.txt')
52        payload = msg.get_payload()
53        eq(type(payload), ListType)
54        eq(len(payload), 12)
55        eq(msg.preamble, None)
56        eq(msg.epilogue, '\n')
57        # Probably the best way to verify the message is parsed correctly is to
58        # dump its structure and compare it against the known structure.
59        fp = StringIO()
60        _structure(msg, fp=fp)
61        neq(fp.getvalue(), """\
62multipart/mixed
63    text/plain
64    message/rfc822
65        multipart/alternative
66            text/plain
67            multipart/mixed
68                text/richtext
69            application/andrew-inset
70    message/rfc822
71        audio/basic
72    audio/basic
73    image/pbm
74    message/rfc822
75        multipart/mixed
76            multipart/mixed
77                text/plain
78                audio/x-sun
79            multipart/mixed
80                image/gif
81                image/gif
82                application/x-be2
83                application/atomicmail
84            audio/x-sun
85    message/rfc822
86        multipart/mixed
87            text/plain
88            image/pgm
89            text/plain
90    message/rfc822
91        multipart/mixed
92            text/plain
93            image/pbm
94    message/rfc822
95        application/postscript
96    image/gif
97    message/rfc822
98        multipart/mixed
99            audio/basic
100            audio/basic
101    message/rfc822
102        multipart/mixed
103            application/postscript
104            text/plain
105            message/rfc822
106                multipart/mixed
107                    text/plain
108                    multipart/parallel
109                        image/gif
110                        audio/basic
111                    application/atomicmail
112                    message/rfc822
113                        audio/x-sun
114""")
115
116
117def _testclasses():
118    mod = sys.modules[__name__]
119    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
120
121
122def suite():
123    suite = unittest.TestSuite()
124    for testclass in _testclasses():
125        suite.addTest(unittest.makeSuite(testclass))
126    return suite
127
128
129def test_main():
130    for testclass in _testclasses():
131        run_unittest(testclass)
132
133
134
135if __name__ == '__main__':
136    unittest.main(defaultTest='suite')
137