1 # Copyright (c) 2019 Viosoft Corporation
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
23 from yardstick.benchmark.contexts import base as ctx_base
24 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
25 from yardstick.network_services.vnf_generic.vnf import tg_vcmts_pktgen
26 from yardstick.common import exceptions
32 class TestPktgenHelper(unittest.TestCase):
34 def test___init__(self):
35 pktgen_helper = tg_vcmts_pktgen.PktgenHelper("localhost", 23000)
36 self.assertEqual(pktgen_helper.host, "localhost")
37 self.assertEqual(pktgen_helper.port, 23000)
38 self.assertFalse(pktgen_helper.connected)
40 def _run_fake_server(self):
41 server_sock = socket.socket()
42 server_sock.bind(('localhost', 23000))
44 client_socket, _ = server_sock.accept()
48 def test__connect(self):
49 pktgen_helper = tg_vcmts_pktgen.PktgenHelper("localhost", 23000)
50 self.assertFalse(pktgen_helper._connect())
51 server_thread = threading.Thread(target=self._run_fake_server)
54 self.assertTrue(pktgen_helper._connect())
55 pktgen_helper._sock.close()
58 @mock.patch('yardstick.network_services.vnf_generic.vnf.tg_vcmts_pktgen.time')
59 def test_connect(self, *args):
60 pktgen_helper = tg_vcmts_pktgen.PktgenHelper("localhost", 23000)
61 pktgen_helper.connected = True
62 self.assertTrue(pktgen_helper.connect())
63 pktgen_helper.connected = False
65 pktgen_helper._connect = mock.MagicMock(return_value=True)
66 self.assertTrue(pktgen_helper.connect())
67 self.assertTrue(pktgen_helper.connected)
69 pktgen_helper = tg_vcmts_pktgen.PktgenHelper("localhost", 23000)
70 pktgen_helper._connect = mock.MagicMock(return_value=False)
71 self.assertFalse(pktgen_helper.connect())
72 self.assertFalse(pktgen_helper.connected)
74 def test_send_command(self):
75 pktgen_helper = tg_vcmts_pktgen.PktgenHelper("localhost", 23000)
76 self.assertFalse(pktgen_helper.send_command(""))
78 pktgen_helper.connected = True
79 pktgen_helper._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
80 self.assertFalse(pktgen_helper.send_command(""))
82 pktgen_helper._sock = mock.MagicMock()
83 self.assertTrue(pktgen_helper.send_command(""))
86 class TestVcmtsPktgenSetupEnvHelper(unittest.TestCase):
88 PKTGEN_PARAMETERS = "export LUA_PATH=/vcmts/Pktgen.lua;"\
89 "export CMK_PROC_FS=/host/proc;"\
90 " /pktgen-config/setup.sh 0 4 18:02.0 "\
91 "18:02.1 18:02.2 18:02.3 00:00.0 00:00.0 "\
92 "00:00.0 00:00.0 imix1_100cms_1ofdm.pcap "\
93 "imix1_100cms_1ofdm.pcap imix1_100cms_1ofdm.pcap "\
94 "imix1_100cms_1ofdm.pcap imix1_100cms_1ofdm.pcap "\
95 "imix1_100cms_1ofdm.pcap imix1_100cms_1ofdm.pcap "\
96 "imix1_100cms_1ofdm.pcap"
99 "pktgen_values": "/tmp/pktgen_values.yaml",
103 "vcmts_influxdb_ip": "10.80.5.150",
104 "vcmts_influxdb_port": 8086,
105 "vcmtsd_values": "/tmp/vcmtsd_values.yaml",
117 vnfd_helper = VnfdHelper(
118 TestVcmtsPktgen.VNFD['vnfd:vnfd-catalog']['vnfd'][0])
119 ssh_helper = mock.Mock()
120 scenario_helper = mock.Mock()
121 scenario_helper.options = self.OPTIONS
123 self.setup_helper = tg_vcmts_pktgen.VcmtsPktgenSetupEnvHelper(
124 vnfd_helper, ssh_helper, scenario_helper)
126 def test_generate_pcap_filename(self):
127 pcap_file_name = self.setup_helper.generate_pcap_filename(\
128 TestVcmtsPktgen.PKTGEN_POD_VALUES[0]['ports'][0])
129 self.assertEquals(pcap_file_name, "imix1_100cms_1ofdm.pcap")
131 def test_find_port_cfg(self):
132 port_cfg = self.setup_helper.find_port_cfg(\
133 TestVcmtsPktgen.PKTGEN_POD_VALUES[0]['ports'], "port_0")
134 self.assertIsNotNone(port_cfg)
136 port_cfg = self.setup_helper.find_port_cfg(\
137 TestVcmtsPktgen.PKTGEN_POD_VALUES[0]['ports'], "port_8")
138 self.assertIsNone(port_cfg)
140 def test_build_pktgen_parameters(self):
141 parameters = self.setup_helper.build_pktgen_parameters(
142 TestVcmtsPktgen.PKTGEN_POD_VALUES[0])
143 self.assertEquals(parameters, self.PKTGEN_PARAMETERS)
145 def test_start_pktgen(self):
146 self.setup_helper.ssh_helper = mock.MagicMock()
147 self.setup_helper.start_pktgen(TestVcmtsPktgen.PKTGEN_POD_VALUES[0])
148 self.setup_helper.ssh_helper.send_command.assert_called_with(
149 self.PKTGEN_PARAMETERS)
151 def test_setup_vnf_environment(self):
152 self.assertIsNone(self.setup_helper.setup_vnf_environment())
154 class TestVcmtsPktgen(unittest.TestCase):
156 VNFD = {'vnfd:vnfd-catalog':
161 "upstream/bits_per_second"
164 "connection-point": [
174 "description": "vCMTS Pktgen Kubernetes",
177 "ip": "192.168.24.150",
178 "key_filename": "/tmp/yardstick_key-a3b663c2",
180 "vdu-id": "vcmtspktgen-kubernetes"
182 "name": "vcmtspktgen",
183 "short-name": "vcmtspktgen",
186 "description": "vCMTS Pktgen Kubernetes",
187 "external-interface": [],
188 "id": "vcmtspktgen-kubernetes",
189 "name": "vcmtspktgen-kubernetes"
199 PKTGEN_POD_VALUES = [
205 "net_pktgen": "18:02.0",
209 "traffic_type": "imix1"
212 "net_pktgen": "18:02.1",
216 "traffic_type": "imix1"
219 "net_pktgen": "18:02.2",
223 "traffic_type": "imix1"
226 "net_pktgen": "18:02.3",
230 "traffic_type": "imix1"
233 "net_pktgen": "00:00.0",
237 "traffic_type": "imix1"
240 "net_pktgen": "00:00.0",
244 "traffic_type": "imix1"
247 "net_pktgen": "00:00.0",
251 "traffic_type": "imix1"
254 "net_pktgen": "00:00.0",
258 "traffic_type": "imix1"
267 "net_pktgen": "18:0a.0",
271 "traffic_type": "imix1"
274 "net_pktgen": "18:0a.1",
278 "traffic_type": "imix1"
281 "net_pktgen": "18:0a.2",
285 "traffic_type": "imix1"
288 "net_pktgen": "18:0a.3",
292 "traffic_type": "imix1"
295 "net_pktgen": "00:00.0",
299 "traffic_type": "imix1"
302 "net_pktgen": "00:00.0",
306 "traffic_type": "imix1"
309 "net_pktgen": "00:00.0",
313 "traffic_type": "imix1"
316 "net_pktgen": "00:00.0",
320 "traffic_type": "imix1"
328 "tg__0": "pktgen0-k8syardstick-a3b663c2",
329 "vnf__0": "vnf0us-k8syardstick-a3b663c2",
330 "vnf__1": "vnf0ds-k8syardstick-a3b663c2"
333 "pktgen_values": "/tmp/pktgen_values.yaml",
337 "vcmts_influxdb_ip": "10.80.5.150",
338 "vcmts_influxdb_port": 8086,
339 "vcmtsd_values": "/tmp/vcmtsd_values.yaml",
349 "task_id": "a3b663c2-e616-4777-b6d0-ec2ea7a06f42",
350 "task_path": "samples/vnf_samples/nsut/cmts",
351 "tc": "tc_vcmts_k8s_pktgen",
352 "topology": "k8s_vcmts_topology.yaml",
353 "traffic_profile": "../../traffic_profiles/fixed.yaml",
371 "VNF model": "../../vnf_descriptors/tg_vcmts_tpl.yaml",
374 "local_ip": "192.168.24.150",
376 "network_name": "flannel"
379 "local_ip": "192.168.24.150",
381 "network_name": "xe0"
384 "local_ip": "192.168.24.150",
386 "network_name": "xe1"
389 "ip": "192.168.24.150",
390 "key_filename": "/tmp/yardstick_key-a3b663c2",
391 "member-vnf-index": "1",
392 "name": "pktgen0-k8syardstick-a3b663c2",
393 "private_ip": "192.168.24.150",
412 "vnfd-id-ref": "tg__0"
415 "VNF model": "../../vnf_descriptors/vnf_vcmts_tpl.yaml",
418 "local_ip": "192.168.100.132",
420 "network_name": "flannel"
423 "local_ip": "192.168.100.132",
425 "network_name": "xe0"
428 "local_ip": "192.168.100.132",
430 "network_name": "xe1"
433 "ip": "192.168.100.132",
434 "key_filename": "/tmp/yardstick_key-a3b663c2",
435 "member-vnf-index": "3",
436 "name": "vnf0us-k8syardstick-a3b663c2",
437 "private_ip": "192.168.100.132",
456 "vnfd-id-ref": "vnf__0"
459 "VNF model": "../../vnf_descriptors/vnf_vcmts_tpl.yaml",
462 "local_ip": "192.168.100.134",
464 "network_name": "flannel"
467 "local_ip": "192.168.100.134",
469 "network_name": "xe0"
472 "local_ip": "192.168.100.134",
474 "network_name": "xe1"
477 "ip": "192.168.100.134",
478 "key_filename": "/tmp/yardstick_key-a3b663c2",
479 "member-vnf-index": "4",
480 "name": "vnf0ds-k8syardstick-a3b663c2",
481 "private_ip": "192.168.100.134",
500 "vnfd-id-ref": "vnf__1"
505 PKTGEN_VALUES_PATH = "/tmp/pktgen_values.yaml"
508 "serviceAccount: cmk-serviceaccount\n" \
510 " vcmts_pktgen: vcmts-pktgen:v18.10\n" \
512 " pktgen_replicas: 8\n" \
514 " - pktgen_id: 0\n" \
518 " traffic_type: 'imix2'\n" \
521 " net_pktgen: 8a:02.0\n" \
523 " traffic_type: 'imix2'\n" \
526 " net_pktgen: 8a:02.1\n" \
528 " traffic_type: 'imix2'\n" \
531 " net_pktgen: 8a:02.2\n" \
533 " traffic_type: 'imix2'\n" \
536 " net_pktgen: 8a:02.3\n" \
538 " traffic_type: 'imix2'\n" \
541 " net_pktgen: 8a:02.4\n" \
543 " traffic_type: 'imix2'\n" \
546 " net_pktgen: 8a:02.5\n" \
548 " traffic_type: 'imix2'\n" \
551 " net_pktgen: 8a:02.6\n" \
553 " traffic_type: 'imix2'\n" \
556 " net_pktgen: 8a:02.7\n"
559 vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]
560 self.vcmts_pktgen = tg_vcmts_pktgen.VcmtsPktgen(NAME, vnfd)
561 self.vcmts_pktgen._start_server = mock.Mock(return_value=0)
562 self.vcmts_pktgen.resource_helper = mock.MagicMock()
563 self.vcmts_pktgen.setup_helper = mock.MagicMock()
565 def test___init__(self):
566 self.assertFalse(self.vcmts_pktgen.traffic_finished)
567 self.assertIsNotNone(self.vcmts_pktgen.setup_helper)
568 self.assertIsNotNone(self.vcmts_pktgen.resource_helper)
570 def test_extract_pod_cfg(self):
571 pod_cfg = self.vcmts_pktgen.extract_pod_cfg(self.PKTGEN_POD_VALUES, "0")
572 self.assertIsNotNone(pod_cfg)
573 self.assertEqual(pod_cfg["pktgen_id"], "0")
574 pod_cfg = self.vcmts_pktgen.extract_pod_cfg(self.PKTGEN_POD_VALUES, "4")
575 self.assertIsNone(pod_cfg)
577 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
578 return_value='fake_context')
579 def test_instantiate_missing_pktgen_values_key(self, *args):
580 err_scenario_cfg = copy.deepcopy(self.SCENARIO_CFG)
581 err_scenario_cfg['options'].pop('pktgen_values', None)
582 with self.assertRaises(KeyError):
583 self.vcmts_pktgen.instantiate(err_scenario_cfg, self.CONTEXT_CFG)
585 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
586 return_value='fake_context')
587 def test_instantiate_missing_pktgen_values_file(self, *args):
588 if os.path.isfile(self.PKTGEN_VALUES_PATH):
589 os.remove(self.PKTGEN_VALUES_PATH)
590 err_scenario_cfg = copy.deepcopy(self.SCENARIO_CFG)
591 err_scenario_cfg['options']['pktgen_values'] = self.PKTGEN_VALUES_PATH
592 with self.assertRaises(RuntimeError):
593 self.vcmts_pktgen.instantiate(err_scenario_cfg, self.CONTEXT_CFG)
595 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
596 return_value='fake_context')
597 def test_instantiate_empty_pktgen_values_file(self, *args):
598 yaml_sample = open(self.PKTGEN_VALUES_PATH, 'w')
599 yaml_sample.write("")
602 err_scenario_cfg = copy.deepcopy(self.SCENARIO_CFG)
603 err_scenario_cfg['options']['pktgen_values'] = self.PKTGEN_VALUES_PATH
604 with self.assertRaises(RuntimeError):
605 self.vcmts_pktgen.instantiate(err_scenario_cfg, self.CONTEXT_CFG)
607 if os.path.isfile(self.PKTGEN_VALUES_PATH):
608 os.remove(self.PKTGEN_VALUES_PATH)
610 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
611 return_value='fake_context')
612 def test_instantiate_invalid_pktgen_id(self, *args):
613 yaml_sample = open(self.PKTGEN_VALUES_PATH, 'w')
614 yaml_sample.write(self.PKTGEN_VALUES)
617 err_scenario_cfg = copy.deepcopy(self.SCENARIO_CFG)
618 err_scenario_cfg['options'][NAME]['pktgen_id'] = 12
619 with self.assertRaises(KeyError):
620 self.vcmts_pktgen.instantiate(err_scenario_cfg, self.CONTEXT_CFG)
622 if os.path.isfile(self.PKTGEN_VALUES_PATH):
623 os.remove(self.PKTGEN_VALUES_PATH)
625 @mock.patch.object(ctx_base.Context, 'get_context_from_server',
626 return_value='fake_context')
627 def test_instantiate_all_valid(self, *args):
628 yaml_sample = open(self.PKTGEN_VALUES_PATH, 'w')
629 yaml_sample.write(self.PKTGEN_VALUES)
632 self.vcmts_pktgen.instantiate(self.SCENARIO_CFG, self.CONTEXT_CFG)
633 self.assertIsNotNone(self.vcmts_pktgen.pod_cfg)
634 self.assertEqual(self.vcmts_pktgen.pod_cfg["pktgen_id"], "0")
636 if os.path.isfile(self.PKTGEN_VALUES_PATH):
637 os.remove(self.PKTGEN_VALUES_PATH)
639 def test_run_traffic_failed_connect(self):
640 self.vcmts_pktgen.pktgen_helper = mock.MagicMock()
641 self.vcmts_pktgen.pktgen_helper.connect.return_value = False
642 with self.assertRaises(exceptions.PktgenActionError):
643 self.vcmts_pktgen.run_traffic({})
645 def test_run_traffic_successful_connect(self):
646 self.vcmts_pktgen.pktgen_helper = mock.MagicMock()
647 self.vcmts_pktgen.pktgen_helper.connect.return_value = True
648 self.vcmts_pktgen.pktgen_rate = 8.0
649 self.assertTrue(self.vcmts_pktgen.run_traffic({}))
650 self.vcmts_pktgen.pktgen_helper.connect.assert_called_once()
651 self.vcmts_pktgen.pktgen_helper.send_command.assert_called_with(
652 'pktgen.start("all");')