Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gabriel Silva Vinha
codespeed
Commits
a5774969
Commit
a5774969
authored
Aug 25, 2017
by
Miquel Torres
Committed by
GitHub
Aug 25, 2017
Browse files
Merge pull request #224 from tobami/default-banch-in-db
Default banch in db
parents
69f74055
3743ece0
Changes
12
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
a5774969
...
...
@@ -185,10 +185,6 @@ several parameters (the file includes comments with full examples).
*
`grid`
: will always show as default the grid of plots
*
`show_none`
: will show a text message (better default when there are lots of benchmarks)
*
`mybench`
: will select benchmark named "mybench"
*
`DEF_BRANCH`
: Defines the default branch to be used when calculating timeline and changes data for presentation. Example values:
*
`default`
: the default value, and usually mercurial's default branch
*
`master`
: usually git's default branch
*
`trunk`
: usually SVN's default branch
### Comparison View
*
`CHART_TYPE`
: Chooses the default chart type (normal bars, stacked bars or
...
...
codespeed/admin.py
View file @
a5774969
# -*- coding: utf-8 -*-
from
django
import
forms
from
django.contrib
import
admin
from
codespeed.models
import
(
Project
,
Revision
,
Executable
,
Benchmark
,
Branch
,
Result
,
Environment
,
Report
)
from
django.contrib
import
admin
class
ProjectForm
(
forms
.
ModelForm
):
default_branch
=
forms
.
CharField
(
max_length
=
32
,
required
=
False
)
def
clean
(
self
):
if
not
self
.
cleaned_data
.
get
(
'default_branch'
):
repo_type
=
self
.
cleaned_data
[
'repo_type'
]
if
repo_type
in
[
Project
.
GIT
,
Project
.
GITHUB
]:
self
.
cleaned_data
[
'default_branch'
]
=
"master"
elif
repo_type
==
Project
.
MERCURIAL
:
self
.
cleaned_data
[
'default_branch'
]
=
"default"
elif
repo_type
==
Project
.
SUBVERSION
:
self
.
cleaned_data
[
'default_branch'
]
=
"trunk"
else
:
self
.
add_error
(
'default_branch'
,
'This field is required.'
)
class
Meta
:
model
=
Project
fields
=
'__all__'
@
admin
.
register
(
Project
)
class
ProjectAdmin
(
admin
.
ModelAdmin
):
list_display
=
(
'name'
,
'repo_type'
,
'repo_path'
,
'track'
)
form
=
ProjectForm
@
admin
.
register
(
Branch
)
class
BranchAdmin
(
admin
.
ModelAdmin
):
...
...
codespeed/feeds.py
View file @
a5774969
...
...
@@ -35,15 +35,14 @@ class ResultFeed(Feed):
class
LatestEntries
(
ResultFeed
):
description
=
"Last
benchmark run
s"
description
=
"Last
Result
s"
def
result_filter
(
self
):
return
Q
(
revision__branch__name
=
settings
.
DEF_BRANCH
)
return
Q
()
class
LatestSignificantEntries
(
ResultFeed
):
description
=
"Last
benchmark run
s with significant changes"
description
=
"Last
result
s with significant changes"
def
result_filter
(
self
):
return
Q
(
revision__branch__name
=
settings
.
DEF_BRANCH
,
colorcode__in
=
(
'red'
,
'green'
))
return
Q
(
colorcode__in
=
(
'red'
,
'green'
))
codespeed/fixtures/timeline_tests.json
View file @
a5774969
...
...
@@ -3,26 +3,28 @@
"pk"
:
1
,
"model"
:
"codespeed.project"
,
"fields"
:
{
"repo_type"
:
"
N
"
,
"repo_type"
:
"
G
"
,
"name"
:
"MyProject"
,
"commit_browsing_url"
:
""
,
"repo_user"
:
""
,
"track"
:
true
,
"repo_pass"
:
""
,
"repo_path"
:
""
"repo_path"
:
""
,
"default_branch"
:
"master"
}
},
{
"pk"
:
2
,
"model"
:
"codespeed.project"
,
"fields"
:
{
"repo_type"
:
"
N
"
,
"repo_type"
:
"
M
"
,
"name"
:
"Other"
,
"commit_browsing_url"
:
""
,
"repo_user"
:
""
,
"track"
:
true
,
"repo_pass"
:
""
,
"repo_path"
:
""
"repo_path"
:
""
,
"default_branch"
:
"default"
}
},
{
...
...
@@ -35,7 +37,8 @@
"repo_user"
:
""
,
"track"
:
false
,
"repo_pass"
:
""
,
"repo_path"
:
""
"repo_path"
:
""
,
"default_branch"
:
"master"
}
},
{
...
...
@@ -59,7 +62,7 @@
"model"
:
"codespeed.branch"
,
"fields"
:
{
"project"
:
2
,
"name"
:
"
master
"
"name"
:
"
default
"
}
},
{
...
...
codespeed/migrations/0003_project_default_branch.py
0 → 100644
View file @
a5774969
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2017-08-04 03:45
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
def
get_default_branch_name
():
from
django.conf
import
settings
try
:
return
settings
.
DEF_BRANCH
except
AttributeError
:
return
"master"
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'codespeed'
,
'0002_median'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'project'
,
name
=
'default_branch'
,
field
=
models
.
CharField
(
default
=
get_default_branch_name
,
max_length
=
32
),
preserve_default
=
False
,
),
migrations
.
AlterField
(
model_name
=
'branch'
,
name
=
'name'
,
field
=
models
.
CharField
(
max_length
=
32
),
),
]
codespeed/models.py
View file @
a5774969
...
...
@@ -42,6 +42,7 @@ class Project(models.Model):
commit_browsing_url
=
models
.
CharField
(
"Commit browsing URL"
,
blank
=
True
,
max_length
=
200
)
track
=
models
.
BooleanField
(
"Track changes"
,
default
=
True
)
default_branch
=
models
.
CharField
(
max_length
=
32
)
def
__str__
(
self
):
return
self
.
name
...
...
@@ -103,7 +104,7 @@ class HistoricalValue(object):
@
python_2_unicode_compatible
class
Branch
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
2
0
)
name
=
models
.
CharField
(
max_length
=
3
2
)
project
=
models
.
ForeignKey
(
Project
,
related_name
=
"branches"
)
def
__str__
(
self
):
...
...
@@ -138,7 +139,7 @@ class Revision(models.Model):
else
:
date
=
self
.
date
.
strftime
(
"%b %d, %H:%M"
)
string
=
" - "
.
join
(
filter
(
None
,
(
date
,
self
.
commitid
,
self
.
tag
)))
if
self
.
branch
.
name
!=
se
ttings
.
DEF_BRANCH
:
if
self
.
branch
.
name
!=
se
lf
.
branch
.
project
.
default_branch
:
string
+=
" - "
+
self
.
branch
.
name
return
string
...
...
codespeed/results.py
View file @
a5774969
...
...
@@ -134,6 +134,9 @@ def save_result(data):
def
create_report_if_enough_data
(
rev
,
exe
,
e
):
"""Triggers Report creation when there are enough results"""
if
exe
.
project
.
track
is
not
True
:
return
False
last_revs
=
Revision
.
objects
.
filter
(
branch
=
rev
.
branch
).
order_by
(
'-date'
)[:
2
]
...
...
codespeed/settings.py
View file @
a5774969
...
...
@@ -6,9 +6,6 @@ WEBSITE_NAME = "MySpeedSite" # This name will be used in the reports RSS feed
DEF_ENVIRONMENT
=
None
# Name of the environment which should be selected as default
DEF_BRANCH
=
"master"
# Defines the default branch to be used.
# In git projects, this branch is usually called "master"
DEF_BASELINE
=
None
# Which executable + revision should be default as a baseline
# Given as the name of the executable and commitid of the revision
# Example: defaultbaseline = {'executable': 'myexe', 'revision': '21'}
...
...
codespeed/tests/test_views.py
View file @
a5774969
...
...
@@ -3,7 +3,6 @@ from datetime import datetime, timedelta
import
copy
import
json
from
django.conf
import
settings
from
django.test
import
TestCase
,
override_settings
from
django.core.urlresolvers
import
reverse
...
...
@@ -342,19 +341,24 @@ class TestTimeline(TestCase):
"base"
:
"2+4"
,
"ben"
:
"float"
,
"env"
:
"1"
,
"revs"
:
2
"revs"
:
"2"
}
response
=
self
.
client
.
get
(
path
,
data
)
self
.
assertEquals
(
response
.
status_code
,
200
)
responsedata
=
json
.
loads
(
response
.
content
.
decode
())
self
.
assertEquals
(
responsedata
[
'error'
],
"None"
,
"there should be no errors"
)
self
.
assertEquals
(
len
(
responsedata
[
'timelines'
]),
1
,
"there should be 1 benchmark"
)
self
.
assertEquals
(
len
(
responsedata
[
'timelines'
][
0
][
'branches'
]
[
'master'
]
),
len
(
responsedata
[
'timelines'
][
0
][
'branches'
]),
2
,
"there should be 2 timelines"
)
"there should be 2 branches"
)
self
.
assertEquals
(
len
(
responsedata
[
'timelines'
][
0
][
'branches'
][
'default'
]),
1
,
"there should be 1 timeline for master"
)
self
.
assertEquals
(
len
(
responsedata
[
'timelines'
][
0
][
'branches'
][
'master'
][
'1'
]),
2
,
...
...
@@ -371,7 +375,7 @@ class TestReports(TestCase):
Environment
.
objects
.
create
(
name
=
'Dual Core'
,
cpu
=
'Core 2 Duo 8200'
)
self
.
data
=
{
'commitid'
:
'abcd1'
,
'branch'
:
settings
.
DEF_BRANCH
,
'branch'
:
'master'
,
'project'
:
'MyProject'
,
'executable'
:
'myexe O3 64bits'
,
'benchmark'
:
'float'
,
...
...
@@ -399,3 +403,13 @@ class TestReports(TestCase):
response
=
self
.
client
.
post
(
reverse
(
'codespeed.views.reports'
),
{})
self
.
assertEqual
(
response
.
status_code
,
405
)
class
TestFeeds
(
TestCase
):
def
test_latest_result_feed
(
self
):
response
=
self
.
client
.
get
(
reverse
(
'latest-results'
))
self
.
assertEqual
(
response
.
status_code
,
200
)
content
=
response
.
content
.
decode
()
self
.
assertIn
(
'<atom:link '
,
content
)
codespeed/urls.py
View file @
a5774969
...
...
@@ -9,9 +9,9 @@ urlpatterns = patterns('',
url
(
r
'^$'
,
TemplateView
.
as_view
(
template_name
=
'home.html'
),
name
=
'home'
),
url
(
r
'^about/$'
,
TemplateView
.
as_view
(
template_name
=
'about.html'
),
name
=
'about'
),
# RSS for reports
url
(
r
'^feeds/latest/$'
,
LatestEntries
(),
name
=
'latest
_feed
s'
),
url
(
r
'^feeds/latest/$'
,
LatestEntries
(),
name
=
'latest
-result
s'
),
url
(
r
'^feeds/latest_significant/$'
,
LatestSignificantEntries
(),
name
=
'latest
_
significant
_feed
s'
),
name
=
'latest
-
significant
-result
s'
),
)
urlpatterns
+=
patterns
(
'codespeed.views'
,
...
...
codespeed/views.py
View file @
a5774969
...
...
@@ -5,17 +5,18 @@ import json
import
logging
import
django
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
django.core.exceptions
import
ValidationError
,
ObjectDoesNotExist
from
django.http
import
HttpResponse
,
Http404
,
HttpResponseBadRequest
,
\
HttpResponseNotFound
from
django.db.models
import
F
from
django.shortcuts
import
get_object_or_404
,
render_to_response
from
django.views.decorators.http
import
require_GET
,
require_POST
from
django.views.decorators.csrf
import
csrf_exempt
from
django.template
import
RequestContext
from
django.conf
import
settings
from
.auth
import
basic_auth_required
from
.auth
import
basic_auth_required
from
.models
import
(
Environment
,
Report
,
Project
,
Revision
,
Result
,
Executable
,
Benchmark
,
Branch
)
from
.views_data
import
(
get_default_environment
,
getbaselineexecutables
,
...
...
@@ -231,8 +232,18 @@ def gettimelinedata(request):
timeline_list
=
{
'error'
:
'None'
,
'timelines'
:
[]}
executables
=
data
.
get
(
'exe'
,
""
).
split
(
","
)
if
not
filter
(
None
,
executables
):
executable_ids
=
data
.
get
(
'exe'
,
''
).
split
(
','
)
executables
=
[]
for
i
in
executable_ids
:
if
not
i
:
continue
try
:
executables
.
append
(
Executable
.
objects
.
get
(
id
=
int
(
i
)))
except
Executable
.
DoesNotExist
:
pass
if
not
executables
:
timeline_list
[
'error'
]
=
"No executables selected"
return
HttpResponse
(
json
.
dumps
(
timeline_list
))
environment
=
None
...
...
@@ -270,16 +281,14 @@ def gettimelinedata(request):
'branches'
:
{},
'baseline'
:
"None"
,
}
# Temporary
trunks
=
[]
if
Branch
.
objects
.
filter
(
name
=
settings
.
DEF_BRANCH
):
trunks
.
append
(
settings
.
DEF_BRANCH
)
# For now, we'll only work with trunk branches
append
=
False
for
branch
in
trunks
:
append
=
False
timeline
[
'branches'
][
branch
]
=
{}
for
branch
in
Branch
.
objects
.
filter
(
project__track
=
True
,
name
=
F
(
'project__default_branch'
)):
# For now, we'll only work with default branches
for
executable
in
executables
:
if
executable
.
project
!=
branch
.
project
:
continue
resultquery
=
Result
.
objects
.
filter
(
benchmark
=
bench
).
filter
(
...
...
@@ -287,12 +296,13 @@ def gettimelinedata(request):
).
filter
(
executable
=
executable
).
filter
(
revision__branch
__name
=
branch
revision__branch
=
branch
).
select_related
(
"revision"
).
order_by
(
'-revision__date'
)[:
number_of_revs
]
if
not
len
(
resultquery
):
continue
timeline
[
'branches'
].
setdefault
(
branch
.
name
,
{})
results
=
[]
for
res
in
resultquery
:
...
...
@@ -313,7 +323,7 @@ def gettimelinedata(request):
[
res
.
revision
.
date
.
strftime
(
'%Y/%m/%d %H:%M:%S %z'
),
res
.
value
,
val_max
,
q3
,
q1
,
val_min
,
res
.
revision
.
get_short_commitid
(),
res
.
revision
.
tag
,
branch
res
.
revision
.
get_short_commitid
(),
res
.
revision
.
tag
,
branch
.
name
]
)
else
:
...
...
@@ -324,34 +334,37 @@ def gettimelinedata(request):
[
res
.
revision
.
date
.
strftime
(
'%Y/%m/%d %H:%M:%S %z'
),
res
.
value
,
std_dev
,
res
.
revision
.
get_short_commitid
(),
res
.
revision
.
tag
,
branch
res
.
revision
.
get_short_commitid
(),
res
.
revision
.
tag
,
branch
.
name
]
)
timeline
[
'branches'
][
branch
][
executable
]
=
results
timeline
[
'branches'
][
branch
.
name
][
executable
.
id
]
=
results
append
=
True
if
baselinerev
is
not
None
and
append
:
try
:
baselinevalue
=
Result
.
objects
.
get
(
executable
=
baselineexe
,
benchmark
=
bench
,
revision
=
baselinerev
,
environment
=
environment
).
value
except
Result
.
DoesNotExist
:
timeline
[
'baseline'
]
=
"None"
else
:
# determine start and end revision (x axis)
# from longest data series
results
=
[]
if
baselinerev
is
not
None
and
append
:
try
:
baselinevalue
=
Result
.
objects
.
get
(
executable
=
baselineexe
,
benchmark
=
bench
,
revision
=
baselinerev
,
environment
=
environment
).
value
except
Result
.
DoesNotExist
:
timeline
[
'baseline'
]
=
"None"
else
:
# determine start and end revision (x axis)
# from longest data series
results
=
[]
for
branch
in
timeline
[
'branches'
]:
for
exe
in
timeline
[
'branches'
][
branch
]:
if
len
(
timeline
[
'branches'
][
branch
][
exe
])
>
len
(
results
):
results
=
timeline
[
'branches'
][
branch
][
exe
]
end
=
results
[
0
][
0
]
start
=
results
[
len
(
results
)
-
1
][
0
]
timeline
[
'baseline'
]
=
[
[
str
(
start
),
baselinevalue
],
[
str
(
end
),
baselinevalue
]
]
end
=
results
[
0
][
0
]
start
=
results
[
len
(
results
)
-
1
][
0
]
timeline
[
'baseline'
]
=
[
[
str
(
start
),
baselinevalue
],
[
str
(
end
),
baselinevalue
]
]
if
append
:
timeline_list
[
'timelines'
].
append
(
timeline
)
...
...
@@ -401,8 +414,8 @@ def timeline(request):
branch_list
.
sort
()
defaultbranch
=
""
if
settings
.
DEF_BRANCH
in
branch_list
:
defaultbranch
=
settings
.
DEF_BRANCH
if
defaultproject
.
default_branch
in
branch_list
:
defaultbranch
=
defaultproject
.
default_branch
if
data
.
get
(
'bran'
)
in
branch_list
:
defaultbranch
=
data
.
get
(
'bran'
)
...
...
@@ -576,7 +589,7 @@ def changes(request):
for
proj
in
Project
.
objects
.
filter
(
track
=
True
):
executables
[
proj
]
=
Executable
.
objects
.
filter
(
project
=
proj
)
projectlist
.
append
(
proj
)
branch
=
Branch
.
objects
.
filter
(
name
=
settings
.
DEF_BRANCH
,
project
=
proj
)
branch
=
Branch
.
objects
.
filter
(
name
=
proj
.
default_branch
,
project
=
proj
)
revisionlists
[
proj
.
name
]
=
list
(
Revision
.
objects
.
filter
(
branch
=
branch
).
order_by
(
'-date'
)[:
revlimit
])
...
...
@@ -631,15 +644,11 @@ def reports(request):
context
=
{}
context
[
'reports'
]
=
\
Report
.
objects
.
filter
(
revision__branch__name
=
settings
.
DEF_BRANCH
).
order_by
(
'-revision__date'
)[:
10
]
context
[
'significant_reports'
]
=
\
Report
.
objects
.
filter
(
revision__branch__name
=
settings
.
DEF_BRANCH
,
colorcode__in
=
(
'red'
,
'green'
)
).
order_by
(
'-revision__date'
)[:
10
]
Report
.
objects
.
order_by
(
'-revision__date'
)[:
10
]
context
[
'significant_reports'
]
=
Report
.
objects
.
filter
(
colorcode__in
=
(
'red'
,
'green'
)
).
order_by
(
'-revision__date'
)[:
10
]
return
render_to_response
(
'codespeed/reports.html'
,
context
,
context_instance
=
RequestContext
(
request
))
...
...
codespeed/views_data.py
View file @
a5774969
...
...
@@ -3,8 +3,9 @@ from __future__ import absolute_import
from
django.conf
import
settings
from
django.core.exceptions
import
ObjectDoesNotExist
from
codespeed.models
import
Executable
,
Revision
,
Project
,
Branch
,
\
Environment
,
Benchmark
,
Result
from
codespeed.models
import
(
Executable
,
Revision
,
Project
,
Branch
,
Environment
,
Benchmark
,
Result
)
def
get_default_environment
(
enviros
,
data
,
multi
=
False
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment