~hardware-certification/zope3/certify-staging-2.5

« back to all changes in this revision

Viewing changes to src/persistent/tests/.svn/text-base/testPersistent.py.svn-base

  • Committer: Marc Tardif
  • Date: 2008-04-26 19:03:34 UTC
  • Revision ID: cr3@lime-20080426190334-u16xo4llz56vliqf
Initial import.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#############################################################################
 
2
#
 
3
# Copyright (c) 2003 Zope Corporation and Contributors.
 
4
# All Rights Reserved.
 
5
#
 
6
# This software is subject to the provisions of the Zope Public License,
 
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
 
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 
11
# FOR A PARTICULAR PURPOSE.
 
12
#
 
13
##############################################################################
 
14
import pickle
 
15
import time
 
16
import unittest
 
17
 
 
18
from persistent import Persistent, GHOST, UPTODATE, CHANGED, STICKY
 
19
from persistent.cPickleCache import PickleCache
 
20
from persistent.TimeStamp import TimeStamp
 
21
from ZODB.utils import p64
 
22
 
 
23
class Jar(object):
 
24
    """Testing stub for _p_jar attribute."""
 
25
 
 
26
    def __init__(self):
 
27
        self.cache = PickleCache(self)
 
28
        self.oid = 1
 
29
        self.registered = {}
 
30
 
 
31
    def add(self, obj):
 
32
        obj._p_oid = p64(self.oid)
 
33
        self.oid += 1
 
34
        obj._p_jar = self
 
35
        self.cache[obj._p_oid] = obj
 
36
 
 
37
    def close(self):
 
38
        pass
 
39
 
 
40
    # the following methods must be implemented to be a jar
 
41
 
 
42
    def setklassstate(self):
 
43
        # I don't know what this method does, but the pickle cache
 
44
        # constructor calls it.
 
45
        pass
 
46
 
 
47
    def register(self, obj):
 
48
        self.registered[obj] = 1
 
49
 
 
50
    def setstate(self, obj):
 
51
        # Trivial setstate() implementation that just re-initializes
 
52
        # the object.  This isn't what setstate() is supposed to do,
 
53
        # but it suffices for the tests.
 
54
        obj.__class__.__init__(obj)
 
55
 
 
56
class P(Persistent):
 
57
    pass
 
58
 
 
59
class H1(Persistent):
 
60
 
 
61
    def __init__(self):
 
62
        self.n = 0
 
63
 
 
64
    def __getattr__(self, attr):
 
65
        self.n += 1
 
66
        return self.n
 
67
 
 
68
class H2(Persistent):
 
69
 
 
70
    def __init__(self):
 
71
        self.n = 0
 
72
 
 
73
    def __getattribute__(self, attr):
 
74
        supergetattr = super(H2, self).__getattribute__
 
75
        try:
 
76
            return supergetattr(attr)
 
77
        except AttributeError:
 
78
            n = supergetattr("n")
 
79
            self.n = n + 1
 
80
            return n + 1
 
81
 
 
82
class PersistenceTest(unittest.TestCase):
 
83
 
 
84
    def setUp(self):
 
85
        self.jar = Jar()
 
86
 
 
87
    def tearDown(self):
 
88
        self.jar.close()
 
89
 
 
90
    def testOidAndJarAttrs(self):
 
91
        obj = P()
 
92
        self.assertEqual(obj._p_oid, None)
 
93
        obj._p_oid = 12
 
94
        self.assertEqual(obj._p_oid, 12)
 
95
        del obj._p_oid
 
96
 
 
97
        self.jar.add(obj)
 
98
 
 
99
        # Can't change oid of cache object.
 
100
        def deloid():
 
101
            del obj._p_oid
 
102
        self.assertRaises(ValueError, deloid)
 
103
        def setoid():
 
104
            obj._p_oid = 12
 
105
        self.assertRaises(ValueError, setoid)
 
106
 
 
107
        def deloid():
 
108
            del obj._p_jar
 
109
        self.assertRaises(ValueError, deloid)
 
110
        def setoid():
 
111
            obj._p_jar = 12
 
112
        self.assertRaises(ValueError, setoid)
 
113
 
 
114
    def testChangedAndState(self):
 
115
        obj = P()
 
116
        self.jar.add(obj)
 
117
 
 
118
        # The value returned for _p_changed can be one of:
 
119
        # 0 -- it is not changed
 
120
        # 1 -- it is changed
 
121
        # None -- it is a ghost
 
122
 
 
123
        obj.x = 1
 
124
        self.assertEqual(obj._p_changed, 1)
 
125
        self.assertEqual(obj._p_state, CHANGED)
 
126
        self.assert_(obj in self.jar.registered)
 
127
 
 
128
        obj._p_changed = 0
 
129
        self.assertEqual(obj._p_changed, 0)
 
130
        self.assertEqual(obj._p_state, UPTODATE)
 
131
        self.jar.registered.clear()
 
132
 
 
133
        obj._p_changed = 1
 
134
        self.assertEqual(obj._p_changed, 1)
 
135
        self.assertEqual(obj._p_state, CHANGED)
 
136
        self.assert_(obj in self.jar.registered)
 
137
 
 
138
        # setting obj._p_changed to None ghostifies if the
 
139
        # object is in the up-to-date state, but not otherwise.
 
140
        obj._p_changed = None
 
141
        self.assertEqual(obj._p_changed, 1)
 
142
        self.assertEqual(obj._p_state, CHANGED)
 
143
        obj._p_changed = 0
 
144
        # Now it's a ghost.
 
145
        obj._p_changed = None
 
146
        self.assertEqual(obj._p_changed, None)
 
147
        self.assertEqual(obj._p_state, GHOST)
 
148
 
 
149
        obj = P()
 
150
        self.jar.add(obj)
 
151
        obj._p_changed = 1
 
152
        # You can transition directly from modified to ghost if
 
153
        # you delete the _p_changed attribute.
 
154
        del obj._p_changed
 
155
        self.assertEqual(obj._p_changed, None)
 
156
        self.assertEqual(obj._p_state, GHOST)
 
157
 
 
158
    def testStateReadonly(self):
 
159
        # make sure we can't write to _p_state; we don't want yet
 
160
        # another way to change state!
 
161
        obj = P()
 
162
        def setstate(value):
 
163
            obj._p_state = value
 
164
        self.assertRaises(TypeError, setstate, GHOST)
 
165
        self.assertRaises(TypeError, setstate, UPTODATE)
 
166
        self.assertRaises(TypeError, setstate, CHANGED)
 
167
        self.assertRaises(TypeError, setstate, STICKY)
 
168
 
 
169
    def testInvalidate(self):
 
170
        obj = P()
 
171
        self.jar.add(obj)
 
172
 
 
173
        self.assertEqual(obj._p_changed, 0)
 
174
        self.assertEqual(obj._p_state, UPTODATE)
 
175
        obj._p_invalidate()
 
176
        self.assertEqual(obj._p_changed, None)
 
177
        self.assertEqual(obj._p_state, GHOST)
 
178
 
 
179
        obj._p_activate()
 
180
        obj.x = 1
 
181
        obj._p_invalidate()
 
182
        self.assertEqual(obj._p_changed, None)
 
183
        self.assertEqual(obj._p_state, GHOST)
 
184
 
 
185
    def testSerial(self):
 
186
        noserial = "\000" * 8
 
187
        obj = P()
 
188
        self.assertEqual(obj._p_serial, noserial)
 
189
 
 
190
        def set(val):
 
191
            obj._p_serial = val
 
192
        self.assertRaises(ValueError, set, 1)
 
193
        self.assertRaises(ValueError, set, "0123")
 
194
        self.assertRaises(ValueError, set, "012345678")
 
195
        self.assertRaises(ValueError, set, u"01234567")
 
196
 
 
197
        obj._p_serial = "01234567"
 
198
        del obj._p_serial
 
199
        self.assertEqual(obj._p_serial, noserial)
 
200
 
 
201
    def testMTime(self):
 
202
        obj = P()
 
203
        self.assertEqual(obj._p_mtime, None)
 
204
 
 
205
        t = int(time.time())
 
206
        ts = TimeStamp(*time.gmtime(t)[:6])
 
207
        obj._p_serial = repr(ts)
 
208
        self.assertEqual(obj._p_mtime, t)
 
209
        self.assert_(isinstance(obj._p_mtime, float))
 
210
 
 
211
    def testPicklable(self):
 
212
        obj = P()
 
213
        obj.attr = "test"
 
214
        s = pickle.dumps(obj)
 
215
        obj2 = pickle.loads(s)
 
216
        self.assertEqual(obj.attr, obj2.attr)
 
217
 
 
218
    def testGetattr(self):
 
219
        obj = H1()
 
220
        self.assertEqual(obj.larry, 1)
 
221
        self.assertEqual(obj.curly, 2)
 
222
        self.assertEqual(obj.moe, 3)
 
223
 
 
224
        self.jar.add(obj)
 
225
        obj._p_deactivate()
 
226
 
 
227
        # The simple Jar used for testing re-initializes the object.
 
228
        self.assertEqual(obj.larry, 1)
 
229
        # The getattr hook modified the object, so it should now be
 
230
        # in the changed state.
 
231
        self.assertEqual(obj._p_changed, 1)
 
232
        self.assertEqual(obj._p_state, CHANGED)
 
233
        self.assertEqual(obj.curly, 2)
 
234
        self.assertEqual(obj.moe, 3)
 
235
 
 
236
    def testGetattribute(self):
 
237
        obj = H2()
 
238
        self.assertEqual(obj.larry, 1)
 
239
        self.assertEqual(obj.curly, 2)
 
240
        self.assertEqual(obj.moe, 3)
 
241
 
 
242
        self.jar.add(obj)
 
243
        obj._p_deactivate()
 
244
 
 
245
        # The simple Jar used for testing re-initializes the object.
 
246
        self.assertEqual(obj.larry, 1)
 
247
        # The getattr hook modified the object, so it should now be
 
248
        # in the changed state.
 
249
        self.assertEqual(obj._p_changed, 1)
 
250
        self.assertEqual(obj._p_state, CHANGED)
 
251
        self.assertEqual(obj.curly, 2)
 
252
        self.assertEqual(obj.moe, 3)
 
253
 
 
254
    # TODO:  Need to decide how __setattr__ and __delattr__ should work,
 
255
    # then write tests.
 
256
 
 
257
 
 
258
def test_suite():
 
259
    return unittest.makeSuite(PersistenceTest)