def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.fakes.juju.config["plugins-site"] = "http://x/" self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data"
def changed(self): """Install optional plugins.""" # extension subordinates may request the principle service install # specified jenkins plugins log("Installing required plugins as requested by jenkins-extension " "subordinate.") plugins = Plugins() plugins.install(relation_get("required_plugins")) api = Api() api.wait() # Wait for the service to be fully up
def changed(self): """Install optional plugins.""" # extension subordinates may request the principle service install # specified jenkins plugins log("Installing required plugins as requested by jenkins-extension " "subordinate.") plugins = Plugins() plugins.install(relation_get("required_plugins")) api = Api() api.wait() # Wait for the service to be fully up
def configure_plugins(): if get_state("extension.connected"): # We've been driven by an extension, let it take control over # plugin. log("External relation detected - skip configuring plugins") return status_set("maintenance", "Configuring plugins") remove_state("jenkins.configured.plugins") plugins = Plugins() plugins.install(config("plugins")) api = Api() api.wait() # Wait for the service to be fully up set_state("jenkins.configured.plugins")
def test_using_json_from_plugin_site(self, mock_restart_jenkins): """ If the configured plugin-site has an update-center.json file, it should be used instead of the default one. """ self.plugins = Plugins() orig_plugins_site = hookenv.config()["plugins-site"] try: hookenv.config( )["plugins-site"] = "https://updates.jenkins.io/stable/" self.plugins = Plugins() finally: hookenv.config()["plugins-site"] = orig_plugins_site
def configure_plugins(): if get_state("extension.connected"): # We've been driven by an extension, let it take control over # plugin. log("External relation detected - skip configuring plugins") return status_set("maintenance", "Configuring plugins") remove_state("jenkins.configured.plugins") plugins = Plugins() plugins.install(config("plugins")) api = Api() api.wait() # Wait for the service to be fully up set_state("jenkins.configured.plugins")
def update_plugins(): last_update = unitdata.kv().get("jenkins.plugins.last_update") if last_update is None: unitdata.kv().set("jenkins.plugins.last_update", 0) last_update = 0 # Only try to update plugins when the interval configured has passed update_interval = time.time() - (config("plugins-auto-update-interval") * 60) if (last_update < update_interval): status_set("maintenance", "Updating plugins") plugins = Plugins() plugins.update(config("plugins")) api = Api() api.wait() # Wait for the service to be fully up unitdata.kv().set("jenkins.plugins.last_update", time.time())
def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.fakes.juju.config["plugins-site"] = "http://x/" self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data"
def joined(self): """Indicate the relation is connected and install required plugins.""" log("Installing and configuring gearman-plugin for Zuul communication") # zuul relation requires we install the required plugins and set the # address of the remote zuul/gearman service in the plugin setting. plugins = Plugins() plugins.install(PLUGINS) self.set_state("{relation_name}.connected") # Generate plugin config with address of remote unit. zuul_host = relation_get("private-address") zuul_config = ZUUL_CONFIG.format(zuul_host).encode("utf-8") write_file( GERMAN_PLUGIN, zuul_config, owner="jenkins", group="nogroup") # Restart jenkins so changes will take efect. service_restart("jenkins") # Trigger the extension hook to update it with zuul relation data, if # it's coded to do so. hooks = Hooks() hooks.execute(["extension-relation-joined"])
def joined(self): """Indicate the relation is connected and install required plugins.""" log("Installing and configuring gearman-plugin for Zuul communication") # zuul relation requires we install the required plugins and set the # address of the remote zuul/gearman service in the plugin setting. plugins = Plugins() plugins.install(PLUGINS) self.set_state("{relation_name}.connected") # Generate plugin config with address of remote unit. zuul_host = relation_get("private-address") zuul_config = ZUUL_CONFIG.format(zuul_host).encode("utf-8") write_file(GERMAN_PLUGIN, zuul_config, owner="jenkins", group="nogroup") # Restart jenkins so changes will take efect. service_restart("jenkins") # Trigger the extension hook to update it with zuul relation data, if # it's coded to do so. hooks = Hooks() hooks.execute(["extension-relation-joined"])
def update_plugins(): last_update = unitdata.kv().get("jenkins.plugins.last_update") if last_update is None: unitdata.kv().set("jenkins.plugins.last_update", 0) last_update = 0 # Only try to update plugins when the interval configured has passed update_interval = time.time() - (config("plugins-auto-update-interval") * 60) if (last_update < update_interval): status_set("maintenance", "Updating plugins") remove_state("jenkins.updated.plugins") plugins = Plugins() plugins.update(config("plugins")) api = Api() api.wait() # Wait for the service to be fully up # Restart jenkins if any plugin got updated last_restart = unitdata.kv().get("jenkins.last_restart") or 0 last_plugin_update_time = ( unitdata.kv().get("jenkins.plugins.last_plugin_update_time") or 0) if (last_restart < last_plugin_update_time): restart() unitdata.kv().set("jenkins.plugins.last_restart", time.time()) set_state("jenkins.updated.plugins") unitdata.kv().set("jenkins.plugins.last_update", time.time())
class PluginsTest(CharmTest): def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.fakes.juju.config["plugins-site"] = "http://x/" self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data" def test_install(self): """ The given plugins are downloaded from the Jenkins site. """ self.plugins.install("plugin") self.assertEqual(["stop", "start"], self.fakes.processes.systemctl.actions["jenkins"]) plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") self.assertThat(plugin_path, FileContains("data")) def test_install_no_certificate_check(self): """ If plugins-check-certificate is set to 'no', the plugins site certificate won't be validated. """ self.fakes.juju.config["plugins-check-certificate"] = "no" self.plugins.install("plugin") self.assertIn("--no-check-certificate", self.fakes.processes.procs[-4].args) def test_install_dont_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'yes', then unlisted plugins are removed from disk. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, Not(PathExists())) def test_install_do_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'no', then unlisted plugins will be left on disk. """ unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) def test_install_skip_non_file_unlisted(self): """ If an unlisted plugin is not actually a file, it's just skipped and doesn't get removed. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") os.mkdir(unlisted_plugin) self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) def test_install_already_installed(self): """ If a plugin is already installed, it doesn't get downloaded. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") with open(plugin_path, "w"): pass self.plugins.install("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertNotIn("wget", commands)
class PluginsTest(CharmTest): def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.orig_plugins_site = hookenv.config()["plugins-site"] hookenv.config()["plugins-site"] = "http://x/" self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data" def tearDown(self): super(PluginsTest, self).tearDown() hookenv.config()["plugins-site"] = self.orig_plugins_site def test_install(self): """ The given plugins are downloaded from the Jenkins site. """ self.plugins.install("plugin") self.assertEqual(["stop", "start"], self.fakes.processes.systemctl.actions["jenkins"]) plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") self.assertThat(plugin_path, FileContains("data")) def test_install_no_certificate_check(self): """ If plugins-check-certificate is set to 'no', the plugins site certificate won't be validated. """ orig_plugins_check_certificate = hookenv.config( )["plugins-check-certificate"] try: hookenv.config()["plugins-check-certificate"] = "no" self.plugins.install("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertIn("--no-check-certificate", self.fakes.processes.procs[-4].args) finally: hookenv.config( )["plugins-check-certificate"] = orig_plugins_check_certificate def test_install_dont_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'yes', then unlisted plugins are removed from disk. """ orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, Not(PathExists())) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_install_do_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'no', then unlisted plugins will be left on disk. """ unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) def test_install_skip_non_file_unlisted(self): """ If an unlisted plugin is not actually a file, it's just skipped and doesn't get removed. """ orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") os.mkdir(unlisted_plugin) self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_install_already_installed(self): """ If a plugin is already installed, it doesn't get downloaded. """ orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" hookenv.config()["plugins-force-reinstall"] = False hookenv.config()["plugins-auto-update"] = False plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") with open(plugin_path, "w"): pass self.plugins.install("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertNotIn("wget", commands) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_install_bad_plugin(self): """ If plugin can't be downloaded we expect error message in the logs """ def broken_download(*args, **kwargs): raise Exception("error") self.plugins._install_plugin = broken_download orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" plugin_path = os.path.join(paths.PLUGINS, "bad_plugin.hpi") with open(plugin_path, "w"): pass self.assertRaises(Exception, self.plugins.install, "bad_plugin") finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_install_force_reinstall(self): """ If a plugin is already installed and plugin-force-reinstall is yes it should get downloaded. """ orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" hookenv.config()["plugins-force-reinstall"] = True plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") with open(plugin_path, "w"): pass self.plugins.install("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertIn("wget", commands) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_update(self): """ The given plugins are downloaded from the Jenkins site if newer versions are available """ hookenv.config()["plugins-auto-update"] = True plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") with open(plugin_path, "w"): pass self.plugins.update("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertIn("wget", commands) def test_update_bad_plugin(self): """ If plugin can't be downloaded we expect error message in the logs """ def broken_download(*args, **kwargs): raise Exception("error") self.plugins._install_plugin = broken_download plugin_path = os.path.join(paths.PLUGINS, "bad_plugin.hpi") with open(plugin_path, "w"): pass self.assertRaises(Exception, self.plugins.update, "bad_plugin")
class PluginsTest(CharmTest): def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.orig_plugins_site = hookenv.config()["plugins-site"] self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data" def tearDown(self): super(PluginsTest, self).tearDown() hookenv.config()["plugins-site"] = self.orig_plugins_site def test_remove_plugin(self, mock_restart_jenkins): """ The given plugin file is removed from disk. """ plugin_name = "plugin" plugin_path = os.path.join(paths.PLUGINS, "{}-1.jpi".format(plugin_name)) orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" with open(plugin_path, "w"): pass # When using a non-existent path it returns None self.assertIsNone(self.plugins._remove_plugin(plugin_name)) self.plugins._remove_plugin(plugin_path) self.assertThat(plugin_path, Not(PathExists())) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") def test_install(self, mock_get_plugin_version, mock_restart_jenkins): """ The given plugins are downloaded from the Jenkins site. """ mock_get_plugin_version.return_value = False plugin_name = "ansicolor" installed_plugin = "" installed_plugin.join(self.plugins.install(plugin_name)) plugin_path = os.path.join(paths.PLUGINS, installed_plugin) self.assertTrue(os.path.exists(plugin_path), msg="Plugin not installed in the proper directory") mock_restart_jenkins.assert_called_with() @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_raises_error(self, mock_get_plugins_to_install, mock_get_plugin_version, mock_restart_jenkins): """ When install fails it should log and raise an error """ def failed_install(*args, **kwargs): raise Exception() plugin_name = "bad_plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = False self.plugins._install_plugins = failed_install self.assertRaises(Exception, self.plugins.install, plugin_name) self.assertEqual( "INFO: Plugin installation failed, check logs for details", self.fakes.juju.log[-1]) mock_restart_jenkins.assert_not_called() @mock.patch("test_plugins.Plugins._install_plugins") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_do_remove_unlisted(self, mock_get_plugins_to_install, mock_install_plugins, mock_restart_jenkins): """ If remove-unlisted-plugins is set to 'yes', then unlisted plugins are removed from disk. """ plugin_name = "plugin" plugin_path = os.path.join(paths.PLUGINS, "{}-1.jpi".format(plugin_name)) mock_get_plugins_to_install.return_value = {plugin_name} mock_install_plugins.return_value = {plugin_path} orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.jpi") with open(unlisted_plugin, "w"): pass self.plugins.install(plugin_name) self.assertThat(unlisted_plugin, Not(PathExists())) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins @mock.patch("test_plugins.Plugins._remove_plugin") @mock.patch("test_plugins.Plugins._install_plugins") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_dont_remove_unlisted(self, mock_get_plugins_to_install, mock_install_plugins, mock_remove_plugin, mock_restart_jenkins): """ If remove-unlisted-plugins is set to 'no', then unlisted plugins will be left on disk. """ plugin_name = "plugin" plugin_path = os.path.join(paths.PLUGINS, "{}-1.jpi".format(plugin_name)) mock_get_plugins_to_install.return_value = {plugin_name} mock_install_plugins.return_value = {plugin_path} unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.jpi") unlisted_plugin_path = "{}{}".format( self.fakes.fs.root.path, os.path.join(paths.PLUGINS, "unlisted.jpi")) with open(unlisted_plugin, "w"): pass self.plugins.install(plugin_name) self.assertEqual( "INFO: Unlisted plugins: ({}) Not removed. Set " "remove-unlisted-plugins to 'yes' to clear them " "away.".format(unlisted_plugin_path), self.fakes.juju.log[-1]) mock_remove_plugin.assert_not_called() @mock.patch("test_plugins.Plugins._install_plugins") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_skip_non_file_unlisted(self, mock_get_plugins_to_install, mock_install_plugins, mock_restart_jenkins): """ If an unlisted plugin is not actually a file, it's just skipped and doesn't get removed. """ mock_get_plugins_to_install.return_value = {"plugin"} mock_install_plugins.return_value = { os.path.join(paths.PLUGINS, "plugin.jpi") } orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") os.mkdir(unlisted_plugin) self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins @mock.patch("test_plugins.Plugins._download_plugin") @mock.patch("test_plugins.Plugins._get_latest_version") @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_already_installed(self, mock_get_plugins_to_install, mock_get_latest_version, mock_get_plugin_version, mock_download_plugin, mock_restart_jenkins): """ If a plugin is already installed, it doesn't get downloaded. """ plugin_name = "plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = "1" mock_get_latest_version.return_value = "1" orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" hookenv.config()["plugins-auto-update"] = False self.plugins.install(plugin_name) mock_download_plugin.assert_not_called() finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins def test_install_bad_plugin(self, mock_restart_jenkins): """ If plugin can't be downloaded we expect error message in the logs """ orig_remove_unlisted_plugins = hookenv.config( )["remove-unlisted-plugins"] try: hookenv.config()["remove-unlisted-plugins"] = "yes" plugin_path = os.path.join(paths.PLUGINS, "bad_plugin.hpi") with open(plugin_path, "w"): pass self.assertRaises(Exception, self.plugins.install, "bad_plugin") finally: hookenv.config( )["remove-unlisted-plugins"] = orig_remove_unlisted_plugins @mock.patch("test_plugins.Plugins._download_plugin") @mock.patch("test_plugins.Plugins._get_latest_version") @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_install_fail(self, mock_get_plugins_to_install, mock_get_plugin_version, mock_get_latest_version, mock_download_plugin, mock_restart_jenkins): """If a plugin is already installed, it doesn't get downloaded.""" plugin_name = "plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = False mock_get_latest_version.return_value = "1" mock_download_plugin.return_value = False hookenv.config()["remove-unlisted-plugins"] = "yes" self.plugins.install(plugin_name) self.assertEqual("INFO: Failed to download plugin", self.fakes.juju.log[-1]) @mock.patch("test_plugins.Plugins._get_plugins_to_install") @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_latest_version") @mock.patch("test_plugins.Plugins._download_plugin") def test_update(self, mock_download_plugin, mock_get_latest_version, mock_get_plugin_version, mock_get_plugins_to_install, mock_restart_jenkins): """ The given plugins are installed from the Jenkins site if newer versions are available """ plugin_name = "plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = "1" mock_get_latest_version.return_value = "1.1" orig_plugins_auto_update = hookenv.config()["plugins-auto-update"] try: hookenv.config()["plugins-auto-update"] = True self.plugins.update(plugin_name) mock_download_plugin.assert_called_with(plugin_name, mock.ANY) mock_restart_jenkins.assert_called_with() finally: hookenv.config()["plugins-auto-update"] = orig_plugins_auto_update @mock.patch("test_plugins.Plugins._get_plugins_to_install") @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_latest_version") @mock.patch("test_plugins.Plugins._download_plugin") def test_dont_update(self, mock_download_plugin, mock_get_latest_version, mock_get_plugin_version, mock_get_plugins_to_install, mock_restart_jenkins): """ No plugins are reinstalled if not necessary. """ plugin_name = "plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = "1" mock_get_latest_version.return_value = "1" orig_plugins_auto_update = hookenv.config()["plugins-auto-update"] try: hookenv.config()["plugins-auto-update"] = True self.plugins.update(plugin_name) mock_download_plugin.assert_not_called() self.assertEqual("INFO: No plugins updated", self.fakes.juju.log[-1]) finally: hookenv.config()["plugins-auto-update"] = orig_plugins_auto_update @mock.patch("charms.layer.jenkins.api.Api.get_plugin_version") @mock.patch("test_plugins.Plugins._get_plugins_to_install") def test_update_raises_error(self, mock_get_plugins_to_install, mock_get_plugin_version, mock_restart_jenkins): """ When install fails it should log and raise an error """ def failed_install(*args, **kwargs): raise Exception() plugin_name = "bad_plugin" mock_get_plugins_to_install.return_value = {plugin_name} mock_get_plugin_version.return_value = False self.plugins._install_plugins = failed_install self.assertRaises(Exception, self.plugins.update, plugin_name) self.assertEqual("INFO: Plugin update failed, check logs for details", self.fakes.juju.log[-1]) mock_restart_jenkins.assert_not_called() def test_update_bad_plugin(self, mock_restart_jenkins): """ If plugin can't be downloaded we expect error message in the logs """ def broken_download(*args, **kwargs): raise Exception("error") self.plugins._install_plugin = broken_download plugin_path = os.path.join(paths.PLUGINS, "bad_plugin.hpi") with open(plugin_path, "w"): pass self.assertRaises(Exception, self.plugins.update, "bad_plugin") def test_using_json_from_plugin_site(self, mock_restart_jenkins): """ If the configured plugin-site has an update-center.json file, it should be used instead of the default one. """ self.plugins = Plugins() orig_plugins_site = hookenv.config()["plugins-site"] try: hookenv.config( )["plugins-site"] = "https://updates.jenkins.io/stable/" self.plugins = Plugins() finally: hookenv.config()["plugins-site"] = orig_plugins_site def test_broken_json_from_plugin_site(self, mock_restart_jenkins): """ If the configured plugin-site has no update-center.json file, it should error. """ orig_plugins_site = hookenv.config()["plugins-site"] try: hookenv.config( )["plugins-site"] = "https://updates.jenkins.io/not-valid/" self.assertRaises(Exception, Plugins) finally: hookenv.config()["plugins-site"] = orig_plugins_site
class PluginsTest(CharmTest): def setUp(self): super(PluginsTest, self).setUp() self.plugins = Plugins() self.fakes.fs.add(paths.PLUGINS) os.makedirs(paths.PLUGINS) self.fakes.users.add("jenkins", 123) self.fakes.groups.add("jenkins", 123) self.fakes.juju.config["plugins-site"] = "http://x/" self.fakes.processes.wget.locations["http://x/plugin.hpi"] = b"data" def test_install(self): """ The given plugins are downloaded from the Jenkins site. """ self.plugins.install("plugin") self.assertEqual( ["stop", "start"], self.fakes.processes.systemctl.actions["jenkins"]) plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") self.assertThat(plugin_path, FileContains("data")) def test_install_no_certificate_check(self): """ If plugins-check-certificate is set to 'no', the plugins site certificate won't be validated. """ self.fakes.juju.config["plugins-check-certificate"] = "no" self.plugins.install("plugin") self.assertIn( "--no-check-certificate", self.fakes.processes.procs[-4].args) def test_install_dont_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'yes', then unlisted plugins are removed from disk. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, Not(PathExists())) def test_install_do_remove_unlisted(self): """ If remove-unlisted-plugins is set to 'no', then unlisted plugins will be left on disk. """ unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") with open(unlisted_plugin, "w"): pass self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) def test_install_skip_non_file_unlisted(self): """ If an unlisted plugin is not actually a file, it's just skipped and doesn't get removed. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" unlisted_plugin = os.path.join(paths.PLUGINS, "unlisted.hpi") os.mkdir(unlisted_plugin) self.plugins.install("plugin") self.assertThat(unlisted_plugin, PathExists()) def test_install_already_installed(self): """ If a plugin is already installed, it doesn't get downloaded. """ self.fakes.juju.config["remove-unlisted-plugins"] = "yes" plugin_path = os.path.join(paths.PLUGINS, "plugin.hpi") with open(plugin_path, "w"): pass self.plugins.install("plugin") commands = [proc.args[0] for proc in self.fakes.processes.procs] self.assertNotIn("wget", commands)
def plugins_layer(): try: plugins = Plugins() except PluginSiteError as e: status_set("error", e.message) return plugins