X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=test%2Ftest_chains.py;h=3cf75cb1b9755182db107844e622b270056a2a11;hb=95f2491ed89ac99b0d8bd006b4a13cbeb1eb96ce;hp=e952eb8b31c5a0147d59e7f0a8e9a544a7455741;hpb=c0ef57f8ec086c07053d529510992c869c30c9d2;p=nfvbench.git diff --git a/test/test_chains.py b/test/test_chains.py index e952eb8..3cf75cb 100644 --- a/test/test_chains.py +++ b/test/test_chains.py @@ -15,13 +15,14 @@ # """Test Chaining functions.""" -from mock_trex import no_op - from mock import MagicMock from mock import patch import pytest +from .mock_trex import no_op + from nfvbench.chain_runner import ChainRunner +from nfvbench.chaining import ChainException from nfvbench.chaining import ChainVnfPort from nfvbench.chaining import InstancePlacer from nfvbench.compute import Compute @@ -37,8 +38,7 @@ from nfvbench.specs import Specs from nfvbench.summarizer import _annotate_chain_stats from nfvbench.traffic_client import TrafficClient from nfvbench.traffic_gen.traffic_base import Latency -from nfvbench.traffic_gen.trex import TRex - +from nfvbench.traffic_gen.trex_gen import TRex # just to get rid of the unused function warning no_op() @@ -49,17 +49,17 @@ def setup_module(module): nfvbench.log.setup(mute_stdout=False) nfvbench.log.set_level(debug=True) -def _get_chain_config(sc=ChainType.PVP, scc=1, shared_net=True): +def _get_chain_config(sc=ChainType.PVP, scc=1, shared_net=True, rate='1Mpps'): config, _ = load_default_config() config.vm_image_file = 'nfvbenchvm-0.0.qcow2' config.service_chain_count = scc config.service_chain = sc config.service_chain_shared_net = shared_net - config.rate = '1Mpps' + config.rate = rate config['traffic_generator']['generator_profile'] = [{'name': 'dummy', 'tool': 'dummy', 'ip': '127.0.0.1', - 'intf_speed': None, + 'intf_speed': '10Gbps', 'interfaces': [{'port': 0, 'pci': '0.0'}, {'port': 1, 'pci': '0.0'}]}] config.ndr_run = False @@ -69,6 +69,9 @@ def _get_chain_config(sc=ChainType.PVP, scc=1, shared_net=True): config.duration_sec = 2 config.interval_sec = 1 config.openrc_file = "dummy.rc" + config.no_flow_stats = False + config.no_latency_stats = False + config.no_latency_streams = False return config def test_chain_runner_ext_no_openstack(): @@ -78,11 +81,31 @@ def test_chain_runner_ext_no_openstack(): config.vlans = [100, 200] config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00'] config['traffic_generator']['mac_addrs_right'] = ['00:00:00:00:01:00'] - runner = ChainRunner(config, None, specs, BasicFactory()) - runner.close() + + for shared_net in [True, False]: + for no_arp in [False, True]: + for vlan_tag in [False, True]: + for scc in [1, 2]: + config = _get_chain_config(ChainType.EXT, scc, shared_net) + config.no_arp = no_arp + if no_arp: + # If EXT and no arp, the config must provide mac (1 pair per chain) + config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00'] * scc + config['traffic_generator']['mac_addrs_right'] = ['00:00:00:00:01:00'] * scc + config['vlan_tagging'] = vlan_tag + if vlan_tag: + # these are the 2 valid forms of vlan ranges + if scc == 1: + config.vlans = [100, 200] + else: + config.vlans = [[port * 100 + index for index in range(scc)] + for port in range(2)] + runner = ChainRunner(config, None, specs, BasicFactory()) + runner.close() + def _mock_find_image(self, image_name): - return True + return MagicMock() @patch.object(Compute, 'find_image', _mock_find_image) @patch('nfvbench.chaining.Client') @@ -99,18 +122,87 @@ def _test_pvp_chain(config, cred, mock_glance, mock_neutron, mock_client): openstack_spec = OpenStackSpec() specs.set_openstack_spec(openstack_spec) cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = True runner = ChainRunner(config, cred, specs, BasicFactory()) runner.close() def test_pvp_chain_runner(): """Test PVP chain runner.""" cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = True for shared_net in [True, False]: for sc in [ChainType.PVP]: for scc in [1, 2]: config = _get_chain_config(sc, scc, shared_net) _test_pvp_chain(config, cred) + +# Test not admin exception with empty value is raised +@patch.object(Compute, 'find_image', _mock_find_image) +@patch('nfvbench.chaining.Client') +@patch('nfvbench.chaining.neutronclient') +@patch('nfvbench.chaining.glanceclient') +def _test_pvp_chain_no_admin_no_config_values(config, cred, mock_glance, mock_neutron, mock_client): + # instance = self.novaclient.servers.create(name=vmname,...) + # instance.status == 'ACTIVE' + mock_client.return_value.servers.create.return_value.status = 'ACTIVE' + netw = {'id': 0, 'provider:network_type': 'vlan', 'provider:segmentation_id': 1000} + mock_neutron.Client.return_value.create_network.return_value = {'network': netw} + mock_neutron.Client.return_value.list_networks.return_value = {'networks': None} + specs = Specs() + openstack_spec = OpenStackSpec() + specs.set_openstack_spec(openstack_spec) + runner = ChainRunner(config, cred, specs, BasicFactory()) + runner.close() + +def test_pvp_chain_runner_no_admin_no_config_values(): + """Test PVP/mock chain runner.""" + cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = False + for shared_net in [True, False]: + for sc in [ChainType.PVP]: + for scc in [1, 2]: + config = _get_chain_config(sc, scc, shared_net) + with pytest.raises(ChainException): + _test_pvp_chain_no_admin_no_config_values(config, cred) + +# Test not admin with mandatory parameters values in config file +@patch.object(Compute, 'find_image', _mock_find_image) +@patch('nfvbench.chaining.Client') +@patch('nfvbench.chaining.neutronclient') +@patch('nfvbench.chaining.glanceclient') +def _test_pvp_chain_no_admin_config_values(config, cred, mock_glance, mock_neutron, mock_client): + # instance = self.novaclient.servers.create(name=vmname,...) + # instance.status == 'ACTIVE' + mock_client.return_value.servers.create.return_value.status = 'ACTIVE' + netw = {'id': 0, 'provider:network_type': 'vlan', 'provider:segmentation_id': 1000} + mock_neutron.Client.return_value.create_network.return_value = {'network': netw} + mock_neutron.Client.return_value.list_networks.return_value = {'networks': None} + specs = Specs() + openstack_spec = OpenStackSpec() + specs.set_openstack_spec(openstack_spec) + runner = ChainRunner(config, cred, specs, BasicFactory()) + runner.close() + +def test_pvp_chain_runner_no_admin_config_values(): + """Test PVP chain runner.""" + cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = False + for shared_net in [True, False]: + for sc in [ChainType.PVP]: + for scc in [1, 2]: + config = _get_chain_config(sc, scc, shared_net) + config.availability_zone = "az" + config.hypervisor_hostname = "server" + # these are the 2 valid forms of vlan ranges + if scc == 1: + config.vlans = [100, 200] + else: + config.vlans = [[port * 100 + index for index in range(scc)] + for port in range(2)] + _test_pvp_chain_no_admin_config_values(config, cred) + + @patch.object(Compute, 'find_image', _mock_find_image) @patch('nfvbench.chaining.Client') @patch('nfvbench.chaining.neutronclient') @@ -125,17 +217,26 @@ def _test_ext_chain(config, cred, mock_glance, mock_neutron, mock_client): openstack_spec = OpenStackSpec() specs.set_openstack_spec(openstack_spec) cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = True runner = ChainRunner(config, cred, specs, BasicFactory()) runner.close() def test_ext_chain_runner(): - """Test openstack+EXT chain runner.""" + """Test openstack+EXT chain runner. + + Test 8 combinations of configs: + shared/not shared net x arp/no_arp x scc 1 or 2 + """ cred = MagicMock(spec=nfvbench.credentials.Credentials) + cred.is_admin = True for shared_net in [True, False]: for no_arp in [False, True]: for scc in [1, 2]: config = _get_chain_config(ChainType.EXT, scc, shared_net) config.no_arp = no_arp + # this time use a tuple of network names + config['external_networks']['left'] = ('ext-lnet00', 'ext-lnet01') + config['external_networks']['right'] = ('ext-rnet00', 'ext-rnet01') if no_arp: # If EXT and no arp, the config must provide mac addresses (1 pair per chain) config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00'] * scc @@ -148,6 +249,9 @@ def _check_nfvbench_openstack(sc=ChainType.PVP, l2_loopback=False): if l2_loopback: config.l2_loopback = True config.vlans = [[100], [200]] + if sc == ChainType.EXT: + config['external_networks']['left'] = 'ext-lnet' + config['external_networks']['right'] = 'ext-rnet' factory = BasicFactory() config_plugin = factory.get_config_plugin_class()(config) config = config_plugin.get_config() @@ -155,7 +259,7 @@ def _check_nfvbench_openstack(sc=ChainType.PVP, l2_loopback=False): nfvb = NFVBench(config, openstack_spec, config_plugin, factory) res = nfvb.run({}, 'pytest') if res['status'] != 'OK': - print res + print(res) assert res['status'] == 'OK' @@ -169,6 +273,7 @@ def _mock_get_mac(dummy): @patch.object(Compute, 'find_image', _mock_find_image) @patch.object(TrafficClient, 'skip_sleep', lambda x: True) @patch.object(ChainVnfPort, 'get_mac', _mock_get_mac) +@patch.object(TrafficClient, 'is_udp', lambda x, y: True) @patch('nfvbench.chaining.Client') @patch('nfvbench.chaining.neutronclient') @patch('nfvbench.chaining.glanceclient') @@ -185,6 +290,7 @@ def test_nfvbench_run(mock_cred, mock_glance, mock_neutron, mock_client): @patch.object(Compute, 'find_image', _mock_find_image) @patch.object(TrafficClient, 'skip_sleep', lambda x: True) +@patch.object(TrafficClient, 'is_udp', lambda x, y: True) @patch('nfvbench.chaining.Client') @patch('nfvbench.chaining.neutronclient') @patch('nfvbench.chaining.glanceclient') @@ -200,6 +306,7 @@ def test_nfvbench_ext_arp(mock_cred, mock_glance, mock_neutron, mock_client): @patch.object(Compute, 'find_image', _mock_find_image) @patch.object(TrafficClient, 'skip_sleep', lambda x: True) +@patch.object(TrafficClient, 'is_udp', lambda x, y: True) @patch('nfvbench.chaining.Client') @patch('nfvbench.chaining.neutronclient') @patch('nfvbench.chaining.glanceclient') @@ -298,7 +405,7 @@ def test_placer_user_az(): def test_placer_user_hyp(): """Test placement when user provides a hypervisor.""" - check_placer(None, 'comp1', 'comp1') + check_placer(None, 'comp1', ':comp1') check_placer('nova', 'comp1', 'nova:comp1', resolved=True) check_placer(None, 'nova:comp1', 'nova:comp1', resolved=True) # hyp overrides az @@ -332,7 +439,11 @@ CHAIN_STATS = [{0: {'packets': [2000054, 1999996, 1999996]}}, 'total': {'packets': [30000004, 30000004, 30000004, 30000004, 30000004, 30000004]}}, {0: {'packets': [15000002, '', 14000002, 14000002, '', 13000002]}, 1: {'packets': [15000002, '', 15000002, 15000002, '', 15000002]}, - 'total': {'packets': [30000004, 29000004, 29000004, 29000004, 29000004, 28000004]}}] + 'total': {'packets': [30000004, 29000004, 29000004, 29000004, 29000004, 28000004]}}, + # example with non-available rx count in last position + {0: {'packets': [2000054, 1999996, None]}, + 1: {'packets': [2000054, 2000054, None]}, + 'total': {'packets': [4000108, 4000050, 4000050]}}] XP_CHAIN_STATS = [{0: {'packets': [2000054, '-58 (-0.0029%)', 1999996]}}, {0: {'packets': [2000054, '-58 (-0.0029%)', 1999996]}, 1: {'packets': [2000054, '=>', 2000054]}, @@ -347,7 +458,10 @@ XP_CHAIN_STATS = [{0: {'packets': [2000054, '-58 (-0.0029%)', 1999996]}}, '-1,000,000 (-7.1429%)']}, 1: {'packets': [15000002, '', '=>', '=>', '', 15000002]}, 'total': {'packets': [30000004, '-1,000,000 (-3.3333%)', '=>', '=>', '=>', - '-1,000,000 (-3.4483%)']}}] + '-1,000,000 (-3.4483%)']}}, + {0: {'packets': [2000054, '-58 (-0.0029%)', 'n/a']}, + 1: {'packets': [2000054, '=>', 'n/a']}, + 'total': {'packets': [4000108, '-58 (-0.0014%)', 4000050]}}] def test_summarizer(): @@ -355,3 +469,28 @@ def test_summarizer(): for stats, exp_stats in zip(CHAIN_STATS, XP_CHAIN_STATS): _annotate_chain_stats(stats) assert stats == exp_stats + +@patch.object(TrafficClient, 'skip_sleep', lambda x: True) +@patch.object(TrafficClient, 'is_udp', lambda x, y: True) +def test_fixed_rate_no_openstack(): + """Test FIxed Rate run - no openstack.""" + config = _get_chain_config(ChainType.EXT, 1, True, rate='100%') + specs = Specs() + config.vlans = [100, 200] + config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00'] + config['traffic_generator']['mac_addrs_right'] = ['00:00:00:00:01:00'] + config.no_arp = True + config['vlan_tagging'] = True + config['traffic'] = {'profile': 'profile_64', + 'bidirectional': True} + config['traffic_profile'] = [{'name': 'profile_64', 'l2frame_size': ['64']}] + + runner = ChainRunner(config, None, specs, BasicFactory()) + tg = runner.traffic_client.gen + + tg.set_response_curve(lr_dr=0, ndr=100, max_actual_tx=50, max_11_tx=50) + # tx packets should be 50% at requested 50% line rate or higher for 64B and no drops... + results = runner.run() + assert results + # pprint.pprint(results['EXT']['result']['result']['64']) + runner.close()