behave_tests: add unit tests for TestAPI client
[nfvbench.git] / nfvbench / stats_collector.py
1 # Copyright 2016 Cisco Systems, Inc.  All rights reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14
15
16 import time
17
18
19 class StatsCollector(object):
20     """Base class for all stats collector classes."""
21
22     def __init__(self, start_time):
23         self.start_time = start_time
24         self.stats = []
25
26     def get(self):
27         return self.stats
28
29     def peek(self):
30         return self.stats[-1]
31
32     @staticmethod
33     def _get_drop_percentage(drop_pkts, total_pkts):
34         return float(drop_pkts * 100) / total_pkts
35
36     @staticmethod
37     def _get_rx_pps(tx_pps, drop_percentage):
38         return (tx_pps * (100 - drop_percentage)) / 100
39
40     def _get_current_time_diff(self):
41         return int((time.time() - self.start_time) * 1000)
42
43
44 class IntervalCollector(StatsCollector):
45     """Collects stats while traffic is running. Frequency is specified by 'interval_sec' setting."""
46
47     last_tx_pkts = 0
48     last_rx_pkts = 0
49     last_time = 0
50
51     def __init__(self, start_time):
52         StatsCollector.__init__(self, start_time)
53         self.notifier = None
54
55     def attach_notifier(self, notifier):
56         self.notifier = notifier
57
58     def add(self, stats):
59         pass
60
61     def reset(self):
62         # don't reset time!
63         self.last_rx_pkts = 0
64         self.last_tx_pkts = 0
65
66     def add_ndr_pdr(self, tag, stats):
67         pass
68
69
70 class IterationCollector(StatsCollector):
71     """Collects stats after traffic is stopped. Frequency is specified by 'duration_sec' setting."""
72
73     def __init__(self, start_time):
74         StatsCollector.__init__(self, start_time)
75
76     def add(self, stats, tx_pps):
77         drop_percentage = self._get_drop_percentage(stats['overall']['rx']['dropped_pkts'],
78                                                     stats['overall']['tx']['total_pkts'])
79
80         record = {
81             'total_tx_pps': int(stats['total_tx_rate']),
82             'tx_pps': tx_pps,
83             'tx_pkts': stats['overall']['tx']['total_pkts'],
84             'rx_pps': self._get_rx_pps(tx_pps, drop_percentage),
85             'rx_pkts': stats['overall']['rx']['total_pkts'],
86             'drop_pct': stats['overall']['rx']['dropped_pkts'],
87             'drop_percentage': drop_percentage,
88             'time_ms': int(time.time() * 1000)
89         }
90
91         if 'warning' in stats:
92             record['warning'] = stats['warning']
93
94         self.stats.append(record)
95
96     def add_ndr_pdr(self, tag, rate):
97         last_stats = self.peek()
98         last_stats['{}_pps'.format(tag)] = rate