diff options
Diffstat (limited to 'tools/pharos-dashboard/src/dashboard')
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)) |