Add "TrafficGeneratorProducer" for "GenericTrafficGen" instances
[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.network_services.vnf_generic.vnf import base
27 from yardstick.ssh import SSH
28
29
30 IP_PIPELINE_CFG_FILE_TPL = ("arp_route_tbl = ({port0_local_ip_hex},"
31                             "{port0_netmask_hex},1,{port1_local_ip_hex}) "
32                             "({port1_local_ip_hex},{port1_netmask_hex},0,"
33                             "{port0_local_ip_hex})")
34
35 IP_PIPELINE_ND_CFG_FILE_TPL = """
36 nd_route_tbl = ({port1_dst_ip_hex6},"""
37 """{port1_dst_netmask_hex6},1,{port1_dst_ip_hex6})"""
38
39 _LOCAL_OBJECT = object()
40
41 VNFD_0 = {
42     'short-name': 'VpeVnf',
43     'vdu': [
44         {
45             'routing_table': [
46                 {
47                     'network': '152.16.100.20',
48                     'netmask': '255.255.255.0',
49                     'gateway': '152.16.100.20',
50                     'if': 'xe0'
51                 },
52                 {
53                     'network': '152.16.40.20',
54                     'netmask': '255.255.255.0',
55                     'gateway': '152.16.40.20',
56                     'if': 'xe1'
57                 },
58             ],
59             'description': 'VPE approximation using DPDK',
60             'name': 'vpevnf-baremetal',
61             'nd_route_tbl': [
62                 {
63                     'network': '0064:ff9b:0:0:0:0:9810:6414',
64                     'netmask': '112',
65                     'gateway': '0064:ff9b:0:0:0:0:9810:6414',
66                     'if': 'xe0'
67                 },
68                 {
69                     'network': '0064:ff9b:0:0:0:0:9810:2814',
70                     'netmask': '112',
71                     'gateway': '0064:ff9b:0:0:0:0:9810:2814',
72                     'if': 'xe1'
73                 },
74             ],
75             'id': 'vpevnf-baremetal',
76             'external-interface': [
77                 {
78                     'virtual-interface': {
79                         'dst_mac': '00:00:00:00:00:03',
80                         'vpci': '0000:05:00.0',
81                         'local_ip': '152.16.100.19',
82                         'type': 'PCI-PASSTHROUGH',
83                         'netmask': '255.255.255.0',
84                         'dpdk_port_num': 0,
85                         'bandwidth': '10 Gbps',
86                         'dst_ip': '152.16.100.20',
87                         'local_mac': '00:00:00:00:00:01'
88                     },
89                     'vnfd-connection-point-ref': 'xe0',
90                     'name': 'xe0'
91                 },
92                 {
93                     'virtual-interface': {
94                         'dst_mac': '00:00:00:00:00:04',
95                         'vpci': '0000:05:00.1',
96                         'local_ip': '152.16.40.19',
97                         'type': 'PCI-PASSTHROUGH',
98                         'netmask': '255.255.255.0',
99                         'dpdk_port_num': 1,
100                         'bandwidth': '10 Gbps',
101                         'dst_ip': '152.16.40.20',
102                         'local_mac': '00:00:00:00:00:02'
103                     },
104                     'vnfd-connection-point-ref': 'xe1',
105                     'name': 'xe1'
106                 },
107             ],
108         },
109     ],
110     'description': 'Vpe approximation using DPDK',
111     'mgmt-interface': {
112         'vdu-id': 'vpevnf-baremetal',
113         'host': '1.1.1.1',
114         'password': 'r00t',
115         'user': 'root',
116         'ip': '1.1.1.1'
117     },
118     'benchmark': {
119         'kpi': [
120             'packets_in',
121             'packets_fwd',
122             'packets_dropped',
123         ],
124     },
125     'connection-point': [
126         {
127             'type': 'VPORT',
128             'name': 'xe0',
129         },
130         {
131             'type': 'VPORT',
132             'name': 'xe1',
133         },
134     ],
135     'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'
136 }
137
138 VNFD = {
139     'vnfd:vnfd-catalog': {
140         'vnfd': [
141             VNFD_0,
142         ]
143     }
144 }
145
146
147 class FileAbsPath(object):
148     def __init__(self, module_file):
149         super(FileAbsPath, self).__init__()
150         self.module_path = os.path.dirname(os.path.abspath(module_file))
151
152     def get_path(self, filename):
153         file_path = os.path.join(self.module_path, filename)
154         return file_path
155
156
157 def mock_ssh(mock_ssh_type, spec=None, exec_result=_LOCAL_OBJECT, run_result=_LOCAL_OBJECT):
158     if spec is None:
159         spec = SSH
160
161     if exec_result is _LOCAL_OBJECT:
162         exec_result = 0, "", ""
163
164     if run_result is _LOCAL_OBJECT:
165         run_result = 0, "", ""
166
167     mock_ssh_instance = mock.Mock(autospec=spec)
168     mock_ssh_instance._get_client.return_value = mock.Mock()
169     mock_ssh_instance.execute.return_value = exec_result
170     mock_ssh_instance.run.return_value = run_result
171     mock_ssh_type.from_node.return_value = mock_ssh_instance
172     return mock_ssh_instance
173
174
175 class TestQueueFileWrapper(unittest.TestCase):
176     def setUp(self):
177         self.prompt = "pipeline>"
178         self.q_in = multiprocessing.Queue()
179         self.q_out = multiprocessing.Queue()
180
181     def test___init__(self):
182         queue_file_wrapper = \
183             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
184         self.assertEqual(queue_file_wrapper.prompt, self.prompt)
185
186     def test_clear(self):
187         queue_file_wrapper = \
188             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
189         queue_file_wrapper.bufsize = 5
190         queue_file_wrapper.write("pipeline>")
191         queue_file_wrapper.close()
192         self.assertIsNone(queue_file_wrapper.clear())
193         self.assertIsNotNone(queue_file_wrapper.q_out.empty())
194
195     def test_close(self):
196         queue_file_wrapper = \
197             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
198         self.assertIsNone(queue_file_wrapper.close())
199
200     def test_read(self):
201         queue_file_wrapper = \
202             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
203         queue_file_wrapper.q_in.put("pipeline>")
204         self.assertEqual("pipeline>", queue_file_wrapper.read(20))
205
206     def test_write(self):
207         queue_file_wrapper = \
208             base.QueueFileWrapper(self.q_in, self.q_out, self.prompt)
209         queue_file_wrapper.write("pipeline>")
210         self.assertIsNotNone(queue_file_wrapper.q_out.empty())
211
212
213 class TestGenericVNF(unittest.TestCase):
214
215     def test_definition(self):
216         """Make sure that the abstract class cannot be instantiated"""
217         with self.assertRaises(TypeError) as exc:
218             # pylint: disable=abstract-class-instantiated
219             base.GenericVNF('vnf1', VNFD['vnfd:vnfd-catalog']['vnfd'][0])
220
221         msg = ("Can't instantiate abstract class GenericVNF with abstract methods "
222                "collect_kpi, instantiate, scale, start_collect, "
223                "stop_collect, terminate, wait_for_instantiate")
224
225         self.assertEqual(msg, str(exc.exception))
226
227
228 class GenericTrafficGenTestCase(unittest.TestCase):
229
230     def test_definition(self):
231         """Make sure that the abstract class cannot be instantiated"""
232         vnfd = VNFD['vnfd:vnfd-catalog']['vnfd'][0]
233         name = 'vnf1'
234         with self.assertRaises(TypeError) as exc:
235             # pylint: disable=abstract-class-instantiated
236             base.GenericTrafficGen(name, vnfd)
237         msg = ("Can't instantiate abstract class GenericTrafficGen with "
238                "abstract methods collect_kpi, instantiate, run_traffic, "
239                "scale, terminate")
240         self.assertEqual(msg, str(exc.exception))
241
242
243 class TrafficGeneratorProducerTestCase(unittest.TestCase):
244
245     @mock.patch.object(oslo_messaging, 'Target', return_value='rpc_target')
246     @mock.patch.object(oslo_messaging, 'RPCClient')
247     @mock.patch.object(oslo_messaging, 'get_rpc_transport',
248                        return_value='rpc_transport')
249     @mock.patch.object(cfg, 'CONF')
250     def test__init(self, mock_config, mock_transport, mock_rpcclient,
251                    mock_target):
252         pid = uuid.uuid1().int
253         tg_producer = base.TrafficGeneratorProducer(pid)
254         mock_transport.assert_called_once_with(
255             mock_config, url='rabbit://yardstick:yardstick@localhost:5672/')
256         mock_target.assert_called_once_with(topic=messaging.TOPIC_TG,
257                                             fanout=True,
258                                             server=messaging.SERVER)
259         mock_rpcclient.assert_called_once_with('rpc_transport', 'rpc_target')
260         self.assertEqual(pid, tg_producer._pid)
261         self.assertEqual(messaging.TOPIC_TG, tg_producer._topic)