| Index: third_party/twisted_8_1/twisted/test/test_jelly.py
|
| diff --git a/third_party/twisted_8_1/twisted/test/test_jelly.py b/third_party/twisted_8_1/twisted/test/test_jelly.py
|
| deleted file mode 100644
|
| index 4c90b9b0d7a8cc98cf3fec1a4961f06fe9bc0424..0000000000000000000000000000000000000000
|
| --- a/third_party/twisted_8_1/twisted/test/test_jelly.py
|
| +++ /dev/null
|
| @@ -1,589 +0,0 @@
|
| -# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
|
| -# See LICENSE for details.
|
| -
|
| -
|
| -"""
|
| -Test cases for L{jelly} object serialization.
|
| -"""
|
| -
|
| -import datetime
|
| -
|
| -try:
|
| - import decimal
|
| -except ImportError:
|
| - decimal = None
|
| -
|
| -from twisted.spread import jelly, pb
|
| -from twisted.python.compat import set, frozenset
|
| -
|
| -from twisted.trial import unittest
|
| -
|
| -
|
| -
|
| -class TestNode(object, jelly.Jellyable):
|
| - """
|
| - An object to test jellyfying of new style class instances.
|
| - """
|
| - classAttr = 4
|
| -
|
| - def __init__(self, parent=None):
|
| - if parent:
|
| - self.id = parent.id + 1
|
| - parent.children.append(self)
|
| - else:
|
| - self.id = 1
|
| - self.parent = parent
|
| - self.children = []
|
| -
|
| -
|
| -
|
| -class A:
|
| - """
|
| - Dummy class.
|
| - """
|
| -
|
| - def amethod(self):
|
| - """
|
| - Method tp be used in serialization tests.
|
| - """
|
| -
|
| -
|
| -
|
| -def afunc(self):
|
| - """
|
| - A dummy function to test function serialization.
|
| - """
|
| -
|
| -
|
| -
|
| -class B:
|
| - """
|
| - Dummy class.
|
| - """
|
| -
|
| - def bmethod(self):
|
| - """
|
| - Method to be used in serialization tests.
|
| - """
|
| -
|
| -
|
| -
|
| -class C:
|
| - """
|
| - Dummy class.
|
| - """
|
| -
|
| - def cmethod(self):
|
| - """
|
| - Method to be used in serialization tests.
|
| - """
|
| -
|
| -
|
| -
|
| -class D(object):
|
| - """
|
| - Dummy new-style class.
|
| - """
|
| -
|
| -
|
| -
|
| -class SimpleJellyTest:
|
| - def __init__(self, x, y):
|
| - self.x = x
|
| - self.y = y
|
| -
|
| - def isTheSameAs(self, other):
|
| - return self.__dict__ == other.__dict__
|
| -
|
| -
|
| -
|
| -class JellyTestCase(unittest.TestCase):
|
| - """
|
| - Testcases for L{jelly} module serialization.
|
| -
|
| - @cvar decimalData: serialized version of decimal data, to be used in tests.
|
| - @type decimalData: C{list}
|
| - """
|
| -
|
| - def _testSecurity(self, inputList, atom):
|
| - """
|
| - Helper test method to test security options for a type.
|
| -
|
| - @param inputList: a sample input for the type.
|
| - @param inputList: C{list}
|
| -
|
| - @param atom: atom identifier for the type.
|
| - @type atom: C{str}
|
| - """
|
| - c = jelly.jelly(inputList)
|
| - taster = jelly.SecurityOptions()
|
| - taster.allowBasicTypes()
|
| - # By default, it should succeed
|
| - jelly.unjelly(c, taster)
|
| - taster.allowedTypes.pop(atom)
|
| - # But it should raise an exception when disallowed
|
| - self.assertRaises(jelly.InsecureJelly, jelly.unjelly, c, taster)
|
| -
|
| -
|
| - def test_methodSelfIdentity(self):
|
| - a = A()
|
| - b = B()
|
| - a.bmethod = b.bmethod
|
| - b.a = a
|
| - im_ = jelly.unjelly(jelly.jelly(b)).a.bmethod
|
| - self.assertEquals(im_.im_class, im_.im_self.__class__)
|
| -
|
| -
|
| - def test_methodsNotSelfIdentity(self):
|
| - """
|
| - If a class change after an instance has been created, L{jelly.unjelly}
|
| - shoud raise a C{TypeError} when trying to unjelly the instance.
|
| - """
|
| - a = A()
|
| - b = B()
|
| - c = C()
|
| - a.bmethod = c.cmethod
|
| - b.a = a
|
| - savecmethod = C.cmethod
|
| - del C.cmethod
|
| - try:
|
| - self.assertRaises(TypeError, jelly.unjelly, jelly.jelly(b))
|
| - finally:
|
| - C.cmethod = savecmethod
|
| -
|
| -
|
| - def test_newStyle(self):
|
| - n = D()
|
| - n.x = 1
|
| - n2 = D()
|
| - n.n2 = n2
|
| - n.n3 = n2
|
| - c = jelly.jelly(n)
|
| - m = jelly.unjelly(c)
|
| - self.assertIsInstance(m, D)
|
| - self.assertIdentical(m.n2, m.n3)
|
| -
|
| -
|
| - def test_dateTime(self):
|
| - dtn = datetime.datetime.now()
|
| - dtd = datetime.datetime.now() - dtn
|
| - input = [dtn, dtd]
|
| - c = jelly.jelly(input)
|
| - output = jelly.unjelly(c)
|
| - self.assertEquals(input, output)
|
| - self.assertNotIdentical(input, output)
|
| -
|
| -
|
| - def test_decimal(self):
|
| - """
|
| - Jellying L{decimal.Decimal} instances and then unjellying the result
|
| - should produce objects which represent the values of the original
|
| - inputs.
|
| - """
|
| - inputList = [decimal.Decimal('9.95'),
|
| - decimal.Decimal(0),
|
| - decimal.Decimal(123456),
|
| - decimal.Decimal('-78.901')]
|
| - c = jelly.jelly(inputList)
|
| - output = jelly.unjelly(c)
|
| - self.assertEquals(inputList, output)
|
| - self.assertNotIdentical(inputList, output)
|
| -
|
| -
|
| - decimalData = ['list', ['decimal', 995, -2], ['decimal', 0, 0],
|
| - ['decimal', 123456, 0], ['decimal', -78901, -3]]
|
| -
|
| -
|
| - def test_decimalUnjelly(self):
|
| - """
|
| - Unjellying the s-expressions produced by jelly for L{decimal.Decimal}
|
| - instances should result in L{decimal.Decimal} instances with the values
|
| - represented by the s-expressions.
|
| -
|
| - This test also verifies that C{self.decimalData} contains valid jellied
|
| - data. This is important since L{test_decimalMissing} re-uses
|
| - C{self.decimalData} and is expected to be unable to produce
|
| - L{decimal.Decimal} instances even though the s-expression correctly
|
| - represents a list of them.
|
| - """
|
| - expected = [decimal.Decimal('9.95'),
|
| - decimal.Decimal(0),
|
| - decimal.Decimal(123456),
|
| - decimal.Decimal('-78.901')]
|
| - output = jelly.unjelly(self.decimalData)
|
| - self.assertEquals(output, expected)
|
| -
|
| -
|
| - def test_decimalMissing(self):
|
| - """
|
| - If decimal is unavailable on the unjelly side, L{jelly.unjelly} should
|
| - gracefully return L{jelly.Unpersistable} objects.
|
| - """
|
| - self.patch(jelly, 'decimal', None)
|
| - output = jelly.unjelly(self.decimalData)
|
| - self.assertEquals(len(output), 4)
|
| - for i in range(4):
|
| - self.assertIsInstance(output[i], jelly.Unpersistable)
|
| - self.assertEquals(output[0].reason,
|
| - "Could not unpersist decimal: 9.95")
|
| - self.assertEquals(output[1].reason,
|
| - "Could not unpersist decimal: 0")
|
| - self.assertEquals(output[2].reason,
|
| - "Could not unpersist decimal: 123456")
|
| - self.assertEquals(output[3].reason,
|
| - "Could not unpersist decimal: -78.901")
|
| -
|
| -
|
| - def test_decimalSecurity(self):
|
| - """
|
| - By default, C{decimal} objects should be allowed by
|
| - L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
|
| - L{jelly.InsecureJelly} when trying to unjelly it.
|
| - """
|
| - inputList = [decimal.Decimal('9.95')]
|
| - self._testSecurity(inputList, "decimal")
|
| -
|
| - if decimal is None:
|
| - skipReason = "decimal not available"
|
| - test_decimal.skip = skipReason
|
| - test_decimalUnjelly.skip = skipReason
|
| - test_decimalSecurity.skip = skipReason
|
| -
|
| -
|
| - def test_set(self):
|
| - """
|
| - Jellying C{set} instances and then unjellying the result
|
| - should produce objects which represent the values of the original
|
| - inputs.
|
| - """
|
| - inputList = [set([1, 2, 3])]
|
| - output = jelly.unjelly(jelly.jelly(inputList))
|
| - self.assertEquals(inputList, output)
|
| - self.assertNotIdentical(inputList, output)
|
| -
|
| -
|
| - def test_frozenset(self):
|
| - """
|
| - Jellying C{frozenset} instances and then unjellying the result
|
| - should produce objects which represent the values of the original
|
| - inputs.
|
| - """
|
| - inputList = [frozenset([1, 2, 3])]
|
| - output = jelly.unjelly(jelly.jelly(inputList))
|
| - self.assertEquals(inputList, output)
|
| - self.assertNotIdentical(inputList, output)
|
| -
|
| -
|
| - def test_setSecurity(self):
|
| - """
|
| - By default, C{set} objects should be allowed by
|
| - L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
|
| - L{jelly.InsecureJelly} when trying to unjelly it.
|
| - """
|
| - inputList = [set([1, 2, 3])]
|
| - self._testSecurity(inputList, "set")
|
| -
|
| -
|
| - def test_frozensetSecurity(self):
|
| - """
|
| - By default, C{frozenset} objects should be allowed by
|
| - L{jelly.SecurityOptions}. If not allowed, L{jelly.unjelly} should raise
|
| - L{jelly.InsecureJelly} when trying to unjelly it.
|
| - """
|
| - inputList = [frozenset([1, 2, 3])]
|
| - self._testSecurity(inputList, "frozenset")
|
| -
|
| -
|
| - def test_oldSets(self):
|
| - """
|
| - Test jellying C{sets.Set}: it should serialize to the same thing as
|
| - C{set} jelly, and be unjellied as C{set} if available.
|
| - """
|
| - inputList = [jelly._sets.Set([1, 2, 3])]
|
| - inputJelly = jelly.jelly(inputList)
|
| - self.assertEquals(inputJelly, jelly.jelly([set([1, 2, 3])]))
|
| - output = jelly.unjelly(inputJelly)
|
| - # Even if the class is different, it should coerce to the same list
|
| - self.assertEquals(list(inputList[0]), list(output[0]))
|
| - if set is jelly._sets.Set:
|
| - self.assertIsInstance(output[0], jelly._sets.Set)
|
| - else:
|
| - self.assertIsInstance(output[0], set)
|
| -
|
| -
|
| - def test_oldImmutableSets(self):
|
| - """
|
| - Test jellying C{sets.ImmutableSet}: it should serialize to the same
|
| - thing as C{frozenset} jelly, and be unjellied as C{frozenset} if
|
| - available.
|
| - """
|
| - inputList = [jelly._sets.ImmutableSet([1, 2, 3])]
|
| - inputJelly = jelly.jelly(inputList)
|
| - self.assertEquals(inputJelly, jelly.jelly([frozenset([1, 2, 3])]))
|
| - output = jelly.unjelly(inputJelly)
|
| - # Even if the class is different, it should coerce to the same list
|
| - self.assertEquals(list(inputList[0]), list(output[0]))
|
| - if frozenset is jelly._sets.ImmutableSet:
|
| - self.assertIsInstance(output[0], jelly._sets.ImmutableSet)
|
| - else:
|
| - self.assertIsInstance(output[0], frozenset)
|
| -
|
| -
|
| - def test_simple(self):
|
| - """
|
| - Simplest test case.
|
| - """
|
| - self.failUnless(SimpleJellyTest('a', 'b').isTheSameAs(
|
| - SimpleJellyTest('a', 'b')))
|
| - a = SimpleJellyTest(1, 2)
|
| - cereal = jelly.jelly(a)
|
| - b = jelly.unjelly(cereal)
|
| - self.failUnless(a.isTheSameAs(b))
|
| -
|
| -
|
| - def test_identity(self):
|
| - """
|
| - Test to make sure that objects retain identity properly.
|
| - """
|
| - x = []
|
| - y = (x)
|
| - x.append(y)
|
| - x.append(y)
|
| - self.assertIdentical(x[0], x[1])
|
| - self.assertIdentical(x[0][0], x)
|
| - s = jelly.jelly(x)
|
| - z = jelly.unjelly(s)
|
| - self.assertIdentical(z[0], z[1])
|
| - self.assertIdentical(z[0][0], z)
|
| -
|
| -
|
| - def test_unicode(self):
|
| - x = unicode('blah')
|
| - y = jelly.unjelly(jelly.jelly(x))
|
| - self.assertEquals(x, y)
|
| - self.assertEquals(type(x), type(y))
|
| -
|
| -
|
| - def test_stressReferences(self):
|
| - reref = []
|
| - toplevelTuple = ({'list': reref}, reref)
|
| - reref.append(toplevelTuple)
|
| - s = jelly.jelly(toplevelTuple)
|
| - z = jelly.unjelly(s)
|
| - self.assertIdentical(z[0]['list'], z[1])
|
| - self.assertIdentical(z[0]['list'][0], z)
|
| -
|
| -
|
| - def test_moreReferences(self):
|
| - a = []
|
| - t = (a,)
|
| - a.append((t,))
|
| - s = jelly.jelly(t)
|
| - z = jelly.unjelly(s)
|
| - self.assertIdentical(z[0][0][0], z)
|
| -
|
| -
|
| - def test_typeSecurity(self):
|
| - """
|
| - Test for type-level security of serialization.
|
| - """
|
| - taster = jelly.SecurityOptions()
|
| - dct = jelly.jelly({})
|
| - self.assertRaises(jelly.InsecureJelly, jelly.unjelly, dct, taster)
|
| -
|
| -
|
| - def test_newStyleClasses(self):
|
| - j = jelly.jelly(D)
|
| - uj = jelly.unjelly(D)
|
| - self.assertIdentical(D, uj)
|
| -
|
| -
|
| - def test_lotsaTypes(self):
|
| - """
|
| - Test for all types currently supported in jelly
|
| - """
|
| - a = A()
|
| - jelly.unjelly(jelly.jelly(a))
|
| - jelly.unjelly(jelly.jelly(a.amethod))
|
| - items = [afunc, [1, 2, 3], not bool(1), bool(1), 'test', 20.3,
|
| - (1, 2, 3), None, A, unittest, {'a': 1}, A.amethod]
|
| - for i in items:
|
| - self.assertEquals(i, jelly.unjelly(jelly.jelly(i)))
|
| -
|
| -
|
| - def test_setState(self):
|
| - global TupleState
|
| - class TupleState:
|
| - def __init__(self, other):
|
| - self.other = other
|
| - def __getstate__(self):
|
| - return (self.other,)
|
| - def __setstate__(self, state):
|
| - self.other = state[0]
|
| - def __hash__(self):
|
| - return hash(self.other)
|
| - a = A()
|
| - t1 = TupleState(a)
|
| - t2 = TupleState(a)
|
| - t3 = TupleState((t1, t2))
|
| - d = {t1: t1, t2: t2, t3: t3, "t3": t3}
|
| - t3prime = jelly.unjelly(jelly.jelly(d))["t3"]
|
| - self.assertIdentical(t3prime.other[0].other, t3prime.other[1].other)
|
| -
|
| -
|
| - def test_classSecurity(self):
|
| - """
|
| - Test for class-level security of serialization.
|
| - """
|
| - taster = jelly.SecurityOptions()
|
| - taster.allowInstancesOf(A, B)
|
| - a = A()
|
| - b = B()
|
| - c = C()
|
| - # add a little complexity to the data
|
| - a.b = b
|
| - a.c = c
|
| - # and a backreference
|
| - a.x = b
|
| - b.c = c
|
| - # first, a friendly insecure serialization
|
| - friendly = jelly.jelly(a, taster)
|
| - x = jelly.unjelly(friendly, taster)
|
| - self.assertIsInstance(x.c, jelly.Unpersistable)
|
| - # now, a malicious one
|
| - mean = jelly.jelly(a)
|
| - self.assertRaises(jelly.InsecureJelly, jelly.unjelly, mean, taster)
|
| - self.assertIdentical(x.x, x.b, "Identity mismatch")
|
| - # test class serialization
|
| - friendly = jelly.jelly(A, taster)
|
| - x = jelly.unjelly(friendly, taster)
|
| - self.assertIdentical(x, A, "A came back: %s" % x)
|
| -
|
| -
|
| - def test_unjellyable(self):
|
| - """
|
| - Test that if Unjellyable is used to deserialize a jellied object,
|
| - state comes out right.
|
| - """
|
| - class JellyableTestClass(jelly.Jellyable):
|
| - pass
|
| - jelly.setUnjellyableForClass(JellyableTestClass, jelly.Unjellyable)
|
| - input = JellyableTestClass()
|
| - input.attribute = 'value'
|
| - output = jelly.unjelly(jelly.jelly(input))
|
| - self.assertEquals(output.attribute, 'value')
|
| - self.assertIsInstance(output, jelly.Unjellyable)
|
| -
|
| -
|
| - def test_persistentStorage(self):
|
| - perst = [{}, 1]
|
| - def persistentStore(obj, jel, perst = perst):
|
| - perst[1] = perst[1] + 1
|
| - perst[0][perst[1]] = obj
|
| - return str(perst[1])
|
| -
|
| - def persistentLoad(pidstr, unj, perst = perst):
|
| - pid = int(pidstr)
|
| - return perst[0][pid]
|
| -
|
| - a = SimpleJellyTest(1, 2)
|
| - b = SimpleJellyTest(3, 4)
|
| - c = SimpleJellyTest(5, 6)
|
| -
|
| - a.b = b
|
| - a.c = c
|
| - c.b = b
|
| -
|
| - jel = jelly.jelly(a, persistentStore = persistentStore)
|
| - x = jelly.unjelly(jel, persistentLoad = persistentLoad)
|
| -
|
| - self.assertIdentical(x.b, x.c.b)
|
| - self.failUnless(perst[0], "persistentStore was not called.")
|
| - self.assertIdentical(x.b, a.b, "Persistent storage identity failure.")
|
| -
|
| -
|
| - def test_newStyleClassesAttributes(self):
|
| - n = TestNode()
|
| - n1 = TestNode(n)
|
| - n11 = TestNode(n1)
|
| - n2 = TestNode(n)
|
| - # Jelly it
|
| - jel = jelly.jelly(n)
|
| - m = jelly.unjelly(jel)
|
| - # Check that it has been restored ok
|
| - self._check_newstyle(n, m)
|
| -
|
| -
|
| - def _check_newstyle(self, a, b):
|
| - self.assertEqual(a.id, b.id)
|
| - self.assertEqual(a.classAttr, 4)
|
| - self.assertEqual(b.classAttr, 4)
|
| - self.assertEqual(len(a.children), len(b.children))
|
| - for x, y in zip(a.children, b.children):
|
| - self._check_newstyle(x, y)
|
| -
|
| -
|
| -
|
| -class ClassA(pb.Copyable, pb.RemoteCopy):
|
| - def __init__(self):
|
| - self.ref = ClassB(self)
|
| -
|
| -
|
| -
|
| -class ClassB(pb.Copyable, pb.RemoteCopy):
|
| - def __init__(self, ref):
|
| - self.ref = ref
|
| -
|
| -
|
| -
|
| -class CircularReferenceTestCase(unittest.TestCase):
|
| - """
|
| - Tests for circular references handling in the jelly/unjelly process.
|
| - """
|
| -
|
| - def test_simpleCircle(self):
|
| - jelly.setUnjellyableForClass(ClassA, ClassA)
|
| - jelly.setUnjellyableForClass(ClassB, ClassB)
|
| - a = jelly.unjelly(jelly.jelly(ClassA()))
|
| - self.assertIdentical(a.ref.ref, a,
|
| - "Identity not preserved in circular reference")
|
| -
|
| -
|
| - def test_circleWithInvoker(self):
|
| - class DummyInvokerClass:
|
| - pass
|
| - dummyInvoker = DummyInvokerClass()
|
| - dummyInvoker.serializingPerspective = None
|
| - a0 = ClassA()
|
| - jelly.setUnjellyableForClass(ClassA, ClassA)
|
| - jelly.setUnjellyableForClass(ClassB, ClassB)
|
| - j = jelly.jelly(a0, invoker=dummyInvoker)
|
| - a1 = jelly.unjelly(j)
|
| - self.failUnlessIdentical(a1.ref.ref, a1,
|
| - "Identity not preserved in circular reference")
|
| -
|
| -
|
| - def test_set(self):
|
| - """
|
| - Check that a C{set} can contain a circular reference and be serialized
|
| - and unserialized without losing the reference.
|
| - """
|
| - s = set()
|
| - a = SimpleJellyTest(s, None)
|
| - s.add(a)
|
| - res = jelly.unjelly(jelly.jelly(a))
|
| - self.assertIsInstance(res.x, set)
|
| - self.assertEquals(list(res.x), [res])
|
| -
|
| -
|
| - def test_frozenset(self):
|
| - """
|
| - Check that a C{frozenset} can contain a circular reference and be
|
| - serializeserialized without losing the reference.
|
| - """
|
| - a = SimpleJellyTest(None, None)
|
| - s = frozenset([a])
|
| - a.x = s
|
| - res = jelly.unjelly(jelly.jelly(a))
|
| - self.assertIsInstance(res.x, frozenset)
|
| - self.assertEquals(list(res.x), [res])
|
|
|