Add a get_nodes method

Until now it has not been possible to enumerate build nodes connected to
the master. This commit adds the support via get_nodes() method, which
returns a list of dicts with name and offline-status for the nodes.

Signed-off-by: Antoine Musso <hashar@free.fr>
Change-Id: Ia51ee71196a80e365693959edac860730e7ea202
This commit is contained in:
Teemu Patja
2015-03-10 18:13:45 +02:00
committed by Antoine Musso
parent 0632d046b1
commit b66509d5df
2 changed files with 76 additions and 1 deletions

View File

@@ -81,7 +81,7 @@ STOP_BUILD = 'job/%(name)s/%(number)s/stop'
BUILD_WITH_PARAMS_JOB = 'job/%(name)s/buildWithParameters'
BUILD_INFO = 'job/%(name)s/%(number)d/api/json?depth=%(depth)s'
BUILD_CONSOLE_OUTPUT = 'job/%(name)s/%(number)d/consoleText'
NODE_LIST = 'computer/api/json'
CREATE_NODE = 'computer/doCreateItem?%s'
DELETE_NODE = 'computer/%(name)s/doDelete'
NODE_INFO = 'computer/%(name)s/api/json?depth=%(depth)s'
@@ -648,6 +648,24 @@ class Jenkins(object):
'''
self.jenkins_open(Request(self.server + STOP_BUILD % self._get_encoded_params(locals())))
def get_nodes(self):
'''Get a list of nodes connected to the Master
Each node is a dict with keys 'name' and 'offline'
:returns: List of nodes, ``[ { str: str, str: bool} ]``
'''
try:
nodes_data = json.loads(self.jenkins_open(Request(self.server + NODE_LIST)))
return [{'name': c["displayName"], 'offline': c["offline"]}
for c in nodes_data["computer"]]
except (HTTPError, BadStatusLine):
raise BadHTTPException("Error communicating with server[%s]"
% self.server)
except ValueError:
raise JenkinsException("Could not parse JSON info for server[%s]"
% self.server)
def get_node_info(self, name, depth=0):
'''Get node information dictionary

View File

@@ -1144,6 +1144,63 @@ class JenkinsTest(unittest.TestCase):
jenkins_mock.call_args[0][0].get_full_url(),
u'http://example.com/queue/cancelItem?id=52')
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_get_nodes(self, jenkins_mock):
jenkins_mock.return_value = json.dumps({
"computer": [{
"displayName": "master",
"offline": False
}],
"busyExecutors": 2})
j = jenkins.Jenkins('http://example.com/', 'test', 'test')
self.assertEqual(j.get_nodes(),
[{'name': 'master', 'offline': False}])
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_get_nodes__invalid_json(self, jenkins_mock):
jenkins_mock.side_effect = [
'Invalid JSON',
]
j = jenkins.Jenkins('http://example.com/', 'test', 'test')
with self.assertRaises(jenkins.JenkinsException) as context_manager:
j.get_nodes()
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
'http://example.com/computer/api/json')
self.assertEqual(
str(context_manager.exception),
'Could not parse JSON info for server[http://example.com/]')
@patch('jenkins.urlopen')
def test_get_nodes__BadStatusLine(self, urlopen_mock):
urlopen_mock.side_effect = jenkins.BadStatusLine('not a valid status line')
j = jenkins.Jenkins('http://example.com/', 'test', 'test')
with self.assertRaises(jenkins.BadHTTPException) as context_manager:
j.get_nodes()
self.assertEqual(
str(context_manager.exception),
'Error communicating with server[http://example.com/]')
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_get_nodes__HTTPError(self, jenkins_mock):
jenkins_mock.side_effect = jenkins.HTTPError(
'http://example.com/job/TestJob',
code=401,
msg="basic auth failed",
hdrs=[],
fp=None)
j = jenkins.Jenkins('http://example.com/', 'test', 'test')
with self.assertRaises(jenkins.JenkinsException) as context_manager:
j.get_nodes()
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
'http://example.com/computer/api/json')
self.assertEqual(
str(context_manager.exception),
'Error communicating with server[http://example.com/]')
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_get_node_info(self, jenkins_mock):
node_info = {