VPP_Device - add baseline tests - part IIb)
[csit.git] / resources / libraries / python / Memif.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 """Memif interface library."""
15
16 from resources.libraries.python.ssh import SSH
17 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
18 from resources.libraries.python.topology import NodeType, Topology
19
20
21 class Memif(object):
22     """Memif interface class."""
23
24     def __init__(self):
25         pass
26
27     @staticmethod
28     def create_memif_interface(node, filename, mid, sid, rxq=1, txq=1,
29                                role='slave'):
30         """Create Memif interface on the given node.
31
32         :param node: Given node to create Memif interface on.
33         :param filename: Memif interface socket filename.
34         :param mid: Memif interface ID.
35         :param sid: Socket ID.
36         :param rxq: Number of RX queues; 0 means do not set.
37         :param txq: Number of TX queues; 0 means do not set.
38         :param role: Memif interface role [master|slave]. Default is master.
39         :type node: dict
40         :type filename: str
41         :type mid: str
42         :type sid: str
43         :type rxq: int
44         :type txq: int
45         :type role: str
46         :returns: SW interface index.
47         :rtype: int
48         :raises ValueError: If command 'create memif' fails.
49         """
50
51         rx_q = 'rx-queues {rxq}'.format(rxq=rxq) if rxq else ''
52         tx_q = 'tx-queues {txq}'.format(txq=txq) if txq else ''
53
54         with VatTerminal(node, json_param=False) as vat:
55             vat.vat_terminal_exec_cmd_from_template(
56                 'memif_socket_filename_add_del.vat',
57                 add_del='add', id=sid, filename='/tmp/'+filename)
58             vat.vat_terminal_exec_cmd_from_template(
59                 'memif_create.vat', id=mid, socket=sid, rx_q=rx_q, tx_q=tx_q,
60                 role=role)
61             if 'sw_if_index' in vat.vat_stdout:
62                 try:
63                     sw_if_idx = int(vat.vat_stdout.split()[4])
64                     if_key = Topology.add_new_port(node, 'memif')
65                     Topology.update_interface_sw_if_index(
66                         node, if_key, sw_if_idx)
67                     ifc_name = Memif.vpp_get_memif_interface_name(
68                         node, sw_if_idx)
69                     Topology.update_interface_name(node, if_key, ifc_name)
70                     ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_idx)
71                     Topology.update_interface_mac_address(node, if_key, ifc_mac)
72                     Topology.update_interface_memif_socket(node, if_key,
73                                                            '/tmp/'+filename)
74                     Topology.update_interface_memif_id(node, if_key, mid)
75                     Topology.update_interface_memif_role(node, if_key, role)
76                     return sw_if_idx
77                 except KeyError:
78                     raise ValueError('Create Memif interface failed on node '
79                                      '{}'.format(node['host']))
80             else:
81                 raise ValueError('Create Memif interface failed on node '
82                                  '{}'.format(node['host']))
83
84     @staticmethod
85     def dump_memif(node):
86         """Dump Memif data for the given node.
87
88         :param node: Given node to show Memif data on.
89         :type node: dict
90         """
91         vat = VatExecutor()
92         vat.execute_script("memif_dump.vat", node, json_out=False)
93
94     @staticmethod
95     def show_memif(node):
96         """Show Memif data for the given node.
97
98         :param node: Given node to show Memif data on.
99         :type node: dict
100         """
101         vat = VatExecutor()
102         vat.execute_script("show_memif.vat", node, json_out=False)
103
104     @staticmethod
105     def show_memif_on_all_duts(nodes):
106         """Show Memif data on all DUTs.
107
108         :param nodes: Topology nodes.
109         :type nodes: dict
110         """
111         for node in nodes.values():
112             if node['type'] == NodeType.DUT:
113                 Memif.show_memif(node)
114
115     @staticmethod
116     def clear_memif_socks(node, *socks):
117         """Clear Memif sockets for the given node.
118
119         :param node: Given node to clear Memif sockets on.
120         :param socks: Memif sockets.
121         :type node: dict
122         :type socks: list
123         """
124         ssh = SSH()
125         ssh.connect(node)
126
127         for sock in socks:
128             ssh.exec_command_sudo('rm -f {}'.format(sock))
129
130     @staticmethod
131     def parse_memif_dump_data(memif_data):
132         """Convert Memif data to dictionary.
133
134         :param memif_data: Dump of Memif interfaces data.
135         :type memif_data: str
136         :returns: Memif interfaces data in dictionary.
137         :rtype: dict
138         :raises RuntimeError: If there is no memif interface name found in
139             provided data.
140         """
141         memif_name = None
142         memif_dict = dict()
143         memif_data = str(memif_data)
144         values = dict()
145
146         clutter = ['vat#']
147         for garbage in clutter:
148             memif_data = memif_data.replace(garbage, '')
149
150         for line in memif_data.splitlines():
151             if not line or line.startswith('Sending'):
152                 continue
153             elif line.startswith('memif'):
154                 if memif_name:
155                     memif_dict[memif_name] = values
156                 line_split = line.split(':', 1)
157                 memif_name = str(line_split[0])
158                 values = dict()
159                 line = line_split[1]
160             line_split = line.split()
161             for i in range(0, len(line_split), 2):
162                 key = str(line_split[i])
163                 try:
164                     value = line_split[i+1]
165                 except IndexError:
166                     value = None
167                 values[key] = value
168         if memif_name:
169             memif_dict[memif_name] = values
170         else:
171             raise RuntimeError('No memif interface name found')
172
173         return memif_dict
174
175     @staticmethod
176     def vpp_get_memif_interface_name(node, sw_if_idx):
177         """Get Memif interface name from Memif interfaces dump.
178
179         :param node: DUT node.
180         :param sw_if_idx: DUT node.
181         :type node: dict
182         :type sw_if_idx: int
183         :returns: Memif interface name, or None if not found.
184         :rtype: str
185         """
186         with VatTerminal(node, json_param=False) as vat:
187             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
188             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
189             for item in memif_data:
190                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
191                     return item
192         return None
193
194     @staticmethod
195     def vpp_get_memif_interface_mac(node, sw_if_idx):
196         """Get Memif interface MAC address from Memif interfaces dump.
197
198         :param node: DUT node.
199         :param sw_if_idx: DUT node.
200         :type node: dict
201         :type sw_if_idx: int
202         :returns: Memif interface MAC address, or None if not found.
203         :rtype: str
204         """
205         with VatTerminal(node, json_param=False) as vat:
206             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
207             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
208             for item in memif_data:
209                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
210                     return memif_data[item].get('mac', None)
211         return None
212
213     @staticmethod
214     def vpp_get_memif_interface_socket(node, sw_if_idx):
215         """Get Memif interface socket path from Memif interfaces dump.
216
217         :param node: DUT node.
218         :param sw_if_idx: DUT node.
219         :type node: dict
220         :type sw_if_idx: int
221         :returns: Memif interface socket path, or None if not found.
222         :rtype: str
223         """
224         with VatTerminal(node, json_param=False) as vat:
225             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
226             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
227             for item in memif_data:
228                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
229                     return memif_data[item].get('socket', None)
230         return None
231
232     @staticmethod
233     def vpp_get_memif_interface_id(node, sw_if_idx):
234         """Get Memif interface ID from Memif interfaces dump.
235
236         :param node: DUT node.
237         :param sw_if_idx: DUT node.
238         :type node: dict
239         :type sw_if_idx: int
240         :returns: Memif interface ID, or None if not found.
241         :rtype: int
242         """
243         with VatTerminal(node, json_param=False) as vat:
244             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
245             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
246             for item in memif_data:
247                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
248                     return int(memif_data[item].get('id', None))
249         return None
250
251     @staticmethod
252     def vpp_get_memif_interface_role(node, sw_if_idx):
253         """Get Memif interface role from Memif interfaces dump.
254
255         :param node: DUT node.
256         :param sw_if_idx: DUT node.
257         :type node: dict
258         :type sw_if_idx: int
259         :returns: Memif interface role, or None if not found.
260         :rtype: int
261         """
262         with VatTerminal(node, json_param=False) as vat:
263             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
264             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
265             for item in memif_data:
266                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
267                     return memif_data[item].get('role', None)
268         return None