PageRenderTime 1259ms CodeModel.GetById 178ms app.highlight 115ms RepoModel.GetById 795ms app.codeStats 0ms

/Lib/test/test_marshal.py

http://unladen-swallow.googlecode.com/
Python | 281 lines | 248 code | 14 blank | 19 comment | 15 complexity | 1ce7ceda96c0a80c24508ddad7715d0b MD5 | raw file
  1#!/usr/bin/env python
  2# -*- coding: iso-8859-1 -*-
  3
  4from test import test_support
  5import marshal
  6import sys
  7import unittest
  8import os
  9
 10class IntTestCase(unittest.TestCase):
 11    def test_ints(self):
 12        # Test the full range of Python ints.
 13        n = sys.maxint
 14        while n:
 15            for expected in (-n, n):
 16                s = marshal.dumps(expected)
 17                got = marshal.loads(s)
 18                self.assertEqual(expected, got)
 19                marshal.dump(expected, file(test_support.TESTFN, "wb"))
 20                got = marshal.load(file(test_support.TESTFN, "rb"))
 21                self.assertEqual(expected, got)
 22            n = n >> 1
 23        os.unlink(test_support.TESTFN)
 24
 25    def test_int64(self):
 26        # Simulate int marshaling on a 64-bit box.  This is most interesting if
 27        # we're running the test on a 32-bit box, of course.
 28
 29        def to_little_endian_string(value, nbytes):
 30            bytes = []
 31            for i in range(nbytes):
 32                bytes.append(chr(value & 0xff))
 33                value >>= 8
 34            return ''.join(bytes)
 35
 36        maxint64 = (1L << 63) - 1
 37        minint64 = -maxint64-1
 38
 39        for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
 40            while base:
 41                s = 'I' + to_little_endian_string(base, 8)
 42                got = marshal.loads(s)
 43                self.assertEqual(base, got)
 44                if base == -1:  # a fixed-point for shifting right 1
 45                    base = 0
 46                else:
 47                    base >>= 1
 48
 49    def test_bool(self):
 50        for b in (True, False):
 51            new = marshal.loads(marshal.dumps(b))
 52            self.assertEqual(b, new)
 53            self.assertEqual(type(b), type(new))
 54            marshal.dump(b, file(test_support.TESTFN, "wb"))
 55            new = marshal.load(file(test_support.TESTFN, "rb"))
 56            self.assertEqual(b, new)
 57            self.assertEqual(type(b), type(new))
 58
 59class FloatTestCase(unittest.TestCase):
 60    def test_floats(self):
 61        # Test a few floats
 62        small = 1e-25
 63        n = sys.maxint * 3.7e250
 64        while n > small:
 65            for expected in (-n, n):
 66                f = float(expected)
 67                s = marshal.dumps(f)
 68                got = marshal.loads(s)
 69                self.assertEqual(f, got)
 70                marshal.dump(f, file(test_support.TESTFN, "wb"))
 71                got = marshal.load(file(test_support.TESTFN, "rb"))
 72                self.assertEqual(f, got)
 73            n /= 123.4567
 74
 75        f = 0.0
 76        s = marshal.dumps(f, 2)
 77        got = marshal.loads(s)
 78        self.assertEqual(f, got)
 79        # and with version <= 1 (floats marshalled differently then)
 80        s = marshal.dumps(f, 1)
 81        got = marshal.loads(s)
 82        self.assertEqual(f, got)
 83
 84        n = sys.maxint * 3.7e-250
 85        while n < small:
 86            for expected in (-n, n):
 87                f = float(expected)
 88
 89                s = marshal.dumps(f)
 90                got = marshal.loads(s)
 91                self.assertEqual(f, got)
 92
 93                s = marshal.dumps(f, 1)
 94                got = marshal.loads(s)
 95                self.assertEqual(f, got)
 96
 97                marshal.dump(f, file(test_support.TESTFN, "wb"))
 98                got = marshal.load(file(test_support.TESTFN, "rb"))
 99                self.assertEqual(f, got)
100
101                marshal.dump(f, file(test_support.TESTFN, "wb"), 1)
102                got = marshal.load(file(test_support.TESTFN, "rb"))
103                self.assertEqual(f, got)
104            n *= 123.4567
105        os.unlink(test_support.TESTFN)
106
107class StringTestCase(unittest.TestCase):
108    def test_unicode(self):
109        for s in [u"", u"Andrč Previn", u"abc", u" "*10000]:
110            new = marshal.loads(marshal.dumps(s))
111            self.assertEqual(s, new)
112            self.assertEqual(type(s), type(new))
113            marshal.dump(s, file(test_support.TESTFN, "wb"))
114            new = marshal.load(file(test_support.TESTFN, "rb"))
115            self.assertEqual(s, new)
116            self.assertEqual(type(s), type(new))
117        os.unlink(test_support.TESTFN)
118
119    def test_string(self):
120        for s in ["", "Andrč Previn", "abc", " "*10000]:
121            new = marshal.loads(marshal.dumps(s))
122            self.assertEqual(s, new)
123            self.assertEqual(type(s), type(new))
124            marshal.dump(s, file(test_support.TESTFN, "wb"))
125            new = marshal.load(file(test_support.TESTFN, "rb"))
126            self.assertEqual(s, new)
127            self.assertEqual(type(s), type(new))
128        os.unlink(test_support.TESTFN)
129
130    def test_buffer(self):
131        for s in ["", "Andrč Previn", "abc", " "*10000]:
132            b = buffer(s)
133            new = marshal.loads(marshal.dumps(b))
134            self.assertEqual(s, new)
135            marshal.dump(b, file(test_support.TESTFN, "wb"))
136            new = marshal.load(file(test_support.TESTFN, "rb"))
137            self.assertEqual(s, new)
138        os.unlink(test_support.TESTFN)
139
140class ExceptionTestCase(unittest.TestCase):
141    def test_exceptions(self):
142        new = marshal.loads(marshal.dumps(StopIteration))
143        self.assertEqual(StopIteration, new)
144
145class CodeTestCase(unittest.TestCase):
146    def test_code(self):
147        co = ExceptionTestCase.test_exceptions.func_code
148        new = marshal.loads(marshal.dumps(co))
149        self.assertEqual(co, new)
150
151class ContainerTestCase(unittest.TestCase):
152    d = {'astring': 'foo@bar.baz.spam',
153         'afloat': 7283.43,
154         'anint': 2**20,
155         'ashortlong': 2L,
156         'alist': ['.zyx.41'],
157         'atuple': ('.zyx.41',)*10,
158         'aboolean': False,
159         'aunicode': u"Andrč Previn"
160         }
161    def test_dict(self):
162        new = marshal.loads(marshal.dumps(self.d))
163        self.assertEqual(self.d, new)
164        marshal.dump(self.d, file(test_support.TESTFN, "wb"))
165        new = marshal.load(file(test_support.TESTFN, "rb"))
166        self.assertEqual(self.d, new)
167        os.unlink(test_support.TESTFN)
168
169    def test_list(self):
170        lst = self.d.items()
171        new = marshal.loads(marshal.dumps(lst))
172        self.assertEqual(lst, new)
173        marshal.dump(lst, file(test_support.TESTFN, "wb"))
174        new = marshal.load(file(test_support.TESTFN, "rb"))
175        self.assertEqual(lst, new)
176        os.unlink(test_support.TESTFN)
177
178    def test_tuple(self):
179        t = tuple(self.d.keys())
180        new = marshal.loads(marshal.dumps(t))
181        self.assertEqual(t, new)
182        marshal.dump(t, file(test_support.TESTFN, "wb"))
183        new = marshal.load(file(test_support.TESTFN, "rb"))
184        self.assertEqual(t, new)
185        os.unlink(test_support.TESTFN)
186
187    def test_sets(self):
188        for constructor in (set, frozenset):
189            t = constructor(self.d.keys())
190            new = marshal.loads(marshal.dumps(t))
191            self.assertEqual(t, new)
192            self.assert_(isinstance(new, constructor))
193            self.assertNotEqual(id(t), id(new))
194            marshal.dump(t, file(test_support.TESTFN, "wb"))
195            new = marshal.load(file(test_support.TESTFN, "rb"))
196            self.assertEqual(t, new)
197            os.unlink(test_support.TESTFN)
198
199class BugsTestCase(unittest.TestCase):
200    def test_bug_5888452(self):
201        # Simple-minded check for SF 588452: Debug build crashes
202        marshal.dumps([128] * 1000)
203
204    def test_patch_873224(self):
205        self.assertRaises(Exception, marshal.loads, '0')
206        self.assertRaises(Exception, marshal.loads, 'f')
207        self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1])
208
209    def test_version_argument(self):
210        # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
211        self.assertEquals(marshal.loads(marshal.dumps(5, 0)), 5)
212        self.assertEquals(marshal.loads(marshal.dumps(5, 1)), 5)
213
214    def test_fuzz(self):
215        # simple test that it's at least not *totally* trivial to
216        # crash from bad marshal data
217        for c in [chr(i) for i in range(256)]:
218            try:
219                marshal.loads(c)
220            except Exception:
221                pass
222
223    def test_loads_recursion(self):
224        s = 'c' + ('X' * 4*4) + '{' * 2**20
225        self.assertRaises(ValueError, marshal.loads, s)
226
227    def test_recursion_limit(self):
228        # Create a deeply nested structure.
229        head = last = []
230        # The max stack depth should match the value in Python/marshal.c.
231        MAX_MARSHAL_STACK_DEPTH = 2000
232        for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
233            last.append([0])
234            last = last[-1]
235
236        # Verify we don't blow out the stack with dumps/load.
237        data = marshal.dumps(head)
238        new_head = marshal.loads(data)
239        # Don't use == to compare objects, it can exceed the recursion limit.
240        self.assertEqual(len(new_head), len(head))
241        self.assertEqual(len(new_head[0]), len(head[0]))
242        self.assertEqual(len(new_head[-1]), len(head[-1]))
243
244        last.append([0])
245        self.assertRaises(ValueError, marshal.dumps, head)
246
247    def test_exact_type_match(self):
248        # Former bug:
249        #   >>> class Int(int): pass
250        #   >>> type(loads(dumps(Int())))
251        #   <type 'int'>
252        for typ in (int, long, float, complex, tuple, list, dict, set, frozenset):
253            # Note: str and unicode sublclasses are not tested because they get handled
254            # by marshal's routines for objects supporting the buffer API.
255            subtyp = type('subtyp', (typ,), {})
256            self.assertRaises(ValueError, marshal.dumps, subtyp())
257
258    # Issue #1792 introduced a change in how marshal increases the size of its
259    # internal buffer; this test ensures that the new code is exercised.
260    def test_large_marshal(self):
261        size = int(1e6)
262        testString = 'abc' * size
263        marshal.dumps(testString)
264
265    def test_invalid_longs(self):
266        # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
267        invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00'
268        self.assertRaises(ValueError, marshal.loads, invalid_string)
269
270
271def test_main():
272    test_support.run_unittest(IntTestCase,
273                              FloatTestCase,
274                              StringTestCase,
275                              CodeTestCase,
276                              ContainerTestCase,
277                              ExceptionTestCase,
278                              BugsTestCase)
279
280if __name__ == "__main__":
281    test_main()