Cleanup iperf graph reporting
Change-Id: I820bcbb6f6568a338427f4cd33ee795b35e832fc
This commit is contained in:
parent
1d3bb002d9
commit
1aa8d702e1
@ -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``
|
||||||
|
@ -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
|
@ -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 }
|
||||||
|
|
26
scenarios/networking/l3_east_west.yaml
Normal file
26
scenarios/networking/l3_east_west.yaml
Normal 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
|
@ -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
|
|
@ -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 }
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 %}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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'])
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user