2 # Copyright 2016 Cisco Systems, Inc. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
17 from keystoneauth1.exceptions import HTTPClientError
18 from mock import patch
21 from .mock_trex import no_op
26 from attrdict import AttrDict
27 from nfvbench.config import config_loads
28 from nfvbench.credentials import Credentials
29 from nfvbench.fluentd import FluentLogHandler
31 import nfvbench.nfvbench
32 from nfvbench.traffic_client import Device
33 from nfvbench.traffic_client import GeneratorConfig
34 from nfvbench.traffic_client import IpBlock
35 from nfvbench.traffic_client import TrafficClient
36 from nfvbench.traffic_client import TrafficClientException
37 from nfvbench.traffic_gen import traffic_utils
38 from nfvbench import utils
40 # just to get rid of the unused function warning
43 def setup_module(module):
45 nfvbench.log.setup(mute_stdout=True)
47 # =========================================================================
48 # Traffic client tests
49 # =========================================================================
51 def test_parse_rate_str():
52 parse_rate_str = traffic_utils.parse_rate_str
54 assert parse_rate_str('100%') == {'rate_percent': '100.0'}
55 assert parse_rate_str('37.5%') == {'rate_percent': '37.5'}
56 assert parse_rate_str('100%') == {'rate_percent': '100.0'}
57 assert parse_rate_str('60pps') == {'rate_pps': '60'}
58 assert parse_rate_str('60kpps') == {'rate_pps': '60000'}
59 assert parse_rate_str('6Mpps') == {'rate_pps': '6000000'}
60 assert parse_rate_str('6gpps') == {'rate_pps': '6000000000'}
61 assert parse_rate_str('80bps') == {'rate_bps': '80'}
62 assert parse_rate_str('80bps') == {'rate_bps': '80'}
63 assert parse_rate_str('80kbps') == {'rate_bps': '80000'}
64 assert parse_rate_str('80kBps') == {'rate_bps': '640000'}
65 assert parse_rate_str('80Mbps') == {'rate_bps': '80000000'}
66 assert parse_rate_str('80 MBps') == {'rate_bps': '640000000'}
67 assert parse_rate_str('80Gbps') == {'rate_bps': '80000000000'}
68 except Exception as exc:
69 assert False, exc.message
71 def should_raise_error(str):
80 assert should_raise_error('101')
81 assert should_raise_error('201%')
82 assert should_raise_error('10Kbps')
83 assert should_raise_error('0kbps')
84 assert should_raise_error('0pps')
85 assert should_raise_error('-1bps')
88 def test_rate_conversion():
89 assert traffic_utils.load_to_bps(50, 10000000000) == pytest.approx(5000000000.0)
90 assert traffic_utils.load_to_bps(37, 10000000000) == pytest.approx(3700000000.0)
91 assert traffic_utils.load_to_bps(100, 10000000000) == pytest.approx(10000000000.0)
93 assert traffic_utils.bps_to_load(5000000000.0, 10000000000) == pytest.approx(50.0)
94 assert traffic_utils.bps_to_load(3700000000.0, 10000000000) == pytest.approx(37.0)
95 assert traffic_utils.bps_to_load(10000000000.0, 10000000000) == pytest.approx(100.0)
97 assert traffic_utils.bps_to_pps(500000, 64) == pytest.approx(744.047619048)
98 assert traffic_utils.bps_to_pps(388888, 1518) == pytest.approx(31.6066319896)
99 assert traffic_utils.bps_to_pps(9298322222, 340.3) == pytest.approx(3225895.85831)
101 assert traffic_utils.pps_to_bps(744.047619048, 64) == pytest.approx(500000)
102 assert traffic_utils.pps_to_bps(31.6066319896, 1518) == pytest.approx(388888)
103 assert traffic_utils.pps_to_bps(3225895.85831, 340.3) == pytest.approx(9298322222)
106 # pps at 10Gbps line rate for 64 byte frames
107 LR_64B_PPS = 14880952
108 LR_1518B_PPS = 812743
110 def assert_equivalence(reference, value, allowance_pct=1):
111 """Assert if a value is equivalent to a reference value with given margin.
113 :param float reference: reference value to compare to
114 :param float value: value to compare to reference
115 :param float allowance_pct: max allowed percentage of margin
116 0 : requires exact match
117 1 : must be equal within 1% of the reference value
124 assert abs(value - reference) * 100 / reference <= allowance_pct
126 def test_load_from_rate():
127 assert traffic_utils.get_load_from_rate('100%') == 100
128 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_64B_PPS) + 'pps'))
129 assert_equivalence(50, traffic_utils.get_load_from_rate(str(LR_64B_PPS / 2) + 'pps'))
130 assert_equivalence(100, traffic_utils.get_load_from_rate('10Gbps'))
131 assert_equivalence(50, traffic_utils.get_load_from_rate('5000Mbps'))
132 assert_equivalence(1, traffic_utils.get_load_from_rate('100Mbps'))
133 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_1518B_PPS) + 'pps',
134 avg_frame_size=1518))
135 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_1518B_PPS * 2) + 'pps',
139 # =========================================================================
141 # =========================================================================
143 def test_no_credentials():
144 with patch.object(openstack, 'connect') as mock:
145 cred = Credentials('/completely/wrong/path/openrc', None, None, False)
147 # shouldn't get valid data unless user set environment variables
151 mock.assert_not_called()
154 def test_clouds_file_credentials():
155 with patch.object(openstack, 'connect') as mock:
156 Credentials(None, 'openstack', None, False)
157 mock.assert_called_once()
160 @patch('nfvbench.nfvbench.credentials')
161 def test_is_not_admin(mock_session):
162 mock_session.Session.return_value.get.return_value.raiseError.side_effect = HTTPClientError
163 cred = Credentials(None, 'openstack', None, False)
171 with patch.object(openstack, 'connect'):
172 cred = Credentials(None, 'openstack', None, False)
180 ipb = IpBlock('10.0.0.0', '0.0.0.1', 256)
181 assert ipb.get_ip() == '10.0.0.0'
182 assert ipb.get_ip(255) == '10.0.0.255'
183 with pytest.raises(IndexError):
185 ipb = IpBlock('10.0.0.0', '0.0.0.1', 1)
186 assert ipb.get_ip() == '10.0.0.0'
187 with pytest.raises(IndexError):
190 ipb = IpBlock('10.0.0.0', '0.0.0.2', 256)
191 assert ipb.get_ip() == '10.0.0.0'
192 assert ipb.get_ip(1) == '10.0.0.2'
193 assert ipb.get_ip(127) == '10.0.0.254'
194 assert ipb.get_ip(128) == '10.0.1.0'
195 with pytest.raises(IndexError):
198 # verify with step larger than 1
199 ipb = IpBlock('10.0.0.0', '0.0.0.2', 256)
200 assert ipb.get_ip() == '10.0.0.0'
201 assert ipb.get_ip(1) == '10.0.0.2'
202 assert ipb.get_ip(128) == '10.0.1.0'
203 assert ipb.get_ip(255) == '10.0.1.254'
204 with pytest.raises(IndexError):
207 ipb = IpBlock('10.0.0.0', '0.0.0.2', 128)
208 assert ipb.get_ip() == '10.0.0.0'
209 assert ipb.get_ip(1) == '10.0.0.2'
210 assert ipb.get_ip(127) == '10.0.0.254'
211 with pytest.raises(IndexError):
214 ipb = IpBlock('10.0.0.0', '0.0.0.4', 64)
215 assert ipb.get_ip() == '10.0.0.0'
216 assert ipb.get_ip(1) == '10.0.0.4'
217 assert ipb.get_ip(63) == '10.0.0.252'
218 with pytest.raises(IndexError):
221 ipb = IpBlock('10.0.0.0', '0.0.0.10', 1)
222 assert ipb.get_ip() == '10.0.0.0'
223 with pytest.raises(IndexError):
228 assert utils.lcm(10, 2) == 10
229 assert utils.lcm(1, 256) == 256
230 assert utils.lcm(10, 256) == 1280
231 assert utils.lcm(utils.lcm(10, 2), utils.lcm(1, 256))
232 with pytest.raises(TypeError):
236 def test_flow_count_limit():
237 # lcm ip src and dst /32
238 lcm_ip = utils.lcm(1, 1) == 1
239 # port udp src = 1 port udp dst [1,29]
245 udp_src_size = Device.check_range_size(int(src_max) - int(src_min) + 1,
247 udp_dst_size = Device.check_range_size(int(dst_max) - int(dst_min) + 1,
249 lcm_port = utils.lcm(udp_src_size, udp_dst_size)
250 assert utils.lcm(lcm_ip, lcm_port) < 29
253 def test_check_range_size():
254 assert Device.check_range_size(256, 1) == 256
255 assert Device.check_range_size(256, 3) == 86
256 assert Device.check_range_size(256, 4) == 64
257 assert Device.check_range_size(16, 10) == 2
258 assert Device.check_range_size(1, 10) == 1
259 with pytest.raises(ZeroDivisionError):
260 Device.check_range_size(256, 0)
263 def test_reserve_ip_range():
264 ipb = IpBlock('10.0.0.0', '0.0.0.1', 256)
265 src_ip_first, src_ip_last = ipb.reserve_ip_range(256)
266 assert src_ip_first == "10.0.0.0"
267 assert src_ip_last == "10.0.0.255"
268 ipb = IpBlock('20.0.0.0', '0.0.0.1', 2)
269 src_ip_first, src_ip_last = ipb.reserve_ip_range(2)
270 assert src_ip_first == "20.0.0.0"
271 assert src_ip_last == "20.0.0.1"
272 ipb = IpBlock('30.0.0.0', '0.0.0.1', 2)
273 with pytest.raises(IndexError):
274 ipb.reserve_ip_range(256)
277 def check_stream_configs(gen_config):
278 """Verify that the range for each chain have adjacent IP ranges without holes between chains."""
279 config = gen_config.config
280 tgc = config['traffic_generator']
281 step = Device.ip_to_int(tgc['ip_addrs_step'])
283 sip = Device.ip_to_int(tgc['ip_addrs'][0].split('/')[0])
284 dip = Device.ip_to_int(tgc['ip_addrs'][1].split('/')[0])
285 stream_configs = gen_config.devices[0].get_stream_configs()
286 for index in range(config['service_chain_count']):
287 stream_cfg = stream_configs[index]
288 # ip_src_static == True
289 assert stream_cfg['ip_src_count'] == 1
291 assert stream_cfg['ip_dst_count'] == 4999
293 assert stream_cfg['ip_dst_count'] == 5000
294 assert stream_cfg['ip_src_addr'] == Device.int_to_ip(sip)
295 assert Device.ip_to_int(stream_cfg['ip_src_addr']) == sip
296 assert Device.ip_to_int(stream_cfg['ip_dst_addr']) == dip
297 count = stream_cfg['ip_dst_count']
301 assert cfc == int(config['flow_count'] / 2)
303 def _check_device_flow_config(step_ip):
304 config = _get_dummy_tg_config('PVP', '1Mpps', scc=10, fc=99999, step_ip=step_ip)
305 gen_config = GeneratorConfig(config)
306 check_stream_configs(gen_config)
308 def test_device_flow_config():
309 _check_device_flow_config('0.0.0.1')
310 _check_device_flow_config('0.0.0.2')
313 def check_udp_stream_configs(gen_config, expected_cfg):
314 """Verify that the range for each chain have adjacent UDP ports without holes between chains."""
315 config = gen_config.config
316 stream_configs = gen_config.devices[0].get_stream_configs()
317 for index in range(config['service_chain_count']):
318 stream_cfg = stream_configs[index]
319 expected = expected_cfg[index]
320 assert stream_cfg['ip_src_addr'] == expected['ip_src_addr']
321 assert stream_cfg['ip_src_addr_max'] == expected['ip_src_addr_max']
322 assert stream_cfg['ip_src_count'] == expected['ip_src_count']
324 assert stream_cfg['ip_dst_addr'] == expected['ip_dst_addr']
325 assert stream_cfg['ip_dst_addr_max'] == expected['ip_dst_addr_max']
326 assert stream_cfg['ip_dst_count'] == expected['ip_dst_count']
328 assert stream_cfg['udp_src_port'] == expected['udp_src_port']
329 assert stream_cfg['udp_src_port_max'] == expected['udp_src_port_max']
330 assert stream_cfg['udp_src_count'] == expected['udp_src_count']
332 assert stream_cfg['udp_dst_port'] == expected['udp_dst_port']
333 assert stream_cfg['udp_dst_port_max'] == expected['udp_dst_port_max']
334 assert stream_cfg['udp_dst_count'] == expected['udp_dst_count']
336 lcm_ip = utils.lcm(stream_cfg['ip_src_count'], stream_cfg['ip_dst_count'])
337 udp_src_size = int(stream_cfg['udp_src_port_max']) - int(stream_cfg['udp_src_port']) + 1
338 udp_dst_size = int(stream_cfg['udp_dst_port_max']) - int(stream_cfg['udp_dst_port']) + 1
339 lcm_udp = utils.lcm(udp_src_size, udp_dst_size)
340 assert utils.lcm(lcm_ip, lcm_udp) >= stream_cfg['count']
343 def _check_device_udp_flow_config(param, expected_cfg):
344 config = _get_dummy_tg_config('PVP', '1Mpps',
346 ip_src_static=param['ip_src_static'],
347 fc=param['flow_count'],
348 ip0=param['ip_src_addr'],
349 ip1=param['ip_dst_addr'],
350 step_ip=param['ip_addrs_step'],
351 src_udp=param['udp_src_port'],
352 dst_udp=param['udp_dst_port'],
353 step_udp=param['udp_port_step'])
354 gen_config = GeneratorConfig(config)
355 check_udp_stream_configs(gen_config, expected_cfg)
358 def __get_udp_params():
359 param = {'ip_src_static': True,
360 'ip_src_addr': '110.0.0.0/32',
361 'ip_dst_addr': '120.0.0.0/32',
362 'ip_addrs_step': '0.0.0.1',
367 'udp_port_step': '1'}
371 def __get_udp_expected_list():
372 expected = {'ip_src_addr': '110.0.0.0',
373 'ip_src_addr_max': '110.0.0.0',
375 'ip_dst_addr': '120.0.0.0',
376 'ip_dst_addr_max': '120.0.0.0',
379 'udp_src_port_max': 53,
382 'udp_dst_port_max': 53,
387 def test_device_udp_flow_config_single_ip_single_port():
388 param = __get_udp_params()
389 expected = __get_udp_expected_list()
390 _check_device_udp_flow_config(param, [expected])
393 def test_device_udp_flow_config_single_ip_multiple_src_ports():
394 param = __get_udp_params()
395 expected = __get_udp_expected_list()
396 # Overwrite the udp_src_port value to define a large range of ports
397 # instead of a single port, in order to check if the imposed
398 # flow count is respected. Notice that udp range >> flow count.
399 param['udp_src_port'] = [53, 1024]
400 param['flow_count'] = 10
401 expected['udp_src_port_max'] = 57
402 expected['udp_src_count'] = 5
403 _check_device_udp_flow_config(param, [expected])
406 def test_device_udp_flow_config_multiple_ip_src_single_port():
407 param = __get_udp_params()
408 expected = __get_udp_expected_list()
409 # Re affect the default udp_src_port values and
410 # overwrite the ip_dst_addr value to define a large range of addresses
411 # instead of a single one, in order to check if the imposed
412 # flow count is respected. Notice that the netmask allows a very larger
413 # range of possible addresses than the flow count value.
414 param['udp_src_port'] = 53
415 param['flow_count'] = 10
416 param['ip_src_static'] = False
417 param['ip_dst_addr'] = '120.0.0.0/24'
419 expected['udp_src_port_max'] = 53
420 expected['udp_src_count'] = 1
421 expected['ip_dst_addr'] = '120.0.0.0'
422 expected['ip_dst_addr_max'] = '120.0.0.4'
423 expected['ip_dst_count'] = 5
424 _check_device_udp_flow_config(param, [expected])
427 def test_device_udp_flow_config_multiple_ip_src_dst_multiple_src_dst_ports():
428 param = __get_udp_params()
429 expected = __get_udp_expected_list()
431 param['udp_src_port'] = [49000, 49031]
432 param['udp_dst_port'] = [50000, 50033]
433 param['ip_src_static'] = False
434 param['flow_count'] = 1000
435 param['ip_src_addr'] = '110.0.0.0/16'
436 param['ip_dst_addr'] = '120.0.0.0/16'
438 expected['udp_src_port'] = 49000
439 expected['udp_src_port_max'] = 49024
440 expected['udp_dst_port'] = 50000
441 expected['udp_dst_port_max'] = 50024
442 expected['udp_src_count'] = 25
443 expected['udp_dst_count'] = 25
444 expected['ip_src_addr_max'] = '110.0.1.243'
445 expected['ip_src_count'] = 500
446 expected['ip_dst_addr'] = '120.0.0.0'
447 expected['ip_dst_addr_max'] = '120.0.1.243'
448 expected['ip_dst_count'] = 500
449 _check_device_udp_flow_config(param, [expected])
454 def test_device_udp_flow_config_random_multiple_ip_src_dst_multiple_src_dst_ports():
455 param = __get_udp_params()
456 expected = __get_udp_expected_list()
458 param['udp_src_port'] = [1025, 65000]
459 param['udp_dst_port'] = [1024, 65000]
460 param['ip_src_static'] = False
461 param['ip_addrs_step'] = 'random'
462 param['udp_port_step'] = 'random'
463 param['flow_count'] = 1000000
464 param['ip_src_addr'] = '110.0.0.0/16'
465 param['ip_dst_addr'] = '120.0.0.0/16'
467 expected['udp_src_port'] = 1025
468 expected['udp_src_port_max'] = 65000
469 expected['udp_dst_port'] = 1024
470 expected['udp_dst_port_max'] = 65000
471 expected['udp_src_count'] = 62500
472 expected['udp_dst_count'] = 62500
473 expected['ip_src_addr_max'] = '110.0.0.31'
474 expected['ip_src_count'] = 32
475 expected['ip_dst_addr'] = '120.0.0.0'
476 expected['ip_dst_addr_max'] = '120.0.0.31'
477 expected['ip_dst_count'] = 32
478 _check_device_udp_flow_config(param, [expected])
480 def test_device_udp_flow_config_random_multiple_ip_srcstatic_dst_multiple_src_dst_ports():
481 param = __get_udp_params()
482 expected = __get_udp_expected_list()
484 param['udp_src_port'] = [1025, 65000]
485 param['udp_dst_port'] = [1024, 65000]
486 param['ip_src_static'] = True
487 param['ip_addrs_step'] = 'random'
488 param['udp_port_step'] = 'random'
489 param['flow_count'] = 1000000
490 param['ip_src_addr'] = '110.0.0.0/16'
491 param['ip_dst_addr'] = '120.0.0.0/16'
493 expected['udp_src_port'] = 1025
494 expected['udp_src_port_max'] = 65000
495 expected['udp_dst_port'] = 1024
496 expected['udp_dst_port_max'] = 65000
497 expected['udp_src_count'] = 1
498 expected['udp_dst_count'] = 62500
499 expected['ip_src_addr_max'] = '110.0.0.0'
500 expected['ip_src_count'] = 1
501 expected['ip_dst_addr'] = '120.0.0.0'
502 expected['ip_dst_addr_max'] = '120.0.0.31'
503 expected['ip_dst_count'] = 32
504 _check_device_udp_flow_config(param, [expected])
508 def test_device_udp_flow_config_single_ip_src_dst_multiple_src_dst_ports():
509 param = __get_udp_params()
510 expected = __get_udp_expected_list()
512 param['udp_src_port'] = [49152, 49154]
513 param['udp_dst_port'] = [50001, 50005]
514 param['ip_src_static'] = False
515 param['flow_count'] = 10
516 param['ip_src_addr'] = '110.0.0.0/32'
517 param['ip_dst_addr'] = '120.0.0.0/32'
519 expected['udp_src_port'] = 49152
520 expected['udp_src_port_max'] = 49152
521 expected['udp_dst_port'] = 50001
522 expected['udp_dst_port_max'] = 50005
523 expected['udp_src_count'] = 1
524 expected['udp_dst_count'] = 5
525 expected['ip_src_addr_max'] = '110.0.0.0'
526 expected['ip_src_count'] = 1
527 expected['ip_dst_addr'] = '120.0.0.0'
528 expected['ip_dst_addr_max'] = '120.0.0.0'
529 expected['ip_dst_count'] = 1
530 _check_device_udp_flow_config(param, [expected])
533 def test_device_udp_flow_config_single_ip_src_dst_single_src_multiple_dst_ports():
534 param = __get_udp_params()
535 expected = __get_udp_expected_list()
537 param['udp_src_port'] = 49152
538 param['udp_dst_port'] = [50001, 50029]
539 param['udp_port_step'] = '3'
540 param['flow_count'] = 58
541 param['ip_src_addr'] = '110.0.0.0/32'
542 param['ip_dst_addr'] = '120.0.0.0/32'
544 expected['udp_src_port'] = 49152
545 expected['udp_src_port_max'] = 49152
546 expected['udp_dst_port'] = 50001
547 expected['udp_dst_port_max'] = 50029
548 expected['udp_src_count'] = 1
549 expected['udp_dst_count'] = 29
550 expected['ip_src_addr_max'] = '110.0.0.0'
551 expected['ip_src_count'] = 1
552 expected['ip_dst_addr'] = '120.0.0.0'
553 expected['ip_dst_addr_max'] = '120.0.0.0'
554 expected['ip_dst_count'] = 1
555 with pytest.raises(TrafficClientException):
556 _check_device_udp_flow_config(param, [expected])
559 def test_device_udp_flow_config_scc3():
560 param = __get_udp_params()
561 expected = __get_udp_expected_list()
564 param['udp_src_port'] = [49000, 49031]
565 param['udp_dst_port'] = [50000, 50033]
566 param['ip_src_static'] = False
567 param['flow_count'] = 10000
568 param['ip_src_addr'] = '110.0.0.0/16'
569 param['ip_dst_addr'] = '120.0.0.0/16'
573 expected_scc0 = dict(expected)
574 expected_scc0['udp_src_port'] = 49000
575 expected_scc0['udp_src_port_max'] = 49016
576 expected_scc0['udp_dst_port'] = 50000
577 expected_scc0['udp_dst_port_max'] = 50033
578 expected_scc0['udp_src_count'] = 17
579 expected_scc0['udp_dst_count'] = 34
580 expected_scc0['ip_src_addr_max'] = '110.0.6.129'
581 expected_scc0['ip_src_count'] = 1666
582 expected_scc0['ip_dst_addr'] = '120.0.0.0'
583 expected_scc0['ip_dst_addr_max'] = '120.0.6.129'
584 expected_scc0['ip_dst_count'] = 1666
585 expected_cfg.append(expected_scc0)
588 expected_scc1 = dict(expected)
589 expected_scc1['udp_src_port'] = 49000
590 expected_scc1['udp_src_port_max'] = 49000
591 expected_scc1['udp_dst_port'] = 50000
592 expected_scc1['udp_dst_port_max'] = 50000
593 expected_scc1['udp_src_count'] = 1
594 expected_scc1['udp_dst_count'] = 1
595 expected_scc1['ip_src_addr'] = '110.0.6.130'
596 expected_scc1['ip_src_addr_max'] = '110.0.13.4'
597 expected_scc1['ip_src_count'] = 1667
598 expected_scc1['ip_dst_addr'] = '120.0.6.130'
599 expected_scc1['ip_dst_addr_max'] = '120.0.13.4'
600 expected_scc1['ip_dst_count'] = 1667
601 expected_cfg.append(expected_scc1)
604 expected_scc2 = dict(expected)
605 expected_scc2['udp_src_port'] = 49000
606 expected_scc2['udp_src_port_max'] = 49000
607 expected_scc2['udp_dst_port'] = 50000
608 expected_scc2['udp_dst_port_max'] = 50000
609 expected_scc2['udp_src_count'] = 1
610 expected_scc2['udp_dst_count'] = 1
611 expected_scc2['ip_src_addr'] = '110.0.13.5'
612 expected_scc2['ip_src_addr_max'] = '110.0.19.135'
613 expected_scc2['ip_src_count'] = 1667
614 expected_scc2['ip_dst_addr'] = '120.0.13.5'
615 expected_scc2['ip_dst_addr_max'] = '120.0.19.135'
616 expected_scc2['ip_dst_count'] = 1667
617 expected_cfg.append(expected_scc2)
619 _check_device_udp_flow_config(param, expected_cfg)
622 def test_device_udp_flow_config_doc_example1(caplog):
624 caplog.set_level(logging.INFO)
625 param = __get_udp_params()
626 expected = __get_udp_expected_list()
628 # Multiflow unitary test corresponding to first example in documentation
630 param['udp_src_port'] = 53
631 param['udp_dst_port'] = 53
632 param['ip_src_static'] = True
633 param['flow_count'] = 100
634 param['ip_src_addr'] = '110.0.0.0/8'
635 param['ip_dst_addr'] = '120.0.0.0/8'
639 expected_scc0 = dict(expected)
640 expected_scc0['udp_src_port'] = 53
641 expected_scc0['udp_src_port_max'] = 53
642 expected_scc0['udp_dst_port'] = 53
643 expected_scc0['udp_dst_port_max'] = 53
644 expected_scc0['udp_src_count'] = 1
645 expected_scc0['udp_dst_count'] = 1
646 expected_scc0['ip_src_addr'] = '110.0.0.0'
647 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
648 expected_scc0['ip_src_count'] = 1
649 expected_scc0['ip_dst_addr'] = '120.0.0.0'
650 expected_scc0['ip_dst_addr_max'] = '120.0.0.15'
651 expected_scc0['ip_dst_count'] = 16
652 expected_cfg.append(expected_scc0)
655 expected_scc1 = dict(expected)
656 expected_scc1['udp_src_port'] = 53
657 expected_scc1['udp_src_port_max'] = 53
658 expected_scc1['udp_dst_port'] = 53
659 expected_scc1['udp_dst_port_max'] = 53
660 expected_scc1['udp_src_count'] = 1
661 expected_scc1['udp_dst_count'] = 1
662 expected_scc1['ip_src_addr'] = '110.0.0.1'
663 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
664 expected_scc1['ip_src_count'] = 1
665 expected_scc1['ip_dst_addr'] = '120.0.0.16'
666 expected_scc1['ip_dst_addr_max'] = '120.0.0.32'
667 expected_scc1['ip_dst_count'] = 17
668 expected_cfg.append(expected_scc1)
671 expected_scc2 = dict(expected)
672 expected_scc2['udp_src_port'] = 53
673 expected_scc2['udp_src_port_max'] = 53
674 expected_scc2['udp_dst_port'] = 53
675 expected_scc2['udp_dst_port_max'] = 53
676 expected_scc2['udp_src_count'] = 1
677 expected_scc2['udp_dst_count'] = 1
678 expected_scc2['ip_src_addr'] = '110.0.0.2'
679 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
680 expected_scc2['ip_src_count'] = 1
681 expected_scc2['ip_dst_addr'] = '120.0.0.33'
682 expected_scc2['ip_dst_addr_max'] = '120.0.0.49'
683 expected_scc2['ip_dst_count'] = 17
684 expected_cfg.append(expected_scc2)
686 _check_device_udp_flow_config(param, expected_cfg)
687 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
690 def test_device_udp_flow_config_doc_example2(caplog):
692 caplog.set_level(logging.INFO)
693 param = __get_udp_params()
694 expected = __get_udp_expected_list()
696 # Multiflow unitary test corresponding to second example in documentation
698 param['udp_src_port'] = 53
699 param['udp_dst_port'] = 53
700 param['ip_src_static'] = True
701 param['ip_addrs_step'] = 'random'
702 param['flow_count'] = 100
703 param['ip_src_addr'] = '110.0.0.0/8'
704 param['ip_dst_addr'] = '120.0.0.0/8'
708 expected_scc0 = dict(expected)
709 expected_scc0['udp_src_port'] = 53
710 expected_scc0['udp_src_port_max'] = 53
711 expected_scc0['udp_dst_port'] = 53
712 expected_scc0['udp_dst_port_max'] = 53
713 expected_scc0['udp_src_count'] = 1
714 expected_scc0['udp_dst_count'] = 1
715 expected_scc0['ip_src_addr'] = '110.0.0.0'
716 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
717 expected_scc0['ip_src_count'] = 1
718 expected_scc0['ip_dst_addr'] = '120.0.0.0'
719 expected_scc0['ip_dst_addr_max'] = '120.0.0.15'
720 expected_scc0['ip_dst_count'] = 16
721 expected_cfg.append(expected_scc0)
724 expected_scc1 = dict(expected)
725 expected_scc1['udp_src_port'] = 53
726 expected_scc1['udp_src_port_max'] = 53
727 expected_scc1['udp_dst_port'] = 53
728 expected_scc1['udp_dst_port_max'] = 53
729 expected_scc1['udp_src_count'] = 1
730 expected_scc1['udp_dst_count'] = 1
731 expected_scc1['ip_src_addr'] = '110.0.0.1'
732 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
733 expected_scc1['ip_src_count'] = 1
734 expected_scc1['ip_dst_addr'] = '120.0.0.16'
735 expected_scc1['ip_dst_addr_max'] = '120.0.0.32'
736 expected_scc1['ip_dst_count'] = 17
737 expected_cfg.append(expected_scc1)
740 expected_scc2 = dict(expected)
741 expected_scc2['udp_src_port'] = 53
742 expected_scc2['udp_src_port_max'] = 53
743 expected_scc2['udp_dst_port'] = 53
744 expected_scc2['udp_dst_port_max'] = 53
745 expected_scc2['udp_src_count'] = 1
746 expected_scc2['udp_dst_count'] = 1
747 expected_scc2['ip_src_addr'] = '110.0.0.2'
748 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
749 expected_scc2['ip_src_count'] = 1
750 expected_scc2['ip_dst_addr'] = '120.0.0.33'
751 expected_scc2['ip_dst_addr_max'] = '120.0.0.49'
752 expected_scc2['ip_dst_count'] = 17
753 expected_cfg.append(expected_scc2)
755 _check_device_udp_flow_config(param, expected_cfg)
756 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
759 def test_device_udp_flow_config_doc_example3(caplog):
761 param = __get_udp_params()
762 expected = __get_udp_expected_list()
764 # Multiflow unitary test corresponding to third example in documentation
766 param['udp_src_port'] = 53
767 param['udp_dst_port'] = 53
768 param['ip_src_static'] = True
769 param['ip_addrs_step'] = '0.0.0.5'
770 param['flow_count'] = 100
771 param['ip_src_addr'] = '110.0.0.0/8'
772 param['ip_dst_addr'] = '120.0.0.0/8'
776 expected_scc0 = dict(expected)
777 expected_scc0['udp_src_port'] = 53
778 expected_scc0['udp_src_port_max'] = 53
779 expected_scc0['udp_dst_port'] = 53
780 expected_scc0['udp_dst_port_max'] = 53
781 expected_scc0['udp_src_count'] = 1
782 expected_scc0['udp_dst_count'] = 1
783 expected_scc0['ip_src_addr'] = '110.0.0.0'
784 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
785 expected_scc0['ip_src_count'] = 1
786 expected_scc0['ip_dst_addr'] = '120.0.0.0'
787 expected_scc0['ip_dst_addr_max'] = '120.0.0.75'
788 expected_scc0['ip_dst_count'] = 16
789 expected_cfg.append(expected_scc0)
792 expected_scc1 = dict(expected)
793 expected_scc1['udp_src_port'] = 53
794 expected_scc1['udp_src_port_max'] = 53
795 expected_scc1['udp_dst_port'] = 53
796 expected_scc1['udp_dst_port_max'] = 53
797 expected_scc1['udp_src_count'] = 1
798 expected_scc1['udp_dst_count'] = 1
799 expected_scc1['ip_src_addr'] = '110.0.0.5'
800 expected_scc1['ip_src_addr_max'] = '110.0.0.5'
801 expected_scc1['ip_src_count'] = 1
802 expected_scc1['ip_dst_addr'] = '120.0.0.80'
803 expected_scc1['ip_dst_addr_max'] = '120.0.0.160'
804 expected_scc1['ip_dst_count'] = 17
805 expected_cfg.append(expected_scc1)
808 expected_scc2 = dict(expected)
809 expected_scc2['udp_src_port'] = 53
810 expected_scc2['udp_src_port_max'] = 53
811 expected_scc2['udp_dst_port'] = 53
812 expected_scc2['udp_dst_port_max'] = 53
813 expected_scc2['udp_src_count'] = 1
814 expected_scc2['udp_dst_count'] = 1
815 expected_scc2['ip_src_addr'] = '110.0.0.10'
816 expected_scc2['ip_src_addr_max'] = '110.0.0.10'
817 expected_scc2['ip_src_count'] = 1
818 expected_scc2['ip_dst_addr'] = '120.0.0.165'
819 expected_scc2['ip_dst_addr_max'] = '120.0.0.245'
820 expected_scc2['ip_dst_count'] = 17
821 expected_cfg.append(expected_scc2)
823 caplog.set_level(logging.INFO)
824 _check_device_udp_flow_config(param, expected_cfg)
825 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
828 def test_device_udp_flow_config_doc_example4(caplog):
830 param = __get_udp_params()
831 expected = __get_udp_expected_list()
833 # Multiflow unitary test corresponding to fourth example in documentation
835 param['udp_src_port'] = [10, 14]
836 param['udp_dst_port'] = [20, 25]
837 param['ip_src_static'] = True
838 param['ip_addrs_step'] = '0.0.0.1'
839 param['udp_port_step'] = 'random'
840 param['flow_count'] = 100
841 param['ip_src_addr'] = '110.0.0.0/29'
842 param['ip_dst_addr'] = '120.0.0.0/30'
846 expected_scc0 = dict(expected)
847 expected_scc0['udp_src_port'] = 10
848 expected_scc0['udp_src_port_max'] = 14
849 expected_scc0['udp_dst_port'] = 20
850 expected_scc0['udp_dst_port_max'] = 25
851 expected_scc0['udp_src_count'] = 5
852 expected_scc0['udp_dst_count'] = 6
853 expected_scc0['ip_src_addr'] = '110.0.0.0'
854 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
855 expected_scc0['ip_src_count'] = 1
856 expected_scc0['ip_dst_addr'] = '120.0.0.0'
857 expected_scc0['ip_dst_addr_max'] = '120.0.0.0'
858 expected_scc0['ip_dst_count'] = 1
859 expected_cfg.append(expected_scc0)
862 expected_scc1 = dict(expected)
863 expected_scc1['udp_src_port'] = 10
864 expected_scc1['udp_src_port_max'] = 14
865 expected_scc1['udp_dst_port'] = 20
866 expected_scc1['udp_dst_port_max'] = 25
867 expected_scc1['udp_src_count'] = 5
868 expected_scc1['udp_dst_count'] = 6
869 expected_scc1['ip_src_addr'] = '110.0.0.1'
870 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
871 expected_scc1['ip_src_count'] = 1
872 expected_scc1['ip_dst_addr'] = '120.0.0.1'
873 expected_scc1['ip_dst_addr_max'] = '120.0.0.1'
874 expected_scc1['ip_dst_count'] = 1
875 expected_cfg.append(expected_scc1)
878 expected_scc2 = dict(expected)
879 expected_scc2['udp_src_port'] = 10
880 expected_scc2['udp_src_port_max'] = 14
881 expected_scc2['udp_dst_port'] = 20
882 expected_scc2['udp_dst_port_max'] = 25
883 expected_scc2['udp_src_count'] = 5
884 expected_scc2['udp_dst_count'] = 6
885 expected_scc2['ip_src_addr'] = '110.0.0.2'
886 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
887 expected_scc2['ip_src_count'] = 1
888 expected_scc2['ip_dst_addr'] = '120.0.0.2'
889 expected_scc2['ip_dst_addr_max'] = '120.0.0.2'
890 expected_scc2['ip_dst_count'] = 1
891 expected_cfg.append(expected_scc2)
892 caplog.set_level(logging.INFO)
893 _check_device_udp_flow_config(param, expected_cfg)
894 assert "Current values of ip_addrs_step and/or udp_port_step properties" in caplog.text
895 assert "udp_port_step='1' (previous value: udp_port_step='random'" in caplog.text
898 def test_device_udp_flow_config_no_random_steps_overridden(caplog):
900 param = __get_udp_params()
901 expected = __get_udp_expected_list()
903 # Multiflow unitary test corresponding to fifth example in documentation
905 param['udp_src_port'] = [10, 14]
906 param['udp_dst_port'] = [20, 25]
907 param['ip_src_static'] = True
908 param['ip_addrs_step'] = 'random'
909 param['udp_port_step'] = 'random'
910 param['flow_count'] = 100
911 param['ip_src_addr'] = '110.0.0.0/29'
912 param['ip_dst_addr'] = '120.0.0.0/30'
916 expected_scc0 = dict(expected)
917 expected_scc0['udp_src_port'] = 10
918 expected_scc0['udp_src_port_max'] = 14
919 expected_scc0['udp_dst_port'] = 20
920 expected_scc0['udp_dst_port_max'] = 25
921 expected_scc0['udp_src_count'] = 5
922 expected_scc0['udp_dst_count'] = 6
923 expected_scc0['ip_src_addr'] = '110.0.0.0'
924 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
925 expected_scc0['ip_src_count'] = 1
926 expected_scc0['ip_dst_addr'] = '120.0.0.0'
927 expected_scc0['ip_dst_addr_max'] = '120.0.0.0'
928 expected_scc0['ip_dst_count'] = 1
929 expected_cfg.append(expected_scc0)
932 expected_scc1 = dict(expected)
933 expected_scc1['udp_src_port'] = 10
934 expected_scc1['udp_src_port_max'] = 14
935 expected_scc1['udp_dst_port'] = 20
936 expected_scc1['udp_dst_port_max'] = 25
937 expected_scc1['udp_src_count'] = 5
938 expected_scc1['udp_dst_count'] = 6
939 expected_scc1['ip_src_addr'] = '110.0.0.1'
940 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
941 expected_scc1['ip_src_count'] = 1
942 expected_scc1['ip_dst_addr'] = '120.0.0.1'
943 expected_scc1['ip_dst_addr_max'] = '120.0.0.1'
944 expected_scc1['ip_dst_count'] = 1
945 expected_cfg.append(expected_scc1)
948 expected_scc2 = dict(expected)
949 expected_scc2['udp_src_port'] = 10
950 expected_scc2['udp_src_port_max'] = 14
951 expected_scc2['udp_dst_port'] = 20
952 expected_scc2['udp_dst_port_max'] = 25
953 expected_scc2['udp_src_count'] = 5
954 expected_scc2['udp_dst_count'] = 6
955 expected_scc2['ip_src_addr'] = '110.0.0.2'
956 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
957 expected_scc2['ip_src_count'] = 1
958 expected_scc2['ip_dst_addr'] = '120.0.0.2'
959 expected_scc2['ip_dst_addr_max'] = '120.0.0.2'
960 expected_scc2['ip_dst_count'] = 1
961 expected_cfg.append(expected_scc2)
962 caplog.set_level(logging.INFO)
963 _check_device_udp_flow_config(param, expected_cfg)
964 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
968 refcfg = {1: 100, 2: {21: 100, 22: 200}, 3: None}
969 res1 = {1: 10, 2: {21: 100, 22: 200}, 3: None}
970 res2 = {1: 100, 2: {21: 1000, 22: 200}, 3: None}
971 res3 = {1: 100, 2: {21: 100, 22: 200}, 3: "abc"}
972 assert config_loads("{}", refcfg) == refcfg
973 assert config_loads("{1: 10}", refcfg) == res1
974 assert config_loads("{2: {21: 1000}}", refcfg) == res2
975 assert config_loads('{3: "abc"}', refcfg) == res3
978 # pairs of input string and expected subset (None if identical)
981 ["{2: {21: 100, 30: 50}}", "{2: {30: 50}}"],
982 ["{2: {0: 1, 1: 2}, 5: 5}", None],
983 ["{1: 'abc', 2: {21: 0}}", "{1: 'abc'}"],
986 for fail_pair in fail_pairs:
987 with pytest.raises(Exception) as e_info:
988 config_loads(fail_pair[0], refcfg)
989 expected = fail_pair[1]
991 expected = fail_pair[0]
992 assert expected in str(e_info)
995 flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0,
996 'extra_specs': {'hw:cpu_policy': 'dedicated'}}}
997 new_flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0,
998 'extra_specs': {'hw:cpu_policy': 'dedicated', 'hw:numa_nodes': 2}}}
999 assert config_loads("{'flavor': {'extra_specs': {'hw:numa_nodes': 2}}}", flavor,
1000 whitelist_keys=['alpha', 'extra_specs']) == new_flavor
1004 logger = logging.getLogger('fluent-logger')
1006 class FluentdConfig(dict):
1007 def __getattr__(self, attr):
1008 return self.get(attr)
1012 'logging_tag': 'nfvbench',
1013 'result_tag': 'resultnfvbench',
1018 'logging_tag': 'nfvbench',
1019 'result_tag': 'resultnfvbench',
1024 'logging_tag': None,
1025 'result_tag': 'resultnfvbench',
1030 'logging_tag': 'nfvbench',
1037 handler = FluentLogHandler(fluentd_configs=fluentd_configs)
1038 logger.addHandler(handler)
1039 logger.setLevel(logging.INFO)
1041 logger.warning('test %d', 100)
1044 raise Exception("test")
1046 logger.exception("got exception")
1048 def assert_ndr_pdr(stats, ndr, ndr_dr, pdr, pdr_dr):
1049 assert stats['ndr']['rate_percent'] == ndr
1050 assert stats['ndr']['stats']['overall']['drop_percentage'] == ndr_dr
1051 assert_equivalence(pdr, stats['pdr']['rate_percent'])
1052 assert_equivalence(pdr_dr, stats['pdr']['stats']['overall']['drop_percentage'])
1054 def _get_dummy_tg_config(chain_type, rate, scc=1, fc=10, step_ip='0.0.0.1',
1055 ip0='10.0.0.0/8', ip1='20.0.0.0/8',
1056 step_udp='1', src_udp=None, dst_udp=None, ip_src_static=True):
1058 'traffic_generator': {'host_name': 'nfvbench_tg',
1059 'default_profile': 'dummy',
1060 'generator_profile': [{'name': 'dummy',
1063 'intf_speed': '10Gbps',
1064 'interfaces': [{'port': 0, 'pci': '0.0'},
1065 {'port': 1, 'pci': '0.0'}]}],
1066 'ip_addrs_step': step_ip,
1067 'ip_addrs': [ip0, ip1],
1068 'ip_src_static': ip_src_static,
1069 'tg_gateway_ip_addrs': ['1.1.0.100', '2.2.0.100'],
1070 'tg_gateway_ip_addrs_step': step_ip,
1071 'gateway_ip_addrs': ['1.1.0.2', '2.2.0.2'],
1072 'gateway_ip_addrs_step': step_ip,
1073 'mac_addrs_left': None,
1074 'mac_addrs_right': None,
1075 'udp_src_port': src_udp,
1076 'udp_dst_port': dst_udp,
1077 'udp_port_step': step_udp},
1078 'traffic': {'profile': 'profile_64',
1079 'bidirectional': True},
1080 'traffic_profile': [{'name': 'profile_64', 'l2frame_size': ['64']}],
1081 'generator_profile': None,
1082 'service_chain': chain_type,
1083 'service_chain_count': scc,
1085 'vlan_tagging': True,
1091 'check_traffic_time_sec': 200,
1092 'generic_poll_sec': 2,
1093 'measurement': {'NDR': 0.001, 'PDR': 0.1, 'load_epsilon': 0.1},
1094 'l2_loopback': False,
1096 'mbuf_factor': None,
1097 'disable_hdrh': None,
1099 'service_mode': False,
1100 'no_flow_stats': False,
1101 'no_latency_stats': False,
1102 'no_latency_streams': False,
1103 'intf_speed': '10Gbps',
1104 'periodic_gratuitous_arp': False,
1105 'gratuitous_arp_pps': 1
1108 def _get_traffic_client(user_info=None):
1109 config = _get_dummy_tg_config('PVP', 'ndr_pdr')
1110 config['vxlan'] = False
1111 config['mpls'] = False
1112 config['ndr_run'] = True
1113 config['pdr_run'] = True
1114 config['generator_profile'] = 'dummy'
1115 config['single_run'] = False
1117 config['user_info'] = user_info
1118 traffic_client = TrafficClient(config)
1119 traffic_client.start_traffic_generator()
1120 traffic_client.set_traffic('64', True)
1121 return traffic_client
1123 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1124 def test_ndr_at_lr():
1125 """Test NDR at line rate."""
1126 traffic_client = _get_traffic_client()
1127 tg = traffic_client.gen
1128 # this is a perfect sut with no loss at LR
1129 tg.set_response_curve(lr_dr=0, ndr=100, max_actual_tx=100, max_11_tx=100)
1130 # tx packets should be line rate for 64B and no drops...
1131 assert tg.get_tx_pps_dropped_pps(100) == (LR_64B_PPS, 0)
1132 # NDR and PDR should be at 100%
1133 # traffic_client.ensure_end_to_end()
1134 results = traffic_client.get_ndr_and_pdr()
1135 assert_ndr_pdr(results, 200.0, 0.0, 200.0, 0.0)
1137 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1138 def test_ndr_at_50():
1139 """Test NDR at 50% line rate.
1141 This is a sut with an NDR of 50% and linear drop rate after NDR up to 20% drops at LR
1142 (meaning that if you send 100% TX, you will only receive 80% RX)
1143 the tg requested TX/actual TX ratio is up to 50%, after 50%
1144 is linear up 80% actuak TX when requesting 100%
1146 traffic_client = _get_traffic_client()
1147 tg = traffic_client.gen
1149 tg.set_response_curve(lr_dr=20, ndr=50, max_actual_tx=80, max_11_tx=50)
1150 # tx packets should be half line rate for 64B and no drops...
1151 assert tg.get_tx_pps_dropped_pps(50) == (LR_64B_PPS / 2, 0)
1152 # at 100% TX requested, actual TX is 80% where the drop rate is 3/5 of 20% of the actual TX
1153 assert tg.get_tx_pps_dropped_pps(100) == (int(LR_64B_PPS * 0.8),
1154 int(LR_64B_PPS * 0.8 * 0.6 * 0.2))
1155 results = traffic_client.get_ndr_and_pdr()
1156 assert_ndr_pdr(results, 100.0, 0.0, 100.781, 0.09374)
1158 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1159 def test_ndr_pdr_low_cpu():
1160 """Test NDR and PDR with too low cpu.
1162 This test is for the case where the TG is underpowered and cannot send fast enough for the NDR
1163 true NDR=40%, actual TX at 50% = 30%, actual measured DR is 0%
1164 The ndr/pdr should bail out with a warning and a best effort measured NDR of 30%
1166 traffic_client = _get_traffic_client()
1167 tg = traffic_client.gen
1168 tg.set_response_curve(lr_dr=50, ndr=40, max_actual_tx=60, max_11_tx=0)
1169 # tx packets should be 30% at requested half line rate for 64B and no drops...
1170 assert tg.get_tx_pps_dropped_pps(50) == (int(LR_64B_PPS * 0.3), 0)
1171 results = traffic_client.get_ndr_and_pdr()
1174 # pp = pprint.PrettyPrinter(indent=4)
1175 # pp.pprint(results)
1177 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1178 def test_ndr_at_lr_sdn_gw_encapsulation():
1179 """Test NDR at line rate with traffic gen outside SUT and connected via SDN GW."""
1180 user_info = {'extra_encapsulation_bytes': 28}
1181 traffic_client = _get_traffic_client(user_info)
1182 tg = traffic_client.gen
1183 # this is a perfect sut with no loss at LR
1184 tg.set_response_curve(lr_dr=0, ndr=100, max_actual_tx=100, max_11_tx=100)
1185 # tx packets should be line rate for 64B and no drops...
1186 assert tg.get_tx_pps_dropped_pps(100) == (LR_64B_PPS, 0)
1187 # NDR and PDR should be at 100%
1188 # traffic_client.ensure_end_to_end()
1189 results = traffic_client.get_ndr_and_pdr()
1190 assert results['ndr']['stats']['theoretical_tx_rate_bps'] == 15000000000.0
1191 assert_ndr_pdr(results, 200.0, 0.0, 200.0, 0.0)
1193 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1194 def test_no_openstack():
1195 """Test nfvbench using main."""
1196 config = _get_dummy_tg_config('EXT', '1000pps')
1197 config.openrc_file = None
1198 config.vlans = [[100], [200]]
1199 config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00']
1200 config['traffic_generator']['mac_addrs_right'] = ['00:00:00:00:01:00']
1201 del config['generator_profile']
1203 sys.argv = [old_argv[0], '-c', json.dumps(config)]
1204 nfvbench.nfvbench.main()