Added ability to query for installed plugins
authorAleksey Maksimov <ctpeko3a@gmail.com>
Wed, 24 Jul 2013 16:19:15 +0000 (00:19 +0800)
committerAleksey Maksimov <ctpeko3a@gmail.com>
Wed, 24 Jul 2013 17:04:40 +0000 (01:04 +0800)
jenkinsapi/jenkins.py
jenkinsapi/plugin.py [new file with mode: 0644]
jenkinsapi/plugins.py [new file with mode: 0644]
jenkinsapi_tests/unittests/test_jenkins.py
jenkinsapi_tests/unittests/test_plugins.py [new file with mode: 0644]

index 08d917bfc656fe738ce7f3023516560e58cfff95..334b49d4018b450df3cef79c250fb42e43649524 100644 (file)
@@ -7,6 +7,7 @@ from jenkinsapi.job import Job
 from jenkinsapi.node import Node
 from jenkinsapi.view import View
 from jenkinsapi.nodes import Nodes
+from jenkinsapi.plugins import Plugins
 from jenkinsapi.views import Views
 from jenkinsapi.queue import Queue
 from jenkinsapi.fingerprint import Fingerprint
@@ -14,10 +15,9 @@ from jenkinsapi.jenkinsbase import JenkinsBase
 from jenkinsapi.utils.requester import Requester
 from jenkinsapi.exceptions import UnknownJob, JenkinsAPIException
 
-
-
 log = logging.getLogger(__name__)
 
+
 class Jenkins(JenkinsBase):
     """
     Represents a jenkins environment.
@@ -315,3 +315,14 @@ class Jenkins(JenkinsBase):
         self.requester.get_and_confirm_status(url)
 
         return Node(nodename=name, baseurl=self.get_node_url(nodename=name), jenkins_obj=self)
+
+    def get_plugins_url(self):
+        # This only ever needs to work on the base object
+        return '%s/pluginManager/api/python?depth=1' % self.baseurl
+
+    def get_plugins(self):
+        url = self.get_plugins_url()
+        return Plugins(url, self)
+
+    def has_plugin(self, plugin_name):
+        return plugin_name in self.get_plugins()
diff --git a/jenkinsapi/plugin.py b/jenkinsapi/plugin.py
new file mode 100644 (file)
index 0000000..b64a706
--- /dev/null
@@ -0,0 +1,7 @@
+class Plugin(object):
+    def __init__(self, plugin_dict):
+        assert(isinstance(plugin_dict, dict))
+        self.__dict__ = plugin_dict
+
+    def __eq__(self, other): 
+        return self.__dict__ == other.__dict__
diff --git a/jenkinsapi/plugins.py b/jenkinsapi/plugins.py
new file mode 100644 (file)
index 0000000..06ae7f1
--- /dev/null
@@ -0,0 +1,53 @@
+import urllib
+import logging
+
+from jenkinsapi.jenkinsbase import JenkinsBase
+from jenkinsapi.plugin import Plugin
+
+
+log = logging.getLogger(__name__)
+
+
+class Plugins(JenkinsBase):
+    def __init__(self, url, jenkins_obj):
+        self.jenkins_obj = jenkins_obj
+        JenkinsBase.__init__(self, url)
+        # print 'DEBUG: Plugins._data=', self._data
+
+    def get_jenkins_obj(self):
+        return self.jenkins_obj
+
+    def _poll(self):
+        return self.get_data(self.baseurl)
+
+    def keys(self):
+        return self.get_plugins_dict().keys()
+
+    def iteritems(self):
+        return self._get_plugins()
+
+    def values(self):
+        return [a[1] for a in self.iteritems()]
+
+    def _get_plugins(self):
+        if not 'plugins' in self._data:
+            pass
+        else:
+            for p_dict in self._data["plugins"]:
+                yield p_dict["shortName"], Plugin(p_dict)
+
+    def get_plugins_dict(self):
+        return dict(self._get_plugins())
+
+    def __len__(self):
+        return len(self.get_plugins_dict().keys())
+
+    def __getitem__(self, plugin_name):
+        return self.get_plugins_dict().get(plugin_name, None)
+
+    def __contains__(self, plugin_name):
+        """
+        True if plugin_name is the name of a defined plugin
+        """
+        return plugin_name in self.keys()
+
index b80e54ee42b8001c46e0cbe473d1210b070cf96c..d42b9d34490f43b64e115da9ba87d771ee8e6405 100644 (file)
@@ -4,6 +4,7 @@ import unittest
 from jenkinsapi.utils.requester import Requester
 from jenkinsapi.exceptions import JenkinsAPIException
 from jenkinsapi.jenkins import Jenkins, JenkinsBase, Job
+from jenkinsapi.plugins import Plugins
 
 
 class TestJenkins(unittest.TestCase):
@@ -355,6 +356,22 @@ class TestJenkinsURLs(unittest.TestCase):
         self.assertEquals(
             J.get_create_url(), 'http://localhost:8080/createItem')
 
+    @mock.patch.object(Jenkins, '_poll')
+    @mock.patch.object(Plugins, '_poll')
+    def test_has_plugin(self, _p_poll, _poll):
+        _poll.return_value = {}
+        _p_poll.return_value = {'plugins': [
+            {'deleted': False, 'hasUpdate': True, 'downgradable': False, 
+            'dependencies': [{}, {}, {}, {}], 
+            'longName': 'Jenkins Subversion Plug-in', 'active': True, 
+            'shortName': 'subversion', 'backupVersion': None, 
+            'url': 'http://wiki.jenkins-ci.org/display/JENKINS/Subversion+Plugin',
+            'enabled': True, 'pinned': False, 'version': '1.45', 
+            'supportsDynamicLoad': 'MAYBE', 'bundled': True}]}
+
+        J = Jenkins('http://localhost:8080/',
+                    username='foouser', password='foopassword')
+        self.assertTrue(J.has_plugin('subversion'))
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/jenkinsapi_tests/unittests/test_plugins.py b/jenkinsapi_tests/unittests/test_plugins.py
new file mode 100644 (file)
index 0000000..2981e2c
--- /dev/null
@@ -0,0 +1,100 @@
+import mock
+import unittest
+
+from jenkinsapi.jenkins import Jenkins
+from jenkinsapi.plugins import Plugins
+from jenkinsapi.plugin import Plugin
+
+
+class TestPlugins(unittest.TestCase):
+    DATA = {'plugins': [
+            {'deleted': False, 'hasUpdate': True, 'downgradable': False, 
+            'dependencies': [{}, {}, {}, {}], 
+            'longName': 'Jenkins Subversion Plug-in', 'active': True, 
+            'shortName': 'subversion', 'backupVersion': None, 
+            'url': 'http://wiki.jenkins-ci.org/display/JENKINS/Subversion+Plugin',
+            'enabled': True, 'pinned': False, 'version': '1.45', 
+            'supportsDynamicLoad': 'MAYBE', 'bundled': True}, 
+            {'deleted': False, 'hasUpdate': True, 'downgradable': False, 
+            'dependencies': [{}, {}], 'longName': 'Maven Integration plugin', 
+            'active': True, 'shortName': 'maven-plugin', 'backupVersion': None, 
+            'url': 'http://wiki.jenkins-ci.org/display/JENKINS/Maven+Project+Plugin', 
+            'enabled': True, 'pinned': False, 'version': '1.521', 
+            'supportsDynamicLoad': 'MAYBE', 'bundled': True}
+        ]}
+
+    @mock.patch.object(Jenkins, '_poll')
+    def setUp(self, _poll_jenkins):
+        _poll_jenkins.return_value = {}
+
+        self.J = Jenkins('http://localhost:8080')
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_get_plugins(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        # Can we produce a repr string for this object
+        self.assertIsInstance(self.J.get_plugins(), Plugins)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugins_len(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        plugins = self.J.get_plugins()
+        self.assertEquals(len(plugins), 2)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugins_contains(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        plugins = self.J.get_plugins()
+        self.assertIn('subversion', plugins)
+        self.assertIn('maven-plugin', plugins)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugins_values(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        p = Plugin({'deleted': False, 'hasUpdate': True, 'downgradable': False, 
+            'dependencies': [{}, {}, {}, {}], 
+            'longName': 'Jenkins Subversion Plug-in', 'active': True, 
+            'shortName': 'subversion', 'backupVersion': None, 
+            'url': 'http://wiki.jenkins-ci.org/display/JENKINS/Subversion+Plugin',
+            'enabled': True, 'pinned': False, 'version': '1.45', 
+            'supportsDynamicLoad': 'MAYBE', 'bundled': True})
+
+        plugins = self.J.get_plugins().values()
+        self.assertIn(p, plugins)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugins_keys(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        plugins = self.J.get_plugins().keys()
+        self.assertIn('subversion', plugins)
+        self.assertIn('maven-plugin', plugins)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugins_empty(self, _poll_plugins):
+        _poll_plugins.return_value = {}
+
+        plugins = self.J.get_plugins().keys()
+        self.assertEquals([], plugins)
+
+    @mock.patch.object(Plugins, '_poll')
+    def test_plugin_get_by_name(self, _poll_plugins):
+        _poll_plugins.return_value = self.DATA
+
+        p = Plugin({'deleted': False, 'hasUpdate': True, 'downgradable': False, 
+            'dependencies': [{}, {}, {}, {}], 
+            'longName': 'Jenkins Subversion Plug-in', 'active': True, 
+            'shortName': 'subversion', 'backupVersion': None, 
+            'url': 'http://wiki.jenkins-ci.org/display/JENKINS/Subversion+Plugin',
+            'enabled': True, 'pinned': False, 'version': '1.45', 
+            'supportsDynamicLoad': 'MAYBE', 'bundled': True})
+
+        plugin = self.J.get_plugins()['subversion']
+        self.assertEquals(p, plugin)
+
+if __name__ == '__main__':
+    unittest.main()