~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/test/test_rebuild.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
 
 
5
import sys, os
 
6
import new
 
7
 
 
8
from twisted.trial import unittest
 
9
from twisted.python import rebuild
 
10
 
 
11
import crash_test_dummy
 
12
f = crash_test_dummy.foo
 
13
 
 
14
class Foo: pass
 
15
class Bar(Foo): pass
 
16
class Baz(object): pass
 
17
class Buz(Bar, Baz): pass
 
18
 
 
19
class HashRaisesRuntimeError:
 
20
    """
 
21
    Things that don't hash (raise an Exception) should be ignored by the
 
22
    rebuilder.
 
23
 
 
24
    @ivar hashCalled: C{bool} set to True when __hash__ is called.
 
25
    """
 
26
    def __init__(self):
 
27
        self.hashCalled = False
 
28
 
 
29
    def __hash__(self):
 
30
        self.hashCalled = True
 
31
        raise RuntimeError('not a TypeError!')
 
32
 
 
33
 
 
34
 
 
35
unhashableObject = None # set in test_hashException
 
36
 
 
37
 
 
38
 
 
39
class RebuildTestCase(unittest.TestCase):
 
40
    """
 
41
    Simple testcase for rebuilding, to at least exercise the code.
 
42
    """
 
43
    def setUp(self):
 
44
        self.libPath = self.mktemp()
 
45
        os.mkdir(self.libPath)
 
46
        self.fakelibPath = os.path.join(self.libPath, 'twisted_rebuild_fakelib')
 
47
        os.mkdir(self.fakelibPath)
 
48
        file(os.path.join(self.fakelibPath, '__init__.py'), 'w').close()
 
49
        sys.path.insert(0, self.libPath)
 
50
 
 
51
    def tearDown(self):
 
52
        sys.path.remove(self.libPath)
 
53
 
 
54
    def testFileRebuild(self):
 
55
        from twisted.python.util import sibpath
 
56
        import shutil, time
 
57
        shutil.copyfile(sibpath(__file__, "myrebuilder1.py"),
 
58
                        os.path.join(self.fakelibPath, "myrebuilder.py"))
 
59
        from twisted_rebuild_fakelib import myrebuilder
 
60
        a = myrebuilder.A()
 
61
        try:
 
62
            object
 
63
        except NameError:
 
64
            pass
 
65
        else:
 
66
            from twisted.test import test_rebuild
 
67
            b = myrebuilder.B()
 
68
            class C(myrebuilder.B):
 
69
                pass
 
70
            test_rebuild.C = C
 
71
            c = C()
 
72
        i = myrebuilder.Inherit()
 
73
        self.assertEquals(a.a(), 'a')
 
74
        # necessary because the file has not "changed" if a second has not gone
 
75
        # by in unix.  This sucks, but it's not often that you'll be doing more
 
76
        # than one reload per second.
 
77
        time.sleep(1.1)
 
78
        shutil.copyfile(sibpath(__file__, "myrebuilder2.py"),
 
79
                        os.path.join(self.fakelibPath, "myrebuilder.py"))
 
80
        rebuild.rebuild(myrebuilder)
 
81
        try:
 
82
            object
 
83
        except NameError:
 
84
            pass
 
85
        else:
 
86
            b2 = myrebuilder.B()
 
87
            self.assertEquals(b2.b(), 'c')
 
88
            self.assertEquals(b.b(), 'c')
 
89
        self.assertEquals(i.a(), 'd')
 
90
        self.assertEquals(a.a(), 'b')
 
91
        # more work to be done on new-style classes
 
92
        # self.assertEquals(c.b(), 'c')
 
93
 
 
94
    def testRebuild(self):
 
95
        """
 
96
        Rebuilding an unchanged module.
 
97
        """
 
98
        # This test would actually pass if rebuild was a no-op, but it
 
99
        # ensures rebuild doesn't break stuff while being a less
 
100
        # complex test than testFileRebuild.
 
101
 
 
102
        x = crash_test_dummy.X('a')
 
103
 
 
104
        rebuild.rebuild(crash_test_dummy, doLog=False)
 
105
        # Instance rebuilding is triggered by attribute access.
 
106
        x.do()
 
107
        self.failUnlessIdentical(x.__class__, crash_test_dummy.X)
 
108
 
 
109
        self.failUnlessIdentical(f, crash_test_dummy.foo)
 
110
 
 
111
    def testComponentInteraction(self):
 
112
        x = crash_test_dummy.XComponent()
 
113
        x.setAdapter(crash_test_dummy.IX, crash_test_dummy.XA)
 
114
        oldComponent = x.getComponent(crash_test_dummy.IX)
 
115
        rebuild.rebuild(crash_test_dummy, 0)
 
116
        newComponent = x.getComponent(crash_test_dummy.IX)
 
117
 
 
118
        newComponent.method()
 
119
 
 
120
        self.assertEquals(newComponent.__class__, crash_test_dummy.XA)
 
121
 
 
122
        # Test that a duplicate registerAdapter is not allowed
 
123
        from twisted.python import components
 
124
        self.failUnlessRaises(ValueError, components.registerAdapter,
 
125
                              crash_test_dummy.XA, crash_test_dummy.X,
 
126
                              crash_test_dummy.IX)
 
127
 
 
128
    def testUpdateInstance(self):
 
129
        global Foo, Buz
 
130
 
 
131
        b = Buz()
 
132
 
 
133
        class Foo:
 
134
            def foo(self):
 
135
                pass
 
136
        class Buz(Bar, Baz):
 
137
            x = 10
 
138
 
 
139
        rebuild.updateInstance(b)
 
140
        assert hasattr(b, 'foo'), "Missing method on rebuilt instance"
 
141
        assert hasattr(b, 'x'), "Missing class attribute on rebuilt instance"
 
142
 
 
143
    def testBananaInteraction(self):
 
144
        from twisted.python import rebuild
 
145
        from twisted.spread import banana
 
146
        rebuild.latestClass(banana.Banana)
 
147
 
 
148
 
 
149
    def test_hashException(self):
 
150
        """
 
151
        Rebuilding something that has a __hash__ that raises a non-TypeError
 
152
        shouldn't cause rebuild to die.
 
153
        """
 
154
        global unhashableObject
 
155
        unhashableObject = HashRaisesRuntimeError()
 
156
        def _cleanup():
 
157
            global unhashableObject
 
158
            unhashableObject = None
 
159
        self.addCleanup(_cleanup)
 
160
        rebuild.rebuild(rebuild)
 
161
        self.assertEquals(unhashableObject.hashCalled, True)
 
162
 
 
163
 
 
164
 
 
165
class NewStyleTestCase(unittest.TestCase):
 
166
    """
 
167
    Tests for rebuilding new-style classes of various sorts.
 
168
    """
 
169
    def setUp(self):
 
170
        self.m = new.module('whipping')
 
171
        sys.modules['whipping'] = self.m
 
172
 
 
173
 
 
174
    def tearDown(self):
 
175
        del sys.modules['whipping']
 
176
        del self.m
 
177
 
 
178
 
 
179
    def test_slots(self):
 
180
        """
 
181
        Try to rebuild a new style class with slots defined.
 
182
        """
 
183
        classDefinition = (
 
184
            "class SlottedClass(object):\n"
 
185
            "    __slots__ = ['a']\n")
 
186
 
 
187
        exec classDefinition in self.m.__dict__
 
188
        inst = self.m.SlottedClass()
 
189
        inst.a = 7
 
190
        exec classDefinition in self.m.__dict__
 
191
        rebuild.updateInstance(inst)
 
192
        self.assertEqual(inst.a, 7)
 
193
        self.assertIdentical(type(inst), self.m.SlottedClass)
 
194
 
 
195
    if sys.version_info < (2, 6):
 
196
        test_slots.skip = "__class__ assignment for class with slots is only available starting Python 2.6"
 
197
 
 
198
 
 
199
    def test_errorSlots(self):
 
200
        """
 
201
        Try to rebuild a new style class with slots defined: this should fail.
 
202
        """
 
203
        classDefinition = (
 
204
            "class SlottedClass(object):\n"
 
205
            "    __slots__ = ['a']\n")
 
206
 
 
207
        exec classDefinition in self.m.__dict__
 
208
        inst = self.m.SlottedClass()
 
209
        inst.a = 7
 
210
        exec classDefinition in self.m.__dict__
 
211
        self.assertRaises(rebuild.RebuildError, rebuild.updateInstance, inst)
 
212
 
 
213
    if sys.version_info >= (2, 6):
 
214
        test_errorSlots.skip = "__class__ assignment for class with slots should work starting Python 2.6"
 
215
 
 
216
 
 
217
    def test_typeSubclass(self):
 
218
        """
 
219
        Try to rebuild a base type subclass.
 
220
        """
 
221
        classDefinition = (
 
222
            "class ListSubclass(list):\n"
 
223
            "    pass\n")
 
224
 
 
225
        exec classDefinition in self.m.__dict__
 
226
        inst = self.m.ListSubclass()
 
227
        inst.append(2)
 
228
        exec classDefinition in self.m.__dict__
 
229
        rebuild.updateInstance(inst)
 
230
        self.assertEqual(inst[0], 2)
 
231
        self.assertIdentical(type(inst), self.m.ListSubclass)
 
232
 
 
233
 
 
234
    def test_instanceSlots(self):
 
235
        """
 
236
        Test that when rebuilding an instance with a __slots__ attribute, it
 
237
        fails accurately instead of giving a L{rebuild.RebuildError}.
 
238
        """
 
239
        classDefinition = (
 
240
            "class NotSlottedClass(object):\n"
 
241
            "    pass\n")
 
242
 
 
243
        exec classDefinition in self.m.__dict__
 
244
        inst = self.m.NotSlottedClass()
 
245
        inst.__slots__ = ['a']
 
246
        classDefinition = (
 
247
            "class NotSlottedClass:\n"
 
248
            "    pass\n")
 
249
        exec classDefinition in self.m.__dict__
 
250
        # Moving from new-style class to old-style should fail.
 
251
        self.assertRaises(TypeError, rebuild.updateInstance, inst)
 
252