Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: third_party/twisted_8_1/twisted/test/test_jelly.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2008 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5 """
6 Test cases for L{jelly} object serialization.
7 """
8
9 import datetime
10
11 try:
12 import decimal
13 except ImportError:
14 decimal = None
15
16 from twisted.spread import jelly, pb
17 from twisted.python.compat import set, frozenset
18
19 from twisted.trial import unittest
20
21
22
23 class TestNode(object, jelly.Jellyable):
24 """
25 An object to test jellyfying of new style class instances.
26 """
27 classAttr = 4
28
29 def __init__(self, parent=None):
30 if parent:
31 self.id = parent.id + 1
32 parent.children.append(self)
33 else:
34 self.id = 1
35 self.parent = parent
36 self.children = []
37
38
39
40 class A:
41 """
42 Dummy class.
43 """
44
45 def amethod(self):
46 """
47 Method tp be used in serialization tests.
48 """
49
50
51
52 def afunc(self):
53 """
54 A dummy function to test function serialization.
55 """
56
57
58
59 class B:
60 """
61 Dummy class.
62 """
63
64 def bmethod(self):
65 """
66 Method to be used in serialization tests.
67 """
68
69
70
71 class C:
72 """
73 Dummy class.
74 """
75
76 def cmethod(self):
77 """
78 Method to be used in serialization tests.
79 """
80
81
82
83 class D(object):
84 """
85 Dummy new-style class.
86 """
87
88
89
90 class SimpleJellyTest:
91 def __init__(self, x, y):
92 self.x = x
93 self.y = y
94
95 def isTheSameAs(self, other):
96 return self.__dict__ == other.__dict__
97
98
99
100 class JellyTestCase(unittest.TestCase):
101 """
102 Testcases for L{jelly} module serialization.
103
104 @cvar decimalData: serialized version of decimal data, to be used in tests.
105 @type decimalData: C{list}
106 """
107
108 def _testSecurity(self, inputList, atom):
109 """
110 Helper test method to test security options for a type.
111
112 @param inputList: a sample input for the type.
113 @param inputList: C{list}
114
115 @param atom: atom identifier for the type.
116 @type atom: C{str}
117 """
118 c = jelly.jelly(inputList)
119 taster = jelly.SecurityOptions()
120 taster.allowBasicTypes()
121 # By default, it should succeed
122 jelly.unjelly(c, taster)
123 taster.allowedTypes.pop(atom)
124 # But it should raise an exception when disallowed
125 self.assertRaises(jelly.InsecureJelly, jelly.unjelly, c, taster)
126
127
128 def test_methodSelfIdentity(self):
129 a = A()
130 b = B()
131 a.bmethod = b.bmethod
132 b.a = a
133 im_ = jelly.unjelly(jelly.jelly(b)).a.bmethod
134 self.assertEquals(im_.im_class, im_.im_self.__class__)
135
136
137 def test_methodsNotSelfIdentity(self):
138 """
139 If a class change after an instance has been created, L{jelly.unjelly}
140 shoud raise a C{TypeError} when trying to unjelly the instance.
141 """
142 a = A()
143 b = B()
144 c = C()
145 a.bmethod = c.cmethod
146 b.a = a
147 savecmethod = C.cmethod
148 del C.cmethod
149 try:
150 self.assertRaises(TypeError, jelly.unjelly, jelly.jelly(b))
151 finally:
152 C.cmethod = savecmethod
153
154
155 def test_newStyle(self):
156 n = D()
157 n.x = 1
158 n2 = D()
159 n.n2 = n2
160 n.n3 = n2
161 c = jelly.jelly(n)
162 m = jelly.unjelly(c)
163 self.assertIsInstance(m, D)
164 self.assertIdentical(m.n2, m.n3)
165
166
167 def test_dateTime(self):
168 dtn = datetime.datetime.now()
169 dtd = datetime.datetime.now() - dtn
170 input = [dtn, dtd]
171 c = jelly.jelly(input)
172 output = jelly.unjelly(c)
173 self.assertEquals(input, output)
174 self.assertNotIdentical(input, output)
175
176
177 def test_decimal(self):
178 """
179 Jellying L{decimal.Decimal} instances and then unjellying the result
180 should produce objects which represent the values of the original
181 inputs.
182 """
183 inputList = [decimal.Decimal('9.95'),
184 decimal.Decimal(0),
185 decimal.Decimal(123456),
186 decimal.Decimal('-78.901')]
187 c = jelly.jelly(inputList)
188 output = jelly.unjelly(c)
189 self.assertEquals(inputList, output)
190 self.assertNotIdentical(inputList, output)
191
192
193 decimalData = ['list', ['decimal', 995, -2], ['decimal', 0, 0],
194 ['decimal', 123456, 0], ['decimal', -78901, -3]]
195
196
197 def test_decimalUnjelly(self):
198 """
199 Unjellying the s-expressions produced by jelly for L{decimal.Decimal}
200 instances should result in L{decimal.Decimal} instances with the values
201 represented by the s-expressions.
202
203 This test also verifies that C{self.decimalData} contains valid jellied
204 data. This is important since L{test_decimalMissing} re-uses
205 C{self.decimalData} and is expected to be unable to produce
206 L{decimal.Decimal} instances even though the s-expression correctly
207 represents a list of them.
208 """
209 expected = [decimal.Decimal('9.95'),
210 decimal.Decimal(0),
211 decimal.Decimal(123456),
212 decimal.Decimal('-78.901')]
213 output = jelly.unjelly(self.decimalData)
214 self.assertEquals(output, expected)
215
216
217 def test_decimalMissing(self):
218 """
219 If decimal is unavailable on the unjelly side, L{jelly.unjelly} should
220 gracefully return L{jelly.Unpersistable} objects.
221 """
222 self.patch(jelly, 'decimal', None)
223 output = jelly.unjelly(self.decimalData)
224 self.assertEquals(len(output), 4)
225 for i in range(4):
226 self.assertIsInstance(output[i], jelly.Unpersistable)
227 self.assertEquals(output[0].reason,
228 "Could not unpersist decimal: 9.95")
229 self.assertEquals(output[1].reason,
230 "Could not unpersist decimal: 0")
231 self.assertEquals(output[2].reason,
232 "Could not unpersist decimal: 123456")
233 self.assertEquals(output[3].reason,
234 "Could not unpersist decimal: -78.901")
235
236
237 def test_decimalSecurity(self):
238 """
239 By default, C{decimal} objects should be allowed by
240 L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
241 L{jelly.InsecureJelly} when trying to unjelly it.
242 """
243 inputList = [decimal.Decimal('9.95')]
244 self._testSecurity(inputList, "decimal")
245
246 if decimal is None:
247 skipReason = "decimal not available"
248 test_decimal.skip = skipReason
249 test_decimalUnjelly.skip = skipReason
250 test_decimalSecurity.skip = skipReason
251
252
253 def test_set(self):
254 """
255 Jellying C{set} instances and then unjellying the result
256 should produce objects which represent the values of the original
257 inputs.
258 """
259 inputList = [set([1, 2, 3])]
260 output = jelly.unjelly(jelly.jelly(inputList))
261 self.assertEquals(inputList, output)
262 self.assertNotIdentical(inputList, output)
263
264
265 def test_frozenset(self):
266 """
267 Jellying C{frozenset} instances and then unjellying the result
268 should produce objects which represent the values of the original
269 inputs.
270 """
271 inputList = [frozenset([1, 2, 3])]
272 output = jelly.unjelly(jelly.jelly(inputList))
273 self.assertEquals(inputList, output)
274 self.assertNotIdentical(inputList, output)
275
276
277 def test_setSecurity(self):
278 """
279 By default, C{set} objects should be allowed by
280 L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
281 L{jelly.InsecureJelly} when trying to unjelly it.
282 """
283 inputList = [set([1, 2, 3])]
284 self._testSecurity(inputList, "set")
285
286
287 def test_frozensetSecurity(self):
288 """
289 By default, C{frozenset} objects should be allowed by
290 L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
291 L{jelly.InsecureJelly} when trying to unjelly it.
292 """
293 inputList = [frozenset([1, 2, 3])]
294 self._testSecurity(inputList, "frozenset")
295
296
297 def test_oldSets(self):
298 """
299 Test jellying C{sets.Set}: it should serialize to the same thing as
300 C{set} jelly, and be unjellied as C{set} if available.
301 """
302 inputList = [jelly._sets.Set([1, 2, 3])]
303 inputJelly = jelly.jelly(inputList)
304 self.assertEquals(inputJelly, jelly.jelly([set([1, 2, 3])]))
305 output = jelly.unjelly(inputJelly)
306 # Even if the class is different, it should coerce to the same list
307 self.assertEquals(list(inputList[0]), list(output[0]))
308 if set is jelly._sets.Set:
309 self.assertIsInstance(output[0], jelly._sets.Set)
310 else:
311 self.assertIsInstance(output[0], set)
312
313
314 def test_oldImmutableSets(self):
315 """
316 Test jellying C{sets.ImmutableSet}: it should serialize to the same
317 thing as C{frozenset} jelly, and be unjellied as C{frozenset} if
318 available.
319 """
320 inputList = [jelly._sets.ImmutableSet([1, 2, 3])]
321 inputJelly = jelly.jelly(inputList)
322 self.assertEquals(inputJelly, jelly.jelly([frozenset([1, 2, 3])]))
323 output = jelly.unjelly(inputJelly)
324 # Even if the class is different, it should coerce to the same list
325 self.assertEquals(list(inputList[0]), list(output[0]))
326 if frozenset is jelly._sets.ImmutableSet:
327 self.assertIsInstance(output[0], jelly._sets.ImmutableSet)
328 else:
329 self.assertIsInstance(output[0], frozenset)
330
331
332 def test_simple(self):
333 """
334 Simplest test case.
335 """
336 self.failUnless(SimpleJellyTest('a', 'b').isTheSameAs(
337 SimpleJellyTest('a', 'b')))
338 a = SimpleJellyTest(1, 2)
339 cereal = jelly.jelly(a)
340 b = jelly.unjelly(cereal)
341 self.failUnless(a.isTheSameAs(b))
342
343
344 def test_identity(self):
345 """
346 Test to make sure that objects retain identity properly.
347 """
348 x = []
349 y = (x)
350 x.append(y)
351 x.append(y)
352 self.assertIdentical(x[0], x[1])
353 self.assertIdentical(x[0][0], x)
354 s = jelly.jelly(x)
355 z = jelly.unjelly(s)
356 self.assertIdentical(z[0], z[1])
357 self.assertIdentical(z[0][0], z)
358
359
360 def test_unicode(self):
361 x = unicode('blah')
362 y = jelly.unjelly(jelly.jelly(x))
363 self.assertEquals(x, y)
364 self.assertEquals(type(x), type(y))
365
366
367 def test_stressReferences(self):
368 reref = []
369 toplevelTuple = ({'list': reref}, reref)
370 reref.append(toplevelTuple)
371 s = jelly.jelly(toplevelTuple)
372 z = jelly.unjelly(s)
373 self.assertIdentical(z[0]['list'], z[1])
374 self.assertIdentical(z[0]['list'][0], z)
375
376
377 def test_moreReferences(self):
378 a = []
379 t = (a,)
380 a.append((t,))
381 s = jelly.jelly(t)
382 z = jelly.unjelly(s)
383 self.assertIdentical(z[0][0][0], z)
384
385
386 def test_typeSecurity(self):
387 """
388 Test for type-level security of serialization.
389 """
390 taster = jelly.SecurityOptions()
391 dct = jelly.jelly({})
392 self.assertRaises(jelly.InsecureJelly, jelly.unjelly, dct, taster)
393
394
395 def test_newStyleClasses(self):
396 j = jelly.jelly(D)
397 uj = jelly.unjelly(D)
398 self.assertIdentical(D, uj)
399
400
401 def test_lotsaTypes(self):
402 """
403 Test for all types currently supported in jelly
404 """
405 a = A()
406 jelly.unjelly(jelly.jelly(a))
407 jelly.unjelly(jelly.jelly(a.amethod))
408 items = [afunc, [1, 2, 3], not bool(1), bool(1), 'test', 20.3,
409 (1, 2, 3), None, A, unittest, {'a': 1}, A.amethod]
410 for i in items:
411 self.assertEquals(i, jelly.unjelly(jelly.jelly(i)))
412
413
414 def test_setState(self):
415 global TupleState
416 class TupleState:
417 def __init__(self, other):
418 self.other = other
419 def __getstate__(self):
420 return (self.other,)
421 def __setstate__(self, state):
422 self.other = state[0]
423 def __hash__(self):
424 return hash(self.other)
425 a = A()
426 t1 = TupleState(a)
427 t2 = TupleState(a)
428 t3 = TupleState((t1, t2))
429 d = {t1: t1, t2: t2, t3: t3, "t3": t3}
430 t3prime = jelly.unjelly(jelly.jelly(d))["t3"]
431 self.assertIdentical(t3prime.other[0].other, t3prime.other[1].other)
432
433
434 def test_classSecurity(self):
435 """
436 Test for class-level security of serialization.
437 """
438 taster = jelly.SecurityOptions()
439 taster.allowInstancesOf(A, B)
440 a = A()
441 b = B()
442 c = C()
443 # add a little complexity to the data
444 a.b = b
445 a.c = c
446 # and a backreference
447 a.x = b
448 b.c = c
449 # first, a friendly insecure serialization
450 friendly = jelly.jelly(a, taster)
451 x = jelly.unjelly(friendly, taster)
452 self.assertIsInstance(x.c, jelly.Unpersistable)
453 # now, a malicious one
454 mean = jelly.jelly(a)
455 self.assertRaises(jelly.InsecureJelly, jelly.unjelly, mean, taster)
456 self.assertIdentical(x.x, x.b, "Identity mismatch")
457 # test class serialization
458 friendly = jelly.jelly(A, taster)
459 x = jelly.unjelly(friendly, taster)
460 self.assertIdentical(x, A, "A came back: %s" % x)
461
462
463 def test_unjellyable(self):
464 """
465 Test that if Unjellyable is used to deserialize a jellied object,
466 state comes out right.
467 """
468 class JellyableTestClass(jelly.Jellyable):
469 pass
470 jelly.setUnjellyableForClass(JellyableTestClass, jelly.Unjellyable)
471 input = JellyableTestClass()
472 input.attribute = 'value'
473 output = jelly.unjelly(jelly.jelly(input))
474 self.assertEquals(output.attribute, 'value')
475 self.assertIsInstance(output, jelly.Unjellyable)
476
477
478 def test_persistentStorage(self):
479 perst = [{}, 1]
480 def persistentStore(obj, jel, perst = perst):
481 perst[1] = perst[1] + 1
482 perst[0][perst[1]] = obj
483 return str(perst[1])
484
485 def persistentLoad(pidstr, unj, perst = perst):
486 pid = int(pidstr)
487 return perst[0][pid]
488
489 a = SimpleJellyTest(1, 2)
490 b = SimpleJellyTest(3, 4)
491 c = SimpleJellyTest(5, 6)
492
493 a.b = b
494 a.c = c
495 c.b = b
496
497 jel = jelly.jelly(a, persistentStore = persistentStore)
498 x = jelly.unjelly(jel, persistentLoad = persistentLoad)
499
500 self.assertIdentical(x.b, x.c.b)
501 self.failUnless(perst[0], "persistentStore was not called.")
502 self.assertIdentical(x.b, a.b, "Persistent storage identity failure.")
503
504
505 def test_newStyleClassesAttributes(self):
506 n = TestNode()
507 n1 = TestNode(n)
508 n11 = TestNode(n1)
509 n2 = TestNode(n)
510 # Jelly it
511 jel = jelly.jelly(n)
512 m = jelly.unjelly(jel)
513 # Check that it has been restored ok
514 self._check_newstyle(n, m)
515
516
517 def _check_newstyle(self, a, b):
518 self.assertEqual(a.id, b.id)
519 self.assertEqual(a.classAttr, 4)
520 self.assertEqual(b.classAttr, 4)
521 self.assertEqual(len(a.children), len(b.children))
522 for x, y in zip(a.children, b.children):
523 self._check_newstyle(x, y)
524
525
526
527 class ClassA(pb.Copyable, pb.RemoteCopy):
528 def __init__(self):
529 self.ref = ClassB(self)
530
531
532
533 class ClassB(pb.Copyable, pb.RemoteCopy):
534 def __init__(self, ref):
535 self.ref = ref
536
537
538
539 class CircularReferenceTestCase(unittest.TestCase):
540 """
541 Tests for circular references handling in the jelly/unjelly process.
542 """
543
544 def test_simpleCircle(self):
545 jelly.setUnjellyableForClass(ClassA, ClassA)
546 jelly.setUnjellyableForClass(ClassB, ClassB)
547 a = jelly.unjelly(jelly.jelly(ClassA()))
548 self.assertIdentical(a.ref.ref, a,
549 "Identity not preserved in circular reference")
550
551
552 def test_circleWithInvoker(self):
553 class DummyInvokerClass:
554 pass
555 dummyInvoker = DummyInvokerClass()
556 dummyInvoker.serializingPerspective = None
557 a0 = ClassA()
558 jelly.setUnjellyableForClass(ClassA, ClassA)
559 jelly.setUnjellyableForClass(ClassB, ClassB)
560 j = jelly.jelly(a0, invoker=dummyInvoker)
561 a1 = jelly.unjelly(j)
562 self.failUnlessIdentical(a1.ref.ref, a1,
563 "Identity not preserved in circular reference")
564
565
566 def test_set(self):
567 """
568 Check that a C{set} can contain a circular reference and be serialized
569 and unserialized without losing the reference.
570 """
571 s = set()
572 a = SimpleJellyTest(s, None)
573 s.add(a)
574 res = jelly.unjelly(jelly.jelly(a))
575 self.assertIsInstance(res.x, set)
576 self.assertEquals(list(res.x), [res])
577
578
579 def test_frozenset(self):
580 """
581 Check that a C{frozenset} can contain a circular reference and be
582 serializeserialized without losing the reference.
583 """
584 a = SimpleJellyTest(None, None)
585 s = frozenset([a])
586 a.x = s
587 res = jelly.unjelly(jelly.jelly(a))
588 self.assertIsInstance(res.x, frozenset)
589 self.assertEquals(list(res.x), [res])
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/test/test_iutils.py ('k') | third_party/twisted_8_1/twisted/test/test_journal.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698