Enable the MQ producer in "SampleVNFTrafficGen" class
[yardstick.git] / yardstick / tests / unit / network_services / vnf_generic / vnf / test_base.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain 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,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15
16 import multiprocessing
17 import os
18 import uuid
19
20 import mock
21 from oslo_config import cfg
22 import oslo_messaging
23 import unittest
24
25 from yardstick.common import messaging
26 from yardstick.common.messaging import payloads
27 from yardstick.network_services.vnf_generic.vnf import base
28 from yardstick.ssh import SSH
29
30
31 IP_PIPELINE_CFG_FILE_TPL = ("arp_route_tbl = ({port0_local_ip_hex},"
32                             "{port0_netmask_hex},1,{port1_local_ip_hex}) "
33                             "({port1_local_ip_hex},{port1_netmask_hex},0,"
34                             "{port0_local_ip_hex})")
35
36 IP_PIPELINE_ND_CFG_FILE_TPL = """
37 nd_route_tbl = ({port1_dst_ip_hex6},"""
38 """{port1_dst_netmask_hex6},1,{port1_dst_ip_hex6})"""
39
40 _LOCAL_OBJECT = object()
41
42 VNFD_0 = {
43     'short-name': 'VpeVnf',
44     'vdu': [
45         {
46             'routing_table': [
47                 {
48                     'network': '152.16.100.20',
49                     'netmask': '255.255.255.0',
50                     'gateway': '152.16.100.20',
51                     'if': 'xe0'
52                 },
53                 {
54                     'network': '152.16.40.20',
55                     'netmask': '255.255.255.0',
56                     'gateway': '152.16.40.20',
57                     'if': 'xe1'
58                 },
59             ],
60             'description': 'VPE approximation using DPDK',
61             'name': 'vpevnf-baremetal',
62             'nd_route_tbl': [
63                 {
64                     'network': '0064:ff9b:0:0:0:0:9810:6414',
65                     'netmask': '112',
66                     'gateway': '0064:ff9b:0:0:0:0:9810:6414',
67                     'if': 'xe0'
68                 },
69                 {
70                     'network': '0064:ff9b:0:0:0:0:9810:2814',
71                     'netmask': '112',
72                     'gateway': '0064:ff9b:0:0:0:0:9810:2814',
73                     'if': 'xe1'
74                 },
75             ],
76             'id': 'vpevnf-baremetal',
77             'external-interface': [
78                 {
79                     'virtual-interface': {
80                         'dst_mac': '00:00:00:00:00:03',
81                         'vpci': '0000:05:00.0',
82                         'local_ip': '152.16.100.19',
83                         'type': 'PCI-PASSTHROUGH',
84                         'netmask': '255.255.255.0',
85                         'dpdk_port_num': 0,
86                         'bandwidth': '10 Gbps',
87                         'dst_ip': '152.16.100.20',
88                         'local_mac': '00:00:00:00:00:01'
89                     },
90                     'vnfd-connection-point-ref': 'xe0',
91                     'name': 'xe0'
92                 },
93                 {
94                     'virtual-interface': {
95                         'dst_mac': '00:00:00:00:00:04',
96                         'vpci': '0000:05:00.1',
97                         'local_ip': '152.16.40.19',
98                         'type': 'PCI-PASSTHROUGH',
99                         'netmask': '255.255.255.0',
100                         'dpdk_port_num': 1,
101                         'bandwidth': '10 Gbps',
102                         'dst_ip': '152.16.40.20',
103                         'local_mac': '00:00:00:00:00:02'
104                     },
105                     'vnfd-connection-point-ref': 'xe1',
106                     'name': 'xe1'
107                 },
108             ],
109         },
110     ],
111     'description': 'Vpe approximation using DPDK',
112     'mgmt-interface': {
113         'vdu-id': 'vpevnf-baremetal',
114         'host': '1.1.1.1',
115         'password': 'r00t',
116         'user': 'root',
117         'ip': '1.1.1.1'
118     },
119     'benchmark': {
120         'kpi': [
121             'packets_in',
122             'packets_fwd',
123             'packets_dropped',
124         ],
125     },
126     'connection-point': [
127         {
128             'type': 'VPORT',
129             'name': 'xe0',
130         },
131         {
132             'type': 'VPORT',
133             'name': 'xe1',
134         },
135     ],
136     'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
137 }
138
139 VNFD = {
140     'vnfd:vnfd-catalog': {
141         'vnfd': [
142             VNFD_0,
143         ]
144     }
145 }
146
147
148 class FileAbsPath(object):
149     def __init__(self, module_file):
150         super(FileAbsPath, self).__init__()
151         self.module_path = os.path.dirname(os.path.abspath(module_file))
152
153     def get_path(self, filename):
154         file_path = os.path.join(self.module_path, filename)
155         return file_path
156
157
158 def mock_ssh(mock_ssh_type, spec=None, exec_result=_LOCAL_OBJECT, run_result=_LOCAL_OBJECT):
159     if spec is None:
160         spec = SSH
161
162     if exec_result is _LOCAL_OBJECT:
163         exec_result = 0, "", ""
164
165     if run_result is _LOCAL_OBJECT:
166         run_result = 0, "", ""
167
168     mock_ssh_instance = mock.Mock(autospec=spec)
169     mock_ssh_instance._get_client.return_value = mock.Mock()
170     mock_ssh_instance.execute.return_value = exec_result
171     mock_ssh_instance.run.return_value = run_result
172     mock_ssh_type.from_node.return_value = mock_ssh_instance
173     return mock_ssh_instance
174
175
176 class TestQueueFileWrapper(unittest.TestCase):
177     def setUp(self):
178         self.prompt = "pipeline>"
179         self.q_in = multiprocessing.Queue()
180         self.q_out = multiprocessing.Queue()
181
182     def test___init__(self):
183         queue_file_wrapper = \
184             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
185         self.assertEqual(queue_file_wrapper.prompt, self.prompt)
186
187     def test_clear(self):
188         queue_file_wrapper = \
189             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
190         queue_file_wrapper.bufsize = 5
191         queue_file_wrapper.write("pipeline>")
192         queue_file_wrapper.close()
193         self.assertIsNone(queue_file_wrapper.clear())
194         self.assertIsNotNone(queue_file_wrapper.q_out.empty())
195
196     def test_close(self):
197         queue_file_wrapper = \
198             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
199         self.assertIsNone(queue_file_wrapper.close())
200
201     def test_read(self):
202         queue_file_wrapper = \
203             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
204         queue_file_wrapper.q_in.put("pipeline>")
205         self.assertEqual("pipeline>", queue_file_wrapper.read(20))
206
207     def test_write(self):
208         queue_file_wrapper = \
209             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
210         queue_file_wrapper.write("pipeline>")
211         self.assertIsNotNone(queue_file_wrapper.q_out.empty())
212
213
214 class TestGenericVNF(unittest.TestCase):
215
216     def test_definition(self):
217         """Make sure that the abstract class cannot be instantiated"""
218         with self.assertRaises(TypeError) as exc:
219             # pylint: disable=abstract-class-instantiated
220             base.GenericVNF('vnf1', VNFD['vnfd:vnfd-catalog']['vnfd'][0])
221
222         msg = ("Can't instantiate abstract class GenericVNF with abstract methods "
223                "collect_kpi, instantiate, scale, start_collect, "
224                "stop_collect, terminate, wait_for_instantiate")
225
226         self.assertEqual(msg, str(exc.exception))
227
228
229 class GenericTrafficGenTestCase(unittest.TestCase):
230
231     def test_definition(self):
232         """Make sure that the abstract class cannot be instantiated"""
233         vnfd = VNFD['vnfd:vnfd-catalog']['vnfd'][0]
234         name = 'vnf1'
235         with self.assertRaises(TypeError) as exc:
236             # pylint: disable=abstract-class-instantiated
237             base.GenericTrafficGen(name, vnfd)
238         msg = ("Can't instantiate abstract class GenericTrafficGen with "
239                "abstract methods collect_kpi, instantiate, run_traffic, "
240                "scale, terminate")
241         self.assertEqual(msg, str(exc.exception))
242
243
244 class TrafficGeneratorProducerTestCase(unittest.TestCase):
245
246     @mock.patch.object(oslo_messaging, 'Target', return_value='rpc_target')
247     @mock.patch.object(oslo_messaging, 'RPCClient')
248     @mock.patch.object(oslo_messaging, 'get_rpc_transport',
249                        return_value='rpc_transport')
250     @mock.patch.object(cfg, 'CONF')
251     def test__init(self, mock_config, mock_transport, mock_rpcclient,
252                    mock_target):
253         pid = uuid.uuid1().int
254         tg_producer = base.TrafficGeneratorProducer(pid)
255         mock_transport.assert_called_once_with(
256             mock_config, url='rabbit://yardstick:yardstick@localhost:5672/')
257         mock_target.assert_called_once_with(topic=messaging.TOPIC_TG,
258                                             fanout=True,
259                                             server=messaging.SERVER)
260         mock_rpcclient.assert_called_once_with('rpc_transport', 'rpc_target')
261         self.assertEqual(pid, tg_producer._pid)
262         self.assertEqual(messaging.TOPIC_TG, tg_producer._topic)
263
264     @mock.patch.object(oslo_messaging, 'Target', return_value='rpc_target')
265     @mock.patch.object(oslo_messaging, 'RPCClient')
266     @mock.patch.object(oslo_messaging, 'get_rpc_transport',
267                        return_value='rpc_transport')
268     @mock.patch.object(payloads, 'TrafficGeneratorPayload',
269                        return_value='tg_pload')
270     def test_tg_method_started(self, mock_tg_payload, *args):
271         tg_producer = base.TrafficGeneratorProducer(uuid.uuid1().int)
272         with mock.patch.object(tg_producer, 'send_message') as mock_message:
273             tg_producer.tg_method_started(version=10)
274
275         mock_message.assert_called_once_with(messaging.TG_METHOD_STARTED,
276                                              'tg_pload')
277         mock_tg_payload.assert_called_once_with(version=10, iteration=0,
278                                                 kpi={})
279
280     @mock.patch.object(oslo_messaging, 'Target', return_value='rpc_target')
281     @mock.patch.object(oslo_messaging, 'RPCClient')
282     @mock.patch.object(oslo_messaging, 'get_rpc_transport',
283                        return_value='rpc_transport')
284     @mock.patch.object(payloads, 'TrafficGeneratorPayload',
285                        return_value='tg_pload')
286     def test_tg_method_finished(self, mock_tg_payload, *args):
287         tg_producer = base.TrafficGeneratorProducer(uuid.uuid1().int)
288         with mock.patch.object(tg_producer, 'send_message') as mock_message:
289             tg_producer.tg_method_finished(version=20)
290
291         mock_message.assert_called_once_with(messaging.TG_METHOD_FINISHED,
292                                              'tg_pload')
293         mock_tg_payload.assert_called_once_with(version=20, iteration=0,
294                                                 kpi={})
295
296     @mock.patch.object(oslo_messaging, 'Target', return_value='rpc_target')
297     @mock.patch.object(oslo_messaging, 'RPCClient')
298     @mock.patch.object(oslo_messaging, 'get_rpc_transport',
299                        return_value='rpc_transport')
300     @mock.patch.object(payloads, 'TrafficGeneratorPayload',
301                        return_value='tg_pload')
302     def test_tg_method_iteration(self, mock_tg_payload, *args):
303         tg_producer = base.TrafficGeneratorProducer(uuid.uuid1().int)
304         with mock.patch.object(tg_producer, 'send_message') as mock_message:
305             tg_producer.tg_method_iteration(100, version=30, kpi={'k': 'v'})
306
307         mock_message.assert_called_once_with(messaging.TG_METHOD_ITERATION,
308                                              'tg_pload')
309         mock_tg_payload.assert_called_once_with(version=30, iteration=100,
310                                                 kpi={'k': 'v'})