~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_plugins.py

  • Committer: Robert Collins
  • Date: 2010-04-08 04:34:03 UTC
  • mfrom: (5138 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5139.
  • Revision ID: robertc@robertcollins.net-20100408043403-56z0d07vdqrx7f3t
Update bugfix for 528114 to trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2007 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
# affects the global state of the process.  See bzrlib/plugins.py for more
21
21
# comments.
22
22
 
 
23
from cStringIO import StringIO
23
24
import logging
24
25
import os
25
 
from StringIO import StringIO
26
26
import sys
27
 
import zipfile
28
27
 
 
28
import bzrlib
29
29
from bzrlib import (
30
30
    osutils,
31
31
    plugin,
 
32
    plugins,
32
33
    tests,
33
 
    )
34
 
import bzrlib.plugin
35
 
import bzrlib.plugins
36
 
import bzrlib.commands
37
 
import bzrlib.help
38
 
from bzrlib.tests import (
39
 
    TestCase,
40
 
    TestCaseInTempDir,
41
 
    TestUtil,
42
 
    )
43
 
from bzrlib.osutils import pathjoin, abspath, normpath
44
 
 
45
 
 
46
 
PLUGIN_TEXT = """\
47
 
import bzrlib.commands
48
 
class cmd_myplug(bzrlib.commands.Command):
49
 
    '''Just a simple test plugin.'''
50
 
    aliases = ['mplg']
51
 
    def run(self):
52
 
        print 'Hello from my plugin'
53
 
"""
 
34
    trace,
 
35
    )
 
36
 
54
37
 
55
38
# TODO: Write a test for plugin decoration of commands.
56
39
 
57
 
class TestLoadingPlugins(TestCaseInTempDir):
 
40
class TestPluginMixin(object):
 
41
 
 
42
    def create_plugin(self, name, source=None, dir='.', file_name=None):
 
43
        if source is None:
 
44
            source = '''\
 
45
"""This is the doc for %s"""
 
46
''' % (name)
 
47
        if file_name is None:
 
48
            file_name = name + '.py'
 
49
        # 'source' must not fail to load
 
50
        path = osutils.pathjoin(dir, file_name)
 
51
        f = open(path, 'w')
 
52
        self.addCleanup(os.unlink, path)
 
53
        try:
 
54
            f.write(source + '\n')
 
55
        finally:
 
56
            f.close()
 
57
 
 
58
    def create_plugin_package(self, name, dir=None, source=None):
 
59
        if dir is None:
 
60
            dir = name
 
61
        if source is None:
 
62
            source = '''\
 
63
"""This is the doc for %s"""
 
64
dir_source = '%s'
 
65
''' % (name, dir)
 
66
        os.makedirs(dir)
 
67
        def cleanup():
 
68
            # Workaround lazy import random? madness
 
69
            osutils.rmtree(dir)
 
70
        self.addCleanup(cleanup)
 
71
        self.create_plugin(name, source, dir,
 
72
                           file_name='__init__.py')
 
73
 
 
74
    def _unregister_plugin(self, name):
 
75
        """Remove the plugin from sys.modules and the bzrlib namespace."""
 
76
        py_name = 'bzrlib.plugins.%s' % name
 
77
        if py_name in sys.modules:
 
78
            del sys.modules[py_name]
 
79
        if getattr(bzrlib.plugins, name, None) is not None:
 
80
            delattr(bzrlib.plugins, name)
 
81
 
 
82
    def assertPluginUnknown(self, name):
 
83
        self.failIf(getattr(bzrlib.plugins, name, None) is not None)
 
84
        self.failIf('bzrlib.plugins.%s' % name in sys.modules)
 
85
 
 
86
    def assertPluginKnown(self, name):
 
87
        self.failUnless(getattr(bzrlib.plugins, name, None) is not None)
 
88
        self.failUnless('bzrlib.plugins.%s' % name in sys.modules)
 
89
 
 
90
 
 
91
class TestLoadingPlugins(tests.TestCaseInTempDir, TestPluginMixin):
58
92
 
59
93
    activeattributes = {}
60
94
 
68
102
        # set a place for the plugins to record their loading, and at the same
69
103
        # time validate that the location the plugins should record to is
70
104
        # valid and correct.
71
 
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
72
 
            [tempattribute] = []
 
105
        self.__class__.activeattributes [tempattribute] = []
73
106
        self.failUnless(tempattribute in self.activeattributes)
74
107
        # create two plugin directories
75
108
        os.mkdir('first')
99
132
        finally:
100
133
            # remove the plugin 'plugin'
101
134
            del self.activeattributes[tempattribute]
102
 
            if 'bzrlib.plugins.plugin' in sys.modules:
103
 
                del sys.modules['bzrlib.plugins.plugin']
104
 
            if getattr(bzrlib.plugins, 'plugin', None):
105
 
                del bzrlib.plugins.plugin
106
 
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
135
            self._unregister_plugin('plugin')
 
136
        self.assertPluginUnknown('plugin')
107
137
 
108
138
    def test_plugins_from_different_dirs_can_demand_load(self):
 
139
        self.failIf('bzrlib.plugins.pluginone' in sys.modules)
 
140
        self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
109
141
        # This test tests that having two plugins in different
110
142
        # directories with different names allows them both to be loaded, when
111
143
        # we do a direct import statement.
143
175
 
144
176
        oldpath = bzrlib.plugins.__path__
145
177
        try:
 
178
            self.failIf('bzrlib.plugins.pluginone' in sys.modules)
 
179
            self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
146
180
            bzrlib.plugins.__path__ = ['first', 'second']
147
181
            exec "import bzrlib.plugins.pluginone"
148
182
            self.assertEqual(['first'], self.activeattributes[tempattribute])
152
186
        finally:
153
187
            # remove the plugin 'plugin'
154
188
            del self.activeattributes[tempattribute]
155
 
            if getattr(bzrlib.plugins, 'pluginone', None):
156
 
                del bzrlib.plugins.pluginone
157
 
            if getattr(bzrlib.plugins, 'plugintwo', None):
158
 
                del bzrlib.plugins.plugintwo
159
 
        self.failIf(getattr(bzrlib.plugins, 'pluginone', None))
160
 
        self.failIf(getattr(bzrlib.plugins, 'plugintwo', None))
 
189
            self._unregister_plugin('pluginone')
 
190
            self._unregister_plugin('plugintwo')
 
191
        self.assertPluginUnknown('pluginone')
 
192
        self.assertPluginUnknown('plugintwo')
161
193
 
162
194
    def test_plugins_can_load_from_directory_with_trailing_slash(self):
163
195
        # This test tests that a plugin can load from a directory when the
164
196
        # directory in the path has a trailing slash.
165
197
        # check the plugin is not loaded already
166
 
        self.failIf(getattr(bzrlib.plugins, 'ts_plugin', None))
 
198
        self.assertPluginUnknown('ts_plugin')
167
199
        tempattribute = "trailing-slash"
168
200
        self.failIf(tempattribute in self.activeattributes)
169
201
        # set a place for the plugin to record its loading, and at the same
190
222
            bzrlib.plugin.load_from_path(['plugin_test'+os.sep])
191
223
            self.assertEqual(['plugin'], self.activeattributes[tempattribute])
192
224
        finally:
193
 
            # remove the plugin 'plugin'
194
225
            del self.activeattributes[tempattribute]
195
 
            if getattr(bzrlib.plugins, 'ts_plugin', None):
196
 
                del bzrlib.plugins.ts_plugin
197
 
        self.failIf(getattr(bzrlib.plugins, 'ts_plugin', None))
 
226
            self._unregister_plugin('ts_plugin')
 
227
        self.assertPluginUnknown('ts_plugin')
198
228
 
199
229
    def load_and_capture(self, name):
200
230
        """Load plugins from '.' capturing the output.
251
281
            "it to 'bad_plugin_name_'\.")
252
282
 
253
283
 
254
 
class TestPlugins(TestCaseInTempDir):
 
284
class TestPlugins(tests.TestCaseInTempDir, TestPluginMixin):
255
285
 
256
286
    def setup_plugin(self, source=""):
257
287
        # This test tests a new plugin appears in bzrlib.plugin.plugins().
258
288
        # check the plugin is not loaded already
259
 
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
289
        self.assertPluginUnknown('plugin')
260
290
        # write a plugin that _cannot_ fail to load.
261
291
        file('plugin.py', 'w').write(source + '\n')
262
292
        self.addCleanup(self.teardown_plugin)
263
 
        bzrlib.plugin.load_from_path(['.'])
 
293
        plugin.load_from_path(['.'])
264
294
 
265
295
    def teardown_plugin(self):
266
 
        # remove the plugin 'plugin'
267
 
        if 'bzrlib.plugins.plugin' in sys.modules:
268
 
            del sys.modules['bzrlib.plugins.plugin']
269
 
        if getattr(bzrlib.plugins, 'plugin', None):
270
 
            del bzrlib.plugins.plugin
271
 
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
296
        self._unregister_plugin('plugin')
 
297
        self.assertPluginUnknown('plugin')
272
298
 
273
299
    def test_plugin_appears_in_plugins(self):
274
300
        self.setup_plugin()
275
 
        self.failUnless('plugin' in bzrlib.plugin.plugins())
276
 
        self.failUnless(getattr(bzrlib.plugins, 'plugin', None))
277
 
        plugins = bzrlib.plugin.plugins()
278
 
        plugin = plugins['plugin']
279
 
        self.assertIsInstance(plugin, bzrlib.plugin.PlugIn)
280
 
        self.assertEqual(bzrlib.plugins.plugin, plugin.module)
 
301
        self.assertPluginKnown('plugin')
 
302
        p = plugin.plugins()['plugin']
 
303
        self.assertIsInstance(p, bzrlib.plugin.PlugIn)
 
304
        self.assertEqual(p.module, plugins.plugin)
281
305
 
282
306
    def test_trivial_plugin_get_path(self):
283
307
        self.setup_plugin()
284
 
        plugins = bzrlib.plugin.plugins()
285
 
        plugin = plugins['plugin']
 
308
        p = plugin.plugins()['plugin']
286
309
        plugin_path = self.test_dir + '/plugin.py'
287
 
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
310
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
288
311
 
289
312
    def test_plugin_get_path_py_not_pyc(self):
290
 
        self.setup_plugin()         # after first import there will be plugin.pyc
 
313
        # first import creates plugin.pyc
 
314
        self.setup_plugin()
291
315
        self.teardown_plugin()
292
 
        bzrlib.plugin.load_from_path(['.']) # import plugin.pyc
293
 
        plugins = bzrlib.plugin.plugins()
294
 
        plugin = plugins['plugin']
 
316
        plugin.load_from_path(['.']) # import plugin.pyc
 
317
        p = plugin.plugins()['plugin']
295
318
        plugin_path = self.test_dir + '/plugin.py'
296
 
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
319
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
297
320
 
298
321
    def test_plugin_get_path_pyc_only(self):
299
 
        self.setup_plugin()         # after first import there will be plugin.pyc
 
322
        # first import creates plugin.pyc (or plugin.pyo depending on __debug__)
 
323
        self.setup_plugin()
300
324
        self.teardown_plugin()
301
325
        os.unlink(self.test_dir + '/plugin.py')
302
 
        bzrlib.plugin.load_from_path(['.']) # import plugin.pyc
303
 
        plugins = bzrlib.plugin.plugins()
304
 
        plugin = plugins['plugin']
 
326
        plugin.load_from_path(['.']) # import plugin.pyc (or .pyo)
 
327
        p = plugin.plugins()['plugin']
305
328
        if __debug__:
306
329
            plugin_path = self.test_dir + '/plugin.pyc'
307
330
        else:
308
331
            plugin_path = self.test_dir + '/plugin.pyo'
309
 
        self.assertIsSameRealPath(plugin_path, normpath(plugin.path()))
 
332
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
310
333
 
311
334
    def test_no_test_suite_gives_None_for_test_suite(self):
312
335
        self.setup_plugin()
313
 
        plugin = bzrlib.plugin.plugins()['plugin']
314
 
        self.assertEqual(None, plugin.test_suite())
 
336
        p = plugin.plugins()['plugin']
 
337
        self.assertEqual(None, p.test_suite())
315
338
 
316
339
    def test_test_suite_gives_test_suite_result(self):
317
340
        source = """def test_suite(): return 'foo'"""
318
341
        self.setup_plugin(source)
319
 
        plugin = bzrlib.plugin.plugins()['plugin']
320
 
        self.assertEqual('foo', plugin.test_suite())
 
342
        p = plugin.plugins()['plugin']
 
343
        self.assertEqual('foo', p.test_suite())
321
344
 
322
345
    def test_no_load_plugin_tests_gives_None_for_load_plugin_tests(self):
323
346
        self.setup_plugin()
324
 
        loader = TestUtil.TestLoader()
325
 
        plugin = bzrlib.plugin.plugins()['plugin']
326
 
        self.assertEqual(None, plugin.load_plugin_tests(loader))
 
347
        loader = tests.TestUtil.TestLoader()
 
348
        p = plugin.plugins()['plugin']
 
349
        self.assertEqual(None, p.load_plugin_tests(loader))
327
350
 
328
351
    def test_load_plugin_tests_gives_load_plugin_tests_result(self):
329
352
        source = """
330
353
def load_tests(standard_tests, module, loader):
331
354
    return 'foo'"""
332
355
        self.setup_plugin(source)
333
 
        loader = TestUtil.TestLoader()
334
 
        plugin = bzrlib.plugin.plugins()['plugin']
335
 
        self.assertEqual('foo', plugin.load_plugin_tests(loader))
 
356
        loader = tests.TestUtil.TestLoader()
 
357
        p = plugin.plugins()['plugin']
 
358
        self.assertEqual('foo', p.load_plugin_tests(loader))
 
359
 
 
360
    def check_version_info(self, expected, source='', name='plugin'):
 
361
        self.setup_plugin(source)
 
362
        self.assertEqual(expected, plugin.plugins()[name].version_info())
336
363
 
337
364
    def test_no_version_info(self):
338
 
        self.setup_plugin()
339
 
        plugin = bzrlib.plugin.plugins()['plugin']
340
 
        self.assertEqual(None, plugin.version_info())
 
365
        self.check_version_info(None)
341
366
 
342
367
    def test_with_version_info(self):
343
 
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
344
 
        plugin = bzrlib.plugin.plugins()['plugin']
345
 
        self.assertEqual((1, 2, 3, 'dev', 4), plugin.version_info())
 
368
        self.check_version_info((1, 2, 3, 'dev', 4),
 
369
                                "version_info = (1, 2, 3, 'dev', 4)")
346
370
 
347
371
    def test_short_version_info_gets_padded(self):
348
372
        # the gtk plugin has version_info = (1,2,3) rather than the 5-tuple.
349
373
        # so we adapt it
350
 
        self.setup_plugin("version_info = (1, 2, 3)")
351
 
        plugin = bzrlib.plugin.plugins()['plugin']
352
 
        self.assertEqual((1, 2, 3, 'final', 0), plugin.version_info())
 
374
        self.check_version_info((1, 2, 3, 'final', 0),
 
375
                                "version_info = (1, 2, 3)")
 
376
 
 
377
    def check_version(self, expected, source=None, name='plugin'):
 
378
        self.setup_plugin(source)
 
379
        self.assertEqual(expected, plugins[name].__version__)
353
380
 
354
381
    def test_no_version_info___version__(self):
355
382
        self.setup_plugin()
407
434
        self.assertEqual("1.2.3.final.2", plugin.__version__)
408
435
 
409
436
 
410
 
class TestPluginHelp(TestCaseInTempDir):
 
437
class TestPluginHelp(tests.TestCaseInTempDir):
411
438
 
412
439
    def split_help_commands(self):
413
440
        help = {}
442
469
    def test_plugin_help_shows_plugin(self):
443
470
        # Create a test plugin
444
471
        os.mkdir('plugin_test')
445
 
        f = open(pathjoin('plugin_test', 'myplug.py'), 'w')
446
 
        f.write(PLUGIN_TEXT)
 
472
        f = open(osutils.pathjoin('plugin_test', 'myplug.py'), 'w')
 
473
        f.write("""\
 
474
from bzrlib import commands
 
475
class cmd_myplug(commands.Command):
 
476
    '''Just a simple test plugin.'''
 
477
    aliases = ['mplg']
 
478
    def run(self):
 
479
        print 'Hello from my plugin'
 
480
 
 
481
"""
 
482
)
447
483
        f.close()
448
484
 
449
485
        try:
575
611
 
576
612
    def setUp(self):
577
613
        super(TestLoadFromPath, self).setUp()
578
 
        # Save the attributes that we're about to monkey-patch.
579
 
        old_plugins_path = bzrlib.plugins.__path__
580
 
        old_loaded = plugin._loaded
581
 
        old_load_from_path = plugin.load_from_path
582
 
 
583
 
        def restore():
584
 
            bzrlib.plugins.__path__ = old_plugins_path
585
 
            plugin._loaded = old_loaded
586
 
            plugin.load_from_path = old_load_from_path
587
 
 
588
 
        self.addCleanup(restore)
589
 
 
590
614
        # Change bzrlib.plugin to think no plugins have been loaded yet.
591
 
        bzrlib.plugins.__path__ = []
592
 
        plugin._loaded = False
 
615
        self.overrideAttr(bzrlib.plugins, '__path__', [])
 
616
        self.overrideAttr(plugin, '_loaded', False)
593
617
 
594
618
        # Monkey-patch load_from_path to stop it from actually loading anything.
595
 
        def load_from_path(dirs):
596
 
            pass
597
 
        plugin.load_from_path = load_from_path
 
619
        self.overrideAttr(plugin, 'load_from_path', lambda dirs: None)
598
620
 
599
621
    def test_set_plugins_path_with_args(self):
600
622
        plugin.set_plugins_path(['a', 'b'])
641
663
        self.assertEqual(path, bzrlib.plugins.__path__)
642
664
 
643
665
 
644
 
class TestEnvPluginPath(tests.TestCaseInTempDir):
 
666
class TestEnvPluginPath(tests.TestCase):
645
667
 
646
668
    def setUp(self):
647
669
        super(TestEnvPluginPath, self).setUp()
648
 
        old_default = plugin.DEFAULT_PLUGIN_PATH
649
 
 
650
 
        def restore():
651
 
            plugin.DEFAULT_PLUGIN_PATH = old_default
652
 
 
653
 
        self.addCleanup(restore)
654
 
 
655
 
        plugin.DEFAULT_PLUGIN_PATH = None
 
670
        self.overrideAttr(plugin, 'DEFAULT_PLUGIN_PATH', None)
656
671
 
657
672
        self.user = plugin.get_user_plugin_path()
658
673
        self.site = plugin.get_site_plugin_path()
701
716
        self.check_path([self.user, self.core, self.site],
702
717
                        ['+user', '+user'])
703
718
        # And only the first reference is kept (since the later references will
704
 
        # onnly produce <plugin> already loaded mutters)
 
719
        # only produce '<plugin> already loaded' mutters)
705
720
        self.check_path([self.user, self.core, self.site],
706
721
                        ['+user', '+user', '+core',
707
722
                         '+user', '+site', '+site',
708
723
                         '+core'])
709
724
 
710
 
    def test_disable_overrides_disable(self):
 
725
    def test_disable_overrides_enable(self):
711
726
        self.check_path([self.core, self.site], ['-user', '+user'])
712
727
 
713
728
    def test_disable_core(self):
740
755
    def test_bogus_references(self):
741
756
        self.check_path(['+foo', '-bar', self.core, self.site],
742
757
                        ['+foo', '-bar'])
 
758
 
 
759
 
 
760
class TestDisablePlugin(tests.TestCaseInTempDir, TestPluginMixin):
 
761
 
 
762
    def setUp(self):
 
763
        super(TestDisablePlugin, self).setUp()
 
764
        self.create_plugin_package('test_foo')
 
765
        # Make sure we don't pollute the plugins namespace
 
766
        self.overrideAttr(plugins, '__path__')
 
767
        # Be paranoid in case a test fail
 
768
        self.addCleanup(self._unregister_plugin, 'test_foo')
 
769
 
 
770
    def test_cannot_import(self):
 
771
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
 
772
        plugin.set_plugins_path(['.'])
 
773
        try:
 
774
            import bzrlib.plugins.test_foo
 
775
        except ImportError:
 
776
            pass
 
777
        self.assertPluginUnknown('test_foo')
 
778
 
 
779
    def test_regular_load(self):
 
780
        self.overrideAttr(plugin, '_loaded', False)
 
781
        plugin.load_plugins(['.'])
 
782
        self.assertPluginKnown('test_foo')
 
783
        self.assertEqual("This is the doc for test_foo",
 
784
                         bzrlib.plugins.test_foo.__doc__)
 
785
 
 
786
    def test_not_loaded(self):
 
787
        self.warnings = []
 
788
        def captured_warning(*args, **kwargs):
 
789
            self.warnings.append((args, kwargs))
 
790
        self.overrideAttr(trace, 'warning', captured_warning)
 
791
        # Reset the flag that protect against double loading
 
792
        self.overrideAttr(plugin, '_loaded', False)
 
793
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
 
794
        plugin.load_plugins(['.'])
 
795
        self.assertPluginUnknown('test_foo')
 
796
        # Make sure we don't warn about the plugin ImportError since this has
 
797
        # been *requested* by the user.
 
798
        self.assertLength(0, self.warnings)
 
799
 
 
800
 
 
801
class TestLoadPluginAt(tests.TestCaseInTempDir, TestPluginMixin):
 
802
 
 
803
    def setUp(self):
 
804
        super(TestLoadPluginAt, self).setUp()
 
805
        # Make sure we don't pollute the plugins namespace
 
806
        self.overrideAttr(plugins, '__path__')
 
807
        # Be paranoid in case a test fail
 
808
        self.addCleanup(self._unregister_plugin, 'test_foo')
 
809
        # Reset the flag that protect against double loading
 
810
        self.overrideAttr(plugin, '_loaded', False)
 
811
        # Create the same plugin in two directories
 
812
        self.create_plugin_package('test_foo', dir='non-standard-dir')
 
813
        # The "normal" directory, we use 'standard' instead of 'plugins' to
 
814
        # avoid depending on the precise naming.
 
815
        self.create_plugin_package('test_foo', dir='standard/test_foo')
 
816
 
 
817
    def assertTestFooLoadedFrom(self, path):
 
818
        self.assertPluginKnown('test_foo')
 
819
        self.assertEqual('This is the doc for test_foo',
 
820
                         bzrlib.plugins.test_foo.__doc__)
 
821
        self.assertEqual(path, bzrlib.plugins.test_foo.dir_source)
 
822
 
 
823
    def test_regular_load(self):
 
824
        plugin.load_plugins(['standard'])
 
825
        self.assertTestFooLoadedFrom('standard/test_foo')
 
826
 
 
827
    def test_import(self):
 
828
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
829
        plugin.set_plugins_path(['standard'])
 
830
        try:
 
831
            import bzrlib.plugins.test_foo
 
832
        except ImportError:
 
833
            pass
 
834
        self.assertTestFooLoadedFrom('non-standard-dir')
 
835
 
 
836
    def test_loading(self):
 
837
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
838
        plugin.load_plugins(['standard'])
 
839
        self.assertTestFooLoadedFrom('non-standard-dir')
 
840
 
 
841
    def test_compiled_loaded(self):
 
842
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
843
        plugin.load_plugins(['standard'])
 
844
        self.assertTestFooLoadedFrom('non-standard-dir')
 
845
        self.assertEqual('non-standard-dir/__init__.py',
 
846
                         bzrlib.plugins.test_foo.__file__)
 
847
 
 
848
        # Try importing again now that the source has been compiled
 
849
        self._unregister_plugin('test_foo')
 
850
        plugin._loaded = False
 
851
        plugin.load_plugins(['standard'])
 
852
        self.assertTestFooLoadedFrom('non-standard-dir')
 
853
        if __debug__:
 
854
            suffix = 'pyc'
 
855
        else:
 
856
            suffix = 'pyo'
 
857
        self.assertEqual('non-standard-dir/__init__.%s' % suffix,
 
858
                         bzrlib.plugins.test_foo.__file__)
 
859
 
 
860
    def test_submodule_loading(self):
 
861
        # We create an additional directory under the one for test_foo
 
862
        self.create_plugin_package('test_bar', dir='non-standard-dir/test_bar')
 
863
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
864
        plugin.set_plugins_path(['standard'])
 
865
        import bzrlib.plugins.test_foo
 
866
        self.assertEqual('bzrlib.plugins.test_foo',
 
867
                         bzrlib.plugins.test_foo.__package__)
 
868
        import bzrlib.plugins.test_foo.test_bar
 
869
        self.assertEqual('non-standard-dir/test_bar/__init__.py',
 
870
                         bzrlib.plugins.test_foo.test_bar.__file__)
 
871
 
 
872
    def test_loading_from___init__only(self):
 
873
        # We rename the existing __init__.py file to ensure that we don't load
 
874
        # a random file
 
875
        init = 'non-standard-dir/__init__.py'
 
876
        random = 'non-standard-dir/setup.py'
 
877
        os.rename(init, random)
 
878
        self.addCleanup(os.rename, random, init)
 
879
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
880
        plugin.load_plugins(['standard'])
 
881
        self.assertPluginUnknown('test_foo')
 
882
 
 
883
    def test_loading_from_specific_file(self):
 
884
        plugin_dir = 'non-standard-dir'
 
885
        plugin_file_name = 'iamtestfoo.py'
 
886
        plugin_path = osutils.pathjoin(plugin_dir, plugin_file_name)
 
887
        source = '''\
 
888
"""This is the doc for %s"""
 
889
dir_source = '%s'
 
890
''' % ('test_foo', plugin_path)
 
891
        self.create_plugin('test_foo', source=source,
 
892
                           dir=plugin_dir, file_name=plugin_file_name)
 
893
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@%s' % plugin_path)
 
894
        plugin.load_plugins(['standard'])
 
895
        self.assertTestFooLoadedFrom(plugin_path)