aboutsummaryrefslogtreecommitdiffstats
path: root/nfvbench/service_chain.py
diff options
context:
space:
mode:
Diffstat (limited to 'nfvbench/service_chain.py')
-rw-r--r--nfvbench/service_chain.py138
1 files changed, 138 insertions, 0 deletions
diff --git a/nfvbench/service_chain.py b/nfvbench/service_chain.py
new file mode 100644
index 0000000..104cfb4
--- /dev/null
+++ b/nfvbench/service_chain.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# Copyright 2016 Cisco Systems, Inc. All rights reserved.
+#
+# 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.
+#
+
+from chain_managers import StageManager
+from collections import OrderedDict
+from log import LOG
+from specs import ChainType
+import time
+
+
+class ServiceChain(object):
+
+ def __init__(self, config, clients, cred, specs, factory, notifier=None):
+ self.config = config
+ self.clients = clients
+ self.cred = cred
+ self.specs = specs
+ self.factory = factory
+ self.notifier = notifier
+ self.chain_name = self.config.service_chain
+ self.vlans = None
+ self.stage_manager = None
+ self.stats_manager = None
+ LOG.info('ServiceChain initialized.')
+
+ def __set_helpers(self):
+ self.stage_manager = StageManager(self.config, self.cred, self.factory)
+ self.clients['vm'] = self.stage_manager
+ self.vlans = self.stage_manager.get_vlans()
+
+ STATS_CLASS = self.factory.get_stats_class(self.config.service_chain)
+ self.stats_manager = STATS_CLASS(self.config,
+ self.clients,
+ self.specs,
+ self.factory,
+ self.vlans,
+ self.notifier)
+
+ def __set_vlan_tags(self):
+ if self.config.vlan_tagging:
+ # override with user-specified vlans if configured
+ vlans = self.config.vlans if self.config.vlans else self.vlans[:2]
+ for vlan, device in zip(vlans, self.config.generator_config.devices):
+ self.stats_manager.set_vlan_tag(device, vlan)
+
+ def __get_result_per_frame_size(self, frame_size, bidirectional):
+ start_time = time.time()
+ traffic_result = {
+ frame_size: {}
+ }
+ result = {}
+ if not self.config.no_traffic:
+ self.clients['traffic'].set_traffic(frame_size, bidirectional)
+
+ if self.config.single_run:
+ result = self.stats_manager.run()
+ else:
+ results = self.clients['traffic'].get_ndr_and_pdr()
+
+ for dr in ['pdr', 'ndr']:
+ if dr in results:
+ traffic_result[frame_size][dr] = results[dr]
+ if 'warning' in results[dr]['stats'] and results[dr]['stats']['warning']:
+ traffic_result['warning'] = results[dr]['stats']['warning']
+ traffic_result[frame_size]['iteration_stats'] = results['iteration_stats']
+
+ result['analysis_duration_sec'] = time.time() - start_time
+ if self.config.single_run:
+ result['run_config'] = self.clients['traffic'].get_run_config(result)
+ required = result['run_config']['direction-total']['orig']['rate_pps']
+ actual = result['stats']['total_tx_rate']
+ warning = self.clients['traffic'].compare_tx_rates(required, actual)
+ if warning is not None:
+ result['run_config']['warning'] = warning
+
+ traffic_result[frame_size].update(result)
+ return traffic_result
+
+ def __get_chain_result(self):
+ result = OrderedDict()
+ for fs in self.config.frame_sizes:
+ result.update(self.__get_result_per_frame_size(fs, self.config.traffic.bidirectional))
+
+ chain_result = {
+ 'flow_count': self.config.flow_count,
+ 'service_chain_count': self.config.service_chain_count,
+ 'bidirectional': self.config.traffic.bidirectional,
+ 'profile': self.config.traffic.profile,
+ 'compute_nodes': self.stats_manager.get_compute_nodes_bios(),
+ 'result': result
+ }
+
+ return chain_result
+
+ def __setup_traffic(self):
+ self.clients['traffic'].setup()
+ if not self.config.no_traffic:
+ if self.config.service_chain == ChainType.EXT and not self.config.no_arp:
+ self.clients['traffic'].ensure_arp_successful()
+ self.clients['traffic'].ensure_end_to_end()
+
+ def run(self):
+ LOG.info('Starting {} chain...'.format(self.chain_name))
+ LOG.info('Dry run: {}'.format(self.config.no_traffic))
+ results = {}
+
+ self.__set_helpers()
+ self.__set_vlan_tags()
+ self.stage_manager.set_vm_macs()
+ self.__setup_traffic()
+ results[self.chain_name] = {'result': self.__get_chain_result()}
+
+ if self.config.service_chain == ChainType.PVVP:
+ results[self.chain_name]['mode'] = 'inter-node' \
+ if self.config.inter_node else 'intra-node'
+
+ LOG.info("Service chain '{}' run completed.".format(self.chain_name))
+ return results
+
+ def get_version(self):
+ return self.stats_manager.get_version()
+
+ def close(self):
+ self.stage_manager.close()
+ self.stats_manager.close()