Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ COMP_EXECUTABLES = [
]
```

### VCS Provider Specific Settings

#### Github

* ``GITHUB_OAUTH_TOKEN`` - Github oAuth token to use for authenticating against
the Github API. If not provided, it will default to unauthenticated API requests
which have low rate limits so an exception may be thrown when retrieving info
from the Github API due to the rate limit being reached.

## Getting help

For help regarding the configuration of Codespeed, or to share any ideas or
Expand Down
2 changes: 1 addition & 1 deletion codespeed/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ProjectAdmin(admin.ModelAdmin):

@admin.register(Branch)
class BranchAdmin(admin.ModelAdmin):
list_display = ('name', 'project')
list_display = ('name', 'project', 'display_on_comparison_page')
list_filter = ('project',)


Expand Down
14 changes: 8 additions & 6 deletions codespeed/commits/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import json

import isodate
from django.conf import settings
from django.core.cache import cache
from django.conf import settings

from .exceptions import CommitLogError

Expand Down Expand Up @@ -103,11 +103,13 @@ def retrieve_revision(commit_id, username, project, revision=None):
if revision:
# Overwrite any existing data we might have for this revision since
# we never want our records to be out of sync with the actual VCS:

# We need to convert the timezone-aware date to a naive (i.e.
# timezone-less) date in UTC to avoid killing MySQL:
revision.date = date.astimezone(
isodate.tzinfo.Utc()).replace(tzinfo=None)
if not getattr(settings, 'USE_TZ_AWARE_DATES', False):
# We need to convert the timezone-aware date to a naive (i.e.
# timezone-less) date in UTC to avoid killing MySQL:
logger.debug('USE_TZ_AWARE_DATES setting is set to False, '
'converting datetime object to a naive one')
revision.date = date.astimezone(
isodate.tzinfo.Utc()).replace(tzinfo=None)
revision.author = commit_json['author']['name']
revision.message = commit_json['message']
revision.full_clean()
Expand Down
3 changes: 3 additions & 0 deletions codespeed/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class Branch(models.Model):
name = models.CharField(max_length=32)
project = models.ForeignKey(
Project, on_delete=models.CASCADE, related_name="branches")
display_on_comparison_page = models.BooleanField(
"True to display this branch in a list on the comparison page",
default=True)

def __str__(self):
return self.project.name + ":" + self.name
Expand Down
10 changes: 10 additions & 0 deletions codespeed/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,22 @@
# ('myexe', '21df2423ra'),
# ('myexe', 'L'),]

TIMELINE_EXECUTABLE_NAME_MAX_LEN = 22 # Maximum length of the executable name used in the
# Changes and Timeline view. If the name is longer, the name
# will be truncated and "..." will be added at the end.

COMPARISON_EXECUTABLE_NAME_MAX_LEN = 20 # Maximum length of the executable name used in the
# Coomparison view. If the name is longer, the name

USE_MEDIAN_BANDS = True # True to enable median bands on Timeline view


ALLOW_ANONYMOUS_POST = True # Whether anonymous users can post results
REQUIRE_SECURE_AUTH = True # Whether auth needs to be over a secure channel

US_TZ_AWARE_DATES = False # True to use timezone aware datetime objects with Github provider.
# NOTE: Some database backends may not support tz aware dates.

GITHUB_OAUTH_TOKEN = None # Github oAuth token to use when using Github repo type. If not
# specified, it will utilize unauthenticated requests which have
# low rate limits.
25 changes: 25 additions & 0 deletions codespeed/tests/test_views_data.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test import override_settings

from codespeed.models import Project, Executable, Branch, Revision
from codespeed.views import getbaselineexecutables
from codespeed.views_data import get_sanitized_executable_name_for_timeline_view
from codespeed.views_data import get_sanitized_executable_name_for_comparison_view


class TestGetBaselineExecutables(TestCase):
Expand Down Expand Up @@ -38,3 +41,25 @@ def test_get_baseline_executables(self):
Revision.objects.create(commitid='3', branch=self.branch)
result = getbaselineexecutables()
self.assertEqual(len(result), 3)


class UtilityFunctionsTestCase(TestCase):
@override_settings(TIMELINE_EXECUTABLE_NAME_MAX_LEN=22)
def test_get_sanitized_executable_name_for_timeline_view(self):
executable = Executable(name='a' * 22)
name = get_sanitized_executable_name_for_timeline_view(executable)
self.assertEqual(name, 'a' * 22)

executable = Executable(name='a' * 25)
name = get_sanitized_executable_name_for_timeline_view(executable)
self.assertEqual(name, 'a' * 22 + '...')

@override_settings(COMPARISON_EXECUTABLE_NAME_MAX_LEN=20)
def test_get_sanitized_executable_name_for_comparision_view(self):
executable = Executable(name='b' * 20)
name = get_sanitized_executable_name_for_comparison_view(executable)
self.assertEqual(name, 'b' * 20)

executable = Executable(name='b' * 25)
name = get_sanitized_executable_name_for_comparison_view(executable)
self.assertEqual(name, 'b' * 20 + '...')
56 changes: 47 additions & 9 deletions codespeed/views_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,10 @@ def getbaselineexecutables():
}]
executables = Executable.objects.select_related('project')
revs = Revision.objects.exclude(tag="").select_related('branch__project')
maxlen = 22
for rev in revs:
# Add executables that correspond to each tagged revision.
for exe in [e for e in executables if e.project == rev.branch.project]:
exestring = str(exe)
if len(exestring) > maxlen:
exestring = str(exe)[0:maxlen] + "..."
exestring = get_sanitized_executable_name_for_timeline_view(exe)
name = exestring + " " + rev.tag
key = str(exe.id) + "+" + str(rev.id)
baseline.append({
Expand Down Expand Up @@ -116,15 +113,14 @@ def getcomparisonexes():
for proj in Project.objects.all():
executables = []
executablekeys = []
maxlen = 20
# add all tagged revs for any project
for exe in baselines:
if exe['key'] != "none" and exe['executable'].project == proj:
executablekeys.append(exe['key'])
executables.append(exe)

# add latest revs of the project
branches = Branch.objects.filter(project=proj)
branches = Branch.objects.filter(project=proj, display_on_comparison_page=True)
for branch in branches:
try:
rev = Revision.objects.filter(branch=branch).latest('date')
Expand All @@ -134,9 +130,7 @@ def getcomparisonexes():
# because we already added tagged revisions
if rev.tag == "":
for exe in Executable.objects.filter(project=proj):
exestring = str(exe)
if len(exestring) > maxlen:
exestring = str(exe)[0:maxlen] + "..."
exestring = get_sanitized_executable_name_for_comparison_view(exe)
name = exestring + " latest"
if branch.name != 'default':
name += " in branch '" + branch.name + "'"
Expand Down Expand Up @@ -260,3 +254,47 @@ def get_stats_with_defaults(res):
if res.q3 is not None:
q3 = res.q3
return q1, q3, val_max, val_min


def get_sanitized_executable_name_for_timeline_view(executable):
"""
Return sanitized executable name which is used in the sidebar in the
Timeline and Changes view.

If the name is longer than settings.TIMELINE_EXECUTABLE_NAME_MAX_LEN,
the name will be truncated to that length and "..." appended to it.

:param executable: Executable object.
:type executable: :class:``codespeed.models.Executable``

:return: ``str``
"""
maxlen = getattr(settings, 'TIMELINE_EXECUTABLE_NAME_MAX_LEN', 20)

exestring = str(executable)
if len(exestring) > maxlen:
exestring = str(executable)[0:maxlen] + "..."

return exestring


def get_sanitized_executable_name_for_comparison_view(executable):
"""
Return sanitized executable name which is used in the sidebar in the
comparision view.

If the name is longer than settings.COMPARISON_EXECUTABLE_NAME_MAX_LEN,
the name will be truncated to that length and "..." appended to it.

:param executable: Executable object.
:type executable: :class:``codespeed.models.Executable``

:return: ``str``
"""
maxlen = getattr(settings, 'COMPARISON_EXECUTABLE_NAME_MAX_LEN', 22)

exestring = str(executable)
if len(exestring) > maxlen:
exestring = str(executable)[0:maxlen] + "..."

return exestring