Cleanup iperf graph reporting

Change-Id: I820bcbb6f6568a338427f4cd33ee795b35e832fc
This commit is contained in:
Ilya Shakhat 2015-02-25 17:22:48 +03:00
parent 1d3bb002d9
commit 1aa8d702e1
12 changed files with 110 additions and 80 deletions

View File

@ -7,9 +7,9 @@ Installation
------------
The tool consists of a single server running on master node and set of dynamically
provisioned agents. In order to run the server needs to know OpenStack parameters
(credentials, auth_url), they can be set via environment (e.g. by sourcing openrc file)
or via parameters.
provisioned agents. In order to run the server needs to know OpenStack parameters
(credentials, auth_url), they can be set via environment (e.g. by sourcing openrc file)
or via parameters.
To install:
1. ``git clone git://git.openstack.org/stackforge/shaker``

View File

@ -12,11 +12,12 @@ execution:
title: Iperf TCP test
class: iperf_graph
time: 60
mss: 1300
-
title: Iperf UDP 5 threads
class: iperf
udp: 1
mss: 1406
mss: 1300
threads: 5
-
title: Netperf TCP_STREAM

View File

@ -79,6 +79,10 @@ resources:
port_range_min: 1,
port_range_max: 65535},
{remote_ip_prefix: 0.0.0.0/0,
protocol: udp,
port_range_min: 1,
port_range_max: 65535},
{remote_ip_prefix: 0.0.0.0/0,
protocol: icmp}]
{% for group in groups %}
@ -124,6 +128,7 @@ resources:
template: |
#!/bin/sh
screen -dmS shaker-agent shaker-agent --server-endpoint=$SERVER_ENDPOINT --debug
screen -dmS sudo nice -n -20 iperf -s --nodelay
params:
"$SERVER_ENDPOINT": { get_param: server_endpoint }

View File

@ -0,0 +1,26 @@
description:
This scenario launches pairs of in the different networks connected to one
router (L3 east-west)
deployment:
template: scenarios/networking/l3_east_west.hot
vm_accommodation: [pair, single_room]
execution:
tests:
-
title: Iperf TCP
class: iperf_graph
time: 60
mss: 1300
-
title: Iperf UDP 5 threads
class: iperf
udp: 1
mss: 1300
threads: 5
-
title: Netperf TCP
class: netperf
method: TCP_STREAM
time: 60

View File

@ -1,24 +0,0 @@
description:
This scenario launches pairs of VMs on the same compute node. VMs are in
the different networks connected in one router
deployment:
template: scenarios/networking/two_nets.hot
vm_accommodation: [pair, double_room]
execution:
size: 'quadratic_progression'
tests:
-
title: iperf TCP test
class: iperf
time: 60
-
class: iperf
udp: 1
mss: 1406
threads: 5
-
class: netperf
method: TCP_STREAM
time: 60

View File

@ -85,6 +85,10 @@ resources:
port_range_min: 1,
port_range_max: 65535},
{remote_ip_prefix: 0.0.0.0/0,
protocol: udp,
port_range_min: 1,
port_range_max: 65535},
{remote_ip_prefix: 0.0.0.0/0,
protocol: icmp}]
{% for group in groups %}
@ -130,6 +134,7 @@ resources:
template: |
#!/bin/sh
screen -dmS shaker-agent shaker-agent --server-endpoint=$SERVER_ENDPOINT --debug
screen -dmS sudo nice -n -20 iperf -s --nodelay
params:
"$SERVER_ENDPOINT": { get_param: server_endpoint }

View File

@ -11,15 +11,18 @@ execution:
size: 'quadratic_progression'
tests:
-
title: iperf TCP test
class: iperf
title: Iperf TCP
class: iperf_graph
time: 60
mss: 1300
-
title: Iperf UDP
class: iperf
udp: 1
mss: 1406
threads: 5
-
title: Netperf TCP
class: netperf
method: TCP_STREAM
time: 60

View File

@ -81,6 +81,10 @@ class IperfExecutor(BaseExecutor):
interval=interval and '--interval %s' % interval or ''))
def _calc_stats(array):
return dict(max=max(array), min=min(array), avg=sum(array) / len(array))
class IperfGraphExecutor(IperfExecutor):
def get_command(self):
self.test_definition['css'] = True
@ -91,32 +95,30 @@ class IperfGraphExecutor(IperfExecutor):
result = super(IperfGraphExecutor, self).process_reply(message)
samples = collections.defaultdict(list)
streams = {}
stream_count = 0
for row in csv.reader(result['stdout'].split('\n')):
if row:
thread = row[5]
samples[thread].append(dict(
time=float(row[6].split('-')[1]),
transfer=int(row[7]),
bandwidth=int(row[8]),
))
if thread not in streams:
streams[thread] = stream_count
stream_count += 1
samples['time'].append(float(row[6].split('-')[1]))
samples['bandwidth_%s' % streams[thread]].append(
float(row[8]) / 1024 / 1024)
# the last line is summary, remove its items
for arr in samples.values():
arr.pop()
result['samples'] = samples
# calc max, min, avg per thread
bandwidth_max = collections.defaultdict(float)
bandwidth_min = collections.defaultdict(float)
bandwidth_avg = collections.defaultdict(float)
for thread, data in samples.items():
arr = [s['bandwidth'] for s in samples[thread]]
bandwidth_max[thread] = max(arr)
bandwidth_min[thread] = min(arr)
bandwidth_avg[thread] = sum(arr) / len(arr)
result['bandwidth_max'] = bandwidth_max
result['bandwidth_min'] = bandwidth_min
result['bandwidth_avg'] = bandwidth_avg
# todo calculate stats correctly for multiple threads
for stream in streams.values():
result['stats'] = _calc_stats(
samples['bandwidth_%s' % stream])
return result

View File

@ -18,8 +18,8 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/c3/0.4.9/c3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.9/c3.min.js"></script>
<style type="text/css">
body {
@ -368,8 +368,15 @@
<h4>Agents:</h4>
<ul>
{% for agent in report.agents %}
<li>ID: {{ agent.id }}, IP: {{ agent.ip }},
mode: {{ agent.mode }}</li>
{% if agent.mode == 'master' %}
<li>Master <i>{{ agent.id }}</i>, IP: <i>{{ agent.ip }}</i>
{% if agent.slave %}
<ul>
<li>Slave <i>{{ agent.slave.id }}</i>, IP: <i>{{ agent.slave.ip }}</i>
</ul>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
@ -389,29 +396,36 @@
({{ result_per_agent.agent.ip }})</h4>
{% if result_per_agent.samples %}
{# <div>{{ result_per_agent.samples }}</div>#}
<h5>Traffic stats</h5>
<dl class="dl-horizontal">
<dt>Max bandwidth</dt><dd>{{ result_per_agent.stats.max|round(3) }} Mbits/s</dd>
<dt>Min bandwidth</dt><dd>{{ result_per_agent.stats.min|round(3) }} Mbits/s</dd>
<dt>Average bandwidth</dt><dd>{{ result_per_agent.stats.avg|round(3) }} Mbits/s</dd>
</dl>
<div id="chart-{{ result_per_agent.uuid }}"></div>
<script type="application/javascript">
var chart = c3.generate({
$(document).ready(function () {
c3.generate({
bindto: '#chart-{{ result_per_agent.uuid }}',
data: {
x: 'x',
x: 'time',
columns: [
{# {% set first_row = first(result_per_agent.samples) %}#}
{# ['x', {{ first_row|map(attribute='time')|join(', ') }}],#}
{% for thread, array in result_per_agent.samples.items() %}
['x', {{ array|map(attribute='time')|join(', ') }}],
['thread{{ thread }}', {{ array|map(attribute='bandwidth')|join(', ') }}]
{% set first_item = True %}
{% for stream, array in result_per_agent.samples.items() %}
{% if not first_item %},{% endif %} {% set first_item = False %}
['{{ stream }}', {{ array|join(', ') }}]
{% endfor %}
],
types: { thread3: 'area' }
types: { bandwidth_0: 'area' }
},
axis: {
x: { label: 'time' },
y: { label: 'Bandwidth, bps' }
y: { label: 'Bandwidth, Mbits/s', min: 0 }
}
});
});
</script>
{% endif %}

View File

@ -178,13 +178,13 @@ def execute(execution, agents):
test_case_result = quorum.run_test_case(executors)
values = test_case_result.values()
for v in values:
v['uuid'] = uuid.uuid4()
v['uuid'] = str(uuid.uuid4())
results_per_iteration.append({
'agents': selected_agents,
'results_per_agent': values,
})
test['uuid'] = uuid.uuid4()
test['uuid'] = str(uuid.uuid4())
result.append({
'results_per_iteration': results_per_iteration,
'definition': test,

View File

@ -36,25 +36,23 @@ class TestIperfGraphExecutor(testtools.TestCase):
executor = executors.IperfGraphExecutor({}, AGENT)
message = {
'stdout': """
20150224134955,172.1.7.77,47351,172.1.76.77,5001,3,0.0-1.0,500686848,4005494784
20150224134956,172.1.7.77,47351,172.1.76.77,5001,3,1.0-2.0,516055040,4128440320
20150224134957,172.1.7.77,47351,172.1.76.77,5001,3,2.0-3.0,508436480,4067491840
20150224134955,172.1.7.77,47351,172.1.76.77,5001,3,0.0-1.0,50068684,399507456
20150224134956,172.1.7.77,47351,172.1.76.77,5001,3,1.0-2.0,51605504,412090368
20150224134957,172.1.7.77,47351,172.1.76.77,5001,3,2.0-3.0,50843648,405798912
20150224134957,172.1.7.77,47351,172.1.76.77,5001,3,0.0-3.0,150843648,400000002
"""
}
expected = {
'samples': {
'3': [
dict(time=1.0, transfer=500686848, bandwidth=4005494784),
dict(time=2.0, transfer=516055040, bandwidth=4128440320),
dict(time=3.0, transfer=508436480, bandwidth=4067491840),
]
'time': [1.0, 2.0, 3.0],
'bandwidth_0': [381.0, 393.0, 387.0],
},
'stats': {
'max': 393.0,
'min': 381.0,
'avg': (381.0 + 393.0 + 387.0) / 3
},
'bandwidth_max': {'3': 4128440320},
'bandwidth_min': {'3': 4005494784},
'bandwidth_avg': {'3': (4005494784 + 4128440320 + 4067491840) / 3},
}
reply = executor.process_reply(message)
self.assertEqual(expected['samples'], reply['samples'])
self.assertEqual(expected['bandwidth_max'], reply['bandwidth_max'])
self.assertEqual(expected['bandwidth_min'], reply['bandwidth_min'])
self.assertEqual(expected['bandwidth_avg'], reply['bandwidth_avg'])
self.assertEqual(expected['stats'], reply['stats'])