From: salimfadhley Date: Mon, 17 Jun 2013 23:44:26 +0000 (+0100) Subject: yet another refactor of nodes, this time with better tests X-Git-Tag: v0.2.23~153 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6466ed97c1dc0558f3331181a1e6631df60286fd;p=tools%2Fpython-jenkinsapi.git yet another refactor of nodes, this time with better tests --- diff --git a/jenkinsapi/exceptions.py b/jenkinsapi/exceptions.py index 04cf7cb..4cee5e8 100644 --- a/jenkinsapi/exceptions.py +++ b/jenkinsapi/exceptions.py @@ -18,6 +18,11 @@ class UnknownView( KeyError, JenkinsAPIException): Jenkins does not recognize the view requested. """ +class UnknownNode( KeyError, JenkinsAPIException): + """ + Jenkins does not recognize the node requested. + """ + class UnknownQueueItem( KeyError, JenkinsAPIException): """ Jenkins does not recognize the requested queue item diff --git a/jenkinsapi/jenkins.py b/jenkinsapi/jenkins.py index 54b2186..8f5afeb 100644 --- a/jenkinsapi/jenkins.py +++ b/jenkinsapi/jenkins.py @@ -216,10 +216,6 @@ class Jenkins(JenkinsBase): str_view_name = str_view_url.split('/view/')[-1].replace('/', '') return View(str_view_url , str_view_name, jenkins_obj=self) - def get_nodes(self): - url = self.get_nodes_url() - return Nodes(url, self) - def __getitem__(self, jobname): """ Get a job by name @@ -239,18 +235,9 @@ class Jenkins(JenkinsBase): """ return jobname in self.get_jobs_list() - def get_node_dict(self): - """Get registered slave nodes on this instance""" - url = self.python_api_url(self.get_node_url()) - node_dict = dict(self.get_data(url)) - return dict( - (node['displayName'], self.python_api_url(self.get_node_url(node['displayName']))) - for node in node_dict['computer']) - def get_node(self, nodename): """Get a node object for a specific node""" - node_url = self.get_node_url(nodename) - return Node(node_url, nodename, jenkins_obj=self) + return self.get_nodes()[nodename] def get_node_url(self, nodename=""): """Return the url for nodes""" @@ -265,6 +252,10 @@ class Jenkins(JenkinsBase): queue_url = self.get_queue_url() return Queue(queue_url, self) + def get_nodes(self): + url = self.get_nodes_url() + return Nodes(url, self) + def has_node(self, nodename): """ Does a node by the name specified exist @@ -272,7 +263,7 @@ class Jenkins(JenkinsBase): :return: boolean """ self.poll() - return nodename in self.get_node_dict() + return nodename in self.get_nodes() def delete_node(self, nodename): """ diff --git a/jenkinsapi/node.py b/jenkinsapi/node.py index 59555f3..1fb9f48 100644 --- a/jenkinsapi/node.py +++ b/jenkinsapi/node.py @@ -58,7 +58,6 @@ class Node(JenkinsBase): (self._data['offline'], self._data['temporarilyOffline'])) elif self._data['offline'] and self._data['temporarilyOffline']: self.toggle_temporarily_offline() - self.poll() if self._data['offline']: raise AssertionError("The node state is still offline, check client connection:" + " offline = %s , temporarilyOffline = %s" % @@ -70,7 +69,6 @@ class Node(JenkinsBase): If after run node state has not been changed raise AssertionError. : param message: optional string explain why you are taking this node offline """ - self.poll() if not self._data['offline']: self.toggle_temporarily_offline(message) self.poll() @@ -87,7 +85,8 @@ class Node(JenkinsBase): """ initial_state = self.is_temporarily_offline() url = self.baseurl + "/toggleOffline?offlineMessage=" + urllib.quote(message) - html_result = self.hit_url(url) + html_result = self.jenkins.requester.get_and_confirm_status(url) + self.poll() log.debug(html_result) if initial_state == self.is_temporarily_offline(): raise AssertionError("The node state has not changed: temporarilyOffline = %s" % state) diff --git a/jenkinsapi/nodes.py b/jenkinsapi/nodes.py index 5c93647..d6001cc 100644 --- a/jenkinsapi/nodes.py +++ b/jenkinsapi/nodes.py @@ -1,5 +1,6 @@ import logging from jenkinsapi.node import Node +from jenkinsapi.exceptions import UnknownNode from jenkinsapi.jenkinsbase import JenkinsBase log = logging.getLogger(__name__) @@ -16,19 +17,36 @@ class Nodes(JenkinsBase): self.jenkins = jenkins_obj JenkinsBase.__init__(self, baseurl) + def get_jenkins_obj(self): + return self.jenkins + def __str__(self): return 'Nodes @ %s' % self.baseurl + def __contains__(self, node_name): + return node_name in self.keys() + + def iterkeys(self): + for item in self._data['computer']: + yield item['displayName'] + + def keys(self): + return list(self.iterkeys()) + def iteritems(self): for item in self._data['computer']: nodename = item['displayName'] - if nodename == 'master': + if nodename.lower() == 'master': nodeurl = '%s/(%s)' % (self.baseurl, nodename) else: nodeurl = '%s/%s' % (self.baseurl, nodename) - yield item['displayName'], Node(nodeurl, nodename, self.jenkins) + try: + yield item['displayName'], Node(nodeurl, nodename, self.jenkins) + except Exception: + import ipdb; ipdb.set_trace() def __getitem__(self, nodename): for k, v in self.iteritems(): if k == nodename: return v + raise UnknownNode(nodename) diff --git a/jenkinsapi/utils/requester.py b/jenkinsapi/utils/requester.py index 3f9a002..c0eb23d 100644 --- a/jenkinsapi/utils/requester.py +++ b/jenkinsapi/utils/requester.py @@ -45,6 +45,7 @@ class Requester(object): requestKwargs = self.get_request_dict(url, params, None, headers) return requests.get(url, **requestKwargs) + def post_url(self, url, params=None, data=None, headers=None): requestKwargs = self.get_request_dict(url, params, data, headers) return requests.post(url, **requestKwargs) diff --git a/jenkinsapi_tests/systests/test_nodes.py b/jenkinsapi_tests/systests/test_nodes.py index 4fb3b90..e485e9f 100644 --- a/jenkinsapi_tests/systests/test_nodes.py +++ b/jenkinsapi_tests/systests/test_nodes.py @@ -11,17 +11,37 @@ log = logging.getLogger(__name__) class TestNodes(BaseSystemTest): + def test_invoke_job_parameterized(self): node_name = random_string() - J = Jenkins('http://localhost:8080') - J.create_node(node_name) - self.assertTrue(J.has_node(node_name)) + self.jenkins.create_node(node_name) + self.assertTrue(self.jenkins.has_node(node_name)) + + N = self.jenkins.get_node(node_name) + self.assertEquals(N.baseurl, self.jenkins.get_node_url(node_name)) + + self.jenkins.delete_node(node_name) + self.assertFalse(self.jenkins.has_node(node_name)) + + def test_online_offline(self): + """ + Can we flip the online / offline state of the master node. + """ + # Master node name should be case insensitive + #mn0 = self.jenkins.get_node('MaStEr') + mn = self.jenkins.get_node('master') + #self.assertEquals(mn, mn0) + + mn.set_online() # It should already be online, hence no-op + self.assertTrue(mn.is_online()) + + mn.set_offline() # We switch that suckah off + mn.set_offline() # This should be a no-op + self.assertFalse(mn.is_online()) - N = J.get_node(node_name) - self.assertEquals(N.baseurl, J.get_node_url(node_name)) + mn.set_online() # Switch it back on + self.assertTrue(mn.is_online()) - J.delete_node(node_name) - self.assertFalse(J.has_node(node_name)) if __name__ == '__main__': logging.basicConfig() diff --git a/jenkinsapi_tests/unittests/test_node.py b/jenkinsapi_tests/unittests/test_node.py index fefd4e5..e595838 100644 --- a/jenkinsapi_tests/unittests/test_node.py +++ b/jenkinsapi_tests/unittests/test_node.py @@ -48,4 +48,9 @@ class TestNode(unittest.TestCase): with self.assertRaises(AttributeError): self.n.id() + def test_online(self): + return assertEquals(self.n, True) + + + self.assertEquals(self.n.name, 'bobnit')