~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/test/test_modules.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) 2006-2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Tests for twisted.python.modules, abstract access to imported or importable
 
6
objects.
 
7
"""
 
8
 
 
9
import os
 
10
import sys
 
11
import itertools
 
12
import zipfile
 
13
import compileall
 
14
 
 
15
import twisted
 
16
from twisted.trial.unittest import TestCase
 
17
 
 
18
from twisted.python import modules
 
19
from twisted.python.filepath import FilePath
 
20
from twisted.python.reflect import namedAny
 
21
 
 
22
from twisted.test.test_paths import zipit
 
23
 
 
24
 
 
25
 
 
26
class PySpaceTestCase(TestCase):
 
27
 
 
28
    def findByIteration(self, modname, where=modules, importPackages=False):
 
29
        """
 
30
        You don't ever actually want to do this, so it's not in the public API, but
 
31
        sometimes we want to compare the result of an iterative call with a
 
32
        lookup call and make sure they're the same for test purposes.
 
33
        """
 
34
        for modinfo in where.walkModules(importPackages=importPackages):
 
35
            if modinfo.name == modname:
 
36
                return modinfo
 
37
        self.fail("Unable to find module %r through iteration." % (modname,))
 
38
 
 
39
 
 
40
 
 
41
class BasicTests(PySpaceTestCase):
 
42
    def test_nonexistentPaths(self):
 
43
        """
 
44
        Verify that L{modules.walkModules} ignores entries in sys.path which
 
45
        do not exist in the filesystem.
 
46
        """
 
47
        existentPath = FilePath(self.mktemp())
 
48
        os.makedirs(existentPath.child("test_package").path)
 
49
        existentPath.child("test_package").child("__init__.py").setContent("")
 
50
 
 
51
        nonexistentPath = FilePath(self.mktemp())
 
52
        self.failIf(nonexistentPath.exists())
 
53
 
 
54
        originalSearchPaths = sys.path[:]
 
55
        sys.path[:] = [existentPath.path]
 
56
        try:
 
57
            expected = [modules.getModule("test_package")]
 
58
 
 
59
            beforeModules = list(modules.walkModules())
 
60
            sys.path.append(nonexistentPath.path)
 
61
            afterModules = list(modules.walkModules())
 
62
        finally:
 
63
            sys.path[:] = originalSearchPaths
 
64
 
 
65
        self.assertEqual(beforeModules, expected)
 
66
        self.assertEqual(afterModules, expected)
 
67
 
 
68
 
 
69
    def test_nonDirectoryPaths(self):
 
70
        """
 
71
        Verify that L{modules.walkModules} ignores entries in sys.path which
 
72
        refer to regular files in the filesystem.
 
73
        """
 
74
        existentPath = FilePath(self.mktemp())
 
75
        os.makedirs(existentPath.child("test_package").path)
 
76
        existentPath.child("test_package").child("__init__.py").setContent("")
 
77
 
 
78
        nonDirectoryPath = FilePath(self.mktemp())
 
79
        self.failIf(nonDirectoryPath.exists())
 
80
        nonDirectoryPath.setContent("zip file or whatever\n")
 
81
 
 
82
        originalSearchPaths = sys.path[:]
 
83
        sys.path[:] = [existentPath.path]
 
84
        try:
 
85
            beforeModules = list(modules.walkModules())
 
86
            sys.path.append(nonDirectoryPath.path)
 
87
            afterModules = list(modules.walkModules())
 
88
        finally:
 
89
            sys.path[:] = originalSearchPaths
 
90
 
 
91
        self.assertEqual(beforeModules, afterModules)
 
92
 
 
93
 
 
94
    def test_twistedShowsUp(self):
 
95
        """
 
96
        Scrounge around in the top-level module namespace and make sure that
 
97
        Twisted shows up, and that the module thusly obtained is the same as
 
98
        the module that we find when we look for it explicitly by name.
 
99
        """
 
100
        self.assertEquals(modules.getModule('twisted'),
 
101
                          self.findByIteration("twisted"))
 
102
 
 
103
 
 
104
    def test_dottedNames(self):
 
105
        """
 
106
        Verify that the walkModules APIs will give us back subpackages, not just
 
107
        subpackages.
 
108
        """
 
109
        self.assertEquals(
 
110
            modules.getModule('twisted.python'),
 
111
            self.findByIteration("twisted.python",
 
112
                                 where=modules.getModule('twisted')))
 
113
 
 
114
 
 
115
    def test_onlyTopModules(self):
 
116
        """
 
117
        Verify that the iterModules API will only return top-level modules and
 
118
        packages, not submodules or subpackages.
 
119
        """
 
120
        for module in modules.iterModules():
 
121
            self.failIf(
 
122
                '.' in module.name,
 
123
                "no nested modules should be returned from iterModules: %r"
 
124
                % (module.filePath))
 
125
 
 
126
 
 
127
    def test_loadPackagesAndModules(self):
 
128
        """
 
129
        Verify that we can locate and load packages, modules, submodules, and
 
130
        subpackages.
 
131
        """
 
132
        for n in ['os',
 
133
                  'twisted',
 
134
                  'twisted.python',
 
135
                  'twisted.python.reflect']:
 
136
            m = namedAny(n)
 
137
            self.failUnlessIdentical(
 
138
                modules.getModule(n).load(),
 
139
                m)
 
140
            self.failUnlessIdentical(
 
141
                self.findByIteration(n).load(),
 
142
                m)
 
143
 
 
144
 
 
145
    def test_pathEntriesOnPath(self):
 
146
        """
 
147
        Verify that path entries discovered via module loading are, in fact, on
 
148
        sys.path somewhere.
 
149
        """
 
150
        for n in ['os',
 
151
                  'twisted',
 
152
                  'twisted.python',
 
153
                  'twisted.python.reflect']:
 
154
            self.failUnlessIn(
 
155
                modules.getModule(n).pathEntry.filePath.path,
 
156
                sys.path)
 
157
 
 
158
 
 
159
    def test_alwaysPreferPy(self):
 
160
        """
 
161
        Verify that .py files will always be preferred to .pyc files, regardless of
 
162
        directory listing order.
 
163
        """
 
164
        mypath = FilePath(self.mktemp())
 
165
        mypath.createDirectory()
 
166
        pp = modules.PythonPath(sysPath=[mypath.path])
 
167
        originalSmartPath = pp._smartPath
 
168
        def _evilSmartPath(pathName):
 
169
            o = originalSmartPath(pathName)
 
170
            originalChildren = o.children
 
171
            def evilChildren():
 
172
                # normally this order is random; let's make sure it always
 
173
                # comes up .pyc-first.
 
174
                x = originalChildren()
 
175
                x.sort()
 
176
                x.reverse()
 
177
                return x
 
178
            o.children = evilChildren
 
179
            return o
 
180
        mypath.child("abcd.py").setContent('\n')
 
181
        compileall.compile_dir(mypath.path, quiet=True)
 
182
        # sanity check
 
183
        self.assertEquals(len(mypath.children()), 2)
 
184
        pp._smartPath = _evilSmartPath
 
185
        self.assertEquals(pp['abcd'].filePath,
 
186
                          mypath.child('abcd.py'))
 
187
 
 
188
 
 
189
    def test_packageMissingPath(self):
 
190
        """
 
191
        A package can delete its __path__ for some reasons,
 
192
        C{modules.PythonPath} should be able to deal with it.
 
193
        """
 
194
        mypath = FilePath(self.mktemp())
 
195
        mypath.createDirectory()
 
196
        pp = modules.PythonPath(sysPath=[mypath.path])
 
197
        subpath = mypath.child("abcd")
 
198
        subpath.createDirectory()
 
199
        subpath.child("__init__.py").setContent('del __path__\n')
 
200
        sys.path.append(mypath.path)
 
201
        import abcd
 
202
        try:
 
203
            l = list(pp.walkModules())
 
204
            self.assertEquals(len(l), 1)
 
205
            self.assertEquals(l[0].name, 'abcd')
 
206
        finally:
 
207
            del abcd
 
208
            del sys.modules['abcd']
 
209
            sys.path.remove(mypath.path)
 
210
 
 
211
 
 
212
 
 
213
class PathModificationTest(PySpaceTestCase):
 
214
    """
 
215
    These tests share setup/cleanup behavior of creating a dummy package and
 
216
    stuffing some code in it.
 
217
    """
 
218
 
 
219
    _serialnum = itertools.count().next # used to generate serial numbers for
 
220
                                        # package names.
 
221
 
 
222
    def setUp(self):
 
223
        self.pathExtensionName = self.mktemp()
 
224
        self.pathExtension = FilePath(self.pathExtensionName)
 
225
        self.pathExtension.createDirectory()
 
226
        self.packageName = "pyspacetests%d" % (self._serialnum(),)
 
227
        self.packagePath = self.pathExtension.child(self.packageName)
 
228
        self.packagePath.createDirectory()
 
229
        self.packagePath.child("__init__.py").setContent("")
 
230
        self.packagePath.child("a.py").setContent("")
 
231
        self.packagePath.child("b.py").setContent("")
 
232
        self.packagePath.child("c__init__.py").setContent("")
 
233
        self.pathSetUp = False
 
234
 
 
235
 
 
236
    def _setupSysPath(self):
 
237
        assert not self.pathSetUp
 
238
        self.pathSetUp = True
 
239
        sys.path.append(self.pathExtensionName)
 
240
 
 
241
 
 
242
    def _underUnderPathTest(self, doImport=True):
 
243
        moddir2 = self.mktemp()
 
244
        fpmd = FilePath(moddir2)
 
245
        fpmd.createDirectory()
 
246
        fpmd.child("foozle.py").setContent("x = 123\n")
 
247
        self.packagePath.child("__init__.py").setContent(
 
248
            "__path__.append(%r)\n" % (moddir2,))
 
249
        # Cut here
 
250
        self._setupSysPath()
 
251
        modinfo = modules.getModule(self.packageName)
 
252
        self.assertEquals(
 
253
            self.findByIteration(self.packageName+".foozle", modinfo,
 
254
                                 importPackages=doImport),
 
255
            modinfo['foozle'])
 
256
        self.assertEquals(modinfo['foozle'].load().x, 123)
 
257
 
 
258
 
 
259
    def test_underUnderPathAlreadyImported(self):
 
260
        """
 
261
        Verify that iterModules will honor the __path__ of already-loaded packages.
 
262
        """
 
263
        self._underUnderPathTest()
 
264
 
 
265
 
 
266
    def test_underUnderPathNotAlreadyImported(self):
 
267
        """
 
268
        Verify that iterModules will honor the __path__ of already-loaded packages.
 
269
        """
 
270
        self._underUnderPathTest(False)
 
271
 
 
272
 
 
273
    test_underUnderPathNotAlreadyImported.todo = (
 
274
        "This may be impossible but it sure would be nice.")
 
275
 
 
276
 
 
277
    def _listModules(self):
 
278
        pkginfo = modules.getModule(self.packageName)
 
279
        nfni = [modinfo.name.split(".")[-1] for modinfo in
 
280
                pkginfo.iterModules()]
 
281
        nfni.sort()
 
282
        self.failUnlessEqual(nfni, ['a', 'b', 'c__init__'])
 
283
 
 
284
 
 
285
    def test_listingModules(self):
 
286
        """
 
287
        Make sure the module list comes back as we expect from iterModules on a
 
288
        package, whether zipped or not.
 
289
        """
 
290
        self._setupSysPath()
 
291
        self._listModules()
 
292
 
 
293
 
 
294
    def test_listingModulesAlreadyImported(self):
 
295
        """
 
296
        Make sure the module list comes back as we expect from iterModules on a
 
297
        package, whether zipped or not, even if the package has already been
 
298
        imported.
 
299
        """
 
300
        self._setupSysPath()
 
301
        namedAny(self.packageName)
 
302
        self._listModules()
 
303
 
 
304
 
 
305
    def tearDown(self):
 
306
        # Intentionally using 'assert' here, this is not a test assertion, this
 
307
        # is just an "oh fuck what is going ON" assertion. -glyph
 
308
        if self.pathSetUp:
 
309
            HORK = "path cleanup failed: don't be surprised if other tests break"
 
310
            assert sys.path.pop() is self.pathExtensionName, HORK+", 1"
 
311
            assert self.pathExtensionName not in sys.path, HORK+", 2"
 
312
 
 
313
 
 
314
 
 
315
class RebindingTest(PathModificationTest):
 
316
    """
 
317
    These tests verify that the default path interrogation API works properly
 
318
    even when sys.path has been rebound to a different object.
 
319
    """
 
320
    def _setupSysPath(self):
 
321
        assert not self.pathSetUp
 
322
        self.pathSetUp = True
 
323
        self.savedSysPath = sys.path
 
324
        sys.path = sys.path[:]
 
325
        sys.path.append(self.pathExtensionName)
 
326
 
 
327
 
 
328
    def tearDown(self):
 
329
        """
 
330
        Clean up sys.path by re-binding our original object.
 
331
        """
 
332
        if self.pathSetUp:
 
333
            sys.path = self.savedSysPath
 
334
 
 
335
 
 
336
 
 
337
class ZipPathModificationTest(PathModificationTest):
 
338
    def _setupSysPath(self):
 
339
        assert not self.pathSetUp
 
340
        zipit(self.pathExtensionName, self.pathExtensionName+'.zip')
 
341
        self.pathExtensionName += '.zip'
 
342
        assert zipfile.is_zipfile(self.pathExtensionName)
 
343
        PathModificationTest._setupSysPath(self)
 
344
 
 
345
 
 
346
class PythonPathTestCase(TestCase):
 
347
    """
 
348
    Tests for the class which provides the implementation for all of the
 
349
    public API of L{twisted.python.modules}, L{PythonPath}.
 
350
    """
 
351
    def test_unhandledImporter(self):
 
352
        """
 
353
        Make sure that the behavior when encountering an unknown importer
 
354
        type is not catastrophic failure.
 
355
        """
 
356
        class SecretImporter(object):
 
357
            pass
 
358
 
 
359
        def hook(name):
 
360
            return SecretImporter()
 
361
 
 
362
        syspath = ['example/path']
 
363
        sysmodules = {}
 
364
        syshooks = [hook]
 
365
        syscache = {}
 
366
        def sysloader(name):
 
367
            return None
 
368
        space = modules.PythonPath(
 
369
            syspath, sysmodules, syshooks, syscache, sysloader)
 
370
        entries = list(space.iterEntries())
 
371
        self.assertEquals(len(entries), 1)
 
372
        self.assertRaises(KeyError, lambda: entries[0]['module'])
 
373
 
 
374
 
 
375
    def test_inconsistentImporterCache(self):
 
376
        """
 
377
        If the path a module loaded with L{PythonPath.__getitem__} is not
 
378
        present in the path importer cache, a warning is emitted, but the
 
379
        L{PythonModule} is returned as usual.
 
380
        """
 
381
        space = modules.PythonPath([], sys.modules, [], {})
 
382
        thisModule = space[__name__]
 
383
        warnings = self.flushWarnings([self.test_inconsistentImporterCache])
 
384
        self.assertEquals(warnings[0]['category'], UserWarning)
 
385
        self.assertEquals(
 
386
            warnings[0]['message'],
 
387
            FilePath(twisted.__file__).parent().dirname() +
 
388
            " (for module " + __name__ + ") not in path importer cache "
 
389
            "(PEP 302 violation - check your local configuration).")
 
390
        self.assertEquals(len(warnings), 1)
 
391
        self.assertEquals(thisModule.name, __name__)