summaryrefslogtreecommitdiffstats
path: root/nfvbench/stats_manager.py
diff options
context:
space:
mode:
authorahothan <ahothan@cisco.com>2018-10-07 15:55:25 -0700
committerahothan <ahothan@cisco.com>2018-10-08 10:44:31 -0700
commit391dcf76fefb747888a3411ae3b8df7b1ad26685 (patch)
treeb823ae8a5f0e837bb285f53acb1502e0aad1bdf0 /nfvbench/stats_manager.py
parent99260f95219301bb5c0b58921e793bcad6ec4990 (diff)
2.0 beta NFVBENCH-91 Allow multi-chaining with separate edge networks
Includes complete refactoring of code Beta for NFVbench 2.0 Change-Id: I2997f0fb7722d5ac626cd11a68692ae458c7676e Signed-off-by: ahothan <ahothan@cisco.com>
Diffstat (limited to 'nfvbench/stats_manager.py')
-rw-r--r--nfvbench/stats_manager.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/nfvbench/stats_manager.py b/nfvbench/stats_manager.py
new file mode 100644
index 0000000..a1fb497
--- /dev/null
+++ b/nfvbench/stats_manager.py
@@ -0,0 +1,101 @@
+#!/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.
+#
+import time
+
+from log import LOG
+from packet_stats import PacketPathStatsManager
+from stats_collector import IntervalCollector
+
+
+class StatsManager(object):
+ """A class to collect detailed stats and handle fixed rate runs for all chain types."""
+
+ def __init__(self, chain_runner):
+ self.chain_runner = chain_runner
+ self.config = chain_runner.config
+ self.traffic_client = chain_runner.traffic_client
+ self.specs = chain_runner.specs
+ self.notifier = chain_runner.notifier
+ self.interval_collector = None
+ self.factory = chain_runner.factory
+ # create a packet path stats manager for fixed rate runs only
+ if self.config.single_run:
+ pps_list = []
+ self.traffic_client.insert_interface_stats(pps_list)
+ self.pps_mgr = PacketPathStatsManager(pps_list)
+ else:
+ self.pps_mgr = None
+ self.worker = None
+
+ def create_worker(self):
+ """Create a worker to fetch custom data.
+
+ This is done late as we need to know the dest MAC for all VNFs, which can happen
+ as late as after ARP discovery.
+ """
+ if not self.worker and self.specs.openstack:
+ WORKER_CLASS = self.factory.get_chain_worker(self.specs.openstack.encaps,
+ self.config.service_chain)
+ self.worker = WORKER_CLASS(self)
+
+ def _generate_traffic(self):
+ if self.config.no_traffic:
+ return {}
+
+ self.interval_collector = IntervalCollector(time.time())
+ self.interval_collector.attach_notifier(self.notifier)
+ LOG.info('Starting to generate traffic...')
+ stats = {}
+ for stats in self.traffic_client.run_traffic():
+ self.interval_collector.add(stats)
+
+ LOG.info('...traffic generating ended.')
+ return stats
+
+ def get_stats(self):
+ return self.interval_collector.get() if self.interval_collector else []
+
+ def get_version(self):
+ return self.worker.get_version() if self.worker else {}
+
+ def _update_interface_stats(self, diff=False):
+ """Update interface stats for both the traffic generator and the worker."""
+ self.traffic_client.update_interface_stats(diff=True)
+ if self.worker:
+ self.worker.update_interface_stats(diff=True)
+
+ def run_fixed_rate(self):
+ """Run a fixed rate and analyze results."""
+ # Baseline the packet path stats
+ self._update_interface_stats()
+
+ in_flight_stats = self._generate_traffic()
+ result = {
+ 'stats': in_flight_stats
+ }
+ # New analysis code with packet path stats
+ # Diff all interface stats and return packet path stats analysis
+ # Diff the packet path stats
+ self._update_interface_stats(diff=True)
+ result['packet_path_stats'] = self.pps_mgr.get_results()
+ return result
+
+ def get_compute_nodes_bios(self):
+ return self.worker.get_compute_nodes_bios() if self.worker else {}
+
+ def close(self):
+ if self.worker:
+ self.worker.close()