~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/test/test_newjelly.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
 
# See LICENSE for details.
3
 
 
4
 
 
5
 
"""Test cases for 'jelly' object serialization.
6
 
"""
7
 
 
8
 
import types
9
 
from twisted.trial import unittest
10
 
from twisted.spread import newjelly, pb
11
 
 
12
 
class A:
13
 
    """
14
 
    dummy class
15
 
    """
16
 
    def amethod(self):
17
 
        pass
18
 
 
19
 
def afunc(self):
20
 
    pass
21
 
 
22
 
class B:
23
 
    """
24
 
    dummy class
25
 
    """
26
 
    def bmethod(self):
27
 
        pass
28
 
 
29
 
 
30
 
class C:
31
 
    """
32
 
    dummy class
33
 
    """
34
 
    def cmethod(self):
35
 
        pass
36
 
 
37
 
 
38
 
class D(object):
39
 
    """
40
 
    newstyle class
41
 
    """
42
 
 
43
 
 
44
 
class SimpleJellyTest:
45
 
    def __init__(self, x, y):
46
 
        self.x = x
47
 
        self.y = y
48
 
        
49
 
    def isTheSameAs(self, other):
50
 
        return self.__dict__ == other.__dict__
51
 
 
52
 
try:
53
 
    object
54
 
    haveObject = 0 # 1 # more work to be done before this really works
55
 
except:
56
 
    haveObject = 0
57
 
else:
58
 
    class NewStyle(object):
59
 
        pass
60
 
 
61
 
try:
62
 
    import datetime
63
 
    haveDatetime = 1
64
 
except ImportError:
65
 
    haveDatetime = 0
66
 
 
67
 
class JellyTestCase(unittest.TestCase):
68
 
    """
69
 
    testcases for `jelly' module serialization.
70
 
    """
71
 
    jc = newjelly
72
 
 
73
 
    def testMethodSelfIdentity(self):
74
 
        a = A()
75
 
        b = B()
76
 
        a.bmethod = b.bmethod
77
 
        b.a = a
78
 
        im_ = self.jc.unjelly(self.jc.jelly(b)).a.bmethod
79
 
        self.assertEquals(im_.im_class, im_.im_self.__class__)
80
 
 
81
 
    if haveObject:
82
 
        def testNewStyle(self):
83
 
            n = NewStyle()
84
 
            n.x = 1
85
 
            n2 = NewStyle()
86
 
            n.n2 = n2
87
 
            n.n3 = n2
88
 
            c = self.jc.jelly(n)
89
 
            m = self.jc.unjelly(c)
90
 
            self.failUnless(isinstance(m, NewStyle))
91
 
            self.assertIdentical(m.n2, m.n3)
92
 
 
93
 
    if haveDatetime:
94
 
        def testDateTime(self):
95
 
            dtn = datetime.datetime.now()
96
 
            dtd = datetime.datetime.now() - dtn
97
 
            input = [dtn, dtd]
98
 
            c = self.jc.jelly(input)
99
 
            output = self.jc.unjelly(c)
100
 
            self.assertEquals(input, output)
101
 
            self.assertNotIdentical(input, output)
102
 
        testDateTime.todo = 'Newjelly does not support datetime yet.'
103
 
 
104
 
    def testSimple(self):
105
 
        """
106
 
        simplest test case
107
 
        """
108
 
        self.failUnless(SimpleJellyTest('a', 'b').isTheSameAs(SimpleJellyTest('a', 'b')))
109
 
        a = SimpleJellyTest(1, 2)
110
 
        cereal = self.jc.jelly(a)
111
 
        b = self.jc.unjelly(cereal)
112
 
        self.failUnless(a.isTheSameAs(b))
113
 
 
114
 
    def testIdentity(self):
115
 
        """
116
 
        test to make sure that objects retain identity properly
117
 
        """
118
 
        x = []
119
 
        y = (x)
120
 
        x.append(y)
121
 
        x.append(y)
122
 
        self.assertIdentical(x[0], x[1])
123
 
        self.assertIdentical(x[0][0], x)
124
 
        s = self.jc.jelly(x)
125
 
        z = self.jc.unjelly(s)
126
 
        self.assertIdentical(z[0], z[1])
127
 
        self.assertIdentical(z[0][0], z)
128
 
 
129
 
    def testUnicode(self):
130
 
        if hasattr(types, 'UnicodeType'):
131
 
            x = unicode('blah')
132
 
            y = self.jc.unjelly(self.jc.jelly(x))
133
 
            self.assertEquals(x, y)
134
 
            self.assertEquals(type(x), type(y))
135
 
 
136
 
    def testStressReferences(self):
137
 
        reref = []
138
 
        toplevelTuple = ({'list': reref}, reref)
139
 
        reref.append(toplevelTuple)
140
 
        s = self.jc.jelly(toplevelTuple)
141
 
        z = self.jc.unjelly(s)
142
 
        self.assertIdentical(z[0]['list'], z[1])
143
 
        self.assertIdentical(z[0]['list'][0], z)
144
 
 
145
 
    def testMoreReferences(self):
146
 
        a = []
147
 
        t = (a,)
148
 
        a.append((t,))
149
 
        s = self.jc.jelly(t)
150
 
        z = self.jc.unjelly(s)
151
 
        self.assertIdentical(z[0][0][0], z)
152
 
 
153
 
    def testTypeSecurity(self):
154
 
        """
155
 
        test for type-level security of serialization
156
 
        """
157
 
        taster = self.jc.SecurityOptions()
158
 
        dct = self.jc.jelly({})
159
 
        try:
160
 
            self.jc.unjelly(dct, taster)
161
 
            self.fail("Insecure Jelly unjellied successfully.")
162
 
        except self.jc.InsecureJelly:
163
 
            # OK, works
164
 
            pass
165
 
 
166
 
    def testNewStyleClasses(self):
167
 
        j = self.jc.jelly(D)
168
 
        uj = self.jc.unjelly(D)
169
 
        self.assertIdentical(D, uj)
170
 
 
171
 
    def testLotsaTypes(self):
172
 
        """
173
 
        test for all types currently supported in jelly
174
 
        """
175
 
        a = A()
176
 
        self.jc.unjelly(self.jc.jelly(a))
177
 
        self.jc.unjelly(self.jc.jelly(a.amethod))
178
 
        items = [afunc, [1, 2, 3], not bool(1), bool(1), 'test', 20.3, (1,2,3), None, A, unittest, {'a':1}, A.amethod]
179
 
        for i in items:
180
 
            self.assertEquals(i, self.jc.unjelly(self.jc.jelly(i)))
181
 
    
182
 
    def testSetState(self):
183
 
        global TupleState
184
 
        class TupleState:
185
 
            def __init__(self, other):
186
 
                self.other = other
187
 
            def __getstate__(self):
188
 
                return (self.other,)
189
 
            def __setstate__(self, state):
190
 
                self.other = state[0]
191
 
            def __hash__(self):
192
 
                return hash(self.other)
193
 
        a = A()
194
 
        t1 = TupleState(a)
195
 
        t2 = TupleState(a)
196
 
        t3 = TupleState((t1, t2))
197
 
        d = {t1: t1, t2: t2, t3: t3, "t3": t3}
198
 
        t3prime = self.jc.unjelly(self.jc.jelly(d))["t3"]
199
 
        self.assertIdentical(t3prime.other[0].other, t3prime.other[1].other)
200
 
 
201
 
    def testClassSecurity(self):
202
 
        """
203
 
        test for class-level security of serialization
204
 
        """
205
 
        taster = self.jc.SecurityOptions()
206
 
        taster.allowInstancesOf(A, B)
207
 
        a = A()
208
 
        b = B()
209
 
        c = C()
210
 
        # add a little complexity to the data
211
 
        a.b = b
212
 
        a.c = c
213
 
        # and a backreference
214
 
        a.x = b
215
 
        b.c = c
216
 
        # first, a friendly insecure serialization
217
 
        friendly = self.jc.jelly(a, taster)
218
 
        x = self.jc.unjelly(friendly, taster)
219
 
        self.failUnless(isinstance(x.c, self.jc.Unpersistable),
220
 
                        "C came back: %s" % x.c.__class__)
221
 
        # now, a malicious one
222
 
        mean = self.jc.jelly(a)
223
 
        try:
224
 
            x = self.jc.unjelly(mean, taster)
225
 
            self.fail("x came back: %s" % x)
226
 
        except self.jc.InsecureJelly:
227
 
            # OK
228
 
            pass
229
 
        self.assertIdentical(x.x, x.b, "Identity mismatch")
230
 
        #test class serialization
231
 
        friendly = self.jc.jelly(A, taster)
232
 
        x = self.jc.unjelly(friendly, taster)
233
 
        self.assertIdentical(x, A, "A came back: %s" % x)
234
 
 
235
 
class ClassA(pb.Copyable, pb.RemoteCopy):
236
 
    def __init__(self):
237
 
        self.ref = ClassB(self)
238
 
 
239
 
class ClassB(pb.Copyable, pb.RemoteCopy):
240
 
    def __init__(self, ref):
241
 
        self.ref = ref
242
 
 
243
 
class CircularReferenceTestCase(unittest.TestCase):
244
 
    jc = newjelly
245
 
    def testSimpleCircle(self):
246
 
        self.jc.setUnjellyableForClass(ClassA, ClassA)
247
 
        self.jc.setUnjellyableForClass(ClassB, ClassB)
248
 
        a = self.jc.unjelly(self.jc.jelly(ClassA()))
249
 
        self.failUnless(a.ref.ref is a, "Identity not preserved in circular reference")
250
 
 
251
 
    def testCircleWithInvoker(self):
252
 
        class dummyInvokerClass: pass
253
 
        dummyInvoker = dummyInvokerClass()
254
 
        dummyInvoker.serializingPerspective = None
255
 
        a0 = ClassA()
256
 
        self.jc.setUnjellyableForClass(ClassA, ClassA)
257
 
        self.jc.setUnjellyableForClass(ClassB, ClassB)
258
 
        j = self.jc.jelly(a0, invoker=dummyInvoker)
259
 
        a1 = self.jc.unjelly(j)
260
 
        self.failUnlessIdentical(a1.ref.ref, a1,
261
 
                                 "Identity not preserved in circular reference")
262
 
        
263
 
testCases = [JellyTestCase, CircularReferenceTestCase]