Merge "Remove TRex installer from ansible directory"
[yardstick.git] / yardstick / tests / unit / network_services / nfvi / test_resource.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 import errno
16
17 import mock
18 import unittest
19
20 from yardstick.common import exceptions
21 from yardstick.common.exceptions import ResourceCommandError
22 from yardstick.network_services.nfvi.resource import ResourceProfile
23 from yardstick.network_services.nfvi import resource, collectd
24
25
26 class TestResourceProfile(unittest.TestCase):
27     VNFD = {'vnfd:vnfd-catalog':
28             {'vnfd':
29              [{'short-name': 'VpeVnf',
30                'vdu':
31                [{'routing_table':
32                  [{'network': '172.16.100.20',
33                    'netmask': '255.255.255.0',
34                    'gateway': '172.16.100.20',
35                    'if': 'xe0'},
36                   {'network': '172.16.40.20',
37                    'netmask': '255.255.255.0',
38                    'gateway': '172.16.40.20',
39                    'if': 'xe1'}],
40                  'description': 'VPE approximation using DPDK',
41                  'name': 'vpevnf-baremetal',
42                  'nd_route_tbl':
43                  [{'network': '0064:ff9b:0:0:0:0:9810:6414',
44                    'netmask': '112',
45                    'gateway': '0064:ff9b:0:0:0:0:9810:6414',
46                    'if': 'xe0'},
47                   {'network': '0064:ff9b:0:0:0:0:9810:2814',
48                    'netmask': '112',
49                    'gateway': '0064:ff9b:0:0:0:0:9810:2814',
50                    'if': 'xe1'}],
51                  'id': 'vpevnf-baremetal',
52                  'external-interface':
53                  [{'virtual-interface':
54                    {'dst_mac': '3c:fd:fe:9e:64:38',
55                     'vpci': '0000:05:00.0',
56                     'local_ip': '172.16.100.19',
57                     'type': 'PCI-PASSTHROUGH',
58                     'netmask': '255.255.255.0',
59                     'dpdk_port_num': 0,
60                     'bandwidth': '10 Gbps',
61                     'dst_ip': '172.16.100.20',
62                     'local_mac': '3c:fd:fe:a1:2b:80'},
63                    'vnfd-connection-point-ref': 'xe0',
64                    'name': 'xe0'},
65                   {'virtual-interface':
66                    {'dst_mac': '00:1e:67:d0:60:5c',
67                     'vpci': '0000:05:00.1',
68                     'local_ip': '172.16.40.19',
69                     'type': 'PCI-PASSTHROUGH',
70                     'netmask': '255.255.255.0',
71                     'dpdk_port_num': 1,
72                     'bandwidth': '10 Gbps',
73                     'dst_ip': '172.16.40.20',
74                     'local_mac': '3c:fd:fe:a1:2b:81'},
75                    'vnfd-connection-point-ref': 'xe1',
76                    'name': 'xe1'}]}],
77                'description': 'Vpe approximation using DPDK',
78                'mgmt-interface':
79                    {'vdu-id': 'vpevnf-baremetal',
80                     'host': '127.0.0.1',
81                     'password': 'r00t',
82                     'user': 'root',
83                     'ip': '127.0.0.1'},
84                'benchmark':
85                    {'kpi': ['packets_in', 'packets_fwd', 'packets_dropped']},
86                'connection-point': [{'type': 'VPORT', 'name': 'xe0'},
87                                     {'type': 'VPORT', 'name': 'xe1'}],
88                'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh'}]}}
89
90     def setUp(self):
91         with mock.patch("yardstick.ssh.AutoConnectSSH") as ssh:
92             self.ssh_mock = mock.Mock(autospec=ssh.SSH)
93             self.ssh_mock.execute = \
94                 mock.Mock(return_value=(0, "", ""))
95             ssh.from_node.return_value = self.ssh_mock
96
97             mgmt = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]['mgmt-interface']
98             # interfaces = \
99             #    self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]['vdu'][0]['external-interface']
100             port_names = \
101                 self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]['vdu'][0]['external-interface']
102             self.resource_profile = \
103                 ResourceProfile(mgmt, port_names)
104             self.resource_profile.connection = self.ssh_mock
105
106     def test___init__(self):
107         self.assertTrue(self.resource_profile.enable)
108
109     def test_check_if_system_agent_running(self):
110         self.assertEqual(self.resource_profile.check_if_system_agent_running("collectd"),
111                          (0, ""))
112
113     def test_check_if_system_agent_running_excetion(self):
114         with mock.patch.object(self.resource_profile.connection, "execute") as mock_execute:
115             mock_execute.side_effect = OSError(errno.ECONNRESET, "error")
116             self.assertEqual(
117                 self.resource_profile.check_if_system_agent_running("collectd"),
118                 (1, None))
119
120     def test_get_cpu_data(self):
121         reskey = ["", "cpufreq", "cpufreq-0"]
122         value = "metric:10"
123         val = self.resource_profile.get_cpu_data(reskey[1], reskey[2], value)
124         self.assertIsNotNone(val)
125
126     def test_get_cpu_data_error(self):
127         reskey = ["", "", ""]
128         value = "metric:10"
129         val = self.resource_profile.get_cpu_data(reskey[0], reskey[1], value)
130         self.assertEqual(val, ('error', 'Invalid', '', ''))
131
132     def test__start_collectd(self):
133         ssh_mock = mock.Mock()
134         ssh_mock.execute = mock.Mock(return_value=(0, "", ""))
135         self.assertIsNone(self.resource_profile._start_collectd(ssh_mock,
136                                                                 "/opt/nsb_bin"))
137
138         ssh_mock.execute = mock.Mock(side_effect=exceptions.SSHError)
139         with self.assertRaises(exceptions.SSHError):
140             self.resource_profile._start_collectd(ssh_mock, "/opt/nsb_bin")
141
142         ssh_mock.execute = mock.Mock(return_value=(1, "", ""))
143         with self.assertRaises(ResourceCommandError):
144             self.resource_profile._start_collectd(ssh_mock, "/opt/nsb_bin")
145
146     def test__reset_rabbitmq(self):
147         ssh_mock = mock.Mock()
148         ssh_mock.execute = mock.Mock(return_value=(1, "", ""))
149         with self.assertRaises(exceptions.ResourceCommandError):
150             self.resource_profile._reset_rabbitmq(ssh_mock)
151
152     def test__check_rabbitmq_user(self):
153         ssh_mock = mock.Mock()
154         ssh_mock.execute = mock.Mock(return_value=(0, "title\nadmin\t[]", ""))
155         self.assertTrue(self.resource_profile._check_rabbitmq_user(ssh_mock))
156
157     def test__set_rabbitmq_admin_user(self):
158         ssh_mock = mock.Mock()
159         ssh_mock.execute = mock.Mock(return_value=(1, "", ""))
160         with self.assertRaises(exceptions.ResourceCommandError):
161             self.resource_profile._set_rabbitmq_admin_user(ssh_mock)
162
163     def test__start_rabbitmq(self):
164         ssh_mock = mock.Mock()
165         self.resource_profile._reset_rabbitmq = mock.Mock()
166         self.resource_profile._set_rabbitmq_admin_user = mock.Mock()
167
168         self.resource_profile._reset_mq_flag = True
169         ssh_mock.execute = mock.Mock(return_value=(1, "", ""))
170         with self.assertRaises(exceptions.ResourceCommandError):
171             self.resource_profile._start_rabbitmq(ssh_mock)
172
173         self.resource_profile._reset_mq_flag = False
174         self.resource_profile._check_rabbitmq_user = mock.Mock(return_value=False)
175         ssh_mock.execute = mock.Mock(return_value=(1, "", ""))
176         with self.assertRaises(exceptions.ResourceCommandError):
177             self.resource_profile._start_rabbitmq(ssh_mock)
178
179     def test__prepare_collectd_conf(self):
180             self.assertIsNone(
181                 self.resource_profile._prepare_collectd_conf("/opt/nsb_bin"))
182
183     def test__setup_ovs_stats(self):
184         # TODO(elfoley): This method doesn't actually return anything, the side
185         # effects should be checked
186         self.assertIsNone(
187             self.resource_profile._setup_ovs_stats(self.ssh_mock))
188
189     def test__provide_config_file(self,):
190         loadplugin = range(5)
191         port_names = range(5)
192         kwargs = {
193             "interval": '25',
194             "loadplugin": loadplugin,
195             "port_names": port_names,
196         }
197         self.resource_profile._provide_config_file("/opt/nsb_bin", "collectd.conf", kwargs)
198         self.ssh_mock.execute.assert_called_once()
199
200     def test_initiate_systemagent(self):
201         self.resource_profile._start_collectd = mock.Mock()
202         self.resource_profile._start_rabbitmq = mock.Mock()
203         self.assertIsNone(
204             self.resource_profile.initiate_systemagent("/opt/nsb_bin"))
205
206     def test_initiate_systemagent_raise(self):
207         self.resource_profile._start_rabbitmq = mock.Mock(side_effect=RuntimeError)
208         with self.assertRaises(RuntimeError):
209             self.resource_profile.initiate_systemagent("/opt/nsb_bin")
210
211     def test__parse_hugepages(self):
212         reskey = ["cpu", "cpuFreq"]
213         value = "timestamp:12345"
214         res = self.resource_profile.parse_hugepages(reskey, value)
215         self.assertEqual({'cpu/cpuFreq': '12345'}, res)
216
217     def test__parse_dpdkstat(self):
218         reskey = ["dpdk0", "0"]
219         value = "tx:12345"
220         res = self.resource_profile.parse_dpdkstat(reskey, value)
221         self.assertEqual({'dpdk0/0': '12345'}, res)
222
223     def test__parse_virt(self):
224         reskey = ["vm0", "cpu"]
225         value = "load:45"
226         res = self.resource_profile.parse_virt(reskey, value)
227         self.assertEqual({'vm0/cpu': '45'}, res)
228
229     def test__parse_ovs_stats(self):
230         reskey = ["ovs", "stats"]
231         value = "tx:45"
232         res = self.resource_profile.parse_ovs_stats(reskey, value)
233         self.assertEqual({'ovs/stats': '45'}, res)
234
235     def test_parse_collectd_result(self):
236         res = self.resource_profile.parse_collectd_result({})
237         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {},
238                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
239                            'virt': {}}
240         self.assertDictEqual(res, expected_result)
241
242     def test_parse_collectd_result_cpu(self):
243         metric = {"nsb_stats/cpu/0/ipc": "101"}
244         self.resource_profile.get_cpu_data = mock.Mock(return_value=[1,
245                                                                      "ipc",
246                                                                      "1234",
247                                                                      ""])
248         res = self.resource_profile.parse_collectd_result(metric)
249         expected_result = {'cpu': {1: {'ipc': '1234'}}, 'dpdkstat': {}, 'hugepages': {},
250                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
251                            'virt': {}}
252         self.assertDictEqual(res, expected_result)
253
254     def test_parse_collectd_result_memory(self):
255         metric = {"nsb_stats/memory/bw": "101"}
256         res = self.resource_profile.parse_collectd_result(metric)
257         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {},
258                            'memory': {'bw': '101'}, 'ovs_stats': {}, 'timestamp': '',
259                            'virt': {}}
260         self.assertDictEqual(res, expected_result)
261
262     def test_parse_collectd_result_hugepage(self):
263         # amqp returns bytes
264         metric = {b"nsb_stats/hugepages/free": b"101"}
265         self.resource_profile.parse_hugepages = mock.Mock(return_value={"free": "101"})
266         res = self.resource_profile.parse_collectd_result(metric)
267         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {'free': '101'},
268                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
269                            'virt': {}}
270         self.assertDictEqual(res, expected_result)
271
272     def test_parse_collectd_result_dpdk_virt_ovs(self):
273         metric = {b"nsb_stats/dpdkstat/tx": b"101",
274                   b"nsb_stats/ovs_stats/tx": b"101",
275                   b"nsb_stats/virt/virt/memory": b"101"}
276         self.resource_profile.parse_dpdkstat = \
277             mock.Mock(return_value={"tx": "101"})
278         self.resource_profile.parse_virt = \
279             mock.Mock(return_value={"memory": "101"})
280         self.resource_profile.parse_ovs_stats = \
281             mock.Mock(return_value={"tx": "101"})
282         res = self.resource_profile.parse_collectd_result(metric)
283         expected_result = {'cpu': {}, 'dpdkstat': {'tx': '101'}, 'hugepages': {},
284                            'memory': {}, 'ovs_stats': {'tx': '101'}, 'timestamp': '',
285                            'virt': {'memory': '101'}}
286         self.assertDictEqual(res, expected_result)
287
288     def test_amqp_process_for_nfvi_kpi(self):
289         self.resource_profile.amqp_client = \
290             mock.MagicMock(side_effect=[None, mock.MagicMock()])
291         self.resource_profile.run_collectd_amqp = \
292             mock.Mock(return_value=0)
293         res = self.resource_profile.amqp_process_for_nfvi_kpi()
294         self.assertIsNone(res)
295
296     def test_amqp_collect_nfvi_kpi(self):
297         self.resource_profile.amqp_client = \
298             mock.MagicMock(side_effect=[None, mock.MagicMock()])
299         self.resource_profile.run_collectd_amqp = \
300             mock.Mock(return_value=0)
301         self.resource_profile.parse_collectd_result = mock.Mock()
302         res = self.resource_profile.amqp_collect_nfvi_kpi()
303         self.assertIsNotNone(res)
304
305     def test_run_collectd_amqp(self):
306         resource.AmqpConsumer = mock.Mock(autospec=collectd)
307         self.assertIsNone(self.resource_profile.run_collectd_amqp())
308
309     def test_start(self):
310         self.assertIsNone(self.resource_profile.start())
311
312     def test_stop(self):
313         self.assertIsNone(self.resource_profile.stop())
314
315     def test_stop_amqp_not_running(self):
316         self.resource_profile.amqp_client = mock.MagicMock()
317         # TODO(efoley): Fix this incorrect test.
318         # Should check that we don't try to stop amqp when it's not running
319         self.assertIsNone(self.resource_profile.stop())