# 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
# -----------------------------------------------------------------------------
# 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
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):
"""
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):
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):
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 = {
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):
return packet_analyzer.get_analysis()
def close(self):
- self.worker.close()
+ if self.worker:
+ self.worker.close()
class PVPStatsManager(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
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)
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": {
}
}
}
+ 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
# 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)
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)
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:
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):
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:')
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"
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
def cleanup(self):
pass
+
+ def set_mode(self):
+ pass
+
+ def resolve_arp(self):
+ return True
# License for the specific language governing permissions and limitations
# under the License.
#
-
+import json
import logging
import os
import sys
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'
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'],
'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)
# 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