Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit955549a

Browse files
committed
wip: Add Performance Telemetry UI page
still WIP, because the page breaks when given too much data.the algorithm for the data looks OK, because it works with the smalldata-set I left in the code. however, given dataset with more than 500runs it fails to display the chart miserably.
1 parent62a61f6 commit955549a

File tree

6 files changed

+191
-0
lines changed

6 files changed

+191
-0
lines changed

‎tcms/settings/common.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@
326326
(_("TestCase health"),reverse_lazy("test-case-health")),
327327
],
328328
),
329+
(
330+
_("Management"),
331+
[
332+
(_("Performance"),reverse_lazy("management-performance")),
333+
],
334+
),
329335
(
330336
"More coming soon",
331337
"http://kiwitcms.org/blog/kiwi-tcms-team/2019/03/03/legacy-reports-become-telemetry/",
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// TODO: account for more users
2+
constcolors=[
3+
'blue',
4+
'red',
5+
'gold',
6+
'orange',
7+
'green',
8+
'cyan',
9+
'purple',
10+
'black',
11+
'lightBlue',
12+
'lightGreen'
13+
]
14+
15+
$(document).ready(()=>{
16+
$('.selectpicker').selectpicker()
17+
$('[data-toggle="tooltip"]').tooltip()
18+
19+
loadInitialProduct(reloadCharts)
20+
21+
$('#id_after').on('dp.change',reloadCharts)
22+
$('#id_before').on('dp.change',reloadCharts)
23+
document.getElementById('id_test_plan').onchange=reloadCharts
24+
document.getElementById('id_product').onchange=()=>{
25+
updateTestPlanSelectFromProduct(reloadCharts)
26+
}
27+
})
28+
29+
functionreloadCharts(){
30+
constquery={}
31+
32+
consttestPlanIds=$('#id_test_plan').val()
33+
constproductIds=$('#id_product').val()
34+
35+
if(testPlanIds.length){
36+
query.plan__in=testPlanIds
37+
}elseif(productIds.length){
38+
query.category__product_id__in=productIds
39+
}
40+
41+
constdateBefore=$('#id_before')
42+
if(dateBefore.val()){
43+
query.create_date__lte=dateBefore.data('DateTimePicker').date().format('YYYY-MM-DD 23:59:59')
44+
}
45+
46+
constdateAfter=$('#id_after')
47+
if(dateAfter.val()){
48+
query.create_date__gte=dateAfter.data('DateTimePicker').date().format('YYYY-MM-DD 00:00:00')
49+
}
50+
51+
jsonRPC('Management.performance',query,result=>{
52+
console.log(result)
53+
54+
// the actual result is in the same format, only it can be much bigger
55+
// and the chart may break
56+
constr={
57+
1:{
58+
1:1,
59+
3:2
60+
},
61+
2:{
62+
1:1,
63+
4:2
64+
},
65+
3:{
66+
1:1,
67+
3:1,
68+
5:1
69+
},
70+
4:{
71+
3:1,
72+
2:1
73+
},
74+
5:{
75+
1:5,
76+
3:2,
77+
4:1
78+
}
79+
}
80+
81+
drawChart(r)
82+
},true)
83+
}
84+
85+
functiondrawChart(data){
86+
// the X axis of the chart - run IDs
87+
constgroupedCategories=[]
88+
// map of user ID -> table column. we use map here for faster lookup by user ID.
89+
constgroupedColumnsDataMap={}
90+
constuserIds=newSet()
91+
92+
// collect all the testers so that we know how much columns we will have
93+
Object.entries(data).forEach(([_testRunId,asigneeCount])=>{
94+
Object.entries(asigneeCount).forEach(([userId,_executionCount])=>userIds.add(userId))
95+
})
96+
97+
userIds.forEach(userId=>(groupedColumnsDataMap[userId]=[`User${userId}`]))
98+
99+
Object.entries(data).forEach(([testRunId,_asigneeCount])=>{
100+
groupedCategories.push(testRunId)
101+
102+
constasigneesCount=data[testRunId]
103+
104+
// for each user in the groupedColumnsDataMap check if that user
105+
// is assigned any executions for this run.
106+
Object.entries(groupedColumnsDataMap).forEach(([userId,data])=>{
107+
constcount=asigneesCount[userId]
108+
if(count){
109+
data.push(count)
110+
}else{
111+
// TODO: find a way to hide the 0 valued-columns
112+
data.push(0)
113+
}
114+
})
115+
})
116+
117+
// C3 does not need a map, but an array of values
118+
// get rid of the keys, because we do not need them anymore
119+
constgroupedColumnsData=Object.values(groupedColumnsDataMap)
120+
121+
constchartConfig=$().c3ChartDefaults().getDefaultGroupedBarConfig()
122+
chartConfig.bindto='#performance-chart'
123+
chartConfig.axis={
124+
x:{
125+
categories:groupedCategories,
126+
type:'category'
127+
},
128+
y:{
129+
tick:{
130+
format:showOnlyRoundNumbers
131+
}
132+
}
133+
}
134+
chartConfig.data={
135+
type:'bar',
136+
columns:groupedColumnsData
137+
}
138+
chartConfig.color={
139+
pattern:colors
140+
}
141+
c3.generate(chartConfig)
142+
}

‎tcms/telemetry/static/telemetry/js/testing/breakdown.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ function drawChart(data, type, selector) {
114114
chartData.push(dataEntry);
115115
});
116116

117+
console.log('data',data)
118+
console.log('groups',groups)
119+
console.log('chartData',chartData)
117120
letchartConfig=$().c3ChartDefaults().getDefaultStackedBarConfig();
118121
chartConfig.bindto=selector;
119122
chartConfig.axis={
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends "base.html" %}
2+
{% load i18n %}
3+
{% load static %}
4+
5+
{% block title %}{% trans "Performance" %}{% endblock %}
6+
7+
{% block contents %}
8+
9+
<divclass="container-fluid container-cards-pf">
10+
{% include "telemetry/include/filters.html" %}
11+
12+
<divclass="col-md-12"style="text-align: center">
13+
<divstyle="text-align: center; font-weight: bold">{% trans "Performance" %}</div>
14+
<divid="performance-chart"></div>
15+
</div>
16+
</div>
17+
18+
<scriptsrc="{% static 'c3/c3.min.js' %}"></script>
19+
<scriptsrc="{% static 'd3/d3.min.js' %}"></script>
20+
21+
<scriptsrc="{% static 'js/utils.js' %}"></script>
22+
<scriptsrc="{% static 'js/jsonrpc.js' %}"></script>
23+
24+
<scriptsrc="{% static 'telemetry/js/testing/utils.js' %}"></script>
25+
<scriptsrc="{% static 'telemetry/js/management/performance.js' %}"></script>
26+
27+
<!-- <link rel="stylesheet" type="text/css" href="{% static 'telemetry/css/testing/test-case-health.css' %}"/> -->
28+
{% endblock %}

‎tcms/telemetry/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@
2323
views.TestingTestCaseHealth.as_view(),
2424
name="test-case-health",
2525
),
26+
re_path(
27+
r"^management/performance/$",
28+
views.ManagementPerformance.as_view(),
29+
name="management-performance",
30+
),
2631
]

‎tcms/telemetry/views.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,10 @@ class TestingExecutionTrendsView(TemplateView):
3333
classTestingTestCaseHealth(TemplateView):
3434

3535
template_name="telemetry/testing/test-case-health.html"
36+
37+
@method_decorator(
38+
login_required,name="dispatch"
39+
)# pylint: disable=missing-permission-required
40+
classManagementPerformance(TemplateView):
41+
42+
template_name="telemetry/management/performance.html"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp