~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_plugins.py

  • Committer: Andrew Bennetts
  • Date: 2010-01-12 03:53:21 UTC
  • mfrom: (4948 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4964.
  • Revision ID: andrew.bennetts@canonical.com-20100112035321-hofpz5p10224ryj3
Merge lp:bzr, resolving conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for plugins"""
18
18
 
26
26
import sys
27
27
import zipfile
28
28
 
29
 
from bzrlib import plugin, tests
 
29
from bzrlib import (
 
30
    osutils,
 
31
    plugin,
 
32
    tests,
 
33
    )
30
34
import bzrlib.plugin
31
35
import bzrlib.plugins
32
36
import bzrlib.commands
33
37
import bzrlib.help
34
 
from bzrlib.symbol_versioning import one_three
35
38
from bzrlib.tests import (
36
39
    TestCase,
37
40
    TestCaseInTempDir,
71
74
        # create two plugin directories
72
75
        os.mkdir('first')
73
76
        os.mkdir('second')
74
 
        # write a plugin that will record when its loaded in the 
 
77
        # write a plugin that will record when its loaded in the
75
78
        # tempattribute list.
76
79
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
77
80
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
119
122
        # create two plugin directories
120
123
        os.mkdir('first')
121
124
        os.mkdir('second')
122
 
        # write plugins that will record when they are loaded in the 
 
125
        # write plugins that will record when they are loaded in the
123
126
        # tempattribute list.
124
127
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
125
128
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
171
174
        self.failUnless(tempattribute in self.activeattributes)
172
175
        # create a directory for the plugin
173
176
        os.mkdir('plugin_test')
174
 
        # write a plugin that will record when its loaded in the 
 
177
        # write a plugin that will record when its loaded in the
175
178
        # tempattribute list.
176
179
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
177
180
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
195
198
 
196
199
    def load_and_capture(self, name):
197
200
        """Load plugins from '.' capturing the output.
198
 
        
 
201
 
199
202
        :param name: The name of the plugin.
200
203
        :return: A string with the log from the plugin loading call.
201
204
        """
221
224
            return stream.getvalue()
222
225
        finally:
223
226
            stream.close()
224
 
    
 
227
 
225
228
    def test_plugin_with_bad_api_version_reports(self):
226
229
        # This plugin asks for bzrlib api version 1.0.0, which is not supported
227
230
        # anymore.
258
261
        file('plugin.py', 'w').write(source + '\n')
259
262
        self.addCleanup(self.teardown_plugin)
260
263
        bzrlib.plugin.load_from_path(['.'])
261
 
    
 
264
 
262
265
    def teardown_plugin(self):
263
266
        # remove the plugin 'plugin'
264
267
        if 'bzrlib.plugins.plugin' in sys.modules:
391
394
    def test_dev_fallback__version__with_version_info(self):
392
395
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
393
396
        plugin = bzrlib.plugin.plugins()['plugin']
394
 
        self.assertEqual("1.2.3.dev.4", plugin.__version__)
 
397
        self.assertEqual("1.2.3dev4", plugin.__version__)
395
398
 
396
399
    def test_final__version__with_version_info(self):
397
400
        self.setup_plugin("version_info = (1, 2, 3, 'final', 0)")
398
401
        plugin = bzrlib.plugin.plugins()['plugin']
399
402
        self.assertEqual("1.2.3", plugin.__version__)
400
403
 
 
404
    def test_final_fallback__version__with_version_info(self):
 
405
        self.setup_plugin("version_info = (1, 2, 3, 'final', 2)")
 
406
        plugin = bzrlib.plugin.plugins()['plugin']
 
407
        self.assertEqual("1.2.3.final.2", plugin.__version__)
 
408
 
401
409
 
402
410
class TestPluginHelp(TestCaseInTempDir):
403
411
 
455
463
                delattr(bzrlib.plugins, 'myplug')
456
464
 
457
465
 
458
 
class TestPluginFromZip(TestCaseInTempDir):
459
 
 
460
 
    def make_zipped_plugin(self, zip_name, filename):
461
 
        z = zipfile.ZipFile(zip_name, 'w')
462
 
        z.writestr(filename, PLUGIN_TEXT)
463
 
        z.close()
464
 
 
465
 
    def check_plugin_load(self, zip_name, plugin_name):
466
 
        self.assertFalse(plugin_name in dir(bzrlib.plugins),
467
 
                         'Plugin already loaded')
468
 
        old_path = bzrlib.plugins.__path__
469
 
        try:
470
 
            # this is normally done by load_plugins -> set_plugins_path
471
 
            bzrlib.plugins.__path__ = [zip_name]
472
 
            self.applyDeprecated(one_three,
473
 
                bzrlib.plugin.load_from_zip, zip_name)
474
 
            self.assertTrue(plugin_name in dir(bzrlib.plugins),
475
 
                            'Plugin is not loaded')
476
 
        finally:
477
 
            # unregister plugin
478
 
            if getattr(bzrlib.plugins, plugin_name, None):
479
 
                delattr(bzrlib.plugins, plugin_name)
480
 
                del sys.modules['bzrlib.plugins.' + plugin_name]
481
 
            bzrlib.plugins.__path__ = old_path
482
 
 
483
 
    def test_load_module(self):
484
 
        self.make_zipped_plugin('./test.zip', 'ziplug.py')
485
 
        self.check_plugin_load('./test.zip', 'ziplug')
486
 
 
487
 
    def test_load_package(self):
488
 
        self.make_zipped_plugin('./test.zip', 'ziplug/__init__.py')
489
 
        self.check_plugin_load('./test.zip', 'ziplug')
490
 
 
491
 
 
492
 
class TestSetPluginsPath(TestCase):
493
 
    
494
 
    def test_set_plugins_path(self):
495
 
        """set_plugins_path should set the module __path__ correctly."""
496
 
        old_path = bzrlib.plugins.__path__
497
 
        try:
498
 
            bzrlib.plugins.__path__ = []
499
 
            expected_path = bzrlib.plugin.set_plugins_path()
500
 
            self.assertEqual(expected_path, bzrlib.plugins.__path__)
501
 
        finally:
502
 
            bzrlib.plugins.__path__ = old_path
503
 
 
504
 
    def test_set_plugins_path_with_trailing_slashes(self):
505
 
        """set_plugins_path should set the module __path__ based on
506
 
        BZR_PLUGIN_PATH after removing all trailing slashes."""
507
 
        old_path = bzrlib.plugins.__path__
508
 
        old_env = os.environ.get('BZR_PLUGIN_PATH')
509
 
        try:
510
 
            bzrlib.plugins.__path__ = []
511
 
            os.environ['BZR_PLUGIN_PATH'] = "first\\//\\" + os.pathsep + \
512
 
                "second/\\/\\/"
513
 
            bzrlib.plugin.set_plugins_path()
514
 
            # We expect our nominated paths to have all path-seps removed,
515
 
            # and this is testing only that.
516
 
            expected_path = ['first', 'second']
517
 
            self.assertEqual(expected_path,
518
 
                bzrlib.plugins.__path__[:len(expected_path)])
519
 
        finally:
520
 
            bzrlib.plugins.__path__ = old_path
521
 
            if old_env is not None:
522
 
                os.environ['BZR_PLUGIN_PATH'] = old_env
523
 
            else:
524
 
                del os.environ['BZR_PLUGIN_PATH']
525
 
 
526
 
 
527
466
class TestHelpIndex(tests.TestCase):
528
467
    """Tests for the PluginsHelpIndex class."""
529
468
 
632
571
        self.assertEqual('foo_bar', topic.get_help_topic())
633
572
 
634
573
 
635
 
def clear_plugins(test_case):
636
 
    # Save the attributes that we're about to monkey-patch.
637
 
    old_plugins_path = bzrlib.plugins.__path__
638
 
    old_loaded = plugin._loaded
639
 
    old_load_from_path = plugin.load_from_path
640
 
    # Change bzrlib.plugin to think no plugins have been loaded yet.
641
 
    bzrlib.plugins.__path__ = []
642
 
    plugin._loaded = False
643
 
    # Monkey-patch load_from_path to stop it from actually loading anything.
644
 
    def load_from_path(dirs):
645
 
        pass
646
 
    plugin.load_from_path = load_from_path
647
 
    def restore_plugins():
648
 
        bzrlib.plugins.__path__ = old_plugins_path
649
 
        plugin._loaded = old_loaded
650
 
        plugin.load_from_path = old_load_from_path
651
 
    test_case.addCleanup(restore_plugins)
652
 
 
653
 
 
654
 
class TestPluginPaths(tests.TestCase):
 
574
class TestLoadFromPath(tests.TestCaseInTempDir):
 
575
 
 
576
    def setUp(self):
 
577
        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
        # Change bzrlib.plugin to think no plugins have been loaded yet.
 
591
        bzrlib.plugins.__path__ = []
 
592
        plugin._loaded = False
 
593
 
 
594
        # 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
655
598
 
656
599
    def test_set_plugins_path_with_args(self):
657
 
        clear_plugins(self)
658
600
        plugin.set_plugins_path(['a', 'b'])
659
601
        self.assertEqual(['a', 'b'], bzrlib.plugins.__path__)
660
602
 
661
603
    def test_set_plugins_path_defaults(self):
662
 
        clear_plugins(self)
663
604
        plugin.set_plugins_path()
664
605
        self.assertEqual(plugin.get_standard_plugins_path(),
665
606
                         bzrlib.plugins.__path__)
666
607
 
667
608
    def test_get_standard_plugins_path(self):
668
609
        path = plugin.get_standard_plugins_path()
669
 
        self.assertEqual(plugin.get_default_plugin_path(), path[0])
670
610
        for directory in path:
671
 
            self.assertNotContainsRe(r'\\/$', directory)
 
611
            self.assertNotContainsRe(directory, r'\\/$')
672
612
        try:
673
613
            from distutils.sysconfig import get_python_lib
674
614
        except ImportError:
684
624
 
685
625
    def test_get_standard_plugins_path_env(self):
686
626
        os.environ['BZR_PLUGIN_PATH'] = 'foo/'
687
 
        self.assertEqual('foo', plugin.get_standard_plugins_path()[0])
688
 
 
689
 
 
690
 
class TestLoadPlugins(tests.TestCaseInTempDir):
 
627
        path = plugin.get_standard_plugins_path()
 
628
        for directory in path:
 
629
            self.assertNotContainsRe(directory, r'\\/$')
691
630
 
692
631
    def test_load_plugins(self):
693
 
        clear_plugins(self)
694
632
        plugin.load_plugins(['.'])
695
633
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
696
634
        # subsequent loads are no-ops
698
636
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
699
637
 
700
638
    def test_load_plugins_default(self):
701
 
        clear_plugins(self)
702
639
        plugin.load_plugins()
703
640
        path = plugin.get_standard_plugins_path()
704
641
        self.assertEqual(path, bzrlib.plugins.__path__)
 
642
 
 
643
 
 
644
class TestEnvPluginPath(tests.TestCaseInTempDir):
 
645
 
 
646
    def setUp(self):
 
647
        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
 
656
 
 
657
        self.user = plugin.get_user_plugin_path()
 
658
        self.site = plugin.get_site_plugin_path()
 
659
        self.core = plugin.get_core_plugin_path()
 
660
 
 
661
    def _list2paths(self, *args):
 
662
        paths = []
 
663
        for p in args:
 
664
            plugin._append_new_path(paths, p)
 
665
        return paths
 
666
 
 
667
    def _set_path(self, *args):
 
668
        path = os.pathsep.join(self._list2paths(*args))
 
669
        osutils.set_or_unset_env('BZR_PLUGIN_PATH', path)
 
670
 
 
671
    def check_path(self, expected_dirs, setting_dirs):
 
672
        if setting_dirs:
 
673
            self._set_path(*setting_dirs)
 
674
        actual = plugin.get_standard_plugins_path()
 
675
        self.assertEquals(self._list2paths(*expected_dirs), actual)
 
676
 
 
677
    def test_default(self):
 
678
        self.check_path([self.user, self.core, self.site],
 
679
                        None)
 
680
 
 
681
    def test_adhoc_policy(self):
 
682
        self.check_path([self.user, self.core, self.site],
 
683
                        ['+user', '+core', '+site'])
 
684
 
 
685
    def test_fallback_policy(self):
 
686
        self.check_path([self.core, self.site, self.user],
 
687
                        ['+core', '+site', '+user'])
 
688
 
 
689
    def test_override_policy(self):
 
690
        self.check_path([self.user, self.site, self.core],
 
691
                        ['+user', '+site', '+core'])
 
692
 
 
693
    def test_disable_user(self):
 
694
        self.check_path([self.core, self.site], ['-user'])
 
695
 
 
696
    def test_disable_user_twice(self):
 
697
        # Ensures multiple removals don't left cruft
 
698
        self.check_path([self.core, self.site], ['-user', '-user'])
 
699
 
 
700
    def test_duplicates_are_removed(self):
 
701
        self.check_path([self.user, self.core, self.site],
 
702
                        ['+user', '+user'])
 
703
        # And only the first reference is kept (since the later references will
 
704
        # onnly produce <plugin> already loaded mutters)
 
705
        self.check_path([self.user, self.core, self.site],
 
706
                        ['+user', '+user', '+core',
 
707
                         '+user', '+site', '+site',
 
708
                         '+core'])
 
709
 
 
710
    def test_disable_overrides_disable(self):
 
711
        self.check_path([self.core, self.site], ['-user', '+user'])
 
712
 
 
713
    def test_disable_core(self):
 
714
        self.check_path([self.site], ['-core'])
 
715
        self.check_path([self.user, self.site], ['+user', '-core'])
 
716
 
 
717
    def test_disable_site(self):
 
718
        self.check_path([self.core], ['-site'])
 
719
        self.check_path([self.user, self.core], ['-site', '+user'])
 
720
 
 
721
    def test_override_site(self):
 
722
        self.check_path(['mysite', self.user, self.core],
 
723
                        ['mysite', '-site', '+user'])
 
724
        self.check_path(['mysite', self.core],
 
725
                        ['mysite', '-site'])
 
726
 
 
727
    def test_override_core(self):
 
728
        self.check_path(['mycore', self.user, self.site],
 
729
                        ['mycore', '-core', '+user', '+site'])
 
730
        self.check_path(['mycore', self.site],
 
731
                        ['mycore', '-core'])
 
732
 
 
733
    def test_my_plugin_only(self):
 
734
        self.check_path(['myplugin'], ['myplugin', '-user', '-core', '-site'])
 
735
 
 
736
    def test_my_plugin_first(self):
 
737
        self.check_path(['myplugin', self.core, self.site, self.user],
 
738
                        ['myplugin', '+core', '+site', '+user'])
 
739
 
 
740
    def test_bogus_references(self):
 
741
        self.check_path(['+foo', '-bar', self.core, self.site],
 
742
                        ['+foo', '-bar'])