add support to create html file for http
Change-Id: If857d9e884c207d1389f632e648592d63f09e7a4
This commit is contained in:
parent
73f07f7f7d
commit
1c0622dd6a
|
@ -664,19 +664,21 @@ class KloudBuster(object):
|
|||
|
||||
return quota_dict
|
||||
|
||||
def create_html(self, html, hfp, template, task_re, label, headless):
|
||||
def create_html(self, hfp, template, task_re):
|
||||
cur_time = time.strftime('%Y-%m-%d %A %X %Z', time.localtime(time.time()))
|
||||
for line in template:
|
||||
line = line.replace('[[time]]', cur_time)
|
||||
if label:
|
||||
line = line.replace('[[label]]', ' - ' + label)
|
||||
if CONF.label and CONF.storage:
|
||||
line = line.replace('[[label]]', ' - ' + CONF.label)
|
||||
elif CONF.label:
|
||||
line = line.replace('[[label]]', CONF.label)
|
||||
else:
|
||||
line = line.replace('[[label]]', '')
|
||||
line = line.replace('[[result]]', task_re)
|
||||
hfp.write(line)
|
||||
if not headless:
|
||||
if not CONF.headless:
|
||||
# bring up the file in the default browser
|
||||
url = 'file://' + os.path.abspath(html)
|
||||
url = 'file://' + os.path.abspath(CONF.html)
|
||||
webbrowser.open(url, new=2)
|
||||
|
||||
|
||||
|
@ -713,10 +715,10 @@ def main():
|
|||
help="Testing cloud password"),
|
||||
cfg.StrOpt("html",
|
||||
default=None,
|
||||
help='store results in HTML file (storage test only)'),
|
||||
help='store results in HTML file'),
|
||||
cfg.StrOpt("label",
|
||||
default=None,
|
||||
help='label for the title in HTML file (storage test only)'),
|
||||
help='label for the title in HTML file'),
|
||||
cfg.BoolOpt("headless",
|
||||
default=False,
|
||||
help="do not show chart in the browser (default=False, only used if --html)"),
|
||||
|
@ -763,17 +765,17 @@ def main():
|
|||
with open(CONF.json, 'w') as jfp:
|
||||
json.dump(kloudbuster.final_result, jfp, indent=4, sort_keys=True)
|
||||
|
||||
if CONF.storage and CONF.html:
|
||||
if CONF.html:
|
||||
'''Save results in HTML format file.'''
|
||||
LOG.info('Saving results in HTML file: ' + CONF.html + "...")
|
||||
template_path = resource_filename(__name__, 'template.html')
|
||||
if CONF.storage:
|
||||
template_path = resource_filename(__name__, 'template_storage.html')
|
||||
else:
|
||||
template_path = resource_filename(__name__, 'template_http.html')
|
||||
with open(CONF.html, 'w') as hfp, open(template_path, 'r') as template:
|
||||
kloudbuster.create_html(CONF.html,
|
||||
hfp,
|
||||
kloudbuster.create_html(hfp,
|
||||
template,
|
||||
json.dumps(kloudbuster.final_result, sort_keys=True),
|
||||
CONF.label,
|
||||
CONF.headless)
|
||||
json.dumps(kloudbuster.final_result, sort_keys=True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
<!--Copyright 2016 Cisco Systems, Inc. All rights reserved.-->
|
||||
|
||||
<!--Licensed 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.-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US" ng-app="app">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>KloudBuster Report</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
|
||||
<script src="https://d3js.org/d3.v3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/line-chart/2.0.3/LineChart.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/line-chart/2.0.3/LineChart.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.js"></script>
|
||||
<link rel="stylesheet" href="https://bootswatch.com/flatly/bootstrap.min.css">
|
||||
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
|
||||
|
||||
<style rel="stylesheet">
|
||||
.hidden {
|
||||
display: inline !important;
|
||||
}
|
||||
.label {
|
||||
padding: 0;
|
||||
font-size: 110%;
|
||||
font-weight: normal;
|
||||
line-height: 16;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body ng-controller="MainCtrl">
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">KloudBuster Report</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="#">[[time]]</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<h3>[[label]]</h3>
|
||||
<div class="my-chart" style="height: 400px;margin-bottom: 10%">
|
||||
<linechart data="data" options="options"></linechart>
|
||||
</div>
|
||||
<table ng-table="tableParams" class="table table-responsive table-condensed table-bordered table-striped">
|
||||
<tr ng-repeat="row in tableParams.data" style="text-align:center;">
|
||||
<td title="cols[0].title" ng-if="cols[0].show" style="margin:0 auto;padding:0;">
|
||||
<button class="btn btn-default btn-xs {{row.seq}}" ng-click=""
|
||||
style="height: 22px;width: 24px;"></button>
|
||||
</td>
|
||||
<td title="cols[1].title" data-sortable="cols[1].field" ng-if="cols[1].show">{{row.connection}}</td>
|
||||
<td title="cols[2].title" data-sortable="cols[2].field" ng-if="cols[2].show">{{row.server_vms}}</td>
|
||||
<td title="cols[3].title" data-sortable="cols[3].field" ng-if="cols[3].show">{{row.requests}}</td>
|
||||
<td title="cols[4].title" data-sortable="cols[4].field" ng-if="cols[4].show">{{row.sock_err}}</td>
|
||||
<td title="cols[5].title" data-sortable="cols[5].field" ng-if="cols[5].show">{{row.rps}}</td>
|
||||
<td title="cols[6].title" data-sortable="cols[6].field" ng-if="cols[6].show">{{row.rate_limit}}</td>
|
||||
<td title="cols[7].title" data-sortable="cols[7].field" ng-if="cols[7].show">{{row.throughput}} Gbps</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
angular.module("app", ["n3-line-chart", "ngTable"]).controller("MainCtrl", function ($scope, color, ngTableParams) {
|
||||
$scope.result = [[result]];
|
||||
var countRep = $scope.result.length;
|
||||
$scope.data = {dataset0: [{x: 0}, {x: 10}, {x: 20}, {x: 30}, {x: 40}, {x: 50}, {x: 60}]};
|
||||
$scope.options = {
|
||||
series: [], axes: {
|
||||
x: {
|
||||
key: "x", type: "linear", tickFormat: function (value) {
|
||||
if (value === 0) {
|
||||
return "50%"
|
||||
} else if (value === 10) {
|
||||
return "75%"
|
||||
} else if (value === 20) {
|
||||
return "90%"
|
||||
} else if (value === 30) {
|
||||
return "99%"
|
||||
} else if (value === 40) {
|
||||
return "99.9%"
|
||||
} else if (value === 50) {
|
||||
return "99.99%"
|
||||
} else if (value === 60) {
|
||||
return "99.999%"
|
||||
}
|
||||
}
|
||||
}, y: {
|
||||
type: "log", ticksFormat: "d", ticks: 10, tickFormat: function (value, index) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}, margin: {top: 20, right: 30, bottom: 20, left: 30}, grid: {x: false, y: true}
|
||||
};
|
||||
$scope.tabledata = [];
|
||||
$scope.cols = [{field: "seq", title: "SEQ", sortable: "seq", show: true}, {
|
||||
field: "connection",
|
||||
title: "Connection",
|
||||
sortable: "connection",
|
||||
show: true
|
||||
}, {field: "server_vms", title: "Server VMs", sortable: "server_vms", show: true}, {
|
||||
field: "requests",
|
||||
title: "Requests",
|
||||
sortable: "requests",
|
||||
show: true
|
||||
}, {field: "sock_err", title: "Error", sortable: "sock_err", show: true}, {
|
||||
field: "rps",
|
||||
title: "RPS measured",
|
||||
sortable: "rps",
|
||||
show: true
|
||||
}, {field: "rate_limit", title: "RPS requested", sortable: "rate_limit", show: true}, {
|
||||
field: "throughput",
|
||||
title: "Throughput",
|
||||
sortable: "throughput",
|
||||
show: true
|
||||
},];
|
||||
$scope.tableParams = new ngTableParams({sorting: {name: "asc"}, "count": 10}, {
|
||||
counts: [],
|
||||
data: $scope.tabledata
|
||||
});
|
||||
$scope.pushTableData = function (taName, taData, pickColor) {
|
||||
var temThrou = (taData.http_throughput_kbytes * 8) / (1000 * 1000);
|
||||
$scope.tabledata.push({
|
||||
"seq": taName,
|
||||
"connection": taData.total_connections,
|
||||
"server_vms": taData.total_server_vms,
|
||||
"requests": taData.http_total_req,
|
||||
"sock_err": taData.http_sock_err + taData.http_sock_timeout,
|
||||
"rps": taData.http_rps,
|
||||
"rate_limit": taData.http_rate_limit,
|
||||
"throughput": temThrou.toFixed(2),
|
||||
"description": taData.description,
|
||||
"color": pickColor
|
||||
});
|
||||
$("<style>button." + taName + " {background-color: " + pickColor + ";</style>").appendTo("head");
|
||||
$scope.tableParams.reload()
|
||||
};
|
||||
for (var i = 0; i < countRep; i++) {
|
||||
$scope.perrow = $scope.result[i];
|
||||
var pickColor = color.getColor();
|
||||
if (1) {
|
||||
chName = "Connection-" + $scope.perrow.total_connections;
|
||||
$scope.options.series.push({
|
||||
label: chName,
|
||||
color: pickColor,
|
||||
dotSize: "3",
|
||||
thickness: "2px",
|
||||
axis: "y",
|
||||
dataset: "dataset0",
|
||||
key: chName,
|
||||
type: ["line", "dot"],
|
||||
id: chName,
|
||||
interpolation: {mode: "cardinal", tension: 0.8}
|
||||
});
|
||||
for (var j = 0; j < 7; j++) {
|
||||
$scope.data.dataset0[j][chName] = $scope.perrow.latency_stats[j][1] / 1000
|
||||
}
|
||||
$scope.pushTableData("Connection-" + $scope.perrow.total_connections, $scope.perrow, pickColor)
|
||||
}
|
||||
}
|
||||
}).service("color", function () {
|
||||
var self = this;
|
||||
var num = -1;
|
||||
var colorList = ["#F44336", "#673AB7", "#03A9F4", "#4CAF50", "#FFEB3B", "#BF360C", "#795548", "#E91E63", "#3F51B5", "#00BCD4", "#CDDC39", "#FF9800", "#9E9E9E", "#9C27B0", "#009688"];
|
||||
var length = colorList.length;
|
||||
this.getColor = function () {
|
||||
num = (num + 1) % length;
|
||||
return colorList[num]
|
||||
};
|
||||
this.reset = function () {
|
||||
num = -1
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||
<!--Copyright 2015 Cisco Systems, Inc. All rights reserved.-->
|
||||
<!--Copyright 2016 Cisco Systems, Inc. All rights reserved.-->
|
||||
|
||||
<!--Licensed under the Apache License, Version 2.0 (the "License"); you may-->
|
||||
<!--not use this file except in compliance with the License. You may obtain-->
|
Loading…
Reference in New Issue