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 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 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) (credentials, auth_url), they can be set via environment (e.g. by sourcing openrc file)
or via parameters. or via parameters.
To install: To install:
1. ``git clone git://git.openstack.org/stackforge/shaker`` 1. ``git clone git://git.openstack.org/stackforge/shaker``

View File

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

View File

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

View File

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

View File

@ -81,6 +81,10 @@ class IperfExecutor(BaseExecutor):
interval=interval and '--interval %s' % interval or '')) 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): class IperfGraphExecutor(IperfExecutor):
def get_command(self): def get_command(self):
self.test_definition['css'] = True self.test_definition['css'] = True
@ -91,32 +95,30 @@ class IperfGraphExecutor(IperfExecutor):
result = super(IperfGraphExecutor, self).process_reply(message) result = super(IperfGraphExecutor, self).process_reply(message)
samples = collections.defaultdict(list) samples = collections.defaultdict(list)
streams = {}
stream_count = 0
for row in csv.reader(result['stdout'].split('\n')): for row in csv.reader(result['stdout'].split('\n')):
if row: if row:
thread = row[5] thread = row[5]
samples[thread].append(dict( if thread not in streams:
time=float(row[6].split('-')[1]), streams[thread] = stream_count
transfer=int(row[7]), stream_count += 1
bandwidth=int(row[8]),
)) 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 result['samples'] = samples
# calc max, min, avg per thread # todo calculate stats correctly for multiple threads
bandwidth_max = collections.defaultdict(float) for stream in streams.values():
bandwidth_min = collections.defaultdict(float) result['stats'] = _calc_stats(
bandwidth_avg = collections.defaultdict(float) samples['bandwidth_%s' % stream])
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
return result 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://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="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="https://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/c3/0.4.9/c3.min.js"></script>
<style type="text/css"> <style type="text/css">
body { body {
@ -368,8 +368,15 @@
<h4>Agents:</h4> <h4>Agents:</h4>
<ul> <ul>
{% for agent in report.agents %} {% for agent in report.agents %}
<li>ID: {{ agent.id }}, IP: {{ agent.ip }}, {% if agent.mode == 'master' %}
mode: {{ agent.mode }}</li> <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 %} {% endfor %}
</ul> </ul>
</div> </div>
@ -389,29 +396,36 @@
({{ result_per_agent.agent.ip }})</h4> ({{ result_per_agent.agent.ip }})</h4>
{% if result_per_agent.samples %} {% 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> <div id="chart-{{ result_per_agent.uuid }}"></div>
<script type="application/javascript"> <script type="application/javascript">
var chart = c3.generate({ $(document).ready(function () {
c3.generate({
bindto: '#chart-{{ result_per_agent.uuid }}', bindto: '#chart-{{ result_per_agent.uuid }}',
data: { data: {
x: 'x', x: 'time',
columns: [ columns: [
{# {% set first_row = first(result_per_agent.samples) %}#} {% set first_item = True %}
{# ['x', {{ first_row|map(attribute='time')|join(', ') }}],#} {% for stream, array in result_per_agent.samples.items() %}
{% if not first_item %},{% endif %} {% set first_item = False %}
{% for thread, array in result_per_agent.samples.items() %} ['{{ stream }}', {{ array|join(', ') }}]
['x', {{ array|map(attribute='time')|join(', ') }}],
['thread{{ thread }}', {{ array|map(attribute='bandwidth')|join(', ') }}]
{% endfor %} {% endfor %}
], ],
types: { thread3: 'area' } types: { bandwidth_0: 'area' }
}, },
axis: { axis: {
x: { label: 'time' }, x: { label: 'time' },
y: { label: 'Bandwidth, bps' } y: { label: 'Bandwidth, Mbits/s', min: 0 }
} }
}); });
});
</script> </script>
{% endif %} {% endif %}

View File

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

View File

@ -36,25 +36,23 @@ class TestIperfGraphExecutor(testtools.TestCase):
executor = executors.IperfGraphExecutor({}, AGENT) executor = executors.IperfGraphExecutor({}, AGENT)
message = { message = {
'stdout': """ 'stdout': """
20150224134955,172.1.7.77,47351,172.1.76.77,5001,3,0.0-1.0,500686848,4005494784 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,516055040,4128440320 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,508436480,4067491840 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 = { expected = {
'samples': { 'samples': {
'3': [ 'time': [1.0, 2.0, 3.0],
dict(time=1.0, transfer=500686848, bandwidth=4005494784), 'bandwidth_0': [381.0, 393.0, 387.0],
dict(time=2.0, transfer=516055040, bandwidth=4128440320), },
dict(time=3.0, transfer=508436480, bandwidth=4067491840), '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) reply = executor.process_reply(message)
self.assertEqual(expected['samples'], reply['samples']) self.assertEqual(expected['samples'], reply['samples'])
self.assertEqual(expected['bandwidth_max'], reply['bandwidth_max']) self.assertEqual(expected['stats'], reply['stats'])
self.assertEqual(expected['bandwidth_min'], reply['bandwidth_min'])
self.assertEqual(expected['bandwidth_avg'], reply['bandwidth_avg'])