Added netperf-wrapper test suite and aggregate report
Change-Id: Iaaa504de674ada557ff3fbe1331f26e1d5de8650
This commit is contained in:
parent
db2076bed2
commit
9be6554a94
@ -13,10 +13,18 @@ execution:
|
|||||||
class: iperf_graph
|
class: iperf_graph
|
||||||
time: 60
|
time: 60
|
||||||
-
|
-
|
||||||
title: Iperf UDP 5 threads
|
title: TCP download
|
||||||
|
class: netperf_wrapper
|
||||||
|
method: tcp_download
|
||||||
|
-
|
||||||
|
title: TCP bi-directional
|
||||||
|
class: netperf_wrapper
|
||||||
|
method: tcp_bidirectional
|
||||||
|
-
|
||||||
|
title: Iperf UDP 8 threads
|
||||||
class: iperf
|
class: iperf
|
||||||
udp: 1
|
udp: 1
|
||||||
threads: 5
|
threads: 8
|
||||||
-
|
-
|
||||||
title: Netperf TCP_STREAM
|
title: Netperf TCP_STREAM
|
||||||
class: netperf
|
class: netperf
|
||||||
|
@ -19,6 +19,7 @@ from shaker.engine.aggregators import traffic
|
|||||||
|
|
||||||
AGGREGATORS = {
|
AGGREGATORS = {
|
||||||
'iperf_graph': traffic.TrafficAggregator,
|
'iperf_graph': traffic.TrafficAggregator,
|
||||||
|
'netperf_wrapper': traffic.TrafficAggregator,
|
||||||
'_default': base.BaseAggregator,
|
'_default': base.BaseAggregator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,9 @@ class BaseAggregator(object):
|
|||||||
def __init__(self, test_definition):
|
def __init__(self, test_definition):
|
||||||
self.test_definition = test_definition
|
self.test_definition = test_definition
|
||||||
|
|
||||||
|
def test_summary(self, test_data):
|
||||||
|
pass
|
||||||
|
|
||||||
def iteration_summary(self, iteration_data):
|
def iteration_summary(self, iteration_data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import collections
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
@ -26,39 +27,75 @@ LOG = logging.getLogger(__name__)
|
|||||||
def mean(array):
|
def mean(array):
|
||||||
if not array:
|
if not array:
|
||||||
return 0
|
return 0
|
||||||
|
array = [x for x in array if x]
|
||||||
return sum(array) / len(array)
|
return sum(array) / len(array)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_max(array):
|
||||||
|
return max(x for x in array if x)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_min(array):
|
||||||
|
return min(x for x in array if x)
|
||||||
|
|
||||||
|
|
||||||
class TrafficAggregator(base.BaseAggregator):
|
class TrafficAggregator(base.BaseAggregator):
|
||||||
def __init__(self, test_definition):
|
def __init__(self, test_definition):
|
||||||
super(TrafficAggregator, self).__init__(test_definition)
|
super(TrafficAggregator, self).__init__(test_definition)
|
||||||
|
|
||||||
|
def test_summary(self, test_data):
|
||||||
|
chart = []
|
||||||
|
xs = []
|
||||||
|
mean_v = collections.defaultdict(list)
|
||||||
|
|
||||||
|
for iteration in test_data['results_per_iteration']:
|
||||||
|
xs.append(len(iteration['results_per_agent']))
|
||||||
|
for k, v in iteration['stats'].items():
|
||||||
|
mean_v[k].append(v['mean'])
|
||||||
|
|
||||||
|
for k in mean_v.keys():
|
||||||
|
chart.append(['Mean %s' % k] + mean_v[k])
|
||||||
|
|
||||||
|
chart.append(['x'] + xs)
|
||||||
|
test_data.update({
|
||||||
|
'chart': chart,
|
||||||
|
})
|
||||||
|
|
||||||
def iteration_summary(self, iteration_data):
|
def iteration_summary(self, iteration_data):
|
||||||
max_v = []
|
max_v = collections.defaultdict(list)
|
||||||
min_v = []
|
min_v = collections.defaultdict(list)
|
||||||
mean_v = []
|
mean_v = collections.defaultdict(list)
|
||||||
|
unit_v = dict()
|
||||||
|
chart = []
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for one in iteration_data['results_per_agent']:
|
for one in iteration_data['results_per_agent']:
|
||||||
nodes.append(one['agent']['node'])
|
nodes.append(one['agent']['node'])
|
||||||
max_v.append(one['stats']['max'])
|
chart += one['chart']
|
||||||
min_v.append(one['stats']['min'])
|
|
||||||
mean_v.append(one['stats']['mean'])
|
for k, v in one['stats'].items():
|
||||||
|
max_v[k].append(v['max'])
|
||||||
|
min_v[k].append(v['min'])
|
||||||
|
mean_v[k].append(v['mean'])
|
||||||
|
unit_v[k] = v['unit']
|
||||||
|
|
||||||
|
stats = {}
|
||||||
|
node_chart = [['x'] + nodes]
|
||||||
|
|
||||||
|
for k in max_v.keys():
|
||||||
|
stats[k] = dict(max=max(max_v[k]),
|
||||||
|
min=min(min_v[k]),
|
||||||
|
mean=mean(mean_v[k]),
|
||||||
|
unit=unit_v[k])
|
||||||
|
node_chart.append(['Mean %s' % k] + mean_v[k])
|
||||||
|
node_chart.append(['Max %s' % k] + max_v[k])
|
||||||
|
node_chart.append(['Min %s' % k] + min_v[k])
|
||||||
|
|
||||||
iteration_data.update({
|
iteration_data.update({
|
||||||
'stats': {
|
'uuid': uuid.uuid4(),
|
||||||
'max': max(max_v),
|
'stats': stats,
|
||||||
'min': min(min_v),
|
'x-chart': chart,
|
||||||
'mean': mean(mean_v),
|
'node_chart': node_chart,
|
||||||
},
|
|
||||||
'agent_chart': {
|
|
||||||
'uuid': uuid.uuid4(),
|
|
||||||
'data': [
|
|
||||||
['x'] + nodes,
|
|
||||||
['min'] + min_v,
|
|
||||||
['mean'] + mean_v,
|
|
||||||
['max'] + max_v,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
def agent_summary(self, agent_data):
|
def agent_summary(self, agent_data):
|
||||||
@ -66,7 +103,8 @@ class TrafficAggregator(base.BaseAggregator):
|
|||||||
for idx, item_meta in enumerate(agent_data['meta']):
|
for idx, item_meta in enumerate(agent_data['meta']):
|
||||||
if item_meta[1] == 'bps':
|
if item_meta[1] == 'bps':
|
||||||
for row in agent_data['samples']:
|
for row in agent_data['samples']:
|
||||||
row[idx] = float(row[idx]) / 1024 / 1024
|
if row[idx]:
|
||||||
|
row[idx] = float(row[idx]) / 1024 / 1024
|
||||||
item_meta[1] = 'Mbps'
|
item_meta[1] = 'Mbps'
|
||||||
|
|
||||||
# calculate stats
|
# calculate stats
|
||||||
@ -76,12 +114,15 @@ class TrafficAggregator(base.BaseAggregator):
|
|||||||
for idx, item_meta in enumerate(agent_data['meta']):
|
for idx, item_meta in enumerate(agent_data['meta']):
|
||||||
column = [row[idx] for row in agent_data['samples']]
|
column = [row[idx] for row in agent_data['samples']]
|
||||||
|
|
||||||
if item_meta[1] == 'Mbps':
|
item_title = item_meta[0]
|
||||||
agent_data['stats']['max'] = max(column)
|
if item_title != 'time':
|
||||||
agent_data['stats']['min'] = min(column)
|
agent_data['stats'][item_title] = {
|
||||||
agent_data['stats']['mean'] = mean(column)
|
'max': safe_max(column),
|
||||||
|
'min': safe_min(column),
|
||||||
agent_data['chart'].append([item_meta[0]] + column)
|
'mean': mean(column),
|
||||||
|
'unit': item_meta[1],
|
||||||
|
}
|
||||||
|
agent_data['chart'].append([item_title] + column)
|
||||||
|
|
||||||
# drop stdout
|
# drop stdout
|
||||||
del agent_data['stdout']
|
del agent_data['stdout']
|
||||||
|
@ -63,5 +63,5 @@ class IperfGraphExecutor(IperfExecutor):
|
|||||||
samples.pop() # the last line is summary, remove it
|
samples.pop() # the last line is summary, remove it
|
||||||
|
|
||||||
result['samples'] = samples
|
result['samples'] = samples
|
||||||
result['meta'] = [['time', 'sec'], ['bandwidth', 'bps']]
|
result['meta'] = [['time', 's'], ['bandwidth', 'bps']]
|
||||||
return result
|
return result
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import csv
|
||||||
|
|
||||||
from shaker.engine.executors import base
|
from shaker.engine.executors import base
|
||||||
|
|
||||||
|
|
||||||
@ -27,7 +29,28 @@ class NetperfExecutor(base.BaseExecutor):
|
|||||||
|
|
||||||
class NetperfWrapperExecutor(base.BaseExecutor):
|
class NetperfWrapperExecutor(base.BaseExecutor):
|
||||||
def get_command(self):
|
def get_command(self):
|
||||||
target_ip = self.agent['slave']['ip']
|
cmd = base.CommandLine('netperf-wrapper')
|
||||||
return ('netperf-wrapper -H %(ip)s -f stats %(method)s' %
|
cmd.add('-H', self.agent['slave']['ip'])
|
||||||
dict(ip=target_ip,
|
cmd.add('-l', self.test_definition.get('time') or 60)
|
||||||
method=self.test_definition['method']))
|
cmd.add('-s', self.test_definition.get('interval') or 1)
|
||||||
|
cmd.add('-f', 'csv')
|
||||||
|
cmd.add(self.test_definition.get('method') or 'tcp_download')
|
||||||
|
return cmd.make()
|
||||||
|
|
||||||
|
def process_reply(self, message):
|
||||||
|
result = super(NetperfWrapperExecutor, self).process_reply(message)
|
||||||
|
|
||||||
|
data_stream = csv.reader(result['stdout'].split('\n'))
|
||||||
|
|
||||||
|
header = next(data_stream)
|
||||||
|
meta = [['time', 's']]
|
||||||
|
for el in header[1:]:
|
||||||
|
if el.find('Ping') >= 0:
|
||||||
|
meta.append([el, 'ms'])
|
||||||
|
else:
|
||||||
|
meta.append([el, 'Mbps'])
|
||||||
|
result['meta'] = meta
|
||||||
|
|
||||||
|
result['samples'] = [[(float(x) if x else None) for x in row]
|
||||||
|
for row in data_stream if row]
|
||||||
|
return result
|
||||||
|
@ -40,6 +40,8 @@ def calculate_stats(data):
|
|||||||
|
|
||||||
aggregator.iteration_summary(iteration_result)
|
aggregator.iteration_summary(iteration_result)
|
||||||
|
|
||||||
|
aggregator.test_summary(test_result)
|
||||||
|
|
||||||
|
|
||||||
def generate_report(report_template, report_filename, data):
|
def generate_report(report_template, report_filename, data):
|
||||||
LOG.debug('Generating report, template: %s, output: %s',
|
LOG.debug('Generating report, template: %s, output: %s',
|
||||||
|
@ -360,13 +360,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</a></li>
|
</a></li>
|
||||||
|
|
||||||
|
{% set iterations = test.results_per_iteration|length %}
|
||||||
{% for result_per_iteration in test.results_per_iteration %}
|
{% for result_per_iteration in test.results_per_iteration %}
|
||||||
{% set cnt = result_per_iteration.agents|length %}
|
{% set cnt = result_per_iteration.agents|length %}
|
||||||
<li class="col-md-offset-1"><a href="#test-{{ test.definition.uuid }}-{{ cnt }}" data-toggle="tab">
|
<li class="col-md-offset-1"><a href="#test-{{ test.definition.uuid }}-{{ cnt }}" data-toggle="tab">
|
||||||
{% if cnt == 1 %}
|
{% if iterations == 1 %}
|
||||||
full iteration
|
Details
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ cnt }} threads
|
{{ cnt }} Threads
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a></li>
|
</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -413,6 +414,31 @@
|
|||||||
<div id="test-{{ test.definition.uuid }}" class="tab-pane">
|
<div id="test-{{ test.definition.uuid }}" class="tab-pane">
|
||||||
<h3>Test Case Specification</h3>
|
<h3>Test Case Specification</h3>
|
||||||
<pre>{{ test.definition|yaml }}</pre>
|
<pre>{{ test.definition|yaml }}</pre>
|
||||||
|
|
||||||
|
{# show summary only of number of iterations > 1 #}
|
||||||
|
{% set iteration_cnt = test.results_per_iteration|length %}
|
||||||
|
{% if iteration_cnt > 1 %}
|
||||||
|
|
||||||
|
{% if test.chart %}
|
||||||
|
<div id="chart-{{ test.definition.uuid }}"></div>
|
||||||
|
<script type="application/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
c3.generate({
|
||||||
|
bindto: '#chart-{{ test.definition.uuid }}',
|
||||||
|
data: {
|
||||||
|
x: 'x',
|
||||||
|
columns: {{ test.chart|json }},
|
||||||
|
type: 'step'
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: { label: '# threads' },
|
||||||
|
y: { label: 'Bandwidth, Mbits/s', min: 0 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% for result_per_iteration in test.results_per_iteration %}
|
{% for result_per_iteration in test.results_per_iteration %}
|
||||||
@ -421,26 +447,57 @@
|
|||||||
|
|
||||||
<h3>Iteration Summary</h3>
|
<h3>Iteration Summary</h3>
|
||||||
|
|
||||||
|
{# show summary only of number of agents > 1 #}
|
||||||
|
{% set agent_cnt = result_per_iteration.results_per_agent|length %}
|
||||||
|
{% if agent_cnt > 1 %}
|
||||||
|
|
||||||
{% if result_per_iteration.stats %}
|
{% if result_per_iteration.stats %}
|
||||||
<h5>Traffic stats</h5>
|
<div class="row">
|
||||||
<dl class="dl-horizontal">
|
{% for stat_title, stat_values in result_per_iteration.stats.items() %}
|
||||||
<dt>Max bandwidth</dt><dd>{{ result_per_iteration.stats.max|round(2) }} Mbits/s</dd>
|
<div class="col-md-4">
|
||||||
<dt>Min bandwidth</dt><dd>{{ result_per_iteration.stats.min|round(2) }} Mbits/s</dd>
|
<h5>Stats for {{ stat_title }}</h5>
|
||||||
<dt>Mean bandwidth</dt><dd>{{ result_per_iteration.stats.mean|round(2) }} Mbits/s</dd>
|
|
||||||
</dl>
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Max</dt><dd>{{ stat_values.max|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
|
<dt>Min</dt><dd>{{ stat_values.min|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
|
<dt>Mean</dt><dd>{{ stat_values.mean|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if result_per_iteration.agent_chart %}
|
{% if result_per_iteration.chart %}
|
||||||
<h5>Agent Chart</h5>
|
<div id="chart-{{ result_per_iteration.uuid }}"></div>
|
||||||
<div id="chart-{{ result_per_iteration.agent_chart.uuid }}"></div>
|
<script type="application/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
c3.generate({
|
||||||
|
bindto: '#chart-{{ result_per_iteration.uuid }}',
|
||||||
|
data: {
|
||||||
|
x: 'time',
|
||||||
|
columns: {{ result_per_iteration.chart|json }},
|
||||||
|
types: { bandwidth: 'area' }
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: { label: 'time' },
|
||||||
|
y: { label: 'Bandwidth, Mbits/s', min: 0 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if result_per_iteration.node_chart %}
|
||||||
|
<h5>Per-node stats</h5>
|
||||||
|
<div id="chart-{{ result_per_iteration.uuid }}-node"></div>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
c3.generate({
|
c3.generate({
|
||||||
bindto: '#chart-{{ result_per_iteration.agent_chart.uuid }}',
|
bindto: '#chart-{{ result_per_iteration.uuid }}-node',
|
||||||
data: {
|
data: {
|
||||||
x: 'x',
|
x: 'x',
|
||||||
columns: {{ result_per_iteration.agent_chart.data|json }},
|
columns: {{ result_per_iteration.node_chart|json }},
|
||||||
type: 'area-step',
|
type: 'step',
|
||||||
order: null
|
order: null
|
||||||
},
|
},
|
||||||
axis: {
|
axis: {
|
||||||
@ -450,21 +507,31 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{#### PER-AGENT DATA ####}
|
{#### PER-AGENT DATA ####}
|
||||||
{% for result_per_agent in result_per_iteration.results_per_agent %}
|
{% for result_per_agent in result_per_iteration.results_per_agent %}
|
||||||
<h4>Agent {{ result_per_agent.agent.id }}
|
<h4>Agent {{ result_per_agent.agent.id }}
|
||||||
({{ result_per_agent.agent.ip }})</h4>
|
({{ result_per_agent.agent.ip }}, {{ result_per_agent.agent.node }})</h4>
|
||||||
|
|
||||||
{% if result_per_agent.samples %}
|
{% if result_per_agent.samples %}
|
||||||
<h5>Traffic stats</h5>
|
{% if result_per_agent.stats %}
|
||||||
|
<div class="row">
|
||||||
|
{% for stat_title, stat_values in result_per_agent.stats.items() %}
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h5>Stats for {{ stat_title }}</h5>
|
||||||
|
|
||||||
<dl class="dl-horizontal">
|
<dl class="dl-horizontal">
|
||||||
<dt>Max bandwidth</dt><dd>{{ result_per_agent.stats.max|round(2) }} Mbits/s</dd>
|
<dt>Max</dt><dd>{{ stat_values.max|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
<dt>Min bandwidth</dt><dd>{{ result_per_agent.stats.min|round(2) }} Mbits/s</dd>
|
<dt>Min</dt><dd>{{ stat_values.min|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
<dt>Mean bandwidth</dt><dd>{{ result_per_agent.stats.mean|round(2) }} Mbits/s</dd>
|
<dt>Mean</dt><dd>{{ stat_values.mean|round(2) }} {{ stat_values.unit }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if result_per_agent.chart %}
|
||||||
<div id="chart-{{ result_per_agent.uuid }}"></div>
|
<div id="chart-{{ result_per_agent.uuid }}"></div>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
@ -482,6 +549,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if result_per_agent.command %}
|
{% if result_per_agent.command %}
|
||||||
|
@ -58,7 +58,7 @@ class TestIperfGraphExecutor(testtools.TestCase):
|
|||||||
[3.0, 405798912],
|
[3.0, 405798912],
|
||||||
],
|
],
|
||||||
'meta': [
|
'meta': [
|
||||||
['time', 'sec'], ['bandwidth', 'bps']
|
['time', 's'], ['bandwidth', 'bps']
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
reply = executor.process_reply(message)
|
reply = executor.process_reply(message)
|
||||||
|
73
tests/test_netperf_wrapper_executor.py
Normal file
73
tests/test_netperf_wrapper_executor.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# Copyright (c) 2015 Mirantis Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from shaker.engine.executors import netperf
|
||||||
|
|
||||||
|
|
||||||
|
IP = '10.0.0.10'
|
||||||
|
AGENT = {'slave': {'ip': IP}}
|
||||||
|
|
||||||
|
|
||||||
|
class TestNetperfWrapperExecutor(testtools.TestCase):
|
||||||
|
|
||||||
|
def test_get_command(self):
|
||||||
|
executor = netperf.NetperfWrapperExecutor({}, AGENT)
|
||||||
|
|
||||||
|
expected = 'netperf-wrapper -H %s -l 60 -s 1 -f csv tcp_download' % IP
|
||||||
|
self.assertEqual(expected, executor.get_command())
|
||||||
|
|
||||||
|
def test_get_command_with_params(self):
|
||||||
|
executor = netperf.NetperfWrapperExecutor(
|
||||||
|
dict(method='ping', time=10, interval=0.5), AGENT)
|
||||||
|
|
||||||
|
expected = 'netperf-wrapper -H %s -l 10 -s 0.5 -f csv ping' % IP
|
||||||
|
self.assertEqual(expected, executor.get_command())
|
||||||
|
|
||||||
|
def test_process_reply(self):
|
||||||
|
executor = netperf.NetperfWrapperExecutor({}, AGENT)
|
||||||
|
message = {
|
||||||
|
'stdout': """tcp_download,Ping ICMP,TCP download
|
||||||
|
0.0,0.09,
|
||||||
|
2.0,0.0800211283506,
|
||||||
|
4.0,0.0602545096056,
|
||||||
|
6.0,0.0502416561724,28555.9
|
||||||
|
8.0,0.05,25341.9871721
|
||||||
|
10.0,0.0500947171761,30486.4518264
|
||||||
|
12.0,0.0603484557656,
|
||||||
|
14.0,0.0603987445198,
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
expected = {
|
||||||
|
'samples': [
|
||||||
|
[0.0, 0.09, None],
|
||||||
|
[2.0, 0.0800211283506, None],
|
||||||
|
[4.0, 0.0602545096056, None],
|
||||||
|
[6.0, 0.0502416561724, 28555.9],
|
||||||
|
[8.0, 0.05, 25341.9871721],
|
||||||
|
[10.0, 0.0500947171761, 30486.4518264],
|
||||||
|
[12.0, 0.0603484557656, None],
|
||||||
|
[14.0, 0.0603987445198, None],
|
||||||
|
],
|
||||||
|
'meta': [
|
||||||
|
['time', 's'], ['Ping ICMP', 'ms'], ['TCP download', 'Mbps'],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
reply = executor.process_reply(message)
|
||||||
|
self.assertEqual(expected['samples'], reply['samples'],
|
||||||
|
message='Samples data')
|
||||||
|
self.assertEqual(expected['meta'], reply['meta'],
|
||||||
|
message='Metadata')
|
131
tests/test_traffic_aggregator.py
Normal file
131
tests/test_traffic_aggregator.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# Copyright (c) 2015 Mirantis Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from shaker.engine.aggregators import traffic
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrafficAggregator(testtools.TestCase):
|
||||||
|
def test_agent_summary(self):
|
||||||
|
aggregator = traffic.TrafficAggregator(None)
|
||||||
|
|
||||||
|
original = {
|
||||||
|
"stderr": "", "stdout": '',
|
||||||
|
"meta": [["time", "s"], ["Ping ICMP", "ms"],
|
||||||
|
["TCP download", "bps"]],
|
||||||
|
"samples": [[0, 1.9, None],
|
||||||
|
[1, 2.4, None],
|
||||||
|
[2, 2.6, 60 * 1024 * 1024],
|
||||||
|
[3, 2.2, 65 * 1024 * 1024],
|
||||||
|
[4, 2.2, 61 * 1024 * 1024],
|
||||||
|
[5, 1.9, None]],
|
||||||
|
}
|
||||||
|
processed = copy.deepcopy(original)
|
||||||
|
aggregator.agent_summary(processed)
|
||||||
|
|
||||||
|
self.assertFalse('stdout' in processed)
|
||||||
|
|
||||||
|
expected_stats = {
|
||||||
|
'Ping ICMP': {
|
||||||
|
'max': 2.6,
|
||||||
|
'min': 1.9,
|
||||||
|
'mean': 2.2,
|
||||||
|
'unit': 'ms',
|
||||||
|
},
|
||||||
|
'TCP download': {
|
||||||
|
'max': 65.0,
|
||||||
|
'min': 60.0,
|
||||||
|
'mean': 62.0,
|
||||||
|
'unit': 'Mbps',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assertEqual(expected_stats, processed['stats'])
|
||||||
|
|
||||||
|
expected_chart = [['time', 0, 1, 2, 3, 4, 5],
|
||||||
|
['Ping ICMP', 1.9, 2.4, 2.6, 2.2, 2.2, 1.9],
|
||||||
|
['TCP download', None, None, 60.0, 65.0, 61.0, None]]
|
||||||
|
self.assertEqual(expected_chart, processed['chart'])
|
||||||
|
|
||||||
|
def test_iteration_summary(self):
|
||||||
|
aggregator = traffic.TrafficAggregator(None)
|
||||||
|
|
||||||
|
original = {
|
||||||
|
'results_per_agent': [
|
||||||
|
{
|
||||||
|
'agent': {'node': 'alpha'},
|
||||||
|
'stats': {
|
||||||
|
'Ping ICMP': {
|
||||||
|
'max': 2.6,
|
||||||
|
'min': 1.9,
|
||||||
|
'mean': 2.2,
|
||||||
|
'unit': 'ms',
|
||||||
|
},
|
||||||
|
'TCP download': {
|
||||||
|
'max': 65.0,
|
||||||
|
'min': 60.0,
|
||||||
|
'mean': 62.0,
|
||||||
|
'unit': 'Mbps',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'chart': [['time', 0, 1, 2, 3, 4, 5],
|
||||||
|
['Ping ICMP', 1.9, 2.4, 2.6, 2.2, 2.2, 1.9],
|
||||||
|
['TCP download', None, None, 60.0, 65.0, 61.0,
|
||||||
|
None]]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'agent': {'node': 'beta'},
|
||||||
|
'stats': {
|
||||||
|
'Ping ICMP': {
|
||||||
|
'max': 3.6,
|
||||||
|
'min': 2.9,
|
||||||
|
'mean': 3.2,
|
||||||
|
'unit': 'ms',
|
||||||
|
},
|
||||||
|
'TCP download': {
|
||||||
|
'max': 75.0,
|
||||||
|
'min': 70.0,
|
||||||
|
'mean': 72.0,
|
||||||
|
'unit': 'Mbps',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'chart': [['time', 0, 1, 2, 3, 4, 5],
|
||||||
|
['Ping ICMP', 2.9, 3.4, 3.6, 3.2, 3.2, 2.9],
|
||||||
|
['TCP download', None, None, 70.0, 75.0, 71.0,
|
||||||
|
None]]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
processed = copy.deepcopy(original)
|
||||||
|
aggregator.iteration_summary(processed)
|
||||||
|
|
||||||
|
expected_stats = {
|
||||||
|
'Ping ICMP': {
|
||||||
|
'max': 3.6,
|
||||||
|
'min': 1.9,
|
||||||
|
'mean': 2.7,
|
||||||
|
'unit': 'ms',
|
||||||
|
},
|
||||||
|
'TCP download': {
|
||||||
|
'max': 75.0,
|
||||||
|
'min': 60.0,
|
||||||
|
'mean': 67.0,
|
||||||
|
'unit': 'Mbps',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(expected_stats, processed['stats'])
|
Loading…
Reference in New Issue
Block a user