592 lines
718 KiB
HTML
592 lines
718 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Test Report for locustfile.py</title>
|
||
|
<link rel="shortcut icon" href="../static/img/favicon.ico" type="image/x-icon"/>
|
||
|
<style>
|
||
|
body {
|
||
|
background: #173529;
|
||
|
}
|
||
|
.container {
|
||
|
width: 1000px;
|
||
|
margin: 0 auto;
|
||
|
padding: 10px;
|
||
|
font-family: Arial, Helvetica, sans-serif;
|
||
|
font-size: 14px;
|
||
|
color: #ecf3ee;
|
||
|
}
|
||
|
|
||
|
.info span {
|
||
|
color: #b3c3bc;
|
||
|
}
|
||
|
|
||
|
.charts-container .chart {
|
||
|
width: 100%;
|
||
|
height: 350px;
|
||
|
margin-bottom: 30px;
|
||
|
}
|
||
|
|
||
|
.download {
|
||
|
float: right;
|
||
|
}
|
||
|
|
||
|
.download a {
|
||
|
color: #00ca5a;
|
||
|
}
|
||
|
|
||
|
/* tables.css */
|
||
|
table.stats {
|
||
|
width: 100%;
|
||
|
border-radius: 3px;
|
||
|
border: 2px solid #11251c;
|
||
|
border-spacing: 0;
|
||
|
margin-bottom: 30px;
|
||
|
}
|
||
|
table.stats thead {
|
||
|
padding: 0;
|
||
|
margin: 0;
|
||
|
color: #a9c5ba;
|
||
|
}
|
||
|
table.stats thead tr {
|
||
|
background: #11251c;
|
||
|
}
|
||
|
table.stats thead tr:nth-child(even) {
|
||
|
background: #11251c;
|
||
|
}
|
||
|
table.stats thead tr:hover {
|
||
|
background: #11251c;
|
||
|
}
|
||
|
table.stats thead th {
|
||
|
font-weight: bold;
|
||
|
cursor: default;
|
||
|
}
|
||
|
table.stats thead th.nowrap {
|
||
|
white-space: nowrap;
|
||
|
}
|
||
|
table.stats thead th[data-sortkey] {
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
table.stats tr:hover {
|
||
|
background: #1d4434;
|
||
|
}
|
||
|
table.stats tr td, table.stats tr th {
|
||
|
padding: 10px;
|
||
|
margin: 0;
|
||
|
text-align: left;
|
||
|
}
|
||
|
table.stats tr td:first-child, table.stats tr th:first-child {
|
||
|
padding-left: 16px;
|
||
|
}
|
||
|
table.stats tr td:last-child, table.stats tr th:last-child {
|
||
|
padding-right: 16px;
|
||
|
}
|
||
|
table.stats tr td.numeric, table.stats tr th.numeric {
|
||
|
text-align: right;
|
||
|
}
|
||
|
table.stats tr td {
|
||
|
max-width: 450px;
|
||
|
overflow: hidden;
|
||
|
word-wrap: break-word;
|
||
|
white-space: no-wrap;
|
||
|
text-overflow: ellipsis;
|
||
|
}
|
||
|
@media (max-width: 1100px) {
|
||
|
table.stats tr td {
|
||
|
max-width: 350px;
|
||
|
}
|
||
|
}
|
||
|
table.stats tr:nth-child(even) {
|
||
|
background: #153126;
|
||
|
}
|
||
|
table.stats tr:nth-child(even):hover {
|
||
|
background: #1d4434;
|
||
|
}
|
||
|
table.stats tr.total {
|
||
|
background: #11251c;
|
||
|
}
|
||
|
table.stats tr.total td {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
|
||
|
/*# sourceMappingURL=tables.css.map */
|
||
|
|
||
|
|
||
|
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="container">
|
||
|
<h1>Locust Test Report</h1>
|
||
|
|
||
|
<div class="info">
|
||
|
|
||
|
<p>During: <span class="l10n datetime">2023-12-29 14:29:09</span> - <span class="l10n datetime">2023-12-29 14:29:46</span></p>
|
||
|
<p>Target Host: <span>localhost:9001</span></p>
|
||
|
<p>Script: <span>locustfile.py</span></p>
|
||
|
</div>
|
||
|
|
||
|
<div class="requests">
|
||
|
<h2>Request Statistics</h2>
|
||
|
<table class="stats">
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th class="sortable">Method</th>
|
||
|
<th class="sortable">Name</th>
|
||
|
<th class="sortable"># Requests</th>
|
||
|
<th class="sortable"># Fails</th>
|
||
|
<th class="sortable">Average (ms)</th>
|
||
|
<th class="sortable">Min (ms)</th>
|
||
|
<th class="sortable">Max (ms)</th>
|
||
|
<th class="sortable">Average size (bytes)</th>
|
||
|
<th class="sortable">RPS</th>
|
||
|
<th class="sortable">Failures/s</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
|
||
|
<tr>
|
||
|
<td>grpc</td>
|
||
|
<td>/dcache.DcacheService/PipelineDcacheOps</td>
|
||
|
<td>3480</td>
|
||
|
<td>0</td>
|
||
|
<td>104</td>
|
||
|
<td>85</td>
|
||
|
<td>842</td>
|
||
|
<td>14999</td>
|
||
|
<td>95.7</td>
|
||
|
<td>0.0</td>
|
||
|
</tr>
|
||
|
|
||
|
<tr class="total">
|
||
|
<td></td>
|
||
|
<td>Aggregated</td>
|
||
|
<td>3480</td>
|
||
|
<td>0</td>
|
||
|
<td>104</td>
|
||
|
<td>85</td>
|
||
|
<td>842</td>
|
||
|
<td>14999</td>
|
||
|
<td>95.7</td>
|
||
|
<td>0.0</td>
|
||
|
</tr>
|
||
|
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<div class="responses">
|
||
|
<h2>Response Time Statistics</h2>
|
||
|
<table class="stats">
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th class="sortable">Method</th>
|
||
|
<th class="sortable">Name</th>
|
||
|
<th class="sortable">50%ile (ms)</th>
|
||
|
<th class="sortable">60%ile (ms)</th>
|
||
|
<th class="sortable">70%ile (ms)</th>
|
||
|
<th class="sortable">80%ile (ms)</th>
|
||
|
<th class="sortable">90%ile (ms)</th>
|
||
|
<th class="sortable">95%ile (ms)</th>
|
||
|
<th class="sortable">99%ile (ms)</th>
|
||
|
<th class="sortable">100%ile (ms)</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
|
||
|
<tr>
|
||
|
<td>grpc</td>
|
||
|
<td>/dcache.DcacheService/PipelineDcacheOps</td>
|
||
|
<td>98</td>
|
||
|
<td>99</td>
|
||
|
<td>100</td>
|
||
|
<td>100</td>
|
||
|
<td>100</td>
|
||
|
<td>110</td>
|
||
|
<td>360</td>
|
||
|
<td>840</td>
|
||
|
</tr>
|
||
|
|
||
|
<tr class="total">
|
||
|
<td></td>
|
||
|
<td>Aggregated</td>
|
||
|
<td>98</td>
|
||
|
<td>99</td>
|
||
|
<td>100</td>
|
||
|
<td>100</td>
|
||
|
<td>100</td>
|
||
|
<td>110</td>
|
||
|
<td>360</td>
|
||
|
<td>840</td>
|
||
|
</tr>
|
||
|
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<div class="charts-container">
|
||
|
<h2>Charts</h2>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<div id="tasks">
|
||
|
<h2>Final ratio</h2>
|
||
|
<div class="tasks" data-tasks="{"per_class": {"HelloGrpcUser": {"ratio": 1.0, "tasks": {"addVotePipeline": {"ratio": 1.0}}}}, "total": {"HelloGrpcUser": {"ratio": 1.0, "tasks": {"addVotePipeline": {"ratio": 1.0}}}}}"></div>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<script>
|
||
|
// jquery-1.11.3.min.js
|
||
|
|
||
|
/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
|
||
|
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each(
|
||
|
|
||
|
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</tex
|
||
|
return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h
|
||
|
|
||
|
|
||
|
|
||
|
// echarts.common.min.js
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||
|
* or more contributor license agreements. See the NOTICE file
|
||
|
* distributed with this work for additional information
|
||
|
* regarding copyright ownership. The ASF licenses this file
|
||
|
* to you under the Apache License, Version 2.0 (the
|
||
|
* "License"); you may not use this file except in compliance
|
||
|
* with the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing,
|
||
|
* software distributed under the License is distributed on an
|
||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
* KIND, either express or implied. See the License for the
|
||
|
* specific language governing permissions and limitations
|
||
|
* under the License.
|
||
|
*/
|
||
|
|
||
|
|
||
|
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).echarts={})}(this,function(t){"use strict";var i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function l(t,e){function n(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var h=function(){return(h=Object.assign||function(t){for(var e,n=1,i=arguments.length;n<i;n++)for(var r in e=arguments[n])Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t}).apply(this,arguments)};function a(){for(var t=0,e=0,n=arguments.length;e<n;e++)t+=arguments[e].length;for(var i=Array(t),r=0,e=0;e<n;e++)for(var o=arguments[e],a=0,s=o.length;a<s;a++,r++)i[r]=o[a];return i}var e=function(){this.firefox=!1,this.ie=!1,this.edge=!1,this.weChat=!1},w=new function(){this.browser=new e,this.node=!1,this.wxa=!1,this.worker=!1,this.canvasSupported=!1,this.svgSupported=!1,this.touchEventsSupported=!1,this.pointerEventsSupported=!1,this.domSupported=!1};"object"==typeof wx&&"function"==typeof wx.getSystemInfoSync?(w.wxa=!0,w.canvasSupported=!0,w.touchEventsSupported=!0):"undefined"==typeof document&&"undefined"!=typeof self?(w.worker=!0,w.canvasSupported=!0):"undefined"==typeof navigator?(w.node=!0,w.canvasSupported=!0,w.svgSupported=!0):function(t,e){var n=e.browser,i=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge\/([\d.]+)/),t=/micromessenger/i.test(t);i&&(n.firefox=!0,n.version=i[1]);r&&(n.ie=!0,n.version=r[1]);o&&(n.edge=!0,n.version=o[1]);t&&(n.weChat=!0);e.canvasSupported=!!document.createElement("canvas").getContext,e.svgSupported="undefined"!=typeof SVGRect,e.touchEventsSupported="ontouchstart"in window&&!n.ie&&!n.edge,e.pointerEventsSupported="onpointerdown"in window&&(n.edge||n.ie&&11<=+n.version),e.domSupported="undefined"!=typeof document}(navigator.userAgent,w);var s={"[object Function]":!0,"[object RegExp]":!0,"[object Date]":!0,"[object Error]":!0,"[object CanvasGradient]":!0,"[object CanvasPattern]":!0,"[object Image]":!0,"[object Canvas]":!0},u={"[object Int8Array]":!0,"[object Uint8Array]":!0,"[object Uint8ClampedArray]":!0,"[object Int16Array]":!0,"[object Uint16Array]":!0,"[object Int32Array]":!0,"[object Uint32Array]":!0,"[object Float32Array]":!0,"[object Float64Array]":!0},c=Object.prototype.toString,n=Array.prototype,p=n.forEach,d=n.filter,r=n.slice,f=n.map,o=function(){}.constructor,g=o?o.prototype:null,y={};function m(t,e){y[t]=e}var v=2311;function _(){return v++}function x(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];"undefined"!=typeof console&&console.error.apply(console,t)}function I(t){if(null==t||"object"!=typeof t)return t;var e=t,n=c.call(t);if("[object Array]"===n){if(!st(t)){e=[];for(var i=0,r=t.length;i<r;i++)e[i]=I(t[i])}}else if(u[n]){if(!st(t)){var o=t.constructor;if(o.from)e=o.from(t);else{e=new o(t.length);for(i=0,r=t.length;i<r;i++)e[i]=I(t[i])}}}else if(!s[n]&&!st(t)&&!Z(t))for(var a in e={},t)t.hasOwnProperty(a)&&(e[a]=I(t[a]));return e}function b(t,e,n){if(!U(e)||!U(t))return n?I(e):t;for(var i in e){var r,o;e.hasOwnProperty(i)&&(r=t[i],!U(o=e[i])||!U(r)||V(o)||V(r)||Z(o)||Z(r)||X(o)||X(r)||st(o)||st(r)?!n&&i in t||(t[i]=I(e[i])):b(r,o,n))}return t}function S(t,e){for(var n=t[0],i=1,r=t.length;i<r;i++)n=b(n,t[i],e);return n}function A(t,e){if(Object.assign)Object.assign(t,e);else for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}function D(t,e,n){for(var i=N(e),r=0;r<i.length;r++){var o=i[r];(n?null!=e[o]:null==t[o])&&(t[o]=e[o])}return t}var k=function(){return y.createCanvas()};function L(t,e){if(t){if(t.indexOf)return t.indexOf(e);for(var n=0,i=t.length;n<i;n++)if(t[n]===e)return n}return-1}function M(t,e){var n,i=t.prototype;function r(){}for(n in r.prototype=e.prototype,t.prototype=new r,i)i.hasOwnProperty(n)&&(t.prototype[n]=i[n]);(t.prototype.constructor=t).superClass=e}function
|
||
|
|
||
|
|
||
|
// vintage.js
|
||
|
|
||
|
(function (root, factory) {
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
// AMD. Register as an anonymous module.
|
||
|
define(['exports', 'echarts'], factory);
|
||
|
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
|
||
|
// CommonJS
|
||
|
factory(exports, require('echarts'));
|
||
|
} else {
|
||
|
// Browser globals
|
||
|
factory({}, root.echarts);
|
||
|
}
|
||
|
}(this, function (exports, echarts) {
|
||
|
var log = function (msg) {
|
||
|
if (typeof console !== 'undefined') {
|
||
|
console && console.error && console.error(msg);
|
||
|
}
|
||
|
};
|
||
|
if (!echarts) {
|
||
|
log('ECharts is not Loaded');
|
||
|
return;
|
||
|
}
|
||
|
var colorPalette = ['#00ca5a','#ffca5a', '#d7ab82', '#6e7074','#61a0a8','#efa18d', '#787464', '#cc7e63', '#724e58', '#4b565b'];
|
||
|
echarts.registerTheme('vintage', {
|
||
|
color: colorPalette,
|
||
|
backgroundColor: '#132b21',
|
||
|
xAxis: {lineColor: "#f00"},
|
||
|
graph: {
|
||
|
color: colorPalette,
|
||
|
},
|
||
|
textStyle: {color:"#b3c3bc"},
|
||
|
title: {
|
||
|
textStyle:{color:"#b3c3bc"}
|
||
|
},
|
||
|
});
|
||
|
}));
|
||
|
|
||
|
|
||
|
// chart.js
|
||
|
|
||
|
(function() {
|
||
|
class LocustLineChart {
|
||
|
/**
|
||
|
* lines should be an array of line names
|
||
|
*/
|
||
|
constructor(container, title, lines, unit, colors) {
|
||
|
this.container = $(container);
|
||
|
this.title = title;
|
||
|
this.lines = lines;
|
||
|
|
||
|
this.element = $('<div class="chart"></div>').css("width", "100%").appendTo(container);
|
||
|
this.data = [];
|
||
|
this.dates = [];
|
||
|
|
||
|
var seriesData = [];
|
||
|
for (var i=0; i<lines.length; i++) {
|
||
|
seriesData.push({
|
||
|
name: lines[i],
|
||
|
type: 'line',
|
||
|
showSymbol: true,
|
||
|
hoverAnimation: false,
|
||
|
data: [],
|
||
|
});
|
||
|
this.data.push([]);
|
||
|
}
|
||
|
|
||
|
this.chart = echarts.init(this.element[0], 'vintage');
|
||
|
this.chart.setOption({
|
||
|
legend: {
|
||
|
icon: 'circle',
|
||
|
inactiveColor: '#b3c3bc',
|
||
|
textStyle: {
|
||
|
color: '#b3c3bc',
|
||
|
}
|
||
|
},
|
||
|
title: {
|
||
|
text: this.title,
|
||
|
x: 10,
|
||
|
y: 10,
|
||
|
},
|
||
|
tooltip: {
|
||
|
trigger: 'axis',
|
||
|
formatter: function (params) {
|
||
|
if (!!params && params.length > 0 && params.some(param => !!param.value)) {
|
||
|
var str = params[0].name;
|
||
|
for (var i=0; i<params.length; i++) {
|
||
|
var param = params[i];
|
||
|
str += '<br><span style="color:' + param.color + ';">' + param.seriesName + ': ' + param.data.value + '</span>';
|
||
|
}
|
||
|
if(param.data.users != undefined){
|
||
|
str += '<br><span style="color:#a3b3ac;">Users: ' + param.data.users + '</span>';
|
||
|
}
|
||
|
return str;
|
||
|
} else {
|
||
|
return "No data";
|
||
|
}
|
||
|
},
|
||
|
axisPointer: {
|
||
|
animation: true
|
||
|
},
|
||
|
textStyle: {
|
||
|
color: '#b3c3bc',
|
||
|
fontSize: 13,
|
||
|
},
|
||
|
backgroundColor: 'rgba(21,35,28, 0.93)',
|
||
|
borderWidth: 0,
|
||
|
extraCssText: "z-index:1;",
|
||
|
},
|
||
|
xAxis: {
|
||
|
type: 'category',
|
||
|
splitLine: {
|
||
|
show: false
|
||
|
},
|
||
|
axisLine: {
|
||
|
lineStyle: {
|
||
|
color: '#5b6f66',
|
||
|
},
|
||
|
},
|
||
|
data: this.dates,
|
||
|
},
|
||
|
yAxis: {
|
||
|
type: 'value',
|
||
|
boundaryGap: [0, '5%'],
|
||
|
splitLine: {
|
||
|
show: false
|
||
|
},
|
||
|
axisLine: {
|
||
|
lineStyle: {
|
||
|
color: '#5b6f66',
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
series: seriesData,
|
||
|
grid: {x:60, y:70, x2:40, y2:40},
|
||
|
color: colors,
|
||
|
toolbox: {
|
||
|
feature: {
|
||
|
saveAsImage: {
|
||
|
name: this.title.replace(/\s+/g, '_').toLowerCase() + '_' + Date.parse(new Date()) / 1000,
|
||
|
title: "Download as PNG",
|
||
|
emphasis: {
|
||
|
iconStyle: {
|
||
|
textPosition: "left"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
addValue(values, user_count=0) {
|
||
|
this.dates.push(new Date().toLocaleTimeString());
|
||
|
var seriesData = [];
|
||
|
for (var i=0; i<values.length; i++) {
|
||
|
var value = Math.round(values[i] * 100) / 100;
|
||
|
this.data[i].push({"value": value, "users": user_count});
|
||
|
seriesData.push({data: this.data[i]});
|
||
|
}
|
||
|
this.chart.setOption({
|
||
|
xAxis: {
|
||
|
data: this.dates,
|
||
|
},
|
||
|
series: seriesData
|
||
|
});
|
||
|
}
|
||
|
|
||
|
resize() {
|
||
|
this.chart.resize();
|
||
|
}
|
||
|
}
|
||
|
window.LocustLineChart = LocustLineChart;
|
||
|
})();
|
||
|
|
||
|
|
||
|
|
||
|
// tasks.js
|
||
|
|
||
|
function getRatioPercent(ratio) {
|
||
|
return (ratio * 100).toFixed(1) + "%";
|
||
|
}
|
||
|
|
||
|
function _initTasks_sub(li, tasks) {
|
||
|
if (tasks) {
|
||
|
var ul = $('<ul></ul>');
|
||
|
for (const [key, task] of Object.entries(tasks)) {
|
||
|
var liTask = $('<li></li>').text(getRatioPercent(task.ratio) + " " + key);
|
||
|
_initTasks_sub(liTask, task.tasks);
|
||
|
ul.append(liTask);
|
||
|
}
|
||
|
li.append(ul);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function _getTasks_div(root, title) {
|
||
|
var taskDiv = $('<div></div>');
|
||
|
var taskDivHeading = $('<h3></h3>').text(title);
|
||
|
taskDiv.append(taskDivHeading);
|
||
|
var ulClasses = $('<ul></ul>');
|
||
|
for (const [key, clazz] of Object.entries(root)) {
|
||
|
var liClass = $('<li></li>').text(getRatioPercent(clazz.ratio) + " " + key);
|
||
|
_initTasks_sub(liClass, clazz.tasks)
|
||
|
ulClasses.append(liClass);
|
||
|
}
|
||
|
taskDiv.append(ulClasses);
|
||
|
return taskDiv
|
||
|
}
|
||
|
|
||
|
function _renderTasks(data) {
|
||
|
var tasks = $('#tasks .tasks');
|
||
|
tasks.empty();
|
||
|
tasks.append(_getTasks_div(data.per_class, 'Ratio per User class'));
|
||
|
tasks.append(_getTasks_div(data.total, 'Total ratio'));
|
||
|
}
|
||
|
|
||
|
function fillTasksFromObj() {
|
||
|
var tasks = $('#tasks .tasks')
|
||
|
var data = tasks.data('tasks');
|
||
|
_renderTasks(data)
|
||
|
}
|
||
|
|
||
|
function fillTasksFromRequest() {
|
||
|
$.get('./tasks', function (data) {
|
||
|
_renderTasks(data)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
</script>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
var stats_history = {
|
||
|
"time": ["14:29:12", "14:29:17", "14:29:22", "14:29:27", "14:29:32", "14:29:37", "14:29:42"].map(server_time => new Date(new Date().setUTCHours(...(server_time.split(":")))).toLocaleTimeString()),
|
||
|
"user_count": [{"value": 10}, {"value": 10}, {"value": 10}, {"value": 10}, {"value": 10}, {"value": 10}, {"value": 10}],
|
||
|
"current_rps": [{"users": 10, "value": 10.0}, {"users": 10, "value": 86.66666666666667}, {"users": 10, "value": 102.0}, {"users": 10, "value": 101.0}, {"users": 10, "value": 100.0}, {"users": 10, "value": 100.0}, {"users": 10, "value": 100.0}],
|
||
|
"current_fail_per_sec": [{"users": 10, "value": 0}, {"users": 10, "value": 0}, {"users": 10, "value": 0}, {"users": 10, "value": 0}, {"users": 10, "value": 0}, {"users": 10, "value": 0}, {"users": 10, "value": 0}],
|
||
|
"response_time_percentile_1": [{"users": 10, "value": 98}, {"users": 10, "value": 98}, {"users": 10, "value": 98}, {"users": 10, "value": 98}, {"users": 10, "value": 99}, {"users": 10, "value": 98}, {"users": 10, "value": 98}],
|
||
|
"response_time_percentile_2": [{"users": 10, "value": 100}, {"users": 10, "value": 100}, {"users": 10, "value": 100}, {"users": 10, "value": 110.0}, {"users": 10, "value": 110.0}, {"users": 10, "value": 110.0}, {"users": 10, "value": 110.0}],
|
||
|
"markers": [],
|
||
|
};
|
||
|
var percentile1 = 0.5
|
||
|
var percentile2 = 0.95
|
||
|
var rpsChart = new LocustLineChart($(".charts-container"), "Total Requests per Second", ["RPS", "Failures/s"], "reqs/s", ['#00ca5a', '#ff6d6d']);
|
||
|
var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", [(percentile1*100).toString() + "th percentile" , (percentile2*100).toString() + "th percentile"], "ms");
|
||
|
var usersChart = new LocustLineChart($(".charts-container"), "Number of Users", ["Users"], "users");
|
||
|
|
||
|
if(stats_history["time"].length > 0){
|
||
|
rpsChart.chart.setOption({
|
||
|
xAxis: {data: stats_history["time"]},
|
||
|
series: [
|
||
|
{data: stats_history["current_rps"]},
|
||
|
{data: stats_history["current_fail_per_sec"]},
|
||
|
]
|
||
|
});
|
||
|
|
||
|
responseTimeChart.chart.setOption({
|
||
|
xAxis: {data: stats_history["time"]},
|
||
|
series: [
|
||
|
{data: stats_history["response_time_percentile_1"]},
|
||
|
{data: stats_history["response_time_percentile_2"]},
|
||
|
]
|
||
|
});
|
||
|
|
||
|
usersChart.chart.setOption({
|
||
|
xAxis: {
|
||
|
data: stats_history["time"]
|
||
|
},
|
||
|
series: [
|
||
|
{data: stats_history["user_count"]},
|
||
|
]
|
||
|
});
|
||
|
}
|
||
|
|
||
|
$(".l10n.datetime").html((index, currentContent) => {
|
||
|
if (!currentContent || !currentContent.includes(" ") || !currentContent.includes(":")) {
|
||
|
return currentContent;
|
||
|
}
|
||
|
|
||
|
return new Date(Date.parse(currentContent.replace(" ", "T") + ".000Z")).toLocaleString();
|
||
|
});
|
||
|
|
||
|
fillTasksFromObj()
|
||
|
</script>
|
||
|
|
||
|
<script>
|
||
|
$('.sortable').click(function() {
|
||
|
var table = $(this).parents('table').eq(0)
|
||
|
var rowArray = table.find('tr:gt(0)').toArray()
|
||
|
var aggregatedRow = rowArray.pop()
|
||
|
var rows = rowArray.sort(comparer($(this).index()))
|
||
|
this.asc = !this.asc
|
||
|
if (!this.asc){rows = rows.reverse()}
|
||
|
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
|
||
|
table.append(aggregatedRow)
|
||
|
})
|
||
|
function comparer(index) {
|
||
|
return function(a,b) {
|
||
|
var valA = getCellValue(a, index), valB = getCellValue(b, index)
|
||
|
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB)
|
||
|
}
|
||
|
}
|
||
|
function getCellValue(row, index) { return $(row).children('td').eq(index).text() }
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|