diff --git a/doc/source/catalog.rst b/doc/source/catalog.rst index d573fd1..da2cf84 100644 --- a/doc/source/catalog.rst +++ b/doc/source/catalog.rst @@ -402,6 +402,19 @@ overridden by command-line parameter, e.g. ``--matrix "{host: 172.10.1.2}"``. To use this scenario specify parameter ``--scenario spot/udp``. Scenario source is available at: https://github.com/openstack/shaker/blob/master/shaker/scenarios/spot/udp.yaml +.. _scenario_sample_tcp_test_with_advanced_iperf_arguments: + +Sample TCP Test with Advanced Iperf Arguments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This test definition demonstrates the use of advanced arguments with iperf. In +this scenario Shaker launches pairs of instances in the same tenant network. +Every instance is hosted on a separate compute node, 1 compute node is +utilized. The traffic goes within the tenant network (L2 domain) and uses +arguments not directly mapped by the iperf executor. + +To use this scenario specify parameter ``--scenario test/sample_with_advanced_iperf``. +Scenario source is available at: https://github.com/openstack/shaker/blob/master/shaker/scenarios/test/sample_with_advanced_iperf.yaml + .. _scenario_sample_tcp_test_with_environment_file: Sample TCP Test with Environment File diff --git a/shaker/engine/executors/iperf.py b/shaker/engine/executors/iperf.py index 7dbceae..ad4a968 100644 --- a/shaker/engine/executors/iperf.py +++ b/shaker/engine/executors/iperf.py @@ -17,9 +17,12 @@ import csv import json import yaml +from oslo_log import log as logging from shaker.engine.executors import base from shaker.engine import utils +LOG = logging.getLogger(__name__) + def add_common_iperf_params(cmd, executor): cmd.add('--client', executor.test_definition.get('host') or @@ -35,7 +38,23 @@ def add_common_iperf_params(cmd, executor): cmd.add('--len', executor.test_definition.get('datagram_size')) if executor.test_definition.get('bandwidth') is not None: cmd.add('--bandwidth', executor.test_definition.get('bandwidth')) - cmd.add('--time', executor.get_expected_duration()) + + if executor.test_definition.get('args'): + args = executor.test_definition.get('args') + for arg in args.split(' '): + cmd.add(arg) + + # if any of these arguments are present user is using advanced mode so + # these should overwrite the default addition of the time argument + mutually_exclusive_with_time = {"-k", "--blockcount", "-n", "--num", "-l", + "--length"} + if mutually_exclusive_with_time.isdisjoint(cmd.tokens): + cmd.add('--time', executor.get_expected_duration()) + else: + LOG.info('Time argument was not added since it is ' + 'mutually exclusive with %s', + ",".join(mutually_exclusive_with_time)) + cmd.add('--parallel', executor.test_definition.get('threads') or 1) if executor.test_definition.get('interval'): cmd.add('--interval', executor.test_definition.get('interval')) diff --git a/shaker/scenarios/test/sample_with_advanced_iperf.yaml b/shaker/scenarios/test/sample_with_advanced_iperf.yaml new file mode 100644 index 0000000..a3ffc7d --- /dev/null +++ b/shaker/scenarios/test/sample_with_advanced_iperf.yaml @@ -0,0 +1,25 @@ +title: Sample TCP Test with Advanced Iperf Arguments + +description: + This test definition demonstrates the use of advanced arguments with iperf. + + In this scenario Shaker launches pairs of instances in the same tenant + network. Every instance is hosted on a separate compute node, 1 compute node + is utilized. The traffic goes within the tenant network (L2 domain) and uses + arguments not directly mapped by the iperf executor. + +deployment: + template: l2_with_env.hot + env_file: env/sample.env + + accommodation: [pair, compute_nodes: 1] + +execution: + tests: + - + title: tcp + class: iperf3 + buffer_size: 9000 + args: "--blockcount 1M --zerocopy --omit 1" + sla: + - "[type == 'agent'] >> (stats.bandwidth.avg > 5000)" diff --git a/shaker/tests/test_iperf_executor.py b/shaker/tests/test_iperf_executor.py index 52cceb5..0e9ae95 100644 --- a/shaker/tests/test_iperf_executor.py +++ b/shaker/tests/test_iperf_executor.py @@ -121,6 +121,56 @@ class TestIperfGraphExecutor(testtools.TestCase): base.ExecutorException, executor.process_reply, message) +class IperfExecutor(testtools.TestCase): + + def test_add_common_iperf_params(self): + executor = iperf.IperfExecutor( + {'bandwidth': '100M', 'time': 30}, AGENT) + + cmd = base.CommandLine('iperf') + iperf.add_common_iperf_params(cmd, executor) + + expected = {'data': ('iperf --client %s --format m --bandwidth 100M' + ' --time 30 --parallel 1 --nodelay') % IP, + 'type': 'program'} + + self.assertEqual(expected, executor.get_command()) + + def test_add_common_iperf_params_with_args(self): + executor = iperf.IperfExecutor( + {'bandwidth': '100M', 'time': 30, 'args': '--zerocopy --omit 1', }, + AGENT) + + cmd = base.CommandLine('iperf') + iperf.add_common_iperf_params(cmd, executor) + + expected = {'data': ('iperf --client %s --format m --bandwidth 100M' + ' --zerocopy --omit 1 --time 30 --parallel 1 ' + '--nodelay') % IP, + 'type': 'program'} + + self.assertEqual(expected, executor.get_command()) + + def test_add_common_iperf_params_args_with_exclusion(self): + executor = iperf.IperfExecutor( + # add time on purpose to make sure it is excluded + {'bandwidth': '100M', 'time': 30, + 'args': '--blockcount 1M --zerocopy --omit 1', }, + AGENT) + + cmd = base.CommandLine('iperf') + iperf.add_common_iperf_params(cmd, executor) + + # time should not be present since it is mutually exclusive with + # -k/blockcount + expected = {'data': ('iperf --client %s --format m --bandwidth 100M' + ' --blockcount 1M --zerocopy --omit 1 ' + '--parallel 1 --nodelay') % IP, + 'type': 'program'} + + self.assertEqual(expected, executor.get_command()) + + class TestIperf3Executor(testtools.TestCase): def test_get_command(self):