Add "duration" parameter to test case definition
[yardstick.git] / yardstick / tests / unit / benchmark / scenarios / networking / test_vnf_generic.py
index fb55b5e..bb1a7aa 100644 (file)
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
 # Copyright (c) 2016-2017 Intel Corporation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
-
-# Unittest for yardstick.benchmark.scenarios.networking.test_vnf_generic
-
-from __future__ import absolute_import
 
+from copy import deepcopy
 import os
-import errno
-import unittest
-import mock
+import sys
 
-from copy import deepcopy
+import mock
+import unittest
 
-from yardstick.tests.unit import STL_MOCKS
-from yardstick.benchmark.scenarios.networking.vnf_generic import \
-    SshManager, NetworkServiceTestCase, IncorrectConfig, \
-    open_relative_file
+from yardstick import tests
+from yardstick.common import exceptions
+from yardstick.common import utils
 from yardstick.network_services.collector.subscriber import Collector
-from yardstick.network_services.vnf_generic.vnf.base import \
-    GenericTrafficGen, GenericVNF
+from yardstick.network_services.traffic_profile import base
+from yardstick.network_services.vnf_generic import vnfdgen
+from yardstick.network_services.vnf_generic.vnf.base import GenericTrafficGen
+from yardstick.network_services.vnf_generic.vnf.base import GenericVNF
+
+
+stl_patch = mock.patch.dict(sys.modules, tests.STL_MOCKS)
+stl_patch.start()
 
+if stl_patch:
+    from yardstick.benchmark.scenarios.networking import vnf_generic
 
 # pylint: disable=unused-argument
 # disable this for now because I keep forgetting mock patch arg ordering
@@ -317,6 +317,7 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             'task_id': 'a70bdf4a-8e67-47a3-9dc1-273c14506eb7',
             'tc': 'tc_ipv4_1Mflow_64B_packetsize',
             'traffic_profile': 'ipv4_throughput_vpe.yaml',
+            'extra_args': {'arg1': 'value1', 'arg2': 'value2'},
             'type': 'ISB',
             'tc_options': {
                 'rfc2544': {
@@ -345,25 +346,16 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             },
         }
 
-        self.s = NetworkServiceTestCase(self.scenario_cfg, self.context_cfg)
+        self.s = vnf_generic.NetworkServiceTestCase(self.scenario_cfg,
+                                                    self.context_cfg)
 
     def _get_file_abspath(self, filename):
         curr_path = os.path.dirname(os.path.abspath(__file__))
         file_path = os.path.join(curr_path, filename)
         return file_path
 
-    def test_ssh_manager(self):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
-            ssh.from_node.return_value = ssh_mock
-            for _, node_dict in self.context_cfg["nodes"].items():
-                with SshManager(node_dict) as conn:
-                    self.assertIsNotNone(conn)
-
     def test___init__(self):
-        assert self.topology
+        self.assertIsNotNone(self.topology)
 
     def test__get_ip_flow_range_string(self):
         self.scenario_cfg["traffic_options"]["flow"] = \
@@ -415,7 +407,10 @@ class TestNetworkServiceTestCase(unittest.TestCase):
                 'public_ip': ['1.1.1.1'],
             },
         }
-
+        # NOTE(ralonsoh): check the expected output. This test could be
+        # incorrect
+        # result = {'flow': {'dst_ip0': '152.16.40.2-152.16.40.254',
+        #                    'src_ip0': '152.16.100.2-152.16.100.254'}}
         self.assertEqual({'flow': {}}, self.s._get_traffic_flow())
 
     def test___get_traffic_flow_error(self):
@@ -425,16 +420,16 @@ class TestNetworkServiceTestCase(unittest.TestCase):
 
     def test_get_vnf_imp(self):
         vnfd = COMPLETE_TREX_VNFD['vnfd:vnfd-catalog']['vnfd'][0]['class-name']
-        with mock.patch.dict("sys.modules", STL_MOCKS):
+        with mock.patch.dict(sys.modules, tests.STL_MOCKS):
             self.assertIsNotNone(self.s.get_vnf_impl(vnfd))
 
-            with self.assertRaises(IncorrectConfig) as raised:
-                self.s.get_vnf_impl('NonExistentClass')
+        with self.assertRaises(exceptions.IncorrectConfig) as raised:
+            self.s.get_vnf_impl('NonExistentClass')
 
-            exc_str = str(raised.exception)
-            print(exc_str)
-            self.assertIn('No implementation', exc_str)
-            self.assertIn('found in', exc_str)
+        exc_str = str(raised.exception)
+        print(exc_str)
+        self.assertIn('No implementation', exc_str)
+        self.assertIn('found in', exc_str)
 
     def test_load_vnf_models_invalid(self):
         self.context_cfg["nodes"]['tg__1']['VNF model'] = \
@@ -456,40 +451,38 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             self.s.load_vnf_models(self.scenario_cfg, self.context_cfg))
 
     def test_map_topology_to_infrastructure(self):
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
-            ssh.from_node.return_value = ssh_mock
-            self.s.map_topology_to_infrastructure()
+        self.s.map_topology_to_infrastructure()
 
         nodes = self.context_cfg["nodes"]
-        self.assertEqual(
-            "../../vnf_descriptors/tg_rfc2544_tpl.yaml", nodes['tg__1']['VNF model'])
-        self.assertEqual("../../vnf_descriptors/vpe_vnf.yaml",
+        self.assertEqual('../../vnf_descriptors/tg_rfc2544_tpl.yaml',
+                         nodes['tg__1']['VNF model'])
+        self.assertEqual('../../vnf_descriptors/vpe_vnf.yaml',
                          nodes['vnf__1']['VNF model'])
 
     def test_map_topology_to_infrastructure_insufficient_nodes(self):
-        del self.context_cfg['nodes']['vnf__1']
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(1, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
-            ssh.from_node.return_value = ssh_mock
+        cfg = deepcopy(self.context_cfg)
+        del cfg['nodes']['vnf__1']
 
-            with self.assertRaises(IncorrectConfig):
+        cfg_patch = mock.patch.object(self.s, 'context_cfg', cfg)
+        with cfg_patch:
+            with self.assertRaises(exceptions.IncorrectConfig):
                 self.s.map_topology_to_infrastructure()
 
     def test_map_topology_to_infrastructure_config_invalid(self):
-        cfg = dict(self.context_cfg)
+        ssh_mock = mock.Mock()
+        ssh_mock.execute.return_value = 0, SYS_CLASS_NET + IP_ADDR_SHOW, ""
+
+        cfg = deepcopy(self.s.context_cfg)
+
+        # delete all, we don't know which will come first
         del cfg['nodes']['vnf__1']['interfaces']['xe0']['local_mac']
-        with mock.patch("yardstick.ssh.SSH") as ssh:
-            ssh_mock = mock.Mock(autospec=ssh.SSH)
-            ssh_mock.execute = \
-                mock.Mock(return_value=(0, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
-            ssh.from_node.return_value = ssh_mock
+        del cfg['nodes']['vnf__1']['interfaces']['xe1']['local_mac']
+        del cfg['nodes']['tg__1']['interfaces']['xe0']['local_mac']
+        del cfg['nodes']['tg__1']['interfaces']['xe1']['local_mac']
 
-            with self.assertRaises(IncorrectConfig):
+        config_patch = mock.patch.object(self.s, 'context_cfg', cfg)
+        with config_patch:
+            with self.assertRaises(exceptions.IncorrectConfig):
                 self.s.map_topology_to_infrastructure()
 
     def test__resolve_topology_invalid_config(self):
@@ -503,10 +496,8 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             for interface in self.tg__1['interfaces'].values():
                 del interface['local_mac']
 
-            with mock.patch(
-                    "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"):
-                with self.assertRaises(IncorrectConfig) as raised:
-                    self.s._resolve_topology()
+            with self.assertRaises(exceptions.IncorrectConfig) as raised:
+                self.s._resolve_topology()
 
             self.assertIn('not found', str(raised.exception))
 
@@ -518,10 +509,8 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             self.s.topology["vld"][0]['vnfd-connection-point-ref'].append(
                 self.s.topology["vld"][0]['vnfd-connection-point-ref'][0])
 
-            with mock.patch(
-                    "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"):
-                with self.assertRaises(IncorrectConfig) as raised:
-                    self.s._resolve_topology()
+            with self.assertRaises(exceptions.IncorrectConfig) as raised:
+                self.s._resolve_topology()
 
             self.assertIn('wrong endpoint count', str(raised.exception))
 
@@ -529,10 +518,8 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             self.s.topology["vld"][0]['vnfd-connection-point-ref'] = \
                 self.s.topology["vld"][0]['vnfd-connection-point-ref'][:1]
 
-            with mock.patch(
-                    "yardstick.benchmark.scenarios.networking.vnf_generic.LOG"):
-                with self.assertRaises(IncorrectConfig) as raised:
-                    self.s._resolve_topology()
+            with self.assertRaises(exceptions.IncorrectConfig) as raised:
+                self.s._resolve_topology()
 
             self.assertIn('wrong endpoint count', str(raised.exception))
 
@@ -578,7 +565,7 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             self.s.load_vnf_models = mock.Mock(return_value=self.s.vnfs)
             self.s._fill_traffic_profile = \
                 mock.Mock(return_value=TRAFFIC_PROFILE)
-            self.assertEqual(None, self.s.setup())
+            self.assertIsNone(self.s.setup())
 
     def test_setup_exception(self):
         with mock.patch("yardstick.ssh.SSH") as ssh:
@@ -625,15 +612,49 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             self.assertEqual({'imix': {'64B': 100}},
                              self.s._get_traffic_imix())
 
-    def test__fill_traffic_profile(self):
-        with mock.patch.dict("sys.modules", STL_MOCKS):
-            self.scenario_cfg["traffic_profile"] = \
-                self._get_file_abspath("ipv4_throughput_vpe.yaml")
-            self.scenario_cfg["traffic_options"]["flow"] = \
-                self._get_file_abspath("ipv4_1flow_Packets_vpe.yaml")
-            self.scenario_cfg["traffic_options"]["imix"] = \
-                self._get_file_abspath("imix_voice.yaml")
-            self.assertIsNotNone(self.s._fill_traffic_profile())
+    @mock.patch.object(base.TrafficProfile, 'get')
+    @mock.patch.object(vnfdgen, 'generate_vnfd')
+    def test__fill_traffic_profile(self, mock_generate, mock_tprofile_get):
+        fake_tprofile = mock.Mock()
+        fake_vnfd = mock.Mock()
+        with mock.patch.object(self.s, '_get_traffic_profile',
+                               return_value=fake_tprofile) as mock_get_tp:
+            mock_generate.return_value = fake_vnfd
+            self.s._fill_traffic_profile()
+            mock_get_tp.assert_called_once()
+            mock_generate.assert_called_once_with(
+                fake_tprofile,
+                {'downlink': {},
+                 'extra_args': {'arg1': 'value1', 'arg2': 'value2'},
+                 'flow': {'flow': {}},
+                 'imix': {'imix': {'64B': 100}},
+                 'uplink': {},
+                 'duration': 30}
+            )
+            mock_tprofile_get.assert_called_once_with(fake_vnfd)
+
+    @mock.patch.object(utils, 'open_relative_file')
+    def test__get_topology(self, mock_open_path):
+        self.s.scenario_cfg['topology'] = 'fake_topology'
+        self.s.scenario_cfg['task_path'] = 'fake_path'
+        mock_open_path.side_effect = mock.mock_open(read_data='fake_data')
+        self.assertEqual('fake_data', self.s._get_topology())
+        mock_open_path.assert_called_once_with('fake_topology', 'fake_path')
+
+    @mock.patch.object(vnfdgen, 'generate_vnfd')
+    def test__render_topology(self, mock_generate):
+        fake_topology = 'fake_topology'
+        mock_generate.return_value = {'nsd:nsd-catalog': {'nsd': ['fake_nsd']}}
+        with mock.patch.object(self.s, '_get_topology',
+                               return_value=fake_topology) as mock_get_topology:
+            self.s._render_topology()
+            mock_get_topology.assert_called_once()
+
+        mock_generate.assert_called_once_with(
+            fake_topology,
+            {'extra_args': {'arg1': 'value1', 'arg2': 'value2'}}
+        )
+        self.assertEqual(self.s.topology, 'fake_nsd')
 
     def test_teardown(self):
         vnf = mock.Mock(autospec=GenericVNF)
@@ -658,141 +679,3 @@ class TestNetworkServiceTestCase(unittest.TestCase):
             mock.Mock(return_value=True)
         with self.assertRaises(RuntimeError):
             self.s.teardown()
-
-    SAMPLE_NETDEVS = {
-        'enp11s0': {
-            'address': '0a:de:ad:be:ef:f5',
-            'device': '0x1533',
-            'driver': 'igb',
-            'ifindex': '2',
-            'interface_name': 'enp11s0',
-            'operstate': 'down',
-            'pci_bus_id': '0000:0b:00.0',
-            'subsystem_device': '0x1533',
-            'subsystem_vendor': '0x15d9',
-            'vendor': '0x8086'
-        },
-        'lan': {
-            'address': '0a:de:ad:be:ef:f4',
-            'device': '0x153a',
-            'driver': 'e1000e',
-            'ifindex': '3',
-            'interface_name': 'lan',
-            'operstate': 'up',
-            'pci_bus_id': '0000:00:19.0',
-            'subsystem_device': '0x153a',
-            'subsystem_vendor': '0x15d9',
-            'vendor': '0x8086'
-        }
-    }
-
-    SAMPLE_VM_NETDEVS = {
-        'eth1': {
-            'address': 'fa:de:ad:be:ef:5b',
-            'device': '0x0001',
-            'driver': 'virtio_net',
-            'ifindex': '3',
-            'interface_name': 'eth1',
-            'operstate': 'down',
-            'pci_bus_id': '0000:00:04.0',
-            'vendor': '0x1af4'
-        }
-    }
-
-    def test_parse_netdev_info(self):
-        output = """\
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/ifindex:2
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/address:0a:de:ad:be:ef:f5
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/operstate:down
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/vendor:0x8086
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/device:0x1533
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/subsystem_vendor:0x15d9
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/device/subsystem_device:0x1533
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/driver:igb
-/sys/devices/pci0000:00/0000:00:1c.3/0000:0b:00.0/net/enp11s0/pci_bus_id:0000:0b:00.0
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/ifindex:3
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/address:0a:de:ad:be:ef:f4
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/operstate:up
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/vendor:0x8086
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/device:0x153a
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/subsystem_vendor:0x15d9
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/device/subsystem_device:0x153a
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/driver:e1000e
-/sys/devices/pci0000:00/0000:00:19.0/net/lan/pci_bus_id:0000:00:19.0
-"""
-        res = NetworkServiceTestCase.parse_netdev_info(output)
-        assert res == self.SAMPLE_NETDEVS
-
-    def test_parse_netdev_info_virtio(self):
-        output = """\
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/ifindex:3
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/address:fa:de:ad:be:ef:5b
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/operstate:down
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/device/vendor:0x1af4
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/device/device:0x0001
-/sys/devices/pci0000:00/0000:00:04.0/virtio1/net/eth1/driver:virtio_net
-"""
-        res = NetworkServiceTestCase.parse_netdev_info(output)
-        assert res == self.SAMPLE_VM_NETDEVS
-
-    def test_probe_missing_values(self):
-        netdevs = self.SAMPLE_NETDEVS.copy()
-        network = {'local_mac': '0a:de:ad:be:ef:f5'}
-        NetworkServiceTestCase._probe_missing_values(netdevs, network)
-        assert network['vpci'] == '0000:0b:00.0'
-
-        network = {'local_mac': '0a:de:ad:be:ef:f4'}
-        NetworkServiceTestCase._probe_missing_values(netdevs, network)
-        assert network['vpci'] == '0000:00:19.0'
-
-    # TODO: Split this into several tests, for different IOError sub-types
-    def test_open_relative_path(self):
-        mock_open = mock.mock_open()
-        mock_open_result = mock_open()
-        mock_open_call_count = 1  # initial call to get result
-
-        module_name = \
-            'yardstick.benchmark.scenarios.networking.vnf_generic.open'
-
-        # test
-        with mock.patch(module_name, mock_open, create=True):
-            self.assertEqual(open_relative_file(
-                'foo', 'bar'), mock_open_result)
-
-            mock_open_call_count += 1  # one more call expected
-            self.assertEqual(mock_open.call_count, mock_open_call_count)
-            self.assertIn('foo', mock_open.call_args_list[-1][0][0])
-            self.assertNotIn('bar', mock_open.call_args_list[-1][0][0])
-
-            def open_effect(*args, **kwargs):
-                if kwargs.get('name', args[0]) == os.path.join('bar', 'foo'):
-                    return mock_open_result
-                raise IOError(errno.ENOENT, 'not found')
-
-            mock_open.side_effect = open_effect
-            self.assertEqual(open_relative_file(
-                'foo', 'bar'), mock_open_result)
-
-            mock_open_call_count += 2  # two more calls expected
-            self.assertEqual(mock_open.call_count, mock_open_call_count)
-            self.assertIn('foo', mock_open.call_args_list[-1][0][0])
-            self.assertIn('bar', mock_open.call_args_list[-1][0][0])
-
-            # test an IOError of type ENOENT
-            mock_open.side_effect = IOError(errno.ENOENT, 'not found')
-            with self.assertRaises(IOError):
-                # the second call still raises
-                open_relative_file('foo', 'bar')
-
-            mock_open_call_count += 2  # two more calls expected
-            self.assertEqual(mock_open.call_count, mock_open_call_count)
-            self.assertIn('foo', mock_open.call_args_list[-1][0][0])
-            self.assertIn('bar', mock_open.call_args_list[-1][0][0])
-
-            # test an IOError other than ENOENT
-            mock_open.side_effect = IOError(errno.EBUSY, 'busy')
-            with self.assertRaises(IOError):
-                open_relative_file('foo', 'bar')
-
-            mock_open_call_count += 1  # one more call expected
-            self.assertEqual(mock_open.call_count, mock_open_call_count)