# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-''' yardstick-plot - a command line tool for visualizing results from the
+""" yardstick-plot - a command line tool for visualizing results from the
output file of yardstick framework.
Example invocation:
$ yardstick-plot -i /tmp/yardstick.out -o /tmp/plots/
-'''
+"""
+
+from __future__ import absolute_import
+from __future__ import print_function
import argparse
-import json
import os
import sys
import time
-import matplotlib.pyplot as plt
+
import matplotlib.lines as mlines
+import matplotlib.pyplot as plt
+from oslo_serialization import jsonutils
+from six.moves import range
+from six.moves import zip
class Parser(object):
- ''' Command-line argument and input file parser for yardstick-plot tool'''
+ """ Command-line argument and input file parser for yardstick-plot tool"""
def __init__(self):
self.data = {
self.scenarios = {}
def _get_parser(self):
- '''get a command-line parser'''
+ """get a command-line parser"""
parser = argparse.ArgumentParser(
prog='yardstick-plot',
description="A tool for visualizing results from yardstick. "
"Currently supports plotting graphs for output files "
- "from tests: " + str(self.data.keys())
+ "from tests: " + str(list(self.data.keys()))
)
parser.add_argument(
'-i', '--input',
return parser
def _add_record(self, record):
- '''add record to the relevant scenario'''
+ """add record to the relevant scenario"""
if "runner_id" in record and "benchmark" not in record:
obj_name = record["scenario_cfg"]["runner"]["object"]
self.scenarios[record["runner_id"]] = obj_name
return
runner_object = self.scenarios[record["runner_id"]]
- for test_type in self.data.keys():
+ for test_type in self.data:
if test_type in runner_object:
self.data[test_type].append(record)
def parse_args(self):
- '''parse command-line arguments'''
+ """parse command-line arguments"""
parser = self._get_parser()
self.args = parser.parse_args()
return self.args
def parse_input_file(self):
- '''parse the input test results file'''
+ """parse the input test results file"""
if self.args.input:
input_file = self.args.input
else:
- print("No input file specified, reading from %s"
- % self.default_input_loc)
+ print(("No input file specified, reading from %s"
+ % self.default_input_loc))
input_file = self.default_input_loc
try:
with open(input_file) as f:
for line in f:
- record = json.loads(line)
+ record = jsonutils.loads(line)
self._add_record(record)
except IOError as e:
- print(os.strerror(e.errno))
+ print((os.strerror(e.errno)))
sys.exit(1)
class Plotter(object):
- '''Graph plotter for scenario-specific results from yardstick framework'''
+ """Graph plotter for scenario-specific results from yardstick framework"""
def __init__(self, data, output_folder):
self.data = data
self.colors = ['g', 'b', 'c', 'm', 'y']
def plot(self):
- '''plot the graph(s)'''
+ """plot the graph(s)"""
for test_type in self.data.keys():
if self.data[test_type]:
plt.figure(self.fig_counter)
self._save_plot(test_type)
def _save_plot(self, test_type):
- '''save the graph to output folder'''
+ """save the graph to output folder"""
timestr = time.strftime("%Y%m%d-%H%M%S")
file_name = test_type + "_" + timestr + ".png"
if not self.output_folder:
os.makedirs(self.output_folder)
new_file = os.path.join(self.output_folder, file_name)
plt.savefig(new_file)
- print("Saved graph to " + new_file)
+ print(("Saved graph to " + new_file))
def _plot_ping(self, records):
- '''ping test result interpretation and visualization on the graph'''
+ """ping test result interpretation and visualization on the graph"""
rtts = [r['benchmark']['data']['rtt'] for r in records]
seqs = [r['benchmark']['sequence'] for r in records]
if len(rtts) == 1:
plt.bar(1, rtts[0], 0.35, color=self.colors[0])
else:
- plt.plot(seqs, rtts, self.colors[0]+'-')
+ plt.plot(seqs, rtts, self.colors[0] + '-')
self._construct_legend(['rtt'])
plt.xlabel("sequence number")
plt.ylabel("round trip time in milliseconds (rtt)")
def _plot_pktgen(self, records):
- '''pktgen test result interpretation and visualization on the graph'''
+ """pktgen test result interpretation and visualization on the graph"""
flows = [r['benchmark']['data']['flows'] for r in records]
sent = [r['benchmark']['data']['packets_sent'] for r in records]
received = [int(r['benchmark']['data']['packets_received'])
received[i] = 0.0
plt.axvline(flows[i], color='r')
- ppm = [1000000.0*(i - j)/i for i, j in zip(sent, received)]
+ ppm = [1000000.0 * (i - j) / i for i, j in zip(sent, received)]
# If there is a single data-point then display a bar-chart
if len(ppm) == 1:
plt.bar(1, ppm[0], 0.35, color=self.colors[0])
else:
- plt.plot(flows, ppm, self.colors[0]+'-')
+ plt.plot(flows, ppm, self.colors[0] + '-')
self._construct_legend(['ppm'])
plt.xlabel("number of flows")
plt.ylabel("lost packets per million packets (ppm)")
def _plot_iperf3(self, records):
- '''iperf3 test result interpretation and visualization on the graph'''
+ """iperf3 test result interpretation and visualization on the graph"""
intervals = []
for r in records:
# If did not fail the SLA
for i, val in enumerate(intervals):
if val:
for j, _ in enumerate(intervals):
- kbps.append(val[j]['sum']['bits_per_second']/1000)
+ kbps.append(val[j]['sum']['bits_per_second'] / 1000)
seconds.append(seconds[-1] + val[j]['sum']['seconds'])
else:
kbps.append(0.0)
plt.axvline(seconds[-1], color='r')
self._construct_legend(['bandwidth'])
- plt.plot(seconds[1:], kbps[1:], self.colors[0]+'-')
+ plt.plot(seconds[1:], kbps[1:], self.colors[0] + '-')
plt.xlabel("time in seconds")
plt.ylabel("bandwidth in Kb/s")
def _plot_fio(self, records):
- '''fio test result interpretation and visualization on the graph'''
+ """fio test result interpretation and visualization on the graph"""
rw_types = [r['sargs']['options']['rw'] for r in records]
seqs = [x for x in range(1, len(records) + 1)]
data = {}
plt.xticks(seqs, seqs)
def _plot_fio_helper(self, data, seqs, key, bar_color, axl):
- '''check if measurements exist for a key and then plot the
- data to a given subplot'''
+ """check if measurements exist for a key and then plot the
+ data to a given subplot"""
if key in data:
if len(data[key]) == 1:
axl.bar(0.1, data[key], 0.35, color=bar_color)
axl.plot(seqs, data[key], line_style)
def _construct_legend(self, legend_texts, obj=plt):
- '''construct legend for the plot or subplot'''
+ """construct legend for the plot or subplot"""
ci = 0
lines = []
print("Plotting graph(s)")
plotter.plot()
+
if __name__ == '__main__':
main()