summaryrefslogtreecommitdiffstats
path: root/tools/pharos-dashboard/src/dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pharos-dashboard/src/dashboard')
-rw-r--r--tools/pharos-dashboard/src/dashboard/models.py2
-rw-r--r--tools/pharos-dashboard/src/dashboard/tasks.py3
-rw-r--r--tools/pharos-dashboard/src/dashboard/templatetags/jira_filters.py3
-rw-r--r--tools/pharos-dashboard/src/dashboard/tests/__init__.py10
-rw-r--r--tools/pharos-dashboard/src/dashboard/tests/test_models.py69
-rw-r--r--tools/pharos-dashboard/src/dashboard/tests/test_views.py75
-rw-r--r--tools/pharos-dashboard/src/dashboard/urls.py1
-rw-r--r--tools/pharos-dashboard/src/dashboard/views.py10
8 files changed, 164 insertions, 9 deletions
diff --git a/tools/pharos-dashboard/src/dashboard/models.py b/tools/pharos-dashboard/src/dashboard/models.py
index e3f22e69..ec6fec76 100644
--- a/tools/pharos-dashboard/src/dashboard/models.py
+++ b/tools/pharos-dashboard/src/dashboard/models.py
@@ -10,9 +10,9 @@
from datetime import timedelta
-from django.utils import timezone
from django.contrib.auth.models import User
from django.db import models
+from django.utils import timezone
from jenkins.models import JenkinsSlave
diff --git a/tools/pharos-dashboard/src/dashboard/tasks.py b/tools/pharos-dashboard/src/dashboard/tasks.py
index 4c09bf90..c5ef5054 100644
--- a/tools/pharos-dashboard/src/dashboard/tasks.py
+++ b/tools/pharos-dashboard/src/dashboard/tasks.py
@@ -8,8 +8,9 @@
##############################################################################
-from celery import shared_task
from datetime import timedelta
+
+from celery import shared_task
from django.utils import timezone
from jenkins.models import JenkinsStatistic
diff --git a/tools/pharos-dashboard/src/dashboard/templatetags/jira_filters.py b/tools/pharos-dashboard/src/dashboard/templatetags/jira_filters.py
index 70208436..9a97c1d5 100644
--- a/tools/pharos-dashboard/src/dashboard/templatetags/jira_filters.py
+++ b/tools/pharos-dashboard/src/dashboard/templatetags/jira_filters.py
@@ -8,9 +8,8 @@
##############################################################################
-from django.template.defaultfilters import register
-
from django.conf import settings
+from django.template.defaultfilters import register
@register.filter
diff --git a/tools/pharos-dashboard/src/dashboard/tests/__init__.py b/tools/pharos-dashboard/src/dashboard/tests/__init__.py
new file mode 100644
index 00000000..b5914ce7
--- /dev/null
+++ b/tools/pharos-dashboard/src/dashboard/tests/__init__.py
@@ -0,0 +1,10 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
diff --git a/tools/pharos-dashboard/src/dashboard/tests/test_models.py b/tools/pharos-dashboard/src/dashboard/tests/test_models.py
new file mode 100644
index 00000000..3a3aeab1
--- /dev/null
+++ b/tools/pharos-dashboard/src/dashboard/tests/test_models.py
@@ -0,0 +1,69 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from datetime import timedelta
+from math import ceil, floor
+
+from django.test import TestCase
+from django.utils import timezone
+
+from booking.models import *
+from dashboard.models import Resource
+from jenkins.models import JenkinsSlave
+
+
+class ResourceModelTestCase(TestCase):
+ def setUp(self):
+ self.slave = JenkinsSlave.objects.create(name='test', url='test')
+ self.owner = User.objects.create(username='owner')
+
+ self.res1 = Resource.objects.create(name='res1', slave=self.slave, description='x',
+ url='x', owner=self.owner)
+
+ def test_booking_utilization(self):
+ utilization = self.res1.get_booking_utilization(1)
+ self.assertTrue(utilization['booked_seconds'] == 0)
+ self.assertTrue(utilization['available_seconds'] == timedelta(weeks=1).total_seconds())
+
+ start = timezone.now() + timedelta(days=1)
+ end = start + timedelta(days=1)
+ booking = Booking.objects.create(start=start, end=end, purpose='test', resource=self.res1,
+ user=self.owner)
+
+ utilization = self.res1.get_booking_utilization(1)
+ booked_seconds = timedelta(days=1).total_seconds()
+ self.assertEqual(utilization['booked_seconds'], booked_seconds)
+
+ utilization = self.res1.get_booking_utilization(-1)
+ self.assertEqual(utilization['booked_seconds'], 0)
+
+ booking.delete()
+ start = timezone.now() - timedelta(days=1)
+ end = start + timedelta(days=2)
+ booking = Booking.objects.create(start=start, end=end, purpose='test', resource=self.res1,
+ user=self.owner)
+ booked_seconds = self.res1.get_booking_utilization(1)['booked_seconds']
+ # use ceil because a fraction of the booked time has already passed now
+ booked_seconds = ceil(booked_seconds)
+ self.assertEqual(booked_seconds, timedelta(days=1).total_seconds())
+
+ booking.delete()
+ start = timezone.now() + timedelta(days=6)
+ end = start + timedelta(days=2)
+ booking = Booking.objects.create(start=start, end=end, purpose='test', resource=self.res1,
+ user=self.owner)
+ booked_seconds = self.res1.get_booking_utilization(1)['booked_seconds']
+ booked_seconds = floor(booked_seconds)
+ self.assertEqual(booked_seconds, timedelta(days=1).total_seconds())
+
+
+
+
+
diff --git a/tools/pharos-dashboard/src/dashboard/tests/test_views.py b/tools/pharos-dashboard/src/dashboard/tests/test_views.py
new file mode 100644
index 00000000..f5e17c2a
--- /dev/null
+++ b/tools/pharos-dashboard/src/dashboard/tests/test_views.py
@@ -0,0 +1,75 @@
+##############################################################################
+# Copyright (c) 2016 Max Breitenfeldt and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from django.test import TestCase
+from django.urls import reverse
+
+from dashboard.models import Resource
+from jenkins.models import JenkinsSlave
+
+
+class DashboardViewTestCase(TestCase):
+ def setUp(self):
+ self.slave_active = JenkinsSlave.objects.create(name='slave_active', url='x', active=True)
+ self.slave_inactive = JenkinsSlave.objects.create(name='slave_inactive', url='x',
+ active=False)
+ self.res_active = Resource.objects.create(name='res_active', slave=self.slave_active,
+ description='x', url='x')
+ self.res_inactive = Resource.objects.create(name='res_inactive', slave=self.slave_inactive,
+ description='x', url='x')
+
+ def test_booking_utilization_json(self):
+ url = reverse('dashboard:booking_utilization', kwargs={'resource_id': 0, 'weeks': 0})
+ self.assertEqual(self.client.get(url).status_code, 404)
+
+ url = reverse('dashboard:booking_utilization', kwargs={'resource_id': self.res_active.id,
+ 'weeks': 0})
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'data')
+
+ def test_jenkins_utilization_json(self):
+ url = reverse('dashboard:jenkins_utilization', kwargs={'resource_id': 0, 'weeks': 0})
+ self.assertEqual(self.client.get(url).status_code, 404)
+
+ url = reverse('dashboard:jenkins_utilization', kwargs={'resource_id': self.res_active.id,
+ 'weeks': 0})
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'data')
+
+ def test_jenkins_slaves_view(self):
+ url = reverse('dashboard:jenkins_slaves')
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ self.assertIn(self.slave_active, response.context['slaves'])
+ self.assertNotIn(self.slave_inactive, response.context['slaves'])
+
+ def test_ci_pods_view(self):
+ url = reverse('dashboard:ci_pods')
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(len(response.context['ci_pods']), 0)
+
+ self.slave_active.ci_slave = True
+ self.slave_inactive.ci_slave = True
+ self.slave_active.save()
+ self.slave_inactive.save()
+
+ response = self.client.get(url)
+ self.assertIn(self.res_active, response.context['ci_pods'])
+ self.assertNotIn(self.res_inactive, response.context['ci_pods'])
+
+ def test_dev_pods_view(self):
+ url = reverse('dashboard:dev_pods')
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(len(response.context['dev_pods']), 0)
+
diff --git a/tools/pharos-dashboard/src/dashboard/urls.py b/tools/pharos-dashboard/src/dashboard/urls.py
index f04f5ca9..609e5d6f 100644
--- a/tools/pharos-dashboard/src/dashboard/urls.py
+++ b/tools/pharos-dashboard/src/dashboard/urls.py
@@ -24,6 +24,7 @@ Including another URLconf
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
+
from dashboard.views import *
urlpatterns = [
diff --git a/tools/pharos-dashboard/src/dashboard/views.py b/tools/pharos-dashboard/src/dashboard/views.py
index 022a4af0..1848844b 100644
--- a/tools/pharos-dashboard/src/dashboard/views.py
+++ b/tools/pharos-dashboard/src/dashboard/views.py
@@ -25,7 +25,7 @@ class JenkinsSlavesView(TemplateView):
template_name = "dashboard/jenkins_slaves.html"
def get_context_data(self, **kwargs):
- slaves = JenkinsSlave.objects.all()
+ slaves = JenkinsSlave.objects.filter(active=True)
context = super(JenkinsSlavesView, self).get_context_data(**kwargs)
context.update({'title': "Jenkins Slaves", 'slaves': slaves})
return context
@@ -35,7 +35,7 @@ class CIPodsView(TemplateView):
template_name = "dashboard/ci_pods.html"
def get_context_data(self, **kwargs):
- ci_pods = Resource.objects.filter(slave__ci_slave=True)
+ ci_pods = Resource.objects.filter(slave__ci_slave=True, slave__active=True)
context = super(CIPodsView, self).get_context_data(**kwargs)
context.update({'title': "CI Pods", 'ci_pods': ci_pods})
return context
@@ -45,7 +45,7 @@ class DevelopmentPodsView(TemplateView):
template_name = "dashboard/dev_pods.html"
def get_context_data(self, **kwargs):
- resources = Resource.objects.filter(slave__dev_pod=True)
+ resources = Resource.objects.filter(slave__dev_pod=True, slave__active=True)
bookings = Booking.objects.filter(start__lte=timezone.now())
bookings = bookings.filter(end__gt=timezone.now())
@@ -55,7 +55,7 @@ class DevelopmentPodsView(TemplateView):
booking_utilization = resource.get_booking_utilization(weeks=4)
total = booking_utilization['booked_seconds'] + booking_utilization['available_seconds']
try:
- utilization_percentage = "%d%%" % (float(booking_utilization['booked_seconds']) /
+ utilization_percentage = "%d%%" % (float(booking_utilization['booked_seconds']) /
total * 100)
except (ValueError, ZeroDivisionError):
return ""
@@ -88,7 +88,7 @@ class LabOwnerView(TemplateView):
template_name = "dashboard/resource_all.html"
def get_context_data(self, **kwargs):
- resources = Resource.objects.filter(slave__dev_pod=True)
+ resources = Resource.objects.filter(slave__dev_pod=True, slave__active=True)
pods = []
for resource in resources:
utilization = resource.slave.get_utilization(timedelta(days=7))