|
| 1 | +"""Tests for the speed.python.org specific views. |
| 2 | +
|
| 3 | +Run with: python manage.py test codespeed speed_python |
| 4 | +""" |
| 5 | +import json |
| 6 | +import os |
| 7 | +from datetime import timedelta |
| 8 | + |
| 9 | +from django.test import TestCase, override_settings |
| 10 | +from django.urls import reverse |
| 11 | +from django.utils import timezone |
| 12 | + |
| 13 | +from codespeed.models import (Project, Benchmark, Revision, Branch, Executable, |
| 14 | + Environment, Result) |
| 15 | + |
| 16 | + |
| 17 | +DUMMY_CACHE = {'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}} |
| 18 | +SITE_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 19 | +# The test settings belong to sample_project; render this site's templates instead. |
| 20 | +SITE_TEMPLATES = [{ |
| 21 | + 'BACKEND': 'django.template.backends.django.DjangoTemplates', |
| 22 | + 'DIRS': [os.path.join(SITE_DIR, 'templates')], |
| 23 | + 'APP_DIRS': True, |
| 24 | + 'OPTIONS': {'context_processors': [ |
| 25 | + 'django.template.context_processors.request', |
| 26 | + 'django.contrib.auth.context_processors.auth', |
| 27 | + 'django.contrib.messages.context_processors.messages', |
| 28 | + ]}, |
| 29 | +}] |
| 30 | + |
| 31 | + |
| 32 | +@override_settings( |
| 33 | + ROOT_URLCONF='speed_python.urls', |
| 34 | + TEMPLATES=SITE_TEMPLATES, |
| 35 | + CACHES=DUMMY_CACHE, |
| 36 | + HOME_GEOMEAN_SERIES=[{'executable': 'myexe', 'environment': 'env1'}]) |
| 37 | +class TestHomeGeomean(TestCase): |
| 38 | + |
| 39 | + def setUp(self): |
| 40 | + self.env = Environment.objects.create(name='env1') |
| 41 | + self.project = Project.objects.create(name='proj', default_branch='main') |
| 42 | + self.branch = Branch.objects.create(name='main', project=self.project) |
| 43 | + self.exe = Executable.objects.create(name='myexe', project=self.project) |
| 44 | + self.b1 = Benchmark.objects.create(name='b1') |
| 45 | + self.b2 = Benchmark.objects.create(name='b2') |
| 46 | + now = timezone.now() |
| 47 | + runs = [ |
| 48 | + # days ago, {benchmark: value} |
| 49 | + (45, {self.b1: 9.0, self.b2: 9.0}), # outside the window |
| 50 | + (20, {self.b1: 1.0, self.b2: 4.0}), # first in window: baseline |
| 51 | + (10, {self.b1: 2.0, self.b2: 2.0}), # geomean of 2.0 and 0.5 -> 1.0 |
| 52 | + (5, {self.b1: 0.5}), # b2 missing: only b1 counts |
| 53 | + ] |
| 54 | + for i, (days_ago, values) in enumerate(runs): |
| 55 | + rev = Revision.objects.create( |
| 56 | + commitid='c%d' % i, branch=self.branch, project=self.project, |
| 57 | + date=now - timedelta(days=days_ago)) |
| 58 | + for bench, value in values.items(): |
| 59 | + Result.objects.create(value=value, revision=rev, executable=self.exe, |
| 60 | + benchmark=bench, environment=self.env) |
| 61 | + |
| 62 | + def get(self): |
| 63 | + response = self.client.get(reverse('gethomegeomeandata')) |
| 64 | + self.assertEqual(response.status_code, 200) |
| 65 | + return json.loads(response.content.decode()) |
| 66 | + |
| 67 | + def test_series_normalised_to_first_revision_in_window(self): |
| 68 | + data = self.get() |
| 69 | + self.assertEqual(data['days'], 30) |
| 70 | + self.assertEqual(len(data['series']), 1) |
| 71 | + series = data['series'][0] |
| 72 | + self.assertEqual(series['label'], 'myexe @ env1') |
| 73 | + self.assertEqual(series['executable'], self.exe.id) |
| 74 | + self.assertEqual(series['environment'], self.env.id) |
| 75 | + self.assertEqual(series['branch'], 'main') |
| 76 | + self.assertEqual(series['baseline_commitid'], 'c1') |
| 77 | + self.assertEqual([p[2] for p in series['points']], ['c1', 'c2', 'c3']) |
| 78 | + self.assertEqual([p[1] for p in series['points']], [1.0, 1.0, 0.5]) |
| 79 | + self.assertEqual([p[3] for p in series['points']], [2, 2, 1]) |
| 80 | + |
| 81 | + def test_branch_filter(self): |
| 82 | + other = Branch.objects.create(name='other', project=self.project) |
| 83 | + rev = Revision.objects.create(commitid='x', branch=other, project=self.project, |
| 84 | + date=timezone.now()) |
| 85 | + Result.objects.create(value=100.0, revision=rev, executable=self.exe, |
| 86 | + benchmark=self.b1, environment=self.env) |
| 87 | + commits = [p[2] for p in self.get()['series'][0]['points']] |
| 88 | + self.assertNotIn('x', commits) |
| 89 | + |
| 90 | + @override_settings(HOME_GEOMEAN_SERIES=[ |
| 91 | + {'executable': 'myexe', 'environment': 'env1', 'branch': 'main'}, |
| 92 | + {'executable': 'nope', 'environment': 'env1'}, |
| 93 | + {'executable': 'myexe', 'environment': 'nope'}]) |
| 94 | + def test_unknown_entries_are_skipped(self): |
| 95 | + data = self.get() |
| 96 | + self.assertEqual([s['label'] for s in data['series']], ['myexe @ env1']) |
| 97 | + |
| 98 | + @override_settings(HOME_GEOMEAN_SERIES=[]) |
| 99 | + def test_unconfigured(self): |
| 100 | + self.assertEqual(self.get()['series'], []) |
| 101 | + |
| 102 | + def test_home_page_embeds_the_chart(self): |
| 103 | + response = self.client.get(reverse('home')) |
| 104 | + self.assertEqual(response.status_code, 200) |
| 105 | + self.assertIn('id="geomean-plot"', response.content.decode()) |
| 106 | + self.assertIn(reverse('gethomegeomeandata'), response.content.decode()) |
0 commit comments