blob: 59fa3eb5ab4d15223f20c11a7827d4d3425caca7 [file] [log] [blame]
Skip Montanaroc1b41542003-08-02 15:02:33 +00001# -*- coding: iso-8859-1 -*-
2
3from test import test_support
Tim Peters82112372001-08-29 02:28:42 +00004import marshal
5import sys
Skip Montanaroc1b41542003-08-02 15:02:33 +00006import unittest
7import os
Tim Peters82112372001-08-29 02:28:42 +00008
Skip Montanaroc1b41542003-08-02 15:02:33 +00009class IntTestCase(unittest.TestCase):
10 def test_ints(self):
11 # Test the full range of Python ints.
12 n = sys.maxint
13 while n:
14 for expected in (-n, n):
15 s = marshal.dumps(expected)
16 got = marshal.loads(s)
17 self.assertEqual(expected, got)
18 marshal.dump(expected, file(test_support.TESTFN, "wb"))
19 got = marshal.load(file(test_support.TESTFN, "rb"))
20 self.assertEqual(expected, got)
21 n = n >> 1
22 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +000023
Skip Montanaroc1b41542003-08-02 15:02:33 +000024 def test_int64(self):
25 # Simulate int marshaling on a 64-bit box. This is most interesting if
26 # we're running the test on a 32-bit box, of course.
27
28 def to_little_endian_string(value, nbytes):
29 bytes = []
30 for i in range(nbytes):
31 bytes.append(chr(value & 0xff))
32 value >>= 8
33 return ''.join(bytes)
34
35 maxint64 = (1L << 63) - 1
36 minint64 = -maxint64-1
37
38 for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
39 while base:
40 s = 'I' + to_little_endian_string(base, 8)
41 got = marshal.loads(s)
42 self.assertEqual(base, got)
43 if base == -1: # a fixed-point for shifting right 1
44 base = 0
45 else:
46 base >>= 1
47
48 def test_bool(self):
49 for b in (True, False):
50 new = marshal.loads(marshal.dumps(b))
51 self.assertEqual(b, new)
52 self.assertEqual(type(b), type(new))
53 marshal.dump(b, file(test_support.TESTFN, "wb"))
54 new = marshal.load(file(test_support.TESTFN, "rb"))
55 self.assertEqual(b, new)
56 self.assertEqual(type(b), type(new))
Tim Peters58eb11c2004-01-18 20:29:55 +000057
Skip Montanaroc1b41542003-08-02 15:02:33 +000058class FloatTestCase(unittest.TestCase):
59 def test_floats(self):
60 # Test a few floats
61 small = 1e-25
62 n = sys.maxint * 3.7e250
63 while n > small:
64 for expected in (-n, n):
65 f = float(expected)
66 s = marshal.dumps(f)
67 got = marshal.loads(s)
68 self.assertEqual(f, got)
69 marshal.dump(f, file(test_support.TESTFN, "wb"))
70 got = marshal.load(file(test_support.TESTFN, "rb"))
71 self.assertEqual(f, got)
72 n /= 123.4567
73
74 f = 0.0
Michael W. Hudsondf888462005-06-03 14:41:55 +000075 s = marshal.dumps(f, 2)
Tim Peters82112372001-08-29 02:28:42 +000076 got = marshal.loads(s)
Skip Montanaroc1b41542003-08-02 15:02:33 +000077 self.assertEqual(f, got)
Michael W. Hudsondf888462005-06-03 14:41:55 +000078 # and with version <= 1 (floats marshalled differently then)
79 s = marshal.dumps(f, 1)
Tim Peters5d36a552005-06-03 22:40:27 +000080 got = marshal.loads(s)
81 self.assertEqual(f, got)
Tim Peters82112372001-08-29 02:28:42 +000082
Skip Montanaroc1b41542003-08-02 15:02:33 +000083 n = sys.maxint * 3.7e-250
84 while n < small:
85 for expected in (-n, n):
86 f = float(expected)
Tim Peters5d36a552005-06-03 22:40:27 +000087
Skip Montanaroc1b41542003-08-02 15:02:33 +000088 s = marshal.dumps(f)
89 got = marshal.loads(s)
90 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +000091
Michael W. Hudsondf888462005-06-03 14:41:55 +000092 s = marshal.dumps(f, 1)
93 got = marshal.loads(s)
94 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +000095
Skip Montanaroc1b41542003-08-02 15:02:33 +000096 marshal.dump(f, file(test_support.TESTFN, "wb"))
97 got = marshal.load(file(test_support.TESTFN, "rb"))
98 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +000099
Michael W. Hudsondf888462005-06-03 14:41:55 +0000100 marshal.dump(f, file(test_support.TESTFN, "wb"), 1)
101 got = marshal.load(file(test_support.TESTFN, "rb"))
102 self.assertEqual(f, got)
Skip Montanaroc1b41542003-08-02 15:02:33 +0000103 n *= 123.4567
104 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000105
Skip Montanaroc1b41542003-08-02 15:02:33 +0000106class StringTestCase(unittest.TestCase):
107 def test_unicode(self):
108 for s in [u"", u"Andrè Previn", u"abc", u" "*10000]:
109 new = marshal.loads(marshal.dumps(s))
110 self.assertEqual(s, new)
111 self.assertEqual(type(s), type(new))
112 marshal.dump(s, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000113 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000114 self.assertEqual(s, new)
115 self.assertEqual(type(s), type(new))
116 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000117
Skip Montanaroc1b41542003-08-02 15:02:33 +0000118 def test_string(self):
119 for s in ["", "Andrè Previn", "abc", " "*10000]:
120 new = marshal.loads(marshal.dumps(s))
121 self.assertEqual(s, new)
122 self.assertEqual(type(s), type(new))
123 marshal.dump(s, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000124 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000125 self.assertEqual(s, new)
126 self.assertEqual(type(s), type(new))
127 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000128
Skip Montanaroc1b41542003-08-02 15:02:33 +0000129 def test_buffer(self):
130 for s in ["", "Andrè Previn", "abc", " "*10000]:
Florent Xicluna07627882010-03-21 01:14:24 +0000131 with test_support.check_py3k_warnings(("buffer.. not supported",
132 DeprecationWarning)):
133 b = buffer(s)
Skip Montanaroc1b41542003-08-02 15:02:33 +0000134 new = marshal.loads(marshal.dumps(b))
135 self.assertEqual(s, new)
136 marshal.dump(b, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000137 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000138 self.assertEqual(s, new)
139 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000140
Skip Montanaroc1b41542003-08-02 15:02:33 +0000141class ExceptionTestCase(unittest.TestCase):
142 def test_exceptions(self):
143 new = marshal.loads(marshal.dumps(StopIteration))
144 self.assertEqual(StopIteration, new)
Thomas Heller3e1c18a2002-07-30 11:40:57 +0000145
Skip Montanaroc1b41542003-08-02 15:02:33 +0000146class CodeTestCase(unittest.TestCase):
147 def test_code(self):
148 co = ExceptionTestCase.test_exceptions.func_code
149 new = marshal.loads(marshal.dumps(co))
150 self.assertEqual(co, new)
151
152class ContainerTestCase(unittest.TestCase):
153 d = {'astring': 'foo@bar.baz.spam',
154 'afloat': 7283.43,
155 'anint': 2**20,
156 'ashortlong': 2L,
157 'alist': ['.zyx.41'],
158 'atuple': ('.zyx.41',)*10,
159 'aboolean': False,
160 'aunicode': u"Andrè Previn"
161 }
162 def test_dict(self):
163 new = marshal.loads(marshal.dumps(self.d))
164 self.assertEqual(self.d, new)
165 marshal.dump(self.d, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000166 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000167 self.assertEqual(self.d, new)
168 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000169
Skip Montanaroc1b41542003-08-02 15:02:33 +0000170 def test_list(self):
171 lst = self.d.items()
172 new = marshal.loads(marshal.dumps(lst))
173 self.assertEqual(lst, new)
174 marshal.dump(lst, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000175 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000176 self.assertEqual(lst, new)
177 os.unlink(test_support.TESTFN)
178
179 def test_tuple(self):
180 t = tuple(self.d.keys())
181 new = marshal.loads(marshal.dumps(t))
182 self.assertEqual(t, new)
183 marshal.dump(t, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000184 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000185 self.assertEqual(t, new)
186 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000187
Raymond Hettingera422c342005-01-11 03:03:27 +0000188 def test_sets(self):
189 for constructor in (set, frozenset):
190 t = constructor(self.d.keys())
191 new = marshal.loads(marshal.dumps(t))
192 self.assertEqual(t, new)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000193 self.assertTrue(isinstance(new, constructor))
Raymond Hettingera422c342005-01-11 03:03:27 +0000194 self.assertNotEqual(id(t), id(new))
195 marshal.dump(t, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000196 new = marshal.load(file(test_support.TESTFN, "rb"))
Raymond Hettingera422c342005-01-11 03:03:27 +0000197 self.assertEqual(t, new)
198 os.unlink(test_support.TESTFN)
199
Skip Montanaroc1b41542003-08-02 15:02:33 +0000200class BugsTestCase(unittest.TestCase):
201 def test_bug_5888452(self):
202 # Simple-minded check for SF 588452: Debug build crashes
203 marshal.dumps([128] * 1000)
204
Armin Rigo01ab2792004-03-26 15:09:27 +0000205 def test_patch_873224(self):
206 self.assertRaises(Exception, marshal.loads, '0')
207 self.assertRaises(Exception, marshal.loads, 'f')
208 self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1])
209
Armin Rigo2ccea172004-12-20 12:25:57 +0000210 def test_version_argument(self):
211 # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
Ezio Melotti2623a372010-11-21 13:34:58 +0000212 self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5)
213 self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5)
Armin Rigo2ccea172004-12-20 12:25:57 +0000214
Michael W. Hudsonf2ca5af2005-06-13 18:28:46 +0000215 def test_fuzz(self):
216 # simple test that it's at least not *totally* trivial to
217 # crash from bad marshal data
218 for c in [chr(i) for i in range(256)]:
219 try:
220 marshal.loads(c)
221 except Exception:
222 pass
223
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000224 def test_loads_recursion(self):
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000225 s = 'c' + ('X' * 4*4) + '{' * 2**20
226 self.assertRaises(ValueError, marshal.loads, s)
227
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000228 def test_recursion_limit(self):
229 # Create a deeply nested structure.
230 head = last = []
231 # The max stack depth should match the value in Python/marshal.c.
232 MAX_MARSHAL_STACK_DEPTH = 2000
233 for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
234 last.append([0])
235 last = last[-1]
236
237 # Verify we don't blow out the stack with dumps/load.
238 data = marshal.dumps(head)
239 new_head = marshal.loads(data)
240 # Don't use == to compare objects, it can exceed the recursion limit.
241 self.assertEqual(len(new_head), len(head))
242 self.assertEqual(len(new_head[0]), len(head[0]))
243 self.assertEqual(len(new_head[-1]), len(head[-1]))
244
245 last.append([0])
246 self.assertRaises(ValueError, marshal.dumps, head)
247
Raymond Hettinger12e94202007-11-07 01:13:09 +0000248 def test_exact_type_match(self):
249 # Former bug:
250 # >>> class Int(int): pass
251 # >>> type(loads(dumps(Int())))
252 # <type 'int'>
253 for typ in (int, long, float, complex, tuple, list, dict, set, frozenset):
Ezio Melottic2077b02011-03-16 12:34:31 +0200254 # Note: str and unicode subclasses are not tested because they get handled
Raymond Hettinger12e94202007-11-07 01:13:09 +0000255 # by marshal's routines for objects supporting the buffer API.
256 subtyp = type('subtyp', (typ,), {})
257 self.assertRaises(ValueError, marshal.dumps, subtyp())
258
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000259 # Issue #1792 introduced a change in how marshal increases the size of its
260 # internal buffer; this test ensures that the new code is exercised.
261 def test_large_marshal(self):
262 size = int(1e6)
263 testString = 'abc' * size
264 marshal.dumps(testString)
265
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000266 def test_invalid_longs(self):
267 # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
268 invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00'
269 self.assertRaises(ValueError, marshal.loads, invalid_string)
270
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200271LARGE_SIZE = 2**31
272character_size = 4 if sys.maxunicode > 0xFFFF else 2
273pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
274
275@unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems")
276class LargeValuesTestCase(unittest.TestCase):
277 def check_unmarshallable(self, data):
278 f = open(test_support.TESTFN, 'wb')
279 self.addCleanup(test_support.unlink, test_support.TESTFN)
280 with f:
281 self.assertRaises(ValueError, marshal.dump, data, f)
282
283 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200284 def test_string(self, size):
285 self.check_unmarshallable('x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200286
287 @test_support.precisionbigmemtest(size=LARGE_SIZE,
Serhiy Storchakac9da0892014-01-10 13:36:56 +0200288 memuse=character_size + 2, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200289 def test_unicode(self, size):
290 self.check_unmarshallable(u'x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200291
292 @test_support.precisionbigmemtest(size=LARGE_SIZE,
293 memuse=pointer_size, dry_run=False)
294 def test_tuple(self, size):
295 self.check_unmarshallable((None,) * size)
296
297 @test_support.precisionbigmemtest(size=LARGE_SIZE,
298 memuse=pointer_size, dry_run=False)
299 def test_list(self, size):
300 self.check_unmarshallable([None] * size)
301
302 @test_support.precisionbigmemtest(size=LARGE_SIZE,
303 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
304 dry_run=False)
305 def test_set(self, size):
306 self.check_unmarshallable(set(range(size)))
307
308 @test_support.precisionbigmemtest(size=LARGE_SIZE,
309 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
310 dry_run=False)
311 def test_frozenset(self, size):
312 self.check_unmarshallable(frozenset(range(size)))
313
314 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
315 def test_bytearray(self, size):
316 self.check_unmarshallable(bytearray(size))
317
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000318
Skip Montanaroc1b41542003-08-02 15:02:33 +0000319def test_main():
320 test_support.run_unittest(IntTestCase,
321 FloatTestCase,
322 StringTestCase,
323 CodeTestCase,
324 ContainerTestCase,
325 ExceptionTestCase,
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200326 BugsTestCase,
327 LargeValuesTestCase,
328 )
Skip Montanaroc1b41542003-08-02 15:02:33 +0000329
330if __name__ == "__main__":
331 test_main()