self.config_plugin = config_plugin
self.factory = factory
self.notifier = notifier
- self.cred = credentials.Credentials(config.openrc_file, None, False) \
- if config.openrc_file else None
+ self.cred = credentials.Credentials(config.openrc_file, config.clouds_detail, None, False) \
+ if config.openrc_file or config.clouds_detail else None
self.chain_runner = None
self.specs = Specs()
self.specs.set_openstack_spec(openstack_spec)
def set_notifier(self, notifier):
self.notifier = notifier
- def run(self, opts, args):
+ def run(self, opts, args, dry_run=False):
"""This run() method is called for every NFVbench benchmark request.
In CLI mode, this method is called only once per invocation.
In REST server mode, this is called once per REST POST request
+ On dry_run, show the running config in json format then exit
"""
status = NFVBench.STATUS_OK
result = None
# recalc the running config based on the base config and options for this run
self._update_config(opts)
+ if dry_run:
+ print((json.dumps(self.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 self.config.openrc_file and self.config.service_chain != ChainType.EXT:
- raise Exception("openrc_file in the configuration is required for PVP/PVVP chains")
+ if (not self.config.openrc_file and not self.config.clouds_detail) and \
+ self.config.service_chain != ChainType.EXT:
+ raise Exception("openrc_file or clouds_detail in the configuration is required"
+ " for PVP/PVVP chains")
self.specs.set_run_spec(self.config_plugin.get_run_spec(self.config,
self.specs.openstack))
'will be created.', path)
os.makedirs(path)
LOG.info('%s is created.', path)
- for h in log.getLogger().handlers:
- if isinstance(h, FileHandler) and h.baseFilename != opts['log_file']:
- # clean log file handler
- log.getLogger().removeHandler(h)
- # add handler if not existing to avoid duplicates handlers
- if len(log.getLogger().handlers) == 1:
+ if not any(isinstance(h, FileHandler) for h in log.getLogger().handlers):
log.add_file_logger(opts['log_file'])
+ else:
+ for h in log.getLogger().handlers:
+ if isinstance(h, FileHandler) and h.baseFilename != opts['log_file']:
+ # clean log file handler
+ log.getLogger().removeHandler(h)
+ log.add_file_logger(opts['log_file'])
self.config.update(opts)
config = self.config
config.cache_size = config.flow_count
# The size must be capped to 10000 (where does this limit come from?)
- if config.cache_size > 10000:
- config.cache_size = 10000
+ config.cache_size = min(config.cache_size, 10000)
config.duration_sec = float(config.duration_sec)
config.interval_sec = float(config.interval_sec)
action='store_true',
help='Use L3 neutron routers to handle traffic')
+ parser.add_argument('-garp', '--gratuitous-arp', dest='periodic_gratuitous_arp',
+ default=None,
+ action='store_true',
+ help='Use gratuitous ARP to maintain session between TG '
+ 'and L3 routers to handle traffic')
+
parser.add_argument('-0', '--no-traffic', dest='no_traffic',
default=None,
action='store_true',
action='store_true',
help='print the default config in yaml format (unedited)')
+ parser.add_argument('--show-pre-config', dest='show_pre_config',
+ default=None,
+ action='store_true',
+ help='print the config in json format (cfg file applied)')
+
parser.add_argument('--show-config', dest='show_config',
default=None,
action='store_true',
- help='print the running config in json format')
+ help='print the running config in json format (final)')
parser.add_argument('-ss', '--show-summary', dest='summary',
action='store',
'tagged with given VLAN id(s) or not (given \'no-tag\') '
'\'true\': use current vlans; \'false\': disable this mode.')
+ parser.add_argument('--i40e-mixed', dest='i40e_mixed',
+ action='store',
+ default=None,
+ metavar='<ignore,check,unbind>',
+ help='TRex behavior when dealing with a i40e network card driver'
+ ' [ https://trex-tgn.cisco.com/youtrack/issue/trex-528 ]')
+
parser.add_argument('--user-info', dest='user_info',
action='append',
metavar='<data>',
sys.exit(0)
if opts.summary:
- with open(opts.summary) as json_data:
+ with open(opts.summary, encoding="utf-8") as json_data:
result = json.load(json_data)
if opts.user_label:
result['config']['user_label'] = opts.user_label
# dump the contents of the trex log file
if opts.show_trex_log:
try:
- print(open('/tmp/trex.log').read(), end="")
+ with open('/tmp/trex.log', encoding="utf-8") as trex_log_file:
+ print(trex_log_file.read(), end="")
except FileNotFoundError:
print("No TRex log file found!")
sys.exit(0)
+ # mask info logging in case of further config dump
+ if opts.show_config or opts.show_pre_config:
+ LOG.setLevel(log.logging.WARNING)
+
config.name = ''
if opts.config:
# do not check extra_specs in flavor as it can contain any key/value pairs
LOG.info('Loading configuration string: %s', opts.config)
config = config_loads(opts.config, config, whitelist_keys)
+ # show current config in json format (before CLI overriding)
+ if opts.show_pre_config:
+ print((json.dumps(config, sort_keys=True, indent=4)))
+ sys.exit(0)
+
# setup the fluent logger as soon as possible right after the config plugin is called,
# if there is any logging or result tag is set then initialize the fluent logger
for fluentd in config.fluentd:
config.service_chain_count = len(vlans[0])
opts.l2_loopback = None
+ if config.i40e_mixed is None:
+ config.i40e_mixed = 'ignore'
if config.use_sriov_middle_net is None:
config.use_sriov_middle_net = False
if opts.use_sriov_middle_net is not None:
if config.service_chain == ChainType.PVVP and config.use_sriov_middle_net:
check_physnet("middle", config.internal_networks.middle)
- # show running config in json format
- if opts.show_config:
- print((json.dumps(config, sort_keys=True, indent=4)))
- sys.exit(0)
-
# 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)
server.run(host=opts.host, port=port)
# server.run() should never return
else:
+ dry_run = opts.show_config
with utils.RunLock():
run_summary_required = True
if unknown_opts:
opts = {k: v for k, v in list(vars(opts).items()) if v is not None}
# get CLI args
params = ' '.join(str(e) for e in sys.argv[1:])
- result = nfvbench_instance.run(opts, params)
+ result = nfvbench_instance.run(opts, params, dry_run=dry_run)
if 'error_message' in result:
raise Exception(result['error_message'])