Skip to content
Merged
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
1 change: 1 addition & 0 deletions codespeed/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ div.about_content { text-align: left; }
.boxbody input { margin-left: 0; vertical-align: top; }
#options li { margin-bottom: 0.8em; }
.seriescolor { float: right; margin-top: 2px; height: 13px; width: 14px; }
.envlinecolor { float: right; font-size: 12px; line-height: 18px; color: #555; }
.compplot-wrap { display: inline-block; }
a.togglefold { font-size: normal; color: #000000; }
a.togglefold::before {
Expand Down
14 changes: 14 additions & 0 deletions codespeed/static/js/changes.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ function updateRevisionMarkers(env_id) {
});
$("#revision").html(options);
$("#revision").val(current);
if (!$("#revision").val()) {
$("#revision").prop('selectedIndex', 0);
}
}

function refreshContent() {
Expand Down Expand Up @@ -123,8 +126,19 @@ function changeRevisions() {
selected_project = projectmatrix[executable];

if (selected_project !== currentproject) {
var oldRevs = revisiondata[currentproject] || [];
var oldEntry = oldRevs.find(function(r) { return r[1] === $("#revision").val(); });
var oldDate = oldEntry ? new Date(oldEntry[0].slice(0, 19)) : null;
currentproject = selected_project;
updateRevisionMarkers($("input[name='environment']:checked").val());
if (oldDate) {
var newRevs = revisiondata[currentproject] || [];
var best = newRevs.reduce(function(bi, r, i) {
return Math.abs(new Date(r[0].slice(0, 19)) - oldDate) <
Math.abs(new Date(newRevs[bi][0].slice(0, 19)) - oldDate) ? i : bi;
}, 0);
$("#revision").prop('selectedIndex', best);
}

//Give visual cue that the select box has changed
var bgc = $("#revision").parent().parent().css("backgroundColor");
Expand Down
224 changes: 162 additions & 62 deletions codespeed/static/js/timeline.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions codespeed/templates/codespeed/timeline.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
<ul>
{% for env in environments %}
<li title="{{ env.os }}, {{ env.cpu }}">
<input id="env{{ env.name }}" type="radio" name="environments" value="{{ env.id }}" />
<label for="env{{ env.name }}">{{ env }}</label>
<input id="env{{ env.name }}" type="checkbox" name="environments" value="{{ env.id }}" />
<label for="env{{ env.name }}">{{ env }}</label><div class="envlinecolor"></div>
</li>
{% endfor %}
</ul>
Expand Down Expand Up @@ -77,7 +77,7 @@
</div>

<div id="configbar">
<span class="options" title="Last {{ defaultlast }} revisions tested">
<span class="options">
Show the last
<select id="revisions">{% for rev in lastrevisions %}
<option value="{{ rev }}">{{ rev }}</option>{% endfor %}
Expand Down Expand Up @@ -121,7 +121,7 @@
executables: [{% for exe in checkedexecutables %}{{ exe.id }}, {% endfor %}],
branches: [{% for b in branch_list %}"{{ branch }}", {% endfor %}],
benchmark: "{{ defaultbenchmark }}",
environment: "{{ defaultenvironment.0.id }}",
environments: [{% for env in defaultenvironments %}{{ env.id }}, {% endfor %}],
equidistant: "{{ defaultequid }}",
quartiles: "{{ defaultquarts }}",
extrema: "{{ defaultextr }}"
Expand Down
4 changes: 2 additions & 2 deletions codespeed/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,11 @@ def test_gettimelinedata(self):
1,
"there should be 1 timeline for master")
self.assertEqual(
len(responsedata['timelines'][0]['branches']['master']['1']),
len(responsedata['timelines'][0]['branches']['master']['1:1']),
2,
"There are 2 datapoints")
self.assertEqual(
responsedata['timelines'][0]['branches']['master']['1'][1],
responsedata['timelines'][0]['branches']['master']['1:1'][1],
[u'2011/04/13 17:04:22 ', 2000.0, 1.11111, u'2', u'', u'master', u''])


Expand Down
135 changes: 77 additions & 58 deletions codespeed/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,18 @@ def gettimelinedata(request):
if not executables:
timeline_list['error'] = "No executables selected"
return HttpResponse(json.dumps(timeline_list))
environment = None
try:
environment = get_object_or_404(Environment, id=data.get('env'))
except ValueError:
Http404()

environments = []
for env_id in data.get('env', '').split(',')[:2]:
if not env_id:
continue
try:
environments.append(get_object_or_404(Environment, id=int(env_id)))
except (ValueError, Http404):
pass
if not environments:
timeline_list['error'] = "No environment selected"
return HttpResponse(json.dumps(timeline_list))

number_of_revs, benchmarks = get_num_revs_and_benchmarks(data)

Expand All @@ -471,13 +478,13 @@ def gettimelinedata(request):
next_benchmarks = int(next_benchmarks)

resp = StreamingHttpResponse(stream_timeline(baseline_exe, baseline_rev, benchmarks, data,
environment, executables, number_of_revs,
environments, executables, number_of_revs,
next_benchmarks),
content_type='application/json')
return resp


def stream_timeline(baseline_exe, baseline_rev, benchmarks, data, environment, executables,
def stream_timeline(baseline_exe, baseline_rev, benchmarks, data, environments, executables,
number_of_revs, next_benchmarks):
yield '{"timelines": ['
num_results = {"results": 0}
Expand All @@ -493,7 +500,7 @@ def stream_timeline(baseline_exe, baseline_rev, benchmarks, data, environment, e
num_benchmark += 1

if not next_benchmarks or num_benchmark > next_benchmarks:
result = get_timeline_for_benchmark(baseline_exe, baseline_rev, bench, environment,
result = get_timeline_for_benchmark(baseline_exe, baseline_rev, bench, environments,
executables, number_of_revs, num_results)
if result != "":
transmitted_benchmarks += 1
Expand All @@ -516,7 +523,7 @@ def stream_timeline(baseline_exe, baseline_rev, benchmarks, data, environment, e
yield ']' + not_first + next_page + ', "error":"None"}\n'


def get_timeline_for_benchmark(baseline_exe, baseline_rev, bench, environment, executables,
def get_timeline_for_benchmark(baseline_exe, baseline_rev, bench, environments, executables,
number_of_revs, num_results):
lessisbetter = bench.lessisbetter and ' (less is better)' or ' (more is better)'
timeline = {
Expand All @@ -528,74 +535,67 @@ def get_timeline_for_benchmark(baseline_exe, baseline_rev, bench, environment, e
'lessisbetter': lessisbetter,
'branches': {},
'baseline': "None",
'environments': [{'id': env.id, 'name': env.name} for env in environments],
}
append = False
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(
environment=environment
).filter(
executable=executable
).filter(
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:
if bench.data_type == 'M':
q1, q3, val_max, val_min = get_stats_with_defaults(res)
results.append(
[
for environment in environments:
for executable in executables:
if executable.project != branch.project:
continue

resultquery = Result.objects.filter(
benchmark=bench,
environment=environment,
executable=executable,
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:
if bench.data_type == 'M':
q1, q3, val_max, val_min = get_stats_with_defaults(res)
results.append([
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.name,
res.suite_version,
]
)
else:
std_dev = ""
if res.std_dev is not None:
std_dev = res.std_dev
results.append(
[
])
else:
std_dev = ""
if res.std_dev is not None:
std_dev = res.std_dev
results.append([
res.revision.date.strftime('%Y/%m/%d %H:%M:%S %z'),
res.value, std_dev,
res.revision.get_short_commitid(), res.revision.tag, branch.name,
res.suite_version,
]
)
timeline['branches'][branch.name][executable.id] = results
append = True
])
# Key is "exe_id:env_id" so multiple environments render as separate series
timeline['branches'][branch.name][f"{executable.id}:{environment.id}"] = results
append = True
if baseline_rev is not None and append:
try:
baselinevalue = Result.objects.get(
executable=baseline_exe,
benchmark=bench,
revision=baseline_rev,
environment=environment
environment=environments[0],
).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]
for key in timeline['branches'][branch]:
if len(timeline['branches'][branch][key]) > len(results):
results = timeline['branches'][branch][key]
end = results[0][0]
start = results[len(results) - 1][0]
timeline['baseline'] = [
Expand Down Expand Up @@ -625,6 +625,10 @@ def timeline(request):
if not enviros:
return no_environment_error(request)
defaultenviro = get_default_environment(enviros, data)
if 'env' in data:
defaultenvironments = get_default_environment(enviros, data, multi=True)[:2]
else:
defaultenvironments = defaultenviro # already respects DEF_ENVIRONMENT

# Default Project
defaultproject = Project.objects.filter(track=True)
Expand All @@ -643,6 +647,15 @@ def timeline(request):
except Executable.DoesNotExist:
pass

if not checkedexecutables:
if hasattr(settings, 'DEF_EXECUTABLES') and settings.DEF_EXECUTABLES:
for def_exe in settings.DEF_EXECUTABLES:
try:
proj = Project.objects.get(name=def_exe['project'])
checkedexecutables.append(
Executable.objects.get(name=def_exe['name'], project=proj))
except (Project.DoesNotExist, Executable.DoesNotExist):
pass
if not checkedexecutables:
checkedexecutables = Executable.objects.filter(project__track=True)

Expand Down Expand Up @@ -671,12 +684,17 @@ def timeline(request):
except ValueError:
pass

lastrevisions = [10, 50, 200, 1000]
lastrevisions = [10, 15, 50, 200]
defaultlast = settings.DEF_TIMELINE_LIMIT
if 'revs' in data:
if int(data['revs']) not in lastrevisions:
lastrevisions.append(data['revs'])
defaultlast = data['revs']
if 'revs' in data and data['revs']:
try:
revs_int = int(data['revs'])
except ValueError:
revs_int = None
if revs_int is not None:
if revs_int not in lastrevisions:
lastrevisions.append(revs_int)
defaultlast = revs_int

benchmarks = Benchmark.objects.all()

Expand Down Expand Up @@ -733,6 +751,7 @@ def timeline(request):
'baseline': baseline,
'defaultbenchmark': defaultbenchmark,
'defaultenvironment': defaultenviro,
'defaultenvironments': defaultenvironments,
'lastrevisions': lastrevisions,
'defaultlast': defaultlast,
'executables': executables,
Expand Down
18 changes: 9 additions & 9 deletions codespeed/views_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ def get_default_environment(enviros, data, multi=False):
# Use permalink values
if 'env' in data:
for env_value in data['env'].split(","):
try:
env_id = int(env_value)
except ValueError:
continue
for env in enviros:
try:
env_id = int(env_value)
except ValueError:
# Not an int
continue
for env in enviros:
if env_id == env.id:
defaultenviros.append(env)
if env_id == env.id:
defaultenviros.append(env)
break
if not multi:
break
# Use settings.py value
Expand Down Expand Up @@ -91,7 +90,8 @@ def getbaselineexecutables(include_tags=None):
if base['key'] == "none":
continue
if (base['executable'].name == exename and
base['revision'].commitid == commitid):
(base['revision'].commitid == commitid or
base['revision'].tag == commitid)):
baseline.remove(base)
baseline.insert(1, base)
break
Expand Down
Loading