aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahothan <ahothan@cisco.com>2018-01-16 12:46:21 -0800
committerahothan <ahothan@cisco.com>2018-01-16 12:46:21 -0800
commit02c8ed97e27b6e417945d27d4d3c2ab8e7dbfa7e (patch)
treec6335c42266f70c77b7fa2560d5b932040e66d9a
parentb481ad4a6c6b98cac760b12e4190f9540869e673 (diff)
[NFVBENCH-62] Add support for non-openstack environments
Add Unit test to validate non-openstack with dummy traffic gen Change-Id: I359ddb7d43169f706d8262842af975d5b4675a3a Signed-off-by: ahothan <ahothan@cisco.com>
-rw-r--r--nfvbench/cfg.default.yaml10
-rw-r--r--nfvbench/chain_clients.py18
-rw-r--r--nfvbench/chain_managers.py30
-rw-r--r--nfvbench/nfvbench.py22
-rw-r--r--nfvbench/specs.py3
-rw-r--r--nfvbench/summarizer.py14
-rw-r--r--nfvbench/traffic_gen/dummy.py10
-rw-r--r--test/test_nfvbench.py37
8 files changed, 98 insertions, 46 deletions
diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml
index bc8921d..07d48f3 100644
--- a/nfvbench/cfg.default.yaml
+++ b/nfvbench/cfg.default.yaml
@@ -18,6 +18,13 @@
# Fields that can be over-ridden at the command line are marked with the corresponding
# option, e.g. "--interval"
+# The OpenStack openrc file to use (must be a valid full pathname). If running
+# in a container, this path must be valid in the container.
+#
+# The only case where this field can be empty is when measuring a system that does not run
+# OpenStack or when OpenStack APIs are not accessible or OpenStack APis use is not
+# desirable. In that case the EXT service chain must be used.
+openrc_file:
# Forwarder to use in nfvbenchvm image. Available options: ['vpp', 'testpmd']
vm_forwarder: testpmd
@@ -195,9 +202,6 @@ traffic_generator:
# -----------------------------------------------------------------------------
# These variables are not likely to be changed
-# The openrc file
-openrc_file:
-
# Number of seconds to wait for VMs to pass traffic in both directions
check_traffic_time_sec: 200
diff --git a/nfvbench/chain_clients.py b/nfvbench/chain_clients.py
index 7106129..faf7c2a 100644
--- a/nfvbench/chain_clients.py
+++ b/nfvbench/chain_clients.py
@@ -416,7 +416,8 @@ class BasicStageClient(object):
Creates two networks and spawn a VM which act as a loop VM connected
with the two networks.
"""
- self._setup_openstack_clients()
+ if self.cred:
+ self._setup_openstack_clients()
def dispose(self, only_vm=False):
"""
@@ -448,12 +449,15 @@ class EXTStageClient(BasicStageClient):
super(EXTStageClient, self).setup()
# Lookup two existing networks
- for net_name in [self.config.external_networks.left, self.config.external_networks.right]:
- net = self._lookup_network(net_name)
- if net:
- self.nets.append(net)
- else:
- raise StageClientException('Existing network {} cannot be found.'.format(net_name))
+ if self.cred:
+ for net_name in [self.config.external_networks.left,
+ self.config.external_networks.right]:
+ net = self._lookup_network(net_name)
+ if net:
+ self.nets.append(net)
+ else:
+ raise StageClientException('Existing network {} cannot be found.'.
+ format(net_name))
class PVPStageClient(BasicStageClient):
diff --git a/nfvbench/chain_managers.py b/nfvbench/chain_managers.py
index 8b605aa..087c751 100644
--- a/nfvbench/chain_managers.py
+++ b/nfvbench/chain_managers.py
@@ -96,11 +96,12 @@ class StatsManager(object):
raise exc
def _get_data(self):
- return self.worker.get_data()
+ return self.worker.get_data() if self.worker else {}
def _get_network(self, traffic_port, index=None, reverse=False):
interfaces = [self.clients['traffic'].get_interface(traffic_port)]
- interfaces.extend(self.worker.get_network_interfaces(index))
+ if self.worker:
+ interfaces.extend(self.worker.get_network_interfaces(index))
return Network(interfaces, reverse)
def _config_interfaces(self):
@@ -127,13 +128,14 @@ class StatsManager(object):
return self.interval_collector.get() if self.interval_collector else []
def get_version(self):
- return self.worker.get_version()
+ return self.worker.get_version() if self.worker else {}
def run(self):
"""
Run analysis in both direction and return the analysis
"""
- self.worker.run()
+ if self.worker:
+ self.worker.run()
stats = self._generate_traffic()
result = {
@@ -157,7 +159,7 @@ class StatsManager(object):
return result
def get_compute_nodes_bios(self):
- return self.worker.get_compute_nodes_bios()
+ return self.worker.get_compute_nodes_bios() if self.worker else {}
@staticmethod
def get_analysis(nets):
@@ -176,7 +178,8 @@ class StatsManager(object):
return packet_analyzer.get_analysis()
def close(self):
- self.worker.close()
+ if self.worker:
+ self.worker.close()
class PVPStatsManager(StatsManager):
@@ -229,10 +232,13 @@ class EXTStatsManager(StatsManager):
StatsManager.__init__(self, config, clients, specs, factory, vlans, notifier)
def _setup(self):
- WORKER_CLASS = self.factory.get_chain_worker(self.specs.openstack.encaps,
- self.config.service_chain)
- self.worker = WORKER_CLASS(self.config, self.clients, self.specs)
- self.worker.set_vlans(self.vlans)
+ if self.specs.openstack:
+ WORKER_CLASS = self.factory.get_chain_worker(self.specs.openstack.encaps,
+ self.config.service_chain)
+ self.worker = WORKER_CLASS(self.config, self.clients, self.specs)
+ self.worker.set_vlans(self.vlans)
- if not self.config.no_int_config:
- self._config_interfaces()
+ if not self.config.no_int_config:
+ self._config_interfaces()
+ else:
+ self.worker = None
diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py
index 6f59e24..8c88248 100644
--- a/nfvbench/nfvbench.py
+++ b/nfvbench/nfvbench.py
@@ -58,7 +58,8 @@ class NFVBench(object):
self.config_plugin = config_plugin
self.factory = factory
self.notifier = notifier
- self.cred = credentials.Credentials(config.openrc_file, None, False)
+ self.cred = credentials.Credentials(config.openrc_file, None, False) \
+ if config.openrc_file else None
self.chain_runner = None
self.specs = Specs()
self.specs.set_openstack_spec(openstack_spec)
@@ -94,10 +95,6 @@ class NFVBench(object):
result = {
"date": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
"nfvbench_version": __version__,
- "openstack_spec": {
- "vswitch": self.specs.openstack.vswitch,
- "encaps": self.specs.openstack.encaps
- },
"config": self.config_plugin.prepare_results_config(copy.deepcopy(self.config)),
"benchmarks": {
"network": {
@@ -106,6 +103,9 @@ class NFVBench(object):
}
}
}
+ if self.specs.openstack:
+ result['openstack_spec'] = {"vswitch": self.specs.openstack.vswitch,
+ "encaps": self.specs.openstack.encaps}
result['benchmarks']['network']['versions'].update(self.config_plugin.get_version())
except Exception:
status = NFVBench.STATUS_ERROR
@@ -444,7 +444,6 @@ def main():
# create config plugin for this platform
config_plugin = factory.get_config_plugin_class()(config)
config = config_plugin.get_config()
- openstack_spec = config_plugin.get_openstack_spec()
opts, unknown_opts = parse_opts_from_cli()
log.set_level(debug=opts.debug)
@@ -520,6 +519,14 @@ def main():
print json.dumps(config, sort_keys=True, indent=4)
sys.exit(0)
+ # check that an empty openrc file (no OpenStack) is only allowed
+ # with EXT chain
+ if not config.openrc_file:
+ if config.service_chain == ChainType.EXT:
+ LOG.info('EXT chain with OpenStack mode disabled')
+ else:
+ raise Exception("openrc_file is empty in the configuration and is required")
+
# update the config in the config plugin as it might have changed
# in a copy of the dict (config plugin still holds the original dict)
config_plugin.set_config(config)
@@ -528,6 +535,9 @@ def main():
if config.log_file:
log.add_file_logger(config.log_file)
+ openstack_spec = config_plugin.get_openstack_spec() if config.openrc_file \
+ else None
+
nfvbench_instance = NFVBench(config, openstack_spec, config_plugin, factory)
if opts.server:
diff --git a/nfvbench/specs.py b/nfvbench/specs.py
index 7a24d5c..a84a55f 100644
--- a/nfvbench/specs.py
+++ b/nfvbench/specs.py
@@ -75,7 +75,8 @@ class OpenStackSpec(object):
class RunSpec(object):
def __init__(self, no_vswitch_access, openstack_spec):
- self.use_vswitch = (not no_vswitch_access) and openstack_spec.vswitch != "BASIC"
+ self.use_vswitch = (not no_vswitch_access) and openstack_spec \
+ and openstack_spec.vswitch != "BASIC"
class Specs(object):
diff --git a/nfvbench/summarizer.py b/nfvbench/summarizer.py
index 1676e93..0ff9c48 100644
--- a/nfvbench/summarizer.py
+++ b/nfvbench/summarizer.py
@@ -221,18 +221,24 @@ class NFVBenchSummarizer(Summarizer):
self.__record_init()
self.__summarize()
+ def __get_openstack_spec(self, property):
+ try:
+ return self.result['openstack_spec'][property]
+ except KeyError:
+ return ''
+
def __summarize(self):
self._put()
self._put('========== NFVBench Summary ==========')
self._put('Date:', self.result['date'])
self._put('NFVBench version', self.result['nfvbench_version'])
self._put('Openstack Neutron:', {
- 'vSwitch': self.result['openstack_spec']['vswitch'],
- 'Encapsulation': self.result['openstack_spec']['encaps']
+ 'vSwitch': self.__get_openstack_spec('vswitch'),
+ 'Encapsulation': self.__get_openstack_spec('encaps')
})
self.__record_header_put('version', self.result['nfvbench_version'])
- self.__record_header_put('vSwitch', self.result['openstack_spec']['vswitch'])
- self.__record_header_put('Encapsulation', self.result['openstack_spec']['encaps'])
+ self.__record_header_put('vSwitch', self.__get_openstack_spec('vswitch'))
+ self.__record_header_put('Encapsulation', self.__get_openstack_spec('encaps'))
self._put('Benchmarks:')
with self._create_block():
self._put('Networks:')
diff --git a/nfvbench/traffic_gen/dummy.py b/nfvbench/traffic_gen/dummy.py
index b43030f..6f57f4d 100644
--- a/nfvbench/traffic_gen/dummy.py
+++ b/nfvbench/traffic_gen/dummy.py
@@ -30,6 +30,7 @@ class DummyTG(AbstractTrafficGenerator):
self.l2_frame_size = 0
self.duration_sec = self.config.duration_sec
self.intf_speed = config.generator_config.intf_speed
+ self.set_response_curve()
def get_version(self):
return "0.1"
@@ -154,6 +155,9 @@ class DummyTG(AbstractTrafficGenerator):
result['total_tx_rate'] = total_tx_pps
return result
+ def get_macs(self):
+ return ['00.00.00.00.00.01', '00.00.00.00.00.02']
+
def clear_stats(self):
pass
@@ -165,3 +169,9 @@ class DummyTG(AbstractTrafficGenerator):
def cleanup(self):
pass
+
+ def set_mode(self):
+ pass
+
+ def resolve_arp(self):
+ return True
diff --git a/test/test_nfvbench.py b/test/test_nfvbench.py
index fc8174f..113ecfd 100644
--- a/test/test_nfvbench.py
+++ b/test/test_nfvbench.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
-
+import json
import logging
import os
import sys
@@ -429,8 +429,6 @@ from nfvbench.traffic_client import IpBlock
from nfvbench.traffic_client import TrafficClient
from nfvbench.traffic_client import TrafficGeneratorFactory
-# pylint: enable=wrong-import-position,ungrouped-imports
-
def test_ip_block():
ipb = IpBlock('10.0.0.0', '0.0.0.1', 256)
assert ipb.get_ip() == '10.0.0.0'
@@ -595,16 +593,16 @@ def assert_ndr_pdr(stats, ndr, ndr_dr, pdr, pdr_dr):
assert_equivalence(pdr, stats['pdr']['rate_percent'])
assert_equivalence(pdr_dr, stats['pdr']['stats']['overall']['drop_percentage'])
-def get_traffic_client():
- config = AttrDict({
+def get_dummy_tg_config(chain_type, rate):
+ return AttrDict({
'traffic_generator': {'host_name': 'nfvbench_tg',
'default_profile': 'dummy',
'generator_profile': [{'name': 'dummy',
'tool': 'dummy',
'ip': '127.0.0.1',
'intf_speed': '10Gbps',
- 'interfaces': [{'port': 0, 'pci': 0},
- {'port': 1, 'pci': 0}]}],
+ 'interfaces': [{'port': 0, 'pci': '0.0'},
+ {'port': 1, 'pci': '0.0'}]}],
'ip_addrs_step': '0.0.0.1',
'ip_addrs': ['10.0.0.0/8', '20.0.0.0/8'],
'tg_gateway_ip_addrs': ['1.1.0.100', '2.2.0.100'],
@@ -613,22 +611,25 @@ def get_traffic_client():
'gateway_ip_addrs_step': '0.0.0.1',
'udp_src_port': None,
'udp_dst_port': None},
- 'generator_profile': 'dummy',
- 'service_chain': 'PVP',
+ 'service_chain': chain_type,
'service_chain_count': 1,
'flow_count': 10,
'vlan_tagging': True,
'no_arp': False,
'duration_sec': 1,
'interval_sec': 1,
- 'single_run': False,
- 'ndr_run': True,
- 'pdr_run': True,
- 'rate': 'ndr_pdr',
+ 'rate': rate,
'check_traffic_time_sec': 200,
'generic_poll_sec': 2,
'measurement': {'NDR': 0.001, 'PDR': 0.1, 'load_epsilon': 0.1},
})
+
+def get_traffic_client():
+ config = get_dummy_tg_config('PVP', 'ndr_pdr')
+ config['ndr_run'] = True
+ config['pdr_run'] = True
+ config['generator_profile'] = 'dummy'
+ config['single_run'] = False
generator_factory = TrafficGeneratorFactory(config)
config.generator_config = generator_factory.get_generator_config(config.generator_profile)
traffic_client = TrafficClient(config, skip_sleep=True)
@@ -680,3 +681,13 @@ def test_ndr_pdr_low_cpu():
# import pprint
# pp = pprint.PrettyPrinter(indent=4)
# pp.pprint(results)
+
+import nfvbench.nfvbench
+
+def test_no_openstack():
+ config = get_dummy_tg_config('EXT', '1000pps')
+ config.openrc_file = None
+ old_argv = sys.argv
+ sys.argv = [old_argv[0], '-c', json.dumps(config)]
+ nfvbench.nfvbench.main()
+ sys.argv = old_argv