Add new scenario NSPerf-RFC2544
[yardstick.git] / yardstick / tests / unit / benchmark / scenarios / networking / test_vnf_generic.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 from copy import deepcopy
16 import os
17 import sys
18
19 import mock
20 import unittest
21
22 from yardstick import tests
23 from yardstick.common import exceptions
24 from yardstick.common import utils
25 from yardstick.network_services.collector.subscriber import Collector
26 from yardstick.network_services.traffic_profile import base
27 from yardstick.network_services.vnf_generic import vnfdgen
28 from yardstick.network_services.vnf_generic.vnf.base import GenericTrafficGen
29 from yardstick.network_services.vnf_generic.vnf.base import GenericVNF
30
31
32 stl_patch = mock.patch.dict(sys.modules, tests.STL_MOCKS)
33 stl_patch.start()
34
35 if stl_patch:
36     from yardstick.benchmark.scenarios.networking import vnf_generic
37
38 # pylint: disable=unused-argument
39 # disable this for now because I keep forgetting mock patch arg ordering
40
41
42 COMPLETE_TREX_VNFD = {
43     'vnfd:vnfd-catalog': {
44         'vnfd': [
45             {
46                 'benchmark': {
47                     'kpi': [
48                         'rx_throughput_fps',
49                         'tx_throughput_fps',
50                         'tx_throughput_mbps',
51                         'rx_throughput_mbps',
52                         'tx_throughput_pc_linerate',
53                         'rx_throughput_pc_linerate',
54                         'min_latency',
55                         'max_latency',
56                         'avg_latency',
57                     ],
58                 },
59                 'connection-point': [
60                     {
61                         'name': 'xe0',
62                         'type': 'VPORT',
63                     },
64                     {
65                         'name': 'xe1',
66                         'type': 'VPORT',
67                     },
68                 ],
69                 'description': 'TRex stateless traffic generator for RFC2544',
70                 'id': 'TrexTrafficGen',
71                 'mgmt-interface': {
72                     'ip': '1.1.1.1',
73                     'password': 'berta',
74                     'user': 'berta',
75                     'vdu-id': 'trexgen-baremetal',
76                 },
77                 'name': 'trexgen',
78                 'short-name': 'trexgen',
79                 'class-name': 'TrexTrafficGen',
80                 'vdu': [
81                     {
82                         'description': 'TRex stateless traffic generator for RFC2544',
83                         'external-interface': [
84                             {
85                                 'name': 'xe0',
86                                 'virtual-interface': {
87                                     'bandwidth': '10 Gbps',
88                                     'dst_ip': '1.1.1.1',
89                                     'dst_mac': '00:01:02:03:04:05',
90                                     'local_ip': '1.1.1.2',
91                                     'local_mac': '00:01:02:03:05:05',
92                                     'type': 'PCI-PASSTHROUGH',
93                                     'netmask': "255.255.255.0",
94                                     'driver': 'i40',
95                                     'vpci': '0000:00:10.2',
96                                 },
97                                 'vnfd-connection-point-ref': 'xe0',
98                             },
99                             {
100                                 'name': 'xe1',
101                                 'virtual-interface': {
102                                     'bandwidth': '10 Gbps',
103                                     'dst_ip': '2.1.1.1',
104                                     'dst_mac': '00:01:02:03:04:06',
105                                     'local_ip': '2.1.1.2',
106                                     'local_mac': '00:01:02:03:05:06',
107                                     'type': 'PCI-PASSTHROUGH',
108                                     'netmask': "255.255.255.0",
109                                     'driver': 'i40',
110                                     'vpci': '0000:00:10.1',
111                                 },
112                                 'vnfd-connection-point-ref': 'xe1',
113                             },
114                         ],
115                         'id': 'trexgen-baremetal',
116                         'name': 'trexgen-baremetal',
117                     },
118                 ],
119             },
120         ],
121     },
122 }
123
124 IP_ADDR_SHOW = """
125 28: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP \
126 group default qlen 1000
127     link/ether 90:e2:ba:a7:6a:c8 brd ff:ff:ff:ff:ff:ff
128     inet 1.1.1.1/8 brd 1.255.255.255 scope global eth1
129     inet6 fe80::92e2:baff:fea7:6ac8/64 scope link
130        valid_lft forever preferred_lft forever
131 29: eth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP \
132 group default qlen 1000
133     link/ether 90:e2:ba:a7:6a:c9 brd ff:ff:ff:ff:ff:ff
134     inet 2.1.1.1/8 brd 2.255.255.255 scope global eth5
135     inet6 fe80::92e2:baff:fea7:6ac9/64 scope link tentative
136        valid_lft forever preferred_lft forever
137 """
138
139 SYS_CLASS_NET = """
140 lrwxrwxrwx 1 root root 0 sie 10 14:16 eth1 -> \
141 ../../devices/pci0000:80/0000:80:02.2/0000:84:00.1/net/eth1
142 lrwxrwxrwx 1 root root 0 sie  3 10:37 eth2 -> \
143 ../../devices/pci0000:00/0000:00:01.1/0000:84:00.2/net/eth5
144 """
145
146 TRAFFIC_PROFILE = {
147     "schema": "isb:traffic_profile:0.1",
148     "name": "fixed",
149     "description": "Fixed traffic profile to run UDP traffic",
150     "traffic_profile": {
151         "traffic_type": "FixedTraffic",
152         "frame_rate": 100,  # pps
153         "flow_number": 10,
154         "frame_size": 64,
155     },
156 }
157
158
159 class TestNetworkServiceTestCase(unittest.TestCase):
160
161     def setUp(self):
162         self.tg__1 = {
163             'name': 'trafficgen_1.yardstick',
164             'ip': '10.10.10.11',
165             'role': 'TrafficGen',
166             'user': 'root',
167             'password': 'r00t',
168             'interfaces': {
169                 'xe0': {
170                     'netmask': '255.255.255.0',
171                     'local_ip': '152.16.100.20',
172                     'local_mac': '00:00:00:00:00:01',
173                     'driver': 'i40e',
174                     'vpci': '0000:07:00.0',
175                     'dpdk_port_num': 0,
176                 },
177                 'xe1': {
178                     'netmask': '255.255.255.0',
179                     'local_ip': '152.16.40.20',
180                     'local_mac': '00:00:00:00:00:02',
181                     'driver': 'i40e',
182                     'vpci': '0000:07:00.1',
183                     'dpdk_port_num': 1,
184                 },
185             },
186         }
187
188         self.vnf__1 = {
189             'name': 'vnf.yardstick',
190             'ip': '10.10.10.12',
191             'host': '10.223.197.164',
192             'role': 'vnf',
193             'user': 'root',
194             'password': 'r00t',
195             'interfaces': {
196                 'xe0': {
197                     'netmask': '255.255.255.0',
198                     'local_ip': '152.16.100.19',
199                     'local_mac': '00:00:00:00:00:03',
200                     'driver': 'i40e',
201                     'vpci': '0000:07:00.0',
202                     'dpdk_port_num': 0,
203                 },
204                 'xe1': {
205                     'netmask': '255.255.255.0',
206                     'local_ip': '152.16.40.19',
207                     'local_mac': '00:00:00:00:00:04',
208                     'driver': 'i40e',
209                     'vpci': '0000:07:00.1',
210                     'dpdk_port_num': 1,
211                 },
212             },
213             'routing_table': [
214                 {
215                     'netmask': '255.255.255.0',
216                     'gateway': '152.16.100.20',
217                     'network': '152.16.100.20',
218                     'if': 'xe0',
219                 },
220                 {
221                     'netmask': '255.255.255.0',
222                     'gateway': '152.16.40.20',
223                     'network': '152.16.40.20',
224                     'if': 'xe1',
225                 },
226             ],
227             'nd_route_tbl': [
228                 {
229                     'netmask': '112',
230                     'gateway': '0064:ff9b:0:0:0:0:9810:6414',
231                     'network': '0064:ff9b:0:0:0:0:9810:6414',
232                     'if': 'xe0',
233                 },
234                 {
235                     'netmask': '112',
236                     'gateway': '0064:ff9b:0:0:0:0:9810:2814',
237                     'network': '0064:ff9b:0:0:0:0:9810:2814',
238                     'if': 'xe1',
239                 },
240             ],
241         }
242
243         self.context_cfg = {
244             'nodes': {
245                 'tg__1': self.tg__1,
246                 'vnf__1': self.vnf__1,
247             },
248             'networks': {
249                 GenericVNF.UPLINK: {
250                     'vld_id': GenericVNF.UPLINK,
251                 },
252                 GenericVNF.DOWNLINK: {
253                     'vld_id': GenericVNF.DOWNLINK,
254                 },
255             },
256         }
257
258         self.vld0 = {
259             'vnfd-connection-point-ref': [
260                 {
261                     'vnfd-connection-point-ref': 'xe0',
262                     'member-vnf-index-ref': '1',
263                     'vnfd-id-ref': 'trexgen'
264                 },
265                 {
266                     'vnfd-connection-point-ref': 'xe0',
267                     'member-vnf-index-ref': '2',
268                     'vnfd-id-ref': 'trexgen'
269                 }
270             ],
271             'type': 'ELAN',
272             'id': GenericVNF.UPLINK,
273             'name': 'tg__1 to vnf__1 link 1'
274         }
275
276         self.vld1 = {
277             'vnfd-connection-point-ref': [
278                 {
279                     'vnfd-connection-point-ref': 'xe1',
280                     'member-vnf-index-ref': '1',
281                     'vnfd-id-ref': 'trexgen'
282                 },
283                 {
284                     'vnfd-connection-point-ref': 'xe1',
285                     'member-vnf-index-ref': '2',
286                     'vnfd-id-ref': 'trexgen'
287                 }
288             ],
289             'type': 'ELAN',
290             'id': GenericVNF.DOWNLINK,
291             'name': 'vnf__1 to tg__1 link 2'
292         }
293
294         self.topology = {
295             'id': 'trex-tg-topology',
296             'short-name': 'trex-tg-topology',
297             'name': 'trex-tg-topology',
298             'description': 'trex-tg-topology',
299             'constituent-vnfd': [
300                 {
301                     'member-vnf-index': '1',
302                     'VNF model': 'tg_trex_tpl.yaml',
303                     'vnfd-id-ref': 'tg__1',
304                 },
305                 {
306                     'member-vnf-index': '2',
307                     'VNF model': 'tg_trex_tpl.yaml',
308                     'vnfd-id-ref': 'vnf__1',
309                 },
310             ],
311             'vld': [self.vld0, self.vld1],
312         }
313
314         self.scenario_cfg = {
315             'task_path': "",
316             "topology": self._get_file_abspath("vpe_vnf_topology.yaml"),
317             'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
318             'tc': 'tc_ipv4_1Mflow_64B_packetsize',
319             'traffic_profile': 'ipv4_throughput_vpe.yaml',
320             'extra_args': {'arg1': 'value1', 'arg2': 'value2'},
321             'type': 'ISB',
322             'tc_options': {
323                 'rfc2544': {
324                     'allowed_drop_rate': '0.8 - 1',
325                 },
326             },
327             'options': {
328                 'simulated_users': {'uplink': [1, 2]},
329                 'page_object': {'uplink': [1, 2]},
330                 'framesize': {'64B': 100}
331             },
332             'runner': {
333                 'object': 'NetworkServiceTestCase',
334                 'interval': 35,
335                 'output_filename': 'yardstick.out',
336                 'runner_id': 74476,
337                 'duration': 400,
338                 'type': 'Duration',
339             },
340             'traffic_options': {
341                 'flow': 'ipv4_1flow_Packets_vpe.yaml',
342                 'imix': 'imix_voice.yaml'
343             },
344             'nodes': {
345                 'tg__2': 'trafficgen_2.yardstick',
346                 'tg__1': 'trafficgen_1.yardstick',
347                 'vnf__1': 'vnf.yardstick',
348             },
349         }
350
351         self.s = vnf_generic.NetworkServiceTestCase(self.scenario_cfg,
352                                                     self.context_cfg)
353
354     def _get_file_abspath(self, filename):
355         curr_path = os.path.dirname(os.path.abspath(__file__))
356         file_path = os.path.join(curr_path, filename)
357         return file_path
358
359     def test___init__(self):
360         self.assertIsNotNone(self.topology)
361
362     def test__get_ip_flow_range_string(self):
363         result = '152.16.100.2-152.16.100.254'
364         self.assertEqual(result, self.s._get_ip_flow_range(
365             '152.16.100.2-152.16.100.254'))
366
367     def test__get_ip_flow_range_no_nodes(self):
368         self.assertEqual('0.0.0.0', self.s._get_ip_flow_range({}))
369
370     def test__get_ip_flow_range_no_node_data(self):
371         node_data = {'tg__0': 'xe0'}
372         self.s.context_cfg['nodes']['tg__0'] = {}
373         result = self.s._get_ip_flow_range(node_data)
374         self.assertEqual('0.0.0.2-0.0.0.254', result)
375
376     def test__et_ip_flow_range_ipv4(self):
377         node_data = {'tg__0': 'xe0'}
378         self.s.context_cfg['nodes']['tg__0'] = {
379             'interfaces': {
380                 'xe0': {'local_ip': '192.168.1.15',
381                         'netmask': '255.255.255.128'}
382             }
383         }
384         result = self.s._get_ip_flow_range(node_data)
385         self.assertEqual('192.168.1.2-192.168.1.126', result)
386
387     def test__get_ip_flow_range_ipv4_mask_30(self):
388         node_data = {'tg__0': 'xe0'}
389         self.s.context_cfg['nodes']['tg__0'] = {
390             'interfaces': {
391                 'xe0': {'local_ip': '192.168.1.15', 'netmask': 30}
392             }
393         }
394         result = self.s._get_ip_flow_range(node_data)
395         self.assertEqual('192.168.1.15', result)
396
397     def test__get_ip_flow_range_ipv6(self):
398         node_data = {'tg__0': 'xe0'}
399         self.s.context_cfg['nodes']['tg__0'] = {
400             'interfaces': {
401                 'xe0': {'local_ip': '2001::11', 'netmask': 64}
402             }
403         }
404         result = self.s._get_ip_flow_range(node_data)
405         self.assertEqual('2001::2-2001::ffff:ffff:ffff:fffe', result)
406
407     def test___get_traffic_flow(self):
408         self.scenario_cfg["traffic_options"]["flow"] = \
409             self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml")
410         self.scenario_cfg['options'] = {
411             'flow': {
412                 'src_ip': [
413                     {
414                         'tg__1': 'xe0',
415                     },
416                 ],
417                 'dst_ip': [
418                     {
419                         'tg__1': 'xe1',
420                     },
421                 ],
422                 'public_ip': ['1.1.1.1'],
423             },
424         }
425         expected_flow = {'flow': {'dst_ip_0': '152.16.40.2-152.16.40.254',
426                                   'public_ip_0': '1.1.1.1',
427                                   'src_ip_0': '152.16.100.2-152.16.100.254'}}
428         self.assertEqual(expected_flow, self.s._get_traffic_flow())
429
430     def test___get_traffic_flow_error(self):
431         self.scenario_cfg["traffic_options"]["flow"] = \
432             "ipv4_1flow_Packets_vpe.yaml1"
433         self.assertEqual({'flow': {}}, self.s._get_traffic_flow())
434
435     def test_get_vnf_imp(self):
436         vnfd = COMPLETE_TREX_VNFD['vnfd:vnfd-catalog']['vnfd'][0]['class-name']
437         with mock.patch.dict(sys.modules, tests.STL_MOCKS):
438             self.assertIsNotNone(self.s.get_vnf_impl(vnfd))
439
440         with self.assertRaises(exceptions.IncorrectConfig) as raised:
441             self.s.get_vnf_impl('NonExistentClass')
442
443         exc_str = str(raised.exception)
444         print(exc_str)
445         self.assertIn('No implementation', exc_str)
446         self.assertIn('found in', exc_str)
447
448     def test_load_vnf_models_invalid(self):
449         self.context_cfg["nodes"]['tg__1']['VNF model'] = \
450             self._get_file_abspath("tg_trex_tpl.yaml")
451         self.context_cfg["nodes"]['vnf__1']['VNF model'] = \
452             self._get_file_abspath("tg_trex_tpl.yaml")
453
454         vnf = mock.Mock(autospec=GenericVNF)
455         self.s.get_vnf_impl = mock.Mock(return_value=vnf)
456
457         self.assertIsNotNone(
458             self.s.load_vnf_models(self.scenario_cfg, self.context_cfg))
459
460     def test_load_vnf_models_no_model(self):
461         vnf = mock.Mock(autospec=GenericVNF)
462         self.s.get_vnf_impl = mock.Mock(return_value=vnf)
463
464         self.assertIsNotNone(
465             self.s.load_vnf_models(self.scenario_cfg, self.context_cfg))
466
467     def test_map_topology_to_infrastructure(self):
468         self.s.map_topology_to_infrastructure()
469
470         nodes = self.context_cfg["nodes"]
471         self.assertEqual('../../vnf_descriptors/tg_rfc2544_tpl.yaml',
472                          nodes['tg__1']['VNF model'])
473         self.assertEqual('../../vnf_descriptors/vpe_vnf.yaml',
474                          nodes['vnf__1']['VNF model'])
475
476     def test_map_topology_to_infrastructure_insufficient_nodes(self):
477         cfg = deepcopy(self.context_cfg)
478         del cfg['nodes']['vnf__1']
479
480         cfg_patch = mock.patch.object(self.s, 'context_cfg', cfg)
481         with cfg_patch:
482             with self.assertRaises(exceptions.IncorrectConfig):
483                 self.s.map_topology_to_infrastructure()
484
485     def test_map_topology_to_infrastructure_config_invalid(self):
486         ssh_mock = mock.Mock()
487         ssh_mock.execute.return_value = 0, SYS_CLASS_NET + IP_ADDR_SHOW, ""
488
489         cfg = deepcopy(self.s.context_cfg)
490
491         # delete all, we don't know which will come first
492         del cfg['nodes']['vnf__1']['interfaces']['xe0']['local_mac']
493         del cfg['nodes']['vnf__1']['interfaces']['xe1']['local_mac']
494         del cfg['nodes']['tg__1']['interfaces']['xe0']['local_mac']
495         del cfg['nodes']['tg__1']['interfaces']['xe1']['local_mac']
496
497         config_patch = mock.patch.object(self.s, 'context_cfg', cfg)
498         with config_patch:
499             with self.assertRaises(exceptions.IncorrectConfig):
500                 self.s.map_topology_to_infrastructure()
501
502     def test__resolve_topology_invalid_config(self):
503         with mock.patch("yardstick.ssh.SSH") as ssh:
504             ssh_mock = mock.Mock(autospec=ssh.SSH)
505             ssh_mock.execute = \
506                 mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
507             ssh.from_node.return_value = ssh_mock
508
509             # purge an important key from the data structure
510             for interface in self.tg__1['interfaces'].values():
511                 del interface['local_mac']
512
513             with self.assertRaises(exceptions.IncorrectConfig) as raised:
514                 self.s._resolve_topology()
515
516             self.assertIn('not found', str(raised.exception))
517
518             # restore local_mac
519             for index, interface in enumerate(self.tg__1['interfaces'].values()):
520                 interface['local_mac'] = '00:00:00:00:00:{:2x}'.format(index)
521
522             # make a connection point ref with 3 points
523             self.s.topology["vld"][0]['vnfd-connection-point-ref'].append(
524                 self.s.topology["vld"][0]['vnfd-connection-point-ref'][0])
525
526             with self.assertRaises(exceptions.IncorrectConfig) as raised:
527                 self.s._resolve_topology()
528
529             self.assertIn('wrong endpoint count', str(raised.exception))
530
531             # make a connection point ref with 1 point
532             self.s.topology["vld"][0]['vnfd-connection-point-ref'] = \
533                 self.s.topology["vld"][0]['vnfd-connection-point-ref'][:1]
534
535             with self.assertRaises(exceptions.IncorrectConfig) as raised:
536                 self.s._resolve_topology()
537
538             self.assertIn('wrong endpoint count', str(raised.exception))
539
540     def test_run(self):
541         tgen = mock.Mock(autospec=GenericTrafficGen)
542         tgen.traffic_finished = True
543         verified_dict = {"verified": True}
544         tgen.verify_traffic = lambda x: verified_dict
545         tgen.name = "tgen__1"
546         vnf = mock.Mock(autospec=GenericVNF)
547         vnf.runs_traffic = False
548         self.s.vnfs = [tgen, vnf]
549         self.s.traffic_profile = mock.Mock()
550         self.s.collector = mock.Mock(autospec=Collector)
551         self.s.collector.get_kpi = \
552             mock.Mock(return_value={tgen.name: verified_dict})
553         result = {}
554         self.s.run(result)
555         self.assertDictEqual(result, {tgen.name: verified_dict})
556
557     def test_setup(self):
558         with mock.patch("yardstick.ssh.SSH") as ssh:
559             ssh_mock = mock.Mock(autospec=ssh.SSH)
560             ssh_mock.execute = \
561                 mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
562             ssh.from_node.return_value = ssh_mock
563
564             tgen = mock.Mock(autospec=GenericTrafficGen)
565             tgen.traffic_finished = True
566             verified_dict = {"verified": True}
567             tgen.verify_traffic = lambda x: verified_dict
568             tgen.terminate = mock.Mock(return_value=True)
569             tgen.name = "tgen__1"
570             vnf = mock.Mock(autospec=GenericVNF)
571             vnf.runs_traffic = False
572             vnf.terminate = mock.Mock(return_value=True)
573             self.s.vnfs = [tgen, vnf]
574             self.s.traffic_profile = mock.Mock()
575             self.s.collector = mock.Mock(autospec=Collector)
576             self.s.collector.get_kpi = \
577                 mock.Mock(return_value={tgen.name: verified_dict})
578             self.s.map_topology_to_infrastructure = mock.Mock(return_value=0)
579             self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs)
580             self.s._fill_traffic_profile = \
581                 mock.Mock(return_value=TRAFFIC_PROFILE)
582             self.assertIsNone(self.s.setup())
583
584     def test_setup_exception(self):
585         with mock.patch("yardstick.ssh.SSH") as ssh:
586             ssh_mock = mock.Mock(autospec=ssh.SSH)
587             ssh_mock.execute = \
588                 mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
589             ssh.from_node.return_value = ssh_mock
590
591             tgen = mock.Mock(autospec=GenericTrafficGen)
592             tgen.traffic_finished = True
593             verified_dict = {"verified": True}
594             tgen.verify_traffic = lambda x: verified_dict
595             tgen.terminate = mock.Mock(return_value=True)
596             tgen.name = "tgen__1"
597             vnf = mock.Mock(autospec=GenericVNF)
598             vnf.runs_traffic = False
599             vnf.instantiate.side_effect = RuntimeError(
600                 "error during instantiate")
601             vnf.terminate = mock.Mock(return_value=True)
602             self.s.vnfs = [tgen, vnf]
603             self.s.traffic_profile = mock.Mock()
604             self.s.collector = mock.Mock(autospec=Collector)
605             self.s.collector.get_kpi = \
606                 mock.Mock(return_value={tgen.name: verified_dict})
607             self.s.map_topology_to_infrastructure = mock.Mock(return_value=0)
608             self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs)
609             self.s._fill_traffic_profile = \
610                 mock.Mock(return_value=TRAFFIC_PROFILE)
611             with self.assertRaises(RuntimeError):
612                 self.s.setup()
613
614     def test__get_traffic_profile(self):
615         self.scenario_cfg["traffic_profile"] = \
616             self._get_file_abspath("ipv4_throughput_vpe.yaml")
617         self.assertIsNotNone(self.s._get_traffic_profile())
618
619     def test__get_traffic_profile_exception(self):
620         with mock.patch.dict(self.scenario_cfg, {'traffic_profile': ''}):
621             with self.assertRaises(IOError):
622                 self.s._get_traffic_profile()
623
624     def test__key_list_to_dict(self):
625         result = self.s._key_list_to_dict("uplink", {"uplink": [1, 2]})
626         self.assertEqual({"uplink_0": 1, "uplink_1": 2}, result)
627
628     def test__get_simulated_users(self):
629         result = self.s._get_simulated_users()
630         self.assertEqual({'simulated_users': {'uplink_0': 1, 'uplink_1': 2}},
631                          result)
632
633     def test__get_page_object(self):
634         result = self.s._get_page_object()
635         self.assertEqual({'page_object': {'uplink_0': 1, 'uplink_1': 2}},
636                          result)
637
638     def test___get_traffic_imix_exception(self):
639         with mock.patch.dict(self.scenario_cfg["traffic_options"], {'imix': ''}):
640             self.assertEqual({'imix': {'64B': 100}},
641                              self.s._get_traffic_imix())
642
643     @mock.patch.object(base.TrafficProfile, 'get')
644     @mock.patch.object(vnfdgen, 'generate_vnfd')
645     def test__fill_traffic_profile(self, mock_generate, mock_tprofile_get):
646         fake_tprofile = mock.Mock()
647         fake_vnfd = mock.MagicMock()
648         with mock.patch.object(self.s, '_get_traffic_profile',
649                                return_value=fake_tprofile) as mock_get_tp:
650             mock_generate.return_value = fake_vnfd
651             self.s._fill_traffic_profile()
652             mock_get_tp.assert_called_once()
653             mock_generate.assert_called_once_with(
654                 fake_tprofile,
655                 {'downlink': {},
656                  'extra_args': {'arg1': 'value1', 'arg2': 'value2'},
657                  'flow': {'flow': {}},
658                  'imix': {'imix': {'64B': 100}},
659                  'uplink': {},
660                  'duration': 30,
661                  'simulated_users': {
662                      'simulated_users': {'uplink_0': 1, 'uplink_1': 2}},
663                  'page_object': {
664                      'page_object': {'uplink_0': 1, 'uplink_1': 2}},}
665             )
666             mock_tprofile_get.assert_called_once_with(fake_vnfd)
667
668     @mock.patch.object(base.TrafficProfile, 'get')
669     @mock.patch.object(vnfdgen, 'generate_vnfd')
670     def test__fill_traffic_profile2(self, mock_generate, mock_tprofile_get):
671         fake_tprofile = mock.Mock()
672         fake_vnfd = {}
673         with mock.patch.object(self.s, '_get_traffic_profile',
674                                return_value=fake_tprofile) as mock_get_tp:
675             mock_generate.return_value = fake_vnfd
676
677             self.s.scenario_cfg["options"] = {"traffic_config": {"duration": 99899}}
678             self.s._fill_traffic_profile()
679             mock_get_tp.assert_called_once()
680             self.assertIn("traffic_profile", fake_vnfd)
681             self.assertIn("duration", fake_vnfd["traffic_profile"])
682             self.assertEqual(99899, fake_vnfd["traffic_profile"]["duration"])
683
684     @mock.patch.object(utils, 'open_relative_file')
685     def test__get_topology(self, mock_open_path):
686         self.s.scenario_cfg['topology'] = 'fake_topology'
687         self.s.scenario_cfg['task_path'] = 'fake_path'
688         mock_open_path.side_effect = mock.mock_open(read_data='fake_data')
689         self.assertEqual('fake_data', self.s._get_topology())
690         mock_open_path.assert_called_once_with('fake_topology', 'fake_path')
691
692     @mock.patch.object(vnfdgen, 'generate_vnfd')
693     def test__render_topology(self, mock_generate):
694         fake_topology = 'fake_topology'
695         mock_generate.return_value = {'nsd:nsd-catalog': {'nsd': ['fake_nsd']}}
696         with mock.patch.object(self.s, '_get_topology',
697                                return_value=fake_topology) as mock_get_topology:
698             self.s._render_topology()
699             mock_get_topology.assert_called_once()
700
701         mock_generate.assert_called_once_with(
702             fake_topology,
703             {'extra_args': {'arg1': 'value1', 'arg2': 'value2'}}
704         )
705         self.assertEqual(self.s.topology, 'fake_nsd')
706
707     def test_teardown(self):
708         vnf = mock.Mock(autospec=GenericVNF)
709         vnf.terminate = mock.Mock(return_value=True)
710         vnf.name = str(vnf)
711         self.s.vnfs = [vnf]
712         self.s.traffic_profile = mock.Mock()
713         self.s.collector = mock.Mock(autospec=Collector)
714         self.s.collector.stop = \
715             mock.Mock(return_value=True)
716         self.assertIsNone(self.s.teardown())
717
718     def test_teardown_exception(self):
719         vnf = mock.Mock(autospec=GenericVNF)
720         vnf.terminate = mock.Mock(
721             side_effect=RuntimeError("error duing terminate"))
722         vnf.name = str(vnf)
723         self.s.vnfs = [vnf]
724         self.s.traffic_profile = mock.Mock()
725         self.s.collector = mock.Mock(autospec=Collector)
726         self.s.collector.stop = \
727             mock.Mock(return_value=True)
728         with self.assertRaises(RuntimeError):
729             self.s.teardown()
730
731
732 class TestNetworkServiceRFC2544TestCase(TestNetworkServiceTestCase):
733
734     def setUp(self):
735         super(TestNetworkServiceRFC2544TestCase, self).setUp()
736         self.s = vnf_generic.NetworkServiceRFC2544(self.scenario_cfg,
737                                                     self.context_cfg)
738
739     def test_run(self):
740         tgen = mock.Mock(autospec=GenericTrafficGen)
741         tgen.traffic_finished = True
742         verified_dict = {"verified": True}
743         tgen.verify_traffic = lambda x: verified_dict
744         tgen.name = "tgen__1"
745         tgen.wait_on_trafic.return_value = 'COMPLETE'
746         vnf = mock.Mock(autospec=GenericVNF)
747         vnf.runs_traffic = False
748         self.s.vnfs = [tgen, vnf]
749         self.s.traffic_profile = mock.Mock()
750         self.s._fill_traffic_profile = mock.Mock()
751         self.s.collector = mock.Mock(autospec=Collector)
752         self.s.collector.get_kpi = mock.Mock(
753             return_value={tgen.name: verified_dict})
754         result = mock.Mock()
755         self.s.run(result)
756         self.s._fill_traffic_profile.assert_called_once()
757         result.push.assert_called_once()
758
759     def test_setup(self):
760         with mock.patch("yardstick.ssh.SSH") as ssh:
761             ssh_mock = mock.Mock(autospec=ssh.SSH)
762             ssh_mock.execute = \
763                 mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
764             ssh.from_node.return_value = ssh_mock
765
766             tgen = mock.Mock(autospec=GenericTrafficGen)
767             tgen.traffic_finished = True
768             verified_dict = {"verified": True}
769             tgen.verify_traffic = lambda x: verified_dict
770             tgen.terminate = mock.Mock(return_value=True)
771             tgen.name = "tgen__1"
772             tgen.run_traffic.return_value = 'tg_id'
773             vnf = mock.Mock(autospec=GenericVNF)
774             vnf.runs_traffic = False
775             vnf.terminate = mock.Mock(return_value=True)
776             self.s.vnfs = [tgen, vnf]
777             self.s.traffic_profile = mock.Mock()
778             self.s.collector = mock.Mock(autospec=Collector)
779             self.s.collector.get_kpi = \
780                 mock.Mock(return_value={tgen.name: verified_dict})
781             self.s.map_topology_to_infrastructure = mock.Mock(return_value=0)
782             self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs)
783             self.s.setup()
784
785     def test_setup_exception(self):
786         with mock.patch("yardstick.ssh.SSH") as ssh:
787             ssh_mock = mock.Mock(autospec=ssh.SSH)
788             ssh_mock.execute = \
789                 mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
790             ssh.from_node.return_value = ssh_mock
791
792             tgen = mock.Mock(autospec=GenericTrafficGen)
793             tgen.traffic_finished = True
794             verified_dict = {"verified": True}
795             tgen.verify_traffic = lambda x: verified_dict
796             tgen.terminate = mock.Mock(return_value=True)
797             tgen.name = "tgen__1"
798             vnf = mock.Mock(autospec=GenericVNF)
799             vnf.runs_traffic = False
800             vnf.instantiate.side_effect = RuntimeError(
801                 "error during instantiate")
802             vnf.terminate = mock.Mock(return_value=True)
803             self.s.vnfs = [tgen, vnf]
804             self.s.traffic_profile = mock.Mock()
805             self.s.collector = mock.Mock(autospec=Collector)
806             self.s.collector.get_kpi = \
807                 mock.Mock(return_value={tgen.name: verified_dict})
808             self.s.map_topology_to_infrastructure = mock.Mock(return_value=0)
809             self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs)
810             self.s._fill_traffic_profile = \
811                 mock.Mock(return_value=TRAFFIC_PROFILE)
812             with self.assertRaises(RuntimeError):
813                 self.s.setup()