~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_plugins.py

  • Committer: John Arbash Meinel
  • Date: 2008-09-26 22:14:42 UTC
  • mto: This revision was merged to the branch mainline in revision 3747.
  • Revision ID: john@arbash-meinel.com-20080926221442-3r67j99sr9rwe9w0
Make message optional, don't check the memory flag directly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# affects the global state of the process.  See bzrlib/plugins.py for more
21
21
# comments.
22
22
 
 
23
import logging
23
24
import os
24
25
from StringIO import StringIO
25
26
import sys
30
31
import bzrlib.plugins
31
32
import bzrlib.commands
32
33
import bzrlib.help
33
 
from bzrlib.tests import TestCase, TestCaseInTempDir
34
 
from bzrlib.osutils import pathjoin, abspath
 
34
from bzrlib.symbol_versioning import one_three
 
35
from bzrlib.tests import (
 
36
    TestCase,
 
37
    TestCaseInTempDir,
 
38
    TestUtil,
 
39
    )
 
40
from bzrlib.osutils import pathjoin, abspath, normpath
35
41
 
36
42
 
37
43
PLUGIN_TEXT = """\
69
75
        # tempattribute list.
70
76
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
71
77
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
72
 
        print >> file(os.path.join('first', 'plugin.py'), 'w'), template % (tempattribute, 'first')
73
 
        print >> file(os.path.join('second', 'plugin.py'), 'w'), template % (tempattribute, 'second')
 
78
 
 
79
        outfile = open(os.path.join('first', 'plugin.py'), 'w')
 
80
        try:
 
81
            outfile.write(template % (tempattribute, 'first'))
 
82
            outfile.write('\n')
 
83
        finally:
 
84
            outfile.close()
 
85
 
 
86
        outfile = open(os.path.join('second', 'plugin.py'), 'w')
 
87
        try:
 
88
            outfile.write(template % (tempattribute, 'second'))
 
89
            outfile.write('\n')
 
90
        finally:
 
91
            outfile.close()
 
92
 
74
93
        try:
75
94
            bzrlib.plugin.load_from_path(['first', 'second'])
76
95
            self.assertEqual(['first'], self.activeattributes[tempattribute])
77
96
        finally:
78
97
            # remove the plugin 'plugin'
79
98
            del self.activeattributes[tempattribute]
 
99
            if 'bzrlib.plugins.plugin' in sys.modules:
 
100
                del sys.modules['bzrlib.plugins.plugin']
80
101
            if getattr(bzrlib.plugins, 'plugin', None):
81
102
                del bzrlib.plugins.plugin
82
103
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
102
123
        # tempattribute list.
103
124
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
104
125
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
105
 
        print >> file(os.path.join('first', 'pluginone.py'), 'w'), template % (tempattribute, 'first')
106
 
        print >> file(os.path.join('second', 'plugintwo.py'), 'w'), template % (tempattribute, 'second')
 
126
 
 
127
        outfile = open(os.path.join('first', 'pluginone.py'), 'w')
 
128
        try:
 
129
            outfile.write(template % (tempattribute, 'first'))
 
130
            outfile.write('\n')
 
131
        finally:
 
132
            outfile.close()
 
133
 
 
134
        outfile = open(os.path.join('second', 'plugintwo.py'), 'w')
 
135
        try:
 
136
            outfile.write(template % (tempattribute, 'second'))
 
137
            outfile.write('\n')
 
138
        finally:
 
139
            outfile.close()
 
140
 
107
141
        oldpath = bzrlib.plugins.__path__
108
142
        try:
109
143
            bzrlib.plugins.__path__ = ['first', 'second']
115
149
        finally:
116
150
            # remove the plugin 'plugin'
117
151
            del self.activeattributes[tempattribute]
118
 
            if getattr(bzrlib.plugins, 'plugin', None):
119
 
                del bzrlib.plugins.plugin
120
 
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
121
 
 
122
 
 
123
 
class TestAllPlugins(TestCaseInTempDir):
124
 
 
125
 
    def test_plugin_appears_in_all_plugins(self):
126
 
        # This test tests a new plugin appears in bzrlib.plugin.all_plugins().
 
152
            if getattr(bzrlib.plugins, 'pluginone', None):
 
153
                del bzrlib.plugins.pluginone
 
154
            if getattr(bzrlib.plugins, 'plugintwo', None):
 
155
                del bzrlib.plugins.plugintwo
 
156
        self.failIf(getattr(bzrlib.plugins, 'pluginone', None))
 
157
        self.failIf(getattr(bzrlib.plugins, 'plugintwo', None))
 
158
 
 
159
    def test_plugins_can_load_from_directory_with_trailing_slash(self):
 
160
        # This test tests that a plugin can load from a directory when the
 
161
        # directory in the path has a trailing slash.
 
162
        # check the plugin is not loaded already
 
163
        self.failIf(getattr(bzrlib.plugins, 'ts_plugin', None))
 
164
        tempattribute = "trailing-slash"
 
165
        self.failIf(tempattribute in self.activeattributes)
 
166
        # set a place for the plugin to record its loading, and at the same
 
167
        # time validate that the location the plugin should record to is
 
168
        # valid and correct.
 
169
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
 
170
            [tempattribute] = []
 
171
        self.failUnless(tempattribute in self.activeattributes)
 
172
        # create a directory for the plugin
 
173
        os.mkdir('plugin_test')
 
174
        # write a plugin that will record when its loaded in the 
 
175
        # tempattribute list.
 
176
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
177
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
 
178
 
 
179
        outfile = open(os.path.join('plugin_test', 'ts_plugin.py'), 'w')
 
180
        try:
 
181
            outfile.write(template % (tempattribute, 'plugin'))
 
182
            outfile.write('\n')
 
183
        finally:
 
184
            outfile.close()
 
185
 
 
186
        try:
 
187
            bzrlib.plugin.load_from_path(['plugin_test'+os.sep])
 
188
            self.assertEqual(['plugin'], self.activeattributes[tempattribute])
 
189
        finally:
 
190
            # remove the plugin 'plugin'
 
191
            del self.activeattributes[tempattribute]
 
192
            if getattr(bzrlib.plugins, 'ts_plugin', None):
 
193
                del bzrlib.plugins.ts_plugin
 
194
        self.failIf(getattr(bzrlib.plugins, 'ts_plugin', None))
 
195
 
 
196
    def test_plugin_with_bad_name_does_not_load(self):
 
197
        # Create badly-named plugin
 
198
        file('bzr-bad plugin-name..py', 'w').close()
 
199
 
 
200
        # Capture output
 
201
        stream = StringIO()
 
202
        handler = logging.StreamHandler(stream)
 
203
        log = logging.getLogger('bzr')
 
204
        log.addHandler(handler)
 
205
 
 
206
        bzrlib.plugin.load_from_dir('.')
 
207
 
 
208
        # Stop capturing output
 
209
        handler.flush()
 
210
        handler.close()
 
211
        log.removeHandler(handler)
 
212
 
 
213
        self.assertContainsRe(stream.getvalue(),
 
214
            r"Unable to load 'bzr-bad plugin-name\.' in '\.' as a plugin "
 
215
            "because the file path isn't a valid module name; try renaming "
 
216
            "it to 'bad_plugin_name_'\.")
 
217
 
 
218
        stream.close()
 
219
 
 
220
 
 
221
class TestPlugins(TestCaseInTempDir):
 
222
 
 
223
    def setup_plugin(self, source=""):
 
224
        # This test tests a new plugin appears in bzrlib.plugin.plugins().
127
225
        # check the plugin is not loaded already
128
226
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
129
227
        # write a plugin that _cannot_ fail to load.
130
 
        print >> file('plugin.py', 'w'), ""
131
 
        try:
132
 
            bzrlib.plugin.load_from_path(['.'])
133
 
            self.failUnless('plugin' in bzrlib.plugin.all_plugins())
134
 
            self.failUnless(getattr(bzrlib.plugins, 'plugin', None))
135
 
            self.assertEqual(bzrlib.plugin.all_plugins()['plugin'],
136
 
                             bzrlib.plugins.plugin)
137
 
        finally:
138
 
            # remove the plugin 'plugin'
139
 
            if 'bzrlib.plugins.plugin' in sys.modules:
140
 
                del sys.modules['bzrlib.plugins.plugin']
141
 
            if getattr(bzrlib.plugins, 'plugin', None):
142
 
                del bzrlib.plugins.plugin
 
228
        file('plugin.py', 'w').write(source + '\n')
 
229
        self.addCleanup(self.teardown_plugin)
 
230
        bzrlib.plugin.load_from_path(['.'])
 
231
    
 
232
    def teardown_plugin(self):
 
233
        # remove the plugin 'plugin'
 
234
        if 'bzrlib.plugins.plugin' in sys.modules:
 
235
            del sys.modules['bzrlib.plugins.plugin']
 
236
        if getattr(bzrlib.plugins, 'plugin', None):
 
237
            del bzrlib.plugins.plugin
143
238
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
144
239
 
 
240
    def test_plugin_appears_in_plugins(self):
 
241
        self.setup_plugin()
 
242
        self.failUnless('plugin' in bzrlib.plugin.plugins())
 
243
        self.failUnless(getattr(bzrlib.plugins, 'plugin', None))
 
244
        plugins = bzrlib.plugin.plugins()
 
245
        plugin = plugins['plugin']
 
246
        self.assertIsInstance(plugin, bzrlib.plugin.PlugIn)
 
247
        self.assertEqual(bzrlib.plugins.plugin, plugin.module)
 
248
 
 
249
    def test_trivial_plugin_get_path(self):
 
250
        self.setup_plugin()
 
251
        plugins = bzrlib.plugin.plugins()
 
252
        plugin = plugins['plugin']
 
253
        plugin_path = self.test_dir + '/plugin.py'
 
254
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
255
 
 
256
    def test_plugin_get_path_py_not_pyc(self):
 
257
        self.setup_plugin()         # after first import there will be plugin.pyc
 
258
        self.teardown_plugin()
 
259
        bzrlib.plugin.load_from_path(['.']) # import plugin.pyc
 
260
        plugins = bzrlib.plugin.plugins()
 
261
        plugin = plugins['plugin']
 
262
        plugin_path = self.test_dir + '/plugin.py'
 
263
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
264
 
 
265
    def test_plugin_get_path_pyc_only(self):
 
266
        self.setup_plugin()         # after first import there will be plugin.pyc
 
267
        self.teardown_plugin()
 
268
        os.unlink(self.test_dir + '/plugin.py')
 
269
        bzrlib.plugin.load_from_path(['.']) # import plugin.pyc
 
270
        plugins = bzrlib.plugin.plugins()
 
271
        plugin = plugins['plugin']
 
272
        if __debug__:
 
273
            plugin_path = self.test_dir + '/plugin.pyc'
 
274
        else:
 
275
            plugin_path = self.test_dir + '/plugin.pyo'
 
276
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
277
 
 
278
    def test_no_test_suite_gives_None_for_test_suite(self):
 
279
        self.setup_plugin()
 
280
        plugin = bzrlib.plugin.plugins()['plugin']
 
281
        self.assertEqual(None, plugin.test_suite())
 
282
 
 
283
    def test_test_suite_gives_test_suite_result(self):
 
284
        source = """def test_suite(): return 'foo'"""
 
285
        self.setup_plugin(source)
 
286
        plugin = bzrlib.plugin.plugins()['plugin']
 
287
        self.assertEqual('foo', plugin.test_suite())
 
288
 
 
289
    def test_no_load_plugin_tests_gives_None_for_load_plugin_tests(self):
 
290
        self.setup_plugin()
 
291
        loader = TestUtil.TestLoader()
 
292
        plugin = bzrlib.plugin.plugins()['plugin']
 
293
        self.assertEqual(None, plugin.load_plugin_tests(loader))
 
294
 
 
295
    def test_load_plugin_tests_gives_load_plugin_tests_result(self):
 
296
        source = """
 
297
def load_tests(standard_tests, module, loader):
 
298
    return 'foo'"""
 
299
        self.setup_plugin(source)
 
300
        loader = TestUtil.TestLoader()
 
301
        plugin = bzrlib.plugin.plugins()['plugin']
 
302
        self.assertEqual('foo', plugin.load_plugin_tests(loader))
 
303
 
 
304
    def test_no_version_info(self):
 
305
        self.setup_plugin()
 
306
        plugin = bzrlib.plugin.plugins()['plugin']
 
307
        self.assertEqual(None, plugin.version_info())
 
308
 
 
309
    def test_with_version_info(self):
 
310
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
 
311
        plugin = bzrlib.plugin.plugins()['plugin']
 
312
        self.assertEqual((1, 2, 3, 'dev', 4), plugin.version_info())
 
313
 
 
314
    def test_short_version_info_gets_padded(self):
 
315
        # the gtk plugin has version_info = (1,2,3) rather than the 5-tuple.
 
316
        # so we adapt it
 
317
        self.setup_plugin("version_info = (1, 2, 3)")
 
318
        plugin = bzrlib.plugin.plugins()['plugin']
 
319
        self.assertEqual((1, 2, 3, 'final', 0), plugin.version_info())
 
320
 
 
321
    def test_no_version_info___version__(self):
 
322
        self.setup_plugin()
 
323
        plugin = bzrlib.plugin.plugins()['plugin']
 
324
        self.assertEqual("unknown", plugin.__version__)
 
325
 
 
326
    def test___version__with_version_info(self):
 
327
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
 
328
        plugin = bzrlib.plugin.plugins()['plugin']
 
329
        self.assertEqual("1.2.3dev4", plugin.__version__)
 
330
 
 
331
    def test_final__version__with_version_info(self):
 
332
        self.setup_plugin("version_info = (1, 2, 3, 'final', 4)")
 
333
        plugin = bzrlib.plugin.plugins()['plugin']
 
334
        self.assertEqual("1.2.3", plugin.__version__)
 
335
 
145
336
 
146
337
class TestPluginHelp(TestCaseInTempDir):
147
338
 
167
358
                # some commands have no help
168
359
                pass
169
360
            else:
170
 
                self.assertNotContainsRe(help, 'From plugin "[^"]*"')
 
361
                self.assertNotContainsRe(help, 'plugin "[^"]*"')
171
362
 
172
363
            if cmd_name in help_commands.keys():
173
364
                # some commands are hidden
174
365
                help = help_commands[cmd_name]
175
 
                self.assertNotContainsRe(help, 'From plugin "[^"]*"')
 
366
                self.assertNotContainsRe(help, 'plugin "[^"]*"')
176
367
 
177
368
    def test_plugin_help_shows_plugin(self):
178
369
        # Create a test plugin
186
377
            bzrlib.plugin.load_from_path(['plugin_test'])
187
378
            bzrlib.commands.register_command( bzrlib.plugins.myplug.cmd_myplug)
188
379
            help = self.run_bzr('help myplug')[0]
189
 
            self.assertContainsRe(help, 'From plugin "myplug"')
 
380
            self.assertContainsRe(help, 'plugin "myplug"')
190
381
            help = self.split_help_commands()['myplug']
191
382
            self.assertContainsRe(help, '\[myplug\]')
192
383
        finally:
212
403
        try:
213
404
            # this is normally done by load_plugins -> set_plugins_path
214
405
            bzrlib.plugins.__path__ = [zip_name]
215
 
            bzrlib.plugin.load_from_zip(zip_name)
 
406
            self.applyDeprecated(one_three,
 
407
                bzrlib.plugin.load_from_zip, zip_name)
216
408
            self.assertTrue(plugin_name in dir(bzrlib.plugins),
217
409
                            'Plugin is not loaded')
218
410
        finally:
243
435
        finally:
244
436
            bzrlib.plugins.__path__ = old_path
245
437
 
 
438
    def test_set_plugins_path_with_trailing_slashes(self):
 
439
        """set_plugins_path should set the module __path__ based on
 
440
        BZR_PLUGIN_PATH after removing all trailing slashes."""
 
441
        old_path = bzrlib.plugins.__path__
 
442
        old_env = os.environ.get('BZR_PLUGIN_PATH')
 
443
        try:
 
444
            bzrlib.plugins.__path__ = []
 
445
            os.environ['BZR_PLUGIN_PATH'] = "first\\//\\" + os.pathsep + \
 
446
                "second/\\/\\/"
 
447
            bzrlib.plugin.set_plugins_path()
 
448
            # We expect our nominated paths to have all path-seps removed,
 
449
            # and this is testing only that.
 
450
            expected_path = ['first', 'second']
 
451
            self.assertEqual(expected_path,
 
452
                bzrlib.plugins.__path__[:len(expected_path)])
 
453
        finally:
 
454
            bzrlib.plugins.__path__ = old_path
 
455
            if old_env is not None:
 
456
                os.environ['BZR_PLUGIN_PATH'] = old_env
 
457
            else:
 
458
                del os.environ['BZR_PLUGIN_PATH']
 
459
 
246
460
 
247
461
class TestHelpIndex(tests.TestCase):
248
462
    """Tests for the PluginsHelpIndex class."""