Beispiel #1
0
 def test_start_calls_register_for_each_plugins_from_array(self):
     plugin_class = Plugin
     with patch.object(Plugin, 'register',
                       wraps=plugin_class.register) as register_wrap:
         Plugin.start(self.working_plugins_list)
         self.assertEqual(len(self.working_plugins_list),
                          register_wrap.call_count)
Beispiel #2
0
    def uninstall(cls, args):
        import lodel.plugin.plugins
        from lodel.plugin.plugins import Plugin
        if len(args.archive) > 0:
            raise RuntimeError("Cannot uninstall plugin using -f --file \
options. Use -d --directory instead")
        to_delete = dict()  # will contain all pathes of plugins to delete
        errors = dict()
        # Uninstall by pathes
        if len(args.directory) > 0:
            # processing & checking -d --directory arguments
            for path in args.directory:
                apath = os.path.abspath(path)
                # We assume plugins are in lodel/plugins
                if not apath.startswith(lodel.plugins.PLUGINS_PATH):
                    errors[path] = "Not a subdir of %s"
                    errors[path] %= lodel.plugins.PLUGINS_PATH
                    continue
                try:
                    pinfos = Plugin.dir_is_plugin(apath)
                except Exception as e:
                    if not args.force:
                        errors[path] = e
                        continue
                to_delete[path] = pinfos

        # Uninstall by plugin's names
        # We retrieve the path of the plugin from its name
        if len(args.plugin_name) > 0:
            # Processing -n --plugin-name arguments
            plist = Plugin._discover(lodel.plugins.PLUGINS_PATH)
            for pinfos in plist:
                if pinfos['name'] in args.plugin_name:
                    to_delete[pinfos['path']] = pinfos

        # Manage errors and exit if there is no force option
        if len(errors) > 0:
            msg = "Following errors detected before begining deletions :\n"
            for path, errmsg in errors.items():
                msg += "\t- For %s : %s" % (path, errmsg)
            print(msg)
            if not args.force:
                exit(1)

        print("Begining deletion :")
        for path, pinfos in to_delete.items():
            # shutil.rmtree(path)
            print("rm -R %s" % path)
            print("\t%s(%s) in %s deleted" % (
                pinfos['name'], pinfos['version'], pinfos['path']))
Beispiel #3
0
    def clean(cls, args):
        import lodel.plugin.plugins
        from lodel.plugin.plugins import Plugin
        if len(args.archive) > 0:
            raise RuntimeError("Cannot specify plugins to uninstall using \
-f --file option. You have to use -d --directory or -n --name")
        if len(args.plugin_name) > 0:
            names = args.plugin_name
        else:
            names = list(Plugin.discover().keys())

        #_discover do not remove duplicated names
        full_list = Plugin._discover(lodel.plugins.PLUGINS_PATH)

        # Casting into a dict with list of plugins infos
        pdict = dict()
        for pinfos in full_list:
            if pinfos['name'] in names:
                if pinfos['name'] in pdict:
                    pdict[pinfos['name']].append(pinfos)
                else:
                    pdict[pinfos['name']] = [pinfos]
        to_clean = list()
        clean_count = 0
        for pname, pinfos_l in pdict.items():
            if len(pinfos_l) > 1:
                # There are some plugins to clean
                tmp_l = sorted(pinfos_l, key=lambda item: item['version'])
                to_clean += tmp_l[:-1]
                msg = "Found %s(%s). Cleaning " % (
                    pname, tmp_l[-1]['version'])
                for pinfos in to_clean:
                    clean_count += 1
                    str_info = '%s(%s)' % (pname, pinfos['version'])
                    msg += "%s, " % (str_info)
                    shutil.rmtree(pinfos['path'])
                print(msg)
        if clean_count > 0:
            print("%d plugins were uninstalled" % clean_count)
        else:
            print("Already clean")
Beispiel #4
0
 def run(cls, args):
     import lodel.plugin.plugins
     from lodel.plugin.plugins import Plugin
     if args.verbose:
         #_discover does not return duplicated names
         tmp_plist = Plugin._discover(lodel.plugin.plugins.PLUGINS_PATH)
         plist = []
         # ordering the list by plugin's name
         for pname in sorted(set([d['name'] for d in tmp_plist])):
             for pinfos in tmp_plist:
                 if pinfos['name'] == pname:
                     plist.append(pinfos)
     else:
         # Retrieve the dict with the list of plugins
         pdict = Plugin.discover()
         # casting to a list ordered by names
         plist = []
         for pname in sorted(pdict.keys()):
             plist.append(pdict[pname])
     if args.csv:
         if args.verbose:
             res = "name,version,path\n"
             fmt = "%s,%s,%s\n"
         else:
             res = "name,version\n"
             fmt = "%s,%s\n"
     else:
         res = "Installed plugins list :\n"
         if args.verbose:
             fmt = "\t- %s(%s) in %s\n"
         else:
             fmt = "\t- %s(%s)\n"
     for pinfos in plist:
         if args.verbose:
             res += fmt % (
                 pinfos['name'], pinfos['version'], pinfos['path'])
         else:
             res += fmt % (pinfos['name'], pinfos['version'])
     print(res)
Beispiel #5
0
    def test_construct(self):
        """ Testing plugin instanciation """
        pname_type = {
            'dummy': Extension,
            'dummy_datasource': DatasourcePlugin,
            #'webui': InterfacePlugin, #singleton, cannot reinstanciate
            #'ram_session': SessionHandlerPlugin, #singleton, cannot resintanciate
        }
        for pname, ptype in pname_type.items():
            pinstance = Plugin.get(pname)
            self.assertIsInstance(
                pinstance, ptype, "Expected plugin '%s' \
to be in an %s instance but found an %s instance" %
                (pname, ptype, pinstance.__class__))
Beispiel #6
0
 def test_get_returns_proper_plugin_instance(self):
     Plugin.register('dummy')
     self.assertTrue(Plugin.get('dummy').__class__, Plugin)
Beispiel #7
0
 def test_register_returns_Plugin_child_object(self):
     self.assertTrue(
         issubclass(Plugin.register('dummy_datasource').__class__, Plugin))
Beispiel #8
0
 def test_register_if_plugin_already_registered_throws_PluginError(self):
     Plugin.register('dummy')
     self.assertRaises(PluginError, Plugin.register, 'dummy')
Beispiel #9
0
 def test_clear_effectively_allow_fresh_new_plugin_reloading(self):
     Plugin.start(self.working_plugins_list)
     Plugin.clear()
     Plugin.start(self.working_plugins_list)
Beispiel #10
0
 def test_loader_module_if_plugin_not_yet_loaded_throws_RuntimeError(self):
     self.assertRaises(RuntimeError, Plugin('dummy').loader_module)
Beispiel #11
0
 def setUp(self):
     Plugin.clear()
     self.working_plugins_list = ['dummy', 'dummy_datasource']
Beispiel #12
0
 def test_construct_invalid(self):
     """ Testing plugin instanciation with a non existing name """
     with self.assertRaises(PluginError):
         Plugin.get("fljkhsfh")
Beispiel #13
0
 def tearDownClass(cls):
     Plugin.clear()
Beispiel #14
0
 def test_plugin_module_name_correctly_returns_module_name_string_from_plugin_name(
         self):
     self.assertEqual(Plugin.plugin_module_name('foo'),
                      "%s.%s" % (VIRTUAL_PACKAGE_NAME, 'foo'))
Beispiel #15
0
 def test_check_deps_returns_empty_list_if_no_dependencies(self):
     self.assertEqual(list(), Plugin('dummy').check_deps())
Beispiel #16
0
 def setUpClass(cls):
     Plugin.clear()
     Plugin.start(['dummy', 'dummy_datasource', 'webui', 'ram_sessions'])
Beispiel #17
0
    def install(cls, args):
        import lodel.plugin.plugins
        from lodel.plugin.plugins import Plugin
        from lodel.plugin.exceptions import PluginError

        # We can't install a plugin with just its name, we have to know where
        # it is
        if len(args.plugin_name) > 0:
            raise RuntimeError("Unable to install a plugin from its name !\
We do not know where to find it...")
        plist = Plugin.discover()
        errors = dict()

        # For now we do not handle archive for plugins
        if len(args.archive) > 0:
            raise NotImplementedError("Not supported yet")

        plugins_infos = {}
        for cur_dir in args.directory:
            # Check that the directories obtained correspond to plugins
            try:
                res = Plugin.dir_is_plugin(cur_dir, assert_in_package=False)
                if res is False:
                    errors[cur_dir] = PluginError("Not a plugin")
                else:
                    plugins_infos[res['name']] = res
            except Exception as e:
                errors[cur_dir] = e

        # Abording because of previous errors
        if len(errors) > 0:
            msg = "Abording installation because of following errors :\n"
            for path, expt in errors.items():
                msg += ("\t- For path '%s' : %s\n" % (path, expt))
            raise RuntimeError(msg)

        # No errors continuing to install
        for pname, pinfos in plugins_infos.items():
            if pname in plist:
                # Found an installed plugin with the same name
                # Checking both versions
                if plist[pname]['version'] == pinfos['version']:
                    errors[pinfos['path']] = 'Abording installation of %s \
found in %s because it seems to be allready installed in %s' % (
                        pname, pinfos['path'], plist[pname]['path'])
                    continue
                if plist[pname]['version'] > pinfos['version']:
                    errors[pinfos['path']] = 'Abording installation of %s \
found in %s because the same plugins with a greater version seems to be \
installed in %s' % (pname, pinfos['path'], plist[pname]['path'])
                    continue
                logger.info("Found a plugin with the same name but with an \
inferior version. Continuing to install")
            # Checking that we can safely copy our plugin
            dst_path = os.path.join(lodel.plugin.plugins.PLUGINS_PATH,
                                    os.path.basename(os.path.dirname(pinfos['path'])))
            orig_path = dst_path
            if os.path.isdir(dst_path):
                dst_path = tempfile.mkdtemp(
                    prefix=os.path.basename(dst_path) + '_',
                    dir=lodel.plugin.plugins.PLUGINS_PATH)
                logger.warning("A plugin already exists in %s. Installing \
in %s" % (orig_path, dst_path))
                shutil.rmtree(dst_path)

            # Install the plugin
            shutil.copytree(pinfos['path'], dst_path, symlinks=False)
            print("%s(%s) installed in %s" % (
                pname, pinfos['version'], dst_path))
        if len(errors) > 0:
            msg = "Following errors occurs during installation process :\n"
            for path, error_msg in errors.items():
                msg += "\t- For '%s' : %s" % (path, error_msg)
            print(msg)