Skip to content

Commit

Permalink
wip: Add Performance Telemetry UI page
Browse files Browse the repository at this point in the history
still WIP, because the page breaks when given too much data.
the algorithm for the data looks OK, because it works with the small
data-set I left in the code. however, given dataset with more than 500
runs it fails to display the chart miserably.
  • Loading branch information
asankov committed Aug 20, 2021
1 parent 62a61f6 commit 955549a
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tcms/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@
(_("TestCase health"), reverse_lazy("test-case-health")),
],
),
(
_("Management"),
[
(_("Performance"), reverse_lazy("management-performance")),
],
),
(
"More coming soon",
"http://kiwitcms.org/blog/kiwi-tcms-team/2019/03/03/legacy-reports-become-telemetry/",
Expand Down
142 changes: 142 additions & 0 deletions tcms/telemetry/static/telemetry/js/management/performance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// TODO: account for more users
const colors = [
'blue',
'red',
'gold',
'orange',
'green',
'cyan',
'purple',
'black',
'lightBlue',
'lightGreen'
]

$(document).ready(() => {
$('.selectpicker').selectpicker()
$('[data-toggle="tooltip"]').tooltip()

loadInitialProduct(reloadCharts)

$('#id_after').on('dp.change', reloadCharts)
$('#id_before').on('dp.change', reloadCharts)
document.getElementById('id_test_plan').onchange = reloadCharts
document.getElementById('id_product').onchange = () => {
updateTestPlanSelectFromProduct(reloadCharts)
}
})

function reloadCharts () {
const query = {}

const testPlanIds = $('#id_test_plan').val()
const productIds = $('#id_product').val()

if (testPlanIds.length) {
query.plan__in = testPlanIds
} else if (productIds.length) {
query.category__product_id__in = productIds
}

const dateBefore = $('#id_before')
if (dateBefore.val()) {
query.create_date__lte = dateBefore.data('DateTimePicker').date().format('YYYY-MM-DD 23:59:59')
}

const dateAfter = $('#id_after')
if (dateAfter.val()) {
query.create_date__gte = dateAfter.data('DateTimePicker').date().format('YYYY-MM-DD 00:00:00')
}

jsonRPC('Management.performance', query, result => {
console.log(result)

// the actual result is in the same format, only it can be much bigger
// and the chart may break
const r = {
1: {
1: 1,
3: 2
},
2: {
1: 1,
4: 2
},
3: {
1: 1,
3: 1,
5: 1
},
4: {
3: 1,
2: 1
},
5: {
1: 5,
3: 2,
4: 1
}
}

drawChart(r)
}, true)
}

function drawChart (data) {
// the X axis of the chart - run IDs
const groupedCategories = []
// map of user ID -> table column. we use map here for faster lookup by user ID.
const groupedColumnsDataMap = {}
const userIds = new Set()

// collect all the testers so that we know how much columns we will have
Object.entries(data).forEach(([_testRunId, asigneeCount]) => {
Object.entries(asigneeCount).forEach(([userId, _executionCount]) => userIds.add(userId))
})

userIds.forEach(userId => (groupedColumnsDataMap[userId] = [`User ${userId}`]))

Object.entries(data).forEach(([testRunId, _asigneeCount]) => {
groupedCategories.push(testRunId)

const asigneesCount = data[testRunId]

// for each user in the groupedColumnsDataMap check if that user
// is assigned any executions for this run.
Object.entries(groupedColumnsDataMap).forEach(([userId, data]) => {
const count = asigneesCount[userId]
if (count) {
data.push(count)
} else {
// TODO: find a way to hide the 0 valued-columns
data.push(0)
}
})
})

// C3 does not need a map, but an array of values
// get rid of the keys, because we do not need them anymore
const groupedColumnsData = Object.values(groupedColumnsDataMap)

const chartConfig = $().c3ChartDefaults().getDefaultGroupedBarConfig()
chartConfig.bindto = '#performance-chart'
chartConfig.axis = {
x: {
categories: groupedCategories,
type: 'category'
},
y: {
tick: {
format: showOnlyRoundNumbers
}
}
}
chartConfig.data = {
type: 'bar',
columns: groupedColumnsData
}
chartConfig.color = {
pattern: colors
}
c3.generate(chartConfig)
}
3 changes: 3 additions & 0 deletions tcms/telemetry/static/telemetry/js/testing/breakdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ function drawChart(data, type, selector) {
chartData.push(dataEntry);
});

console.log('data', data)
console.log('groups', groups)
console.log('chartData', chartData)
let chartConfig = $().c3ChartDefaults().getDefaultStackedBarConfig();
chartConfig.bindto = selector;
chartConfig.axis = {
Expand Down
28 changes: 28 additions & 0 deletions tcms/telemetry/templates/telemetry/management/performance.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% extends "base.html" %}
{% load i18n %}
{% load static %}

{% block title %}{% trans "Performance" %}{% endblock %}

{% block contents %}

<div class="container-fluid container-cards-pf">
{% include "telemetry/include/filters.html" %}

<div class="col-md-12" style="text-align: center">
<div style="text-align: center; font-weight: bold">{% trans "Performance" %}</div>
<div id="performance-chart"></div>
</div>
</div>

<script src="{% static 'c3/c3.min.js' %}"></script>
<script src="{% static 'd3/d3.min.js' %}"></script>

<script src="{% static 'js/utils.js' %}"></script>
<script src="{% static 'js/jsonrpc.js' %}"></script>

<script src="{% static 'telemetry/js/testing/utils.js' %}"></script>
<script src="{% static 'telemetry/js/management/performance.js' %}"></script>

<!-- <link rel="stylesheet" type="text/css" href="{% static 'telemetry/css/testing/test-case-health.css' %}"/> -->
{% endblock %}
5 changes: 5 additions & 0 deletions tcms/telemetry/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@
views.TestingTestCaseHealth.as_view(),
name="test-case-health",
),
re_path(
r"^management/performance/$",
views.ManagementPerformance.as_view(),
name="management-performance",
),
]
7 changes: 7 additions & 0 deletions tcms/telemetry/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ class TestingExecutionTrendsView(TemplateView):
class TestingTestCaseHealth(TemplateView):

template_name = "telemetry/testing/test-case-health.html"

@method_decorator(
login_required, name="dispatch"
) # pylint: disable=missing-permission-required
class ManagementPerformance(TemplateView):

template_name = "telemetry/management/performance.html"

0 comments on commit 955549a

Please sign in to comment.