FIX: Pylint + Container mount
[csit.git] / resources / libraries / python / VppCounters.py
1 # Copyright (c) 2019 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """VPP counters utilities library."""
15
16 from pprint import pformat
17
18 from robot.api import logger
19 from resources.libraries.python.PapiExecutor import PapiExecutor
20 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
21 from resources.libraries.python.topology import Topology, SocketType, NodeType
22
23
24 class VppCounters(object):
25     """VPP counters utilities."""
26
27     def __init__(self):
28         self._stats_table = None
29
30     @staticmethod
31     def vpp_show_errors(node):
32         """Run "show errors" debug CLI command.
33
34         :param node: Node to run command on.
35         :type node: dict
36         """
37         PapiSocketExecutor.run_cli_cmd_on_all_sockets(
38             node, 'show errors')
39
40     @staticmethod
41     def vpp_show_errors_on_all_duts(nodes):
42         """Show errors on all DUTs.
43
44         :param nodes: VPP nodes.
45         :type nodes: dict
46         """
47         for node in nodes.values():
48             if node['type'] == NodeType.DUT:
49                 VppCounters.vpp_show_errors(node)
50
51     @staticmethod
52     def vpp_show_runtime(node, log_zeros=False):
53         """Run "show runtime" CLI command.
54
55         :param node: Node to run command on.
56         :param log_zeros: Log also items with zero values.
57         :type node: dict
58         :type log_zeros: bool
59         """
60         args = dict(path='^/sys/node')
61         sockets = Topology.get_node_sockets(node, socket_type=SocketType.STATS)
62         if sockets:
63             for socket in sockets.values():
64                 with PapiExecutor(node) as papi_exec:
65                     stats = papi_exec.add("vpp-stats", **args).\
66                         get_stats(socket=socket)[0]
67
68                 names = stats['/sys/node/names']
69
70                 if not names:
71                     return
72
73                 runtime = []
74                 runtime_nz = []
75
76                 for name in names:
77                     runtime.append({'name': name})
78
79                 for idx, runtime_item in enumerate(runtime):
80
81                     calls_th = []
82                     for thread in stats['/sys/node/calls']:
83                         calls_th.append(thread[idx])
84                     runtime_item["calls"] = calls_th
85
86                     vectors_th = []
87                     for thread in stats['/sys/node/vectors']:
88                         vectors_th.append(thread[idx])
89                     runtime_item["vectors"] = vectors_th
90
91                     suspends_th = []
92                     for thread in stats['/sys/node/suspends']:
93                         suspends_th.append(thread[idx])
94                     runtime_item["suspends"] = suspends_th
95
96                     clocks_th = []
97                     for thread in stats['/sys/node/clocks']:
98                         clocks_th.append(thread[idx])
99                     runtime_item["clocks"] = clocks_th
100
101                     if (sum(calls_th) or sum(vectors_th) or
102                             sum(suspends_th) or sum(clocks_th)):
103                         runtime_nz.append(runtime_item)
104
105                 if log_zeros:
106                     logger.info(
107                         "stats runtime ({host} - {socket}):\n{runtime}".
108                         format(
109                             host=node['host'], runtime=pformat(runtime),
110                             socket=socket))
111                 else:
112                     logger.info(
113                         "stats runtime ({host} - {socket}):\n{runtime}".
114                         format(
115                             host=node['host'], runtime=pformat(runtime_nz),
116                             socket=socket))
117
118     @staticmethod
119     def vpp_show_runtime_counters_on_all_duts(nodes):
120         """Clear VPP runtime counters on all DUTs.
121
122         :param nodes: VPP nodes.
123         :type nodes: dict
124         """
125         for node in nodes.values():
126             if node['type'] == NodeType.DUT:
127                 VppCounters.vpp_show_runtime(node)
128
129     @staticmethod
130     def vpp_show_hardware_verbose(node):
131         """Run "show hardware-interfaces verbose" debug CLI command.
132
133         :param node: Node to run command on.
134         :type node: dict
135         """
136         PapiSocketExecutor.run_cli_cmd_on_all_sockets(
137             node, 'show hardware verbose')
138
139     @staticmethod
140     def vpp_show_memory(node):
141         """Run "show memory" debug CLI command.
142
143         Currently, every flag is hardcoded, giving the longest output.
144
145         :param node: Node to run command on.
146         :type node: dict
147         """
148         PapiSocketExecutor.run_cli_cmd(
149             node, 'show memory verbose api-segment stats-segment main-heap')
150
151     @staticmethod
152     def vpp_clear_runtime(node):
153         """Run "clear runtime" CLI command.
154
155         :param node: Node to run command on.
156         :type node: dict
157         """
158         PapiSocketExecutor.run_cli_cmd_on_all_sockets(
159             node, 'clear runtime', log=False)
160
161     @staticmethod
162     def vpp_clear_runtime_counters_on_all_duts(nodes):
163         """Run "clear runtime" CLI command on all DUTs.
164
165         :param nodes: VPP nodes.
166         :type nodes: dict
167         """
168         for node in nodes.values():
169             if node['type'] == NodeType.DUT:
170                 VppCounters.vpp_clear_runtime(node)
171
172     @staticmethod
173     def vpp_clear_hardware_counters(node):
174         """Run "clear hardware" CLI command.
175
176         :param node: Node to run command on.
177         :type node: dict
178         :returns: Verified data from PAPI response.
179         :rtype: dict
180         """
181         PapiSocketExecutor.run_cli_cmd_on_all_sockets(
182             node, 'clear hardware', log=False)
183
184     @staticmethod
185     def vpp_clear_hardware_counters_on_all_duts(nodes):
186         """Clear hardware counters on all DUTs.
187
188         :param nodes: VPP nodes.
189         :type nodes: dict
190         """
191         for node in nodes.values():
192             if node['type'] == NodeType.DUT:
193                 VppCounters.vpp_clear_hardware_counters(node)
194
195     @staticmethod
196     def vpp_clear_errors_counters(node):
197         """Run "clear errors" CLI command.
198
199         :param node: Node to run command on.
200         :type node: dict
201         """
202         PapiSocketExecutor.run_cli_cmd_on_all_sockets(
203             node, 'clear errors', log=False)
204
205     @staticmethod
206     def vpp_clear_error_counters_on_all_duts(nodes):
207         """Clear VPP errors counters on all DUTs.
208
209         :param nodes: VPP nodes.
210         :type nodes: dict
211         """
212         for node in nodes.values():
213             if node['type'] == NodeType.DUT:
214                 VppCounters.vpp_clear_errors_counters(node)
215
216     @staticmethod
217     def show_vpp_statistics(node):
218         """Show [error, hardware, interface] stats.
219
220         :param node: VPP node.
221         :type node: dict
222         """
223         VppCounters.vpp_show_errors(node)
224         VppCounters.vpp_show_hardware_verbose(node)
225         VppCounters.vpp_show_runtime(node)
226         VppCounters.vpp_show_memory(node)
227
228     @staticmethod
229     def show_statistics_on_all_duts(nodes):
230         """Show statistics on all DUTs.
231
232         :param nodes: DUT nodes.
233         :type nodes: dict
234         """
235         for node in nodes.values():
236             if node['type'] == NodeType.DUT:
237                 VppCounters.show_vpp_statistics(node)
238
239     @staticmethod
240     def clear_vpp_statistics(node):
241         """Clear [error, hardware, interface] stats.
242
243         :param node: VPP node.
244         :type node: dict
245         """
246         VppCounters.vpp_clear_errors_counters(node)
247         VppCounters.vpp_clear_hardware_counters(node)
248         VppCounters.vpp_clear_runtime(node)
249
250     @staticmethod
251     def clear_statistics_on_all_duts(nodes):
252         """Clear statistics on all DUTs.
253
254         :param nodes: DUT nodes.
255         :type nodes: dict
256         """
257         for node in nodes.values():
258             if node['type'] == NodeType.DUT:
259                 VppCounters.clear_vpp_statistics(node)