Home | History | Annotate | Download | only in test
      1 #!/usr/bin/env python

      2 # -*- coding: iso-8859-1 -*-

      3 
      4 from test import test_support
      5 import marshal
      6 import sys
      7 import unittest
      8 import os
      9 
     10 class 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 
     59 class 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 
    107 class 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             with test_support.check_py3k_warnings(("buffer.. not supported",
    133                                                      DeprecationWarning)):
    134                 b = buffer(s)
    135             new = marshal.loads(marshal.dumps(b))
    136             self.assertEqual(s, new)
    137             marshal.dump(b, file(test_support.TESTFN, "wb"))
    138             new = marshal.load(file(test_support.TESTFN, "rb"))
    139             self.assertEqual(s, new)
    140         os.unlink(test_support.TESTFN)
    141 
    142 class ExceptionTestCase(unittest.TestCase):
    143     def test_exceptions(self):
    144         new = marshal.loads(marshal.dumps(StopIteration))
    145         self.assertEqual(StopIteration, new)
    146 
    147 class CodeTestCase(unittest.TestCase):
    148     def test_code(self):
    149         co = ExceptionTestCase.test_exceptions.func_code
    150         new = marshal.loads(marshal.dumps(co))
    151         self.assertEqual(co, new)
    152 
    153 class ContainerTestCase(unittest.TestCase):
    154     d = {'astring': 'foo (at] bar.baz.spam',
    155          'afloat': 7283.43,
    156          'anint': 2**20,
    157          'ashortlong': 2L,
    158          'alist': ['.zyx.41'],
    159          'atuple': ('.zyx.41',)*10,
    160          'aboolean': False,
    161          'aunicode': u"Andr Previn"
    162          }
    163     def test_dict(self):
    164         new = marshal.loads(marshal.dumps(self.d))
    165         self.assertEqual(self.d, new)
    166         marshal.dump(self.d, file(test_support.TESTFN, "wb"))
    167         new = marshal.load(file(test_support.TESTFN, "rb"))
    168         self.assertEqual(self.d, new)
    169         os.unlink(test_support.TESTFN)
    170 
    171     def test_list(self):
    172         lst = self.d.items()
    173         new = marshal.loads(marshal.dumps(lst))
    174         self.assertEqual(lst, new)
    175         marshal.dump(lst, file(test_support.TESTFN, "wb"))
    176         new = marshal.load(file(test_support.TESTFN, "rb"))
    177         self.assertEqual(lst, new)
    178         os.unlink(test_support.TESTFN)
    179 
    180     def test_tuple(self):
    181         t = tuple(self.d.keys())
    182         new = marshal.loads(marshal.dumps(t))
    183         self.assertEqual(t, new)
    184         marshal.dump(t, file(test_support.TESTFN, "wb"))
    185         new = marshal.load(file(test_support.TESTFN, "rb"))
    186         self.assertEqual(t, new)
    187         os.unlink(test_support.TESTFN)
    188 
    189     def test_sets(self):
    190         for constructor in (set, frozenset):
    191             t = constructor(self.d.keys())
    192             new = marshal.loads(marshal.dumps(t))
    193             self.assertEqual(t, new)
    194             self.assertTrue(isinstance(new, constructor))
    195             self.assertNotEqual(id(t), id(new))
    196             marshal.dump(t, file(test_support.TESTFN, "wb"))
    197             new = marshal.load(file(test_support.TESTFN, "rb"))
    198             self.assertEqual(t, new)
    199             os.unlink(test_support.TESTFN)
    200 
    201 class BugsTestCase(unittest.TestCase):
    202     def test_bug_5888452(self):
    203         # Simple-minded check for SF 588452: Debug build crashes

    204         marshal.dumps([128] * 1000)
    205 
    206     def test_patch_873224(self):
    207         self.assertRaises(Exception, marshal.loads, '0')
    208         self.assertRaises(Exception, marshal.loads, 'f')
    209         self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1])
    210 
    211     def test_version_argument(self):
    212         # Python 2.4.0 crashes for any call to marshal.dumps(x, y)

    213         self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5)
    214         self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5)
    215 
    216     def test_fuzz(self):
    217         # simple test that it's at least not *totally* trivial to

    218         # crash from bad marshal data

    219         for c in [chr(i) for i in range(256)]:
    220             try:
    221                 marshal.loads(c)
    222             except Exception:
    223                 pass
    224 
    225     def test_loads_recursion(self):
    226         s = 'c' + ('X' * 4*4) + '{' * 2**20
    227         self.assertRaises(ValueError, marshal.loads, s)
    228 
    229     def test_recursion_limit(self):
    230         # Create a deeply nested structure.

    231         head = last = []
    232         # The max stack depth should match the value in Python/marshal.c.

    233         MAX_MARSHAL_STACK_DEPTH = 2000
    234         for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
    235             last.append([0])
    236             last = last[-1]
    237 
    238         # Verify we don't blow out the stack with dumps/load.

    239         data = marshal.dumps(head)
    240         new_head = marshal.loads(data)
    241         # Don't use == to compare objects, it can exceed the recursion limit.

    242         self.assertEqual(len(new_head), len(head))
    243         self.assertEqual(len(new_head[0]), len(head[0]))
    244         self.assertEqual(len(new_head[-1]), len(head[-1]))
    245 
    246         last.append([0])
    247         self.assertRaises(ValueError, marshal.dumps, head)
    248 
    249     def test_exact_type_match(self):
    250         # Former bug:

    251         #   >>> class Int(int): pass

    252         #   >>> type(loads(dumps(Int())))

    253         #   <type 'int'>

    254         for typ in (int, long, float, complex, tuple, list, dict, set, frozenset):
    255             # Note: str and unicode subclasses are not tested because they get handled

    256             # by marshal's routines for objects supporting the buffer API.

    257             subtyp = type('subtyp', (typ,), {})
    258             self.assertRaises(ValueError, marshal.dumps, subtyp())
    259 
    260     # Issue #1792 introduced a change in how marshal increases the size of its

    261     # internal buffer; this test ensures that the new code is exercised.

    262     def test_large_marshal(self):
    263         size = int(1e6)
    264         testString = 'abc' * size
    265         marshal.dumps(testString)
    266 
    267     def test_invalid_longs(self):
    268         # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs

    269         invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00'
    270         self.assertRaises(ValueError, marshal.loads, invalid_string)
    271 
    272 
    273 def test_main():
    274     test_support.run_unittest(IntTestCase,
    275                               FloatTestCase,
    276                               StringTestCase,
    277                               CodeTestCase,
    278                               ContainerTestCase,
    279                               ExceptionTestCase,
    280                               BugsTestCase)
    281 
    282 if __name__ == "__main__":
    283     test_main()
    284