summaryrefslogtreecommitdiffstats
path: root/pharos-dashboard/jenkins
diff options
context:
space:
mode:
authormaxbr <maxbr@mi.fu-berlin.de>2016-08-19 17:10:31 +0200
committermaxbr <maxbr@mi.fu-berlin.de>2016-08-19 17:10:31 +0200
commit79aec84973032e15ae9d36fcbd7d7d42af3283d1 (patch)
treec02fbd44cd53b0eed105bc648c743b10c62bfeb4 /pharos-dashboard/jenkins
parent639cd5db77064c275253828780c17ae59551d95c (diff)
Split the dashboard into different apps, add tests
JIRA: RELENG-12 Signed-off-by: maxbr <maxbr@mi.fu-berlin.de>
Diffstat (limited to 'pharos-dashboard/jenkins')
-rw-r--r--pharos-dashboard/jenkins/__init__.py0
-rw-r--r--pharos-dashboard/jenkins/adapter.py153
-rw-r--r--pharos-dashboard/jenkins/apps.py5
-rw-r--r--pharos-dashboard/jenkins/tests.py42
4 files changed, 200 insertions, 0 deletions
diff --git a/pharos-dashboard/jenkins/__init__.py b/pharos-dashboard/jenkins/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pharos-dashboard/jenkins/__init__.py
diff --git a/pharos-dashboard/jenkins/adapter.py b/pharos-dashboard/jenkins/adapter.py
new file mode 100644
index 0000000..06233af
--- /dev/null
+++ b/pharos-dashboard/jenkins/adapter.py
@@ -0,0 +1,153 @@
+import logging
+
+import re
+import requests
+from django.core.cache import cache
+
+logger = logging.getLogger(__name__)
+
+
+# TODO: implement caching decorator, cache get_* functions
+def get_json(url):
+ if cache.get(url) is None:
+ try:
+ response = requests.get(url)
+ json = response.json()
+ cache.set(url, json, 180) # cache result for 180 seconds
+ return response.json()
+ except requests.exceptions.RequestException as e:
+ logger.exception(e)
+ except ValueError as e:
+ logger.exception(e)
+ else:
+ return cache.get(url)
+
+
+def get_all_slaves():
+ url = "https://build.opnfv.org/ci/computer/api/json?tree=computer[displayName,offline,idle]"
+ json = get_json(url)
+ if json is not None:
+ return json['computer'] # return list of dictionaries
+ return []
+
+
+def get_slave(slavename):
+ slaves = get_all_slaves()
+ for slave in slaves:
+ if slave['displayName'] == slavename:
+ return slave
+ return {}
+
+
+def get_ci_slaves():
+ url = "https://build.opnfv.org/ci/label/ci-pod/api/json?tree=nodes[nodeName,offline,idle]"
+ json = get_json(url)
+ if json is not None:
+ return json['nodes']
+ return []
+
+
+def get_all_jobs():
+ url = "https://build.opnfv.org/ci/api/json?tree=jobs[displayName,url,lastBuild[fullDisplayName,building,builtOn,timestamp,result]]"
+ json = get_json(url)
+ if json is not None:
+ return json['jobs'] # return list of dictionaries
+ return []
+
+
+def get_jenkins_job(slavename):
+ jobs = get_all_jobs()
+ max_time = 0
+ last_job = None
+ for job in jobs:
+ if job['lastBuild'] is not None:
+ if job['lastBuild']['builtOn'] == slavename:
+ if job['lastBuild']['building'] is True:
+ return job # return active build
+ if job['lastBuild']['timestamp'] > max_time:
+ last_job = job
+ max_time = job['lastBuild']['timestamp']
+ return last_job
+
+
+def is_ci_slave(slavename):
+ ci_slaves = get_ci_slaves()
+ for ci_slave in ci_slaves:
+ if ci_slave['nodeName'] == slavename:
+ return True
+ return False
+
+
+def is_dev_pod(slavename):
+ if is_ci_slave(slavename):
+ return False
+ if slavename.find('pod') != -1:
+ return True
+ return False
+
+def parse_slave_data(slave_dict, slave):
+ slave_dict['status'] = get_slave_status(slave)
+ slave_dict['status_color'] = get_status_color(slave)
+ slave_dict['slaveurl'] = get_slave_url(slave)
+ job = get_jenkins_job(slave['displayName'])
+ if job is not None:
+ slave_dict['last_job'] = parse_job(job)
+
+
+def parse_job(job):
+ result = parse_job_string(job['lastBuild']['fullDisplayName'])
+ result['url'] = job['url']
+ result['color'] = get_job_color(job)
+ if job['lastBuild']['building']:
+ result['blink'] = 'class=blink_me'
+ return result
+
+
+def parse_job_string(full_displayname):
+ job = {}
+ tokens = re.split(r'[ -]', full_displayname)
+ for i in range(len(tokens)):
+ if tokens[i] == 'os':
+ job['scenario'] = '-'.join(tokens[i: i + 4])
+ elif tokens[i] in ['fuel', 'joid', 'apex', 'compass']:
+ job['installer'] = tokens[i]
+ elif tokens[i] in ['master', 'arno', 'brahmaputra', 'colorado']:
+ job['branch'] = tokens[i]
+
+ tokens = full_displayname.split(' ')
+ job['name'] = tokens[0]
+ return job
+
+
+# TODO: use css
+def get_job_color(job):
+ if job['lastBuild']['building'] is True:
+ return '#646F73'
+ result = job['lastBuild']['result']
+ if result == 'SUCCESS':
+ return '#5cb85c'
+ if result == 'FAILURE':
+ return '#d9534f'
+ if result == 'UNSTABLE':
+ return '#EDD62B'
+
+
+# TODO: use css
+def get_status_color(slave):
+ if not slave['offline'] and slave['idle']:
+ return '#5bc0de'
+ if not slave['offline']:
+ return '#5cb85c'
+ return '#d9534f'
+
+
+def get_slave_url(slave):
+ return 'https://build.opnfv.org/ci/computer/' + slave['displayName']
+
+
+def get_slave_status(slave):
+ if not slave['offline'] and slave['idle']:
+ return 'online / idle'
+ if not slave['offline']:
+ return 'online'
+ return 'offline'
diff --git a/pharos-dashboard/jenkins/apps.py b/pharos-dashboard/jenkins/apps.py
new file mode 100644
index 0000000..5abd215
--- /dev/null
+++ b/pharos-dashboard/jenkins/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class JenkinsConfig(AppConfig):
+ name = 'jenkins'
diff --git a/pharos-dashboard/jenkins/tests.py b/pharos-dashboard/jenkins/tests.py
new file mode 100644
index 0000000..b141451
--- /dev/null
+++ b/pharos-dashboard/jenkins/tests.py
@@ -0,0 +1,42 @@
+from unittest import TestCase
+
+import jenkins.adapter as jenkins
+
+
+# Tests that the data we get with the jenkinsadapter contains all the
+# data we need. These test will fail if;
+# - there is no internet connection
+# - the opnfv jenkins url has changed
+# - the jenkins api has changed
+# - jenkins is not set up / there is no data
+class JenkinsAdapterTestCase(TestCase):
+ def test_get_all_slaves(self):
+ slaves = jenkins.get_all_slaves()
+ self.assertTrue(len(slaves) > 0)
+ for slave in slaves:
+ self.assertTrue('displayName' in slave)
+ self.assertTrue('idle' in slave)
+ self.assertTrue('offline' in slave)
+
+ def test_get_ci_slaves(self):
+ slaves = jenkins.get_ci_slaves()
+ self.assertTrue(len(slaves) > 0)
+ for slave in slaves:
+ self.assertTrue('nodeName' in slave)
+
+ def test_get_all_jobs(self):
+ jobs = jenkins.get_all_jobs()
+ lastBuild = False
+ self.assertTrue(len(jobs) > 0)
+ for job in jobs:
+ self.assertTrue('displayName' in job)
+ self.assertTrue('url' in job)
+ self.assertTrue('lastBuild' in job)
+ if job['lastBuild'] is not None:
+ lastBuild = True
+ self.assertTrue('building' in job['lastBuild'])
+ self.assertTrue('fullDisplayName' in job['lastBuild'])
+ self.assertTrue('result' in job['lastBuild'])
+ self.assertTrue('timestamp' in job['lastBuild'])
+ self.assertTrue('builtOn' in job['lastBuild'])
+ self.assertTrue(lastBuild)