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
16 from mock import patch
19 from .mock_trex import no_op
24 from attrdict import AttrDict
25 from nfvbench.config import config_loads
26 from nfvbench.credentials import Credentials
27 from nfvbench.fluentd import FluentLogHandler
29 import nfvbench.nfvbench
30 from nfvbench.traffic_client import Device
31 from nfvbench.traffic_client import GeneratorConfig
32 from nfvbench.traffic_client import IpBlock
33 from nfvbench.traffic_client import TrafficClient
34 from nfvbench.traffic_client import TrafficClientException
35 import nfvbench.traffic_gen.traffic_utils as traffic_utils
36 import nfvbench.utils as utils
38 # just to get rid of the unused function warning
41 def setup_module(module):
43 nfvbench.log.setup(mute_stdout=True)
45 # =========================================================================
46 # Traffic client tests
47 # =========================================================================
49 def test_parse_rate_str():
50 parse_rate_str = traffic_utils.parse_rate_str
52 assert parse_rate_str('100%') == {'rate_percent': '100.0'}
53 assert parse_rate_str('37.5%') == {'rate_percent': '37.5'}
54 assert parse_rate_str('100%') == {'rate_percent': '100.0'}
55 assert parse_rate_str('60pps') == {'rate_pps': '60'}
56 assert parse_rate_str('60kpps') == {'rate_pps': '60000'}
57 assert parse_rate_str('6Mpps') == {'rate_pps': '6000000'}
58 assert parse_rate_str('6gpps') == {'rate_pps': '6000000000'}
59 assert parse_rate_str('80bps') == {'rate_bps': '80'}
60 assert parse_rate_str('80bps') == {'rate_bps': '80'}
61 assert parse_rate_str('80kbps') == {'rate_bps': '80000'}
62 assert parse_rate_str('80kBps') == {'rate_bps': '640000'}
63 assert parse_rate_str('80Mbps') == {'rate_bps': '80000000'}
64 assert parse_rate_str('80 MBps') == {'rate_bps': '640000000'}
65 assert parse_rate_str('80Gbps') == {'rate_bps': '80000000000'}
66 except Exception as exc:
67 assert False, exc.message
69 def should_raise_error(str):
78 assert should_raise_error('101')
79 assert should_raise_error('201%')
80 assert should_raise_error('10Kbps')
81 assert should_raise_error('0kbps')
82 assert should_raise_error('0pps')
83 assert should_raise_error('-1bps')
86 def test_rate_conversion():
87 assert traffic_utils.load_to_bps(50, 10000000000) == pytest.approx(5000000000.0)
88 assert traffic_utils.load_to_bps(37, 10000000000) == pytest.approx(3700000000.0)
89 assert traffic_utils.load_to_bps(100, 10000000000) == pytest.approx(10000000000.0)
91 assert traffic_utils.bps_to_load(5000000000.0, 10000000000) == pytest.approx(50.0)
92 assert traffic_utils.bps_to_load(3700000000.0, 10000000000) == pytest.approx(37.0)
93 assert traffic_utils.bps_to_load(10000000000.0, 10000000000) == pytest.approx(100.0)
95 assert traffic_utils.bps_to_pps(500000, 64) == pytest.approx(744.047619048)
96 assert traffic_utils.bps_to_pps(388888, 1518) == pytest.approx(31.6066319896)
97 assert traffic_utils.bps_to_pps(9298322222, 340.3) == pytest.approx(3225895.85831)
99 assert traffic_utils.pps_to_bps(744.047619048, 64) == pytest.approx(500000)
100 assert traffic_utils.pps_to_bps(31.6066319896, 1518) == pytest.approx(388888)
101 assert traffic_utils.pps_to_bps(3225895.85831, 340.3) == pytest.approx(9298322222)
104 # pps at 10Gbps line rate for 64 byte frames
105 LR_64B_PPS = 14880952
106 LR_1518B_PPS = 812743
108 def assert_equivalence(reference, value, allowance_pct=1):
109 """Assert if a value is equivalent to a reference value with given margin.
111 :param float reference: reference value to compare to
112 :param float value: value to compare to reference
113 :param float allowance_pct: max allowed percentage of margin
114 0 : requires exact match
115 1 : must be equal within 1% of the reference value
122 assert abs(value - reference) * 100 / reference <= allowance_pct
124 def test_load_from_rate():
125 assert traffic_utils.get_load_from_rate('100%') == 100
126 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_64B_PPS) + 'pps'))
127 assert_equivalence(50, traffic_utils.get_load_from_rate(str(LR_64B_PPS / 2) + 'pps'))
128 assert_equivalence(100, traffic_utils.get_load_from_rate('10Gbps'))
129 assert_equivalence(50, traffic_utils.get_load_from_rate('5000Mbps'))
130 assert_equivalence(1, traffic_utils.get_load_from_rate('100Mbps'))
131 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_1518B_PPS) + 'pps',
132 avg_frame_size=1518))
133 assert_equivalence(100, traffic_utils.get_load_from_rate(str(LR_1518B_PPS * 2) + 'pps',
137 # =========================================================================
139 # =========================================================================
141 def test_no_credentials():
142 cred = Credentials('/completely/wrong/path/openrc', None, False)
144 # shouldn't get valid data unless user set environment variables
150 ipb = IpBlock('10.0.0.0', '0.0.0.1', 256)
151 assert ipb.get_ip() == '10.0.0.0'
152 assert ipb.get_ip(255) == '10.0.0.255'
153 with pytest.raises(IndexError):
155 ipb = IpBlock('10.0.0.0', '0.0.0.1', 1)
156 assert ipb.get_ip() == '10.0.0.0'
157 with pytest.raises(IndexError):
160 ipb = IpBlock('10.0.0.0', '0.0.0.2', 256)
161 assert ipb.get_ip() == '10.0.0.0'
162 assert ipb.get_ip(1) == '10.0.0.2'
163 assert ipb.get_ip(127) == '10.0.0.254'
164 assert ipb.get_ip(128) == '10.0.1.0'
165 with pytest.raises(IndexError):
168 # verify with step larger than 1
169 ipb = IpBlock('10.0.0.0', '0.0.0.2', 256)
170 assert ipb.get_ip() == '10.0.0.0'
171 assert ipb.get_ip(1) == '10.0.0.2'
172 assert ipb.get_ip(128) == '10.0.1.0'
173 assert ipb.get_ip(255) == '10.0.1.254'
174 with pytest.raises(IndexError):
177 ipb = IpBlock('10.0.0.0', '0.0.0.2', 128)
178 assert ipb.get_ip() == '10.0.0.0'
179 assert ipb.get_ip(1) == '10.0.0.2'
180 assert ipb.get_ip(127) == '10.0.0.254'
181 with pytest.raises(IndexError):
184 ipb = IpBlock('10.0.0.0', '0.0.0.4', 64)
185 assert ipb.get_ip() == '10.0.0.0'
186 assert ipb.get_ip(1) == '10.0.0.4'
187 assert ipb.get_ip(63) == '10.0.0.252'
188 with pytest.raises(IndexError):
191 ipb = IpBlock('10.0.0.0', '0.0.0.10', 1)
192 assert ipb.get_ip() == '10.0.0.0'
193 with pytest.raises(IndexError):
198 assert utils.lcm(10, 2) == 10
199 assert utils.lcm(1, 256) == 256
200 assert utils.lcm(10, 256) == 1280
201 assert utils.lcm(utils.lcm(10, 2), utils.lcm(1, 256))
202 with pytest.raises(TypeError):
206 def test_flow_count_limit():
207 # lcm ip src and dst /32
208 lcm_ip = utils.lcm(1, 1) == 1
209 # port udp src = 1 port udp dst [1,29]
215 udp_src_size = Device.check_range_size(int(src_max) - int(src_min) + 1,
217 udp_dst_size = Device.check_range_size(int(dst_max) - int(dst_min) + 1,
219 lcm_port = utils.lcm(udp_src_size, udp_dst_size)
220 assert utils.lcm(lcm_ip, lcm_port) < 29
223 def test_check_range_size():
224 assert Device.check_range_size(256, 1) == 256
225 assert Device.check_range_size(256, 3) == 86
226 assert Device.check_range_size(256, 4) == 64
227 assert Device.check_range_size(16, 10) == 2
228 assert Device.check_range_size(1, 10) == 1
229 with pytest.raises(ZeroDivisionError):
230 Device.check_range_size(256, 0)
233 def test_reserve_ip_range():
234 ipb = IpBlock('10.0.0.0', '0.0.0.1', 256)
235 src_ip_first, src_ip_last = ipb.reserve_ip_range(256)
236 assert src_ip_first == "10.0.0.0"
237 assert src_ip_last == "10.0.0.255"
238 ipb = IpBlock('20.0.0.0', '0.0.0.1', 2)
239 src_ip_first, src_ip_last = ipb.reserve_ip_range(2)
240 assert src_ip_first == "20.0.0.0"
241 assert src_ip_last == "20.0.0.1"
242 ipb = IpBlock('30.0.0.0', '0.0.0.1', 2)
243 with pytest.raises(IndexError):
244 ipb.reserve_ip_range(256)
247 def check_stream_configs(gen_config):
248 """Verify that the range for each chain have adjacent IP ranges without holes between chains."""
249 config = gen_config.config
250 tgc = config['traffic_generator']
251 step = Device.ip_to_int(tgc['ip_addrs_step'])
253 sip = Device.ip_to_int(tgc['ip_addrs'][0].split('/')[0])
254 dip = Device.ip_to_int(tgc['ip_addrs'][1].split('/')[0])
255 stream_configs = gen_config.devices[0].get_stream_configs()
256 for index in range(config['service_chain_count']):
257 stream_cfg = stream_configs[index]
258 # ip_src_static == True
259 assert stream_cfg['ip_src_count'] == 1
261 assert stream_cfg['ip_dst_count'] == 4999
263 assert stream_cfg['ip_dst_count'] == 5000
264 assert stream_cfg['ip_src_addr'] == Device.int_to_ip(sip)
265 assert Device.ip_to_int(stream_cfg['ip_src_addr']) == sip
266 assert Device.ip_to_int(stream_cfg['ip_dst_addr']) == dip
267 count = stream_cfg['ip_dst_count']
271 assert cfc == int(config['flow_count'] / 2)
273 def _check_device_flow_config(step_ip):
274 config = _get_dummy_tg_config('PVP', '1Mpps', scc=10, fc=99999, step_ip=step_ip)
275 gen_config = GeneratorConfig(config)
276 check_stream_configs(gen_config)
278 def test_device_flow_config():
279 _check_device_flow_config('0.0.0.1')
280 _check_device_flow_config('0.0.0.2')
283 def check_udp_stream_configs(gen_config, expected_cfg):
284 """Verify that the range for each chain have adjacent UDP ports without holes between chains."""
285 config = gen_config.config
286 stream_configs = gen_config.devices[0].get_stream_configs()
287 for index in range(config['service_chain_count']):
288 stream_cfg = stream_configs[index]
289 expected = expected_cfg[index]
290 assert stream_cfg['ip_src_addr'] == expected['ip_src_addr']
291 assert stream_cfg['ip_src_addr_max'] == expected['ip_src_addr_max']
292 assert stream_cfg['ip_src_count'] == expected['ip_src_count']
294 assert stream_cfg['ip_dst_addr'] == expected['ip_dst_addr']
295 assert stream_cfg['ip_dst_addr_max'] == expected['ip_dst_addr_max']
296 assert stream_cfg['ip_dst_count'] == expected['ip_dst_count']
298 assert stream_cfg['udp_src_port'] == expected['udp_src_port']
299 assert stream_cfg['udp_src_port_max'] == expected['udp_src_port_max']
300 assert stream_cfg['udp_src_count'] == expected['udp_src_count']
302 assert stream_cfg['udp_dst_port'] == expected['udp_dst_port']
303 assert stream_cfg['udp_dst_port_max'] == expected['udp_dst_port_max']
304 assert stream_cfg['udp_dst_count'] == expected['udp_dst_count']
306 lcm_ip = utils.lcm(stream_cfg['ip_src_count'], stream_cfg['ip_dst_count'])
307 udp_src_size = int(stream_cfg['udp_src_port_max']) - int(stream_cfg['udp_src_port']) + 1
308 udp_dst_size = int(stream_cfg['udp_dst_port_max']) - int(stream_cfg['udp_dst_port']) + 1
309 lcm_udp = utils.lcm(udp_src_size, udp_dst_size)
310 assert utils.lcm(lcm_ip, lcm_udp) >= stream_cfg['count']
313 def _check_device_udp_flow_config(param, expected_cfg):
314 config = _get_dummy_tg_config('PVP', '1Mpps',
316 ip_src_static=param['ip_src_static'],
317 fc=param['flow_count'],
318 ip0=param['ip_src_addr'],
319 ip1=param['ip_dst_addr'],
320 step_ip=param['ip_addrs_step'],
321 src_udp=param['udp_src_port'],
322 dst_udp=param['udp_dst_port'],
323 step_udp=param['udp_port_step'])
324 gen_config = GeneratorConfig(config)
325 check_udp_stream_configs(gen_config, expected_cfg)
328 def __get_udp_params():
329 param = {'ip_src_static': True,
330 'ip_src_addr': '110.0.0.0/32',
331 'ip_dst_addr': '120.0.0.0/32',
332 'ip_addrs_step': '0.0.0.1',
337 'udp_port_step': '1'}
341 def __get_udp_expected_list():
342 expected = {'ip_src_addr': '110.0.0.0',
343 'ip_src_addr_max': '110.0.0.0',
345 'ip_dst_addr': '120.0.0.0',
346 'ip_dst_addr_max': '120.0.0.0',
349 'udp_src_port_max': 53,
352 'udp_dst_port_max': 53,
357 def test_device_udp_flow_config_single_ip_single_port():
358 param = __get_udp_params()
359 expected = __get_udp_expected_list()
360 _check_device_udp_flow_config(param, [expected])
363 def test_device_udp_flow_config_single_ip_multiple_src_ports():
364 param = __get_udp_params()
365 expected = __get_udp_expected_list()
366 # Overwrite the udp_src_port value to define a large range of ports
367 # instead of a single port, in order to check if the imposed
368 # flow count is respected. Notice that udp range >> flow count.
369 param['udp_src_port'] = [53, 1024]
370 param['flow_count'] = 10
371 expected['udp_src_port_max'] = 57
372 expected['udp_src_count'] = 5
373 _check_device_udp_flow_config(param, [expected])
376 def test_device_udp_flow_config_multiple_ip_src_single_port():
377 param = __get_udp_params()
378 expected = __get_udp_expected_list()
379 # Re affect the default udp_src_port values and
380 # overwrite the ip_dst_addr value to define a large range of addresses
381 # instead of a single one, in order to check if the imposed
382 # flow count is respected. Notice that the netmask allows a very larger
383 # range of possible addresses than the flow count value.
384 param['udp_src_port'] = 53
385 param['flow_count'] = 10
386 param['ip_src_static'] = False
387 param['ip_dst_addr'] = '120.0.0.0/24'
389 expected['udp_src_port_max'] = 53
390 expected['udp_src_count'] = 1
391 expected['ip_dst_addr'] = '120.0.0.0'
392 expected['ip_dst_addr_max'] = '120.0.0.4'
393 expected['ip_dst_count'] = 5
394 _check_device_udp_flow_config(param, [expected])
397 def test_device_udp_flow_config_multiple_ip_src_dst_multiple_src_dst_ports():
398 param = __get_udp_params()
399 expected = __get_udp_expected_list()
401 param['udp_src_port'] = [49000, 49031]
402 param['udp_dst_port'] = [50000, 50033]
403 param['ip_src_static'] = False
404 param['flow_count'] = 1000
405 param['ip_src_addr'] = '110.0.0.0/16'
406 param['ip_dst_addr'] = '120.0.0.0/16'
408 expected['udp_src_port'] = 49000
409 expected['udp_src_port_max'] = 49024
410 expected['udp_dst_port'] = 50000
411 expected['udp_dst_port_max'] = 50024
412 expected['udp_src_count'] = 25
413 expected['udp_dst_count'] = 25
414 expected['ip_src_addr_max'] = '110.0.1.243'
415 expected['ip_src_count'] = 500
416 expected['ip_dst_addr'] = '120.0.0.0'
417 expected['ip_dst_addr_max'] = '120.0.1.243'
418 expected['ip_dst_count'] = 500
419 _check_device_udp_flow_config(param, [expected])
424 def test_device_udp_flow_config_random_multiple_ip_src_dst_multiple_src_dst_ports():
425 param = __get_udp_params()
426 expected = __get_udp_expected_list()
428 param['udp_src_port'] = [1025, 65000]
429 param['udp_dst_port'] = [1024, 65000]
430 param['ip_src_static'] = False
431 param['ip_addrs_step'] = 'random'
432 param['udp_port_step'] = 'random'
433 param['flow_count'] = 1000000
434 param['ip_src_addr'] = '110.0.0.0/16'
435 param['ip_dst_addr'] = '120.0.0.0/16'
437 expected['udp_src_port'] = 1025
438 expected['udp_src_port_max'] = 65000
439 expected['udp_dst_port'] = 1024
440 expected['udp_dst_port_max'] = 65000
441 expected['udp_src_count'] = 62500
442 expected['udp_dst_count'] = 62500
443 expected['ip_src_addr_max'] = '110.0.0.31'
444 expected['ip_src_count'] = 32
445 expected['ip_dst_addr'] = '120.0.0.0'
446 expected['ip_dst_addr_max'] = '120.0.0.31'
447 expected['ip_dst_count'] = 32
448 _check_device_udp_flow_config(param, [expected])
450 def test_device_udp_flow_config_random_multiple_ip_srcstatic_dst_multiple_src_dst_ports():
451 param = __get_udp_params()
452 expected = __get_udp_expected_list()
454 param['udp_src_port'] = [1025, 65000]
455 param['udp_dst_port'] = [1024, 65000]
456 param['ip_src_static'] = True
457 param['ip_addrs_step'] = 'random'
458 param['udp_port_step'] = 'random'
459 param['flow_count'] = 1000000
460 param['ip_src_addr'] = '110.0.0.0/16'
461 param['ip_dst_addr'] = '120.0.0.0/16'
463 expected['udp_src_port'] = 1025
464 expected['udp_src_port_max'] = 65000
465 expected['udp_dst_port'] = 1024
466 expected['udp_dst_port_max'] = 65000
467 expected['udp_src_count'] = 1
468 expected['udp_dst_count'] = 62500
469 expected['ip_src_addr_max'] = '110.0.0.0'
470 expected['ip_src_count'] = 1
471 expected['ip_dst_addr'] = '120.0.0.0'
472 expected['ip_dst_addr_max'] = '120.0.0.31'
473 expected['ip_dst_count'] = 32
474 _check_device_udp_flow_config(param, [expected])
478 def test_device_udp_flow_config_single_ip_src_dst_multiple_src_dst_ports():
479 param = __get_udp_params()
480 expected = __get_udp_expected_list()
482 param['udp_src_port'] = [49152, 49154]
483 param['udp_dst_port'] = [50001, 50005]
484 param['ip_src_static'] = False
485 param['flow_count'] = 10
486 param['ip_src_addr'] = '110.0.0.0/32'
487 param['ip_dst_addr'] = '120.0.0.0/32'
489 expected['udp_src_port'] = 49152
490 expected['udp_src_port_max'] = 49152
491 expected['udp_dst_port'] = 50001
492 expected['udp_dst_port_max'] = 50005
493 expected['udp_src_count'] = 1
494 expected['udp_dst_count'] = 5
495 expected['ip_src_addr_max'] = '110.0.0.0'
496 expected['ip_src_count'] = 1
497 expected['ip_dst_addr'] = '120.0.0.0'
498 expected['ip_dst_addr_max'] = '120.0.0.0'
499 expected['ip_dst_count'] = 1
500 _check_device_udp_flow_config(param, [expected])
503 def test_device_udp_flow_config_single_ip_src_dst_single_src_multiple_dst_ports():
504 param = __get_udp_params()
505 expected = __get_udp_expected_list()
507 param['udp_src_port'] = 49152
508 param['udp_dst_port'] = [50001, 50029]
509 param['udp_port_step'] = '3'
510 param['flow_count'] = 58
511 param['ip_src_addr'] = '110.0.0.0/32'
512 param['ip_dst_addr'] = '120.0.0.0/32'
514 expected['udp_src_port'] = 49152
515 expected['udp_src_port_max'] = 49152
516 expected['udp_dst_port'] = 50001
517 expected['udp_dst_port_max'] = 50029
518 expected['udp_src_count'] = 1
519 expected['udp_dst_count'] = 29
520 expected['ip_src_addr_max'] = '110.0.0.0'
521 expected['ip_src_count'] = 1
522 expected['ip_dst_addr'] = '120.0.0.0'
523 expected['ip_dst_addr_max'] = '120.0.0.0'
524 expected['ip_dst_count'] = 1
525 with pytest.raises(TrafficClientException):
526 _check_device_udp_flow_config(param, [expected])
529 def test_device_udp_flow_config_scc3():
530 param = __get_udp_params()
531 expected = __get_udp_expected_list()
534 param['udp_src_port'] = [49000, 49031]
535 param['udp_dst_port'] = [50000, 50033]
536 param['ip_src_static'] = False
537 param['flow_count'] = 10000
538 param['ip_src_addr'] = '110.0.0.0/16'
539 param['ip_dst_addr'] = '120.0.0.0/16'
543 expected_scc0 = dict(expected)
544 expected_scc0['udp_src_port'] = 49000
545 expected_scc0['udp_src_port_max'] = 49016
546 expected_scc0['udp_dst_port'] = 50000
547 expected_scc0['udp_dst_port_max'] = 50033
548 expected_scc0['udp_src_count'] = 17
549 expected_scc0['udp_dst_count'] = 34
550 expected_scc0['ip_src_addr_max'] = '110.0.6.129'
551 expected_scc0['ip_src_count'] = 1666
552 expected_scc0['ip_dst_addr'] = '120.0.0.0'
553 expected_scc0['ip_dst_addr_max'] = '120.0.6.129'
554 expected_scc0['ip_dst_count'] = 1666
555 expected_cfg.append(expected_scc0)
558 expected_scc1 = dict(expected)
559 expected_scc1['udp_src_port'] = 49000
560 expected_scc1['udp_src_port_max'] = 49000
561 expected_scc1['udp_dst_port'] = 50000
562 expected_scc1['udp_dst_port_max'] = 50000
563 expected_scc1['udp_src_count'] = 1
564 expected_scc1['udp_dst_count'] = 1
565 expected_scc1['ip_src_addr'] = '110.0.6.130'
566 expected_scc1['ip_src_addr_max'] = '110.0.13.4'
567 expected_scc1['ip_src_count'] = 1667
568 expected_scc1['ip_dst_addr'] = '120.0.6.130'
569 expected_scc1['ip_dst_addr_max'] = '120.0.13.4'
570 expected_scc1['ip_dst_count'] = 1667
571 expected_cfg.append(expected_scc1)
574 expected_scc2 = dict(expected)
575 expected_scc2['udp_src_port'] = 49000
576 expected_scc2['udp_src_port_max'] = 49000
577 expected_scc2['udp_dst_port'] = 50000
578 expected_scc2['udp_dst_port_max'] = 50000
579 expected_scc2['udp_src_count'] = 1
580 expected_scc2['udp_dst_count'] = 1
581 expected_scc2['ip_src_addr'] = '110.0.13.5'
582 expected_scc2['ip_src_addr_max'] = '110.0.19.135'
583 expected_scc2['ip_src_count'] = 1667
584 expected_scc2['ip_dst_addr'] = '120.0.13.5'
585 expected_scc2['ip_dst_addr_max'] = '120.0.19.135'
586 expected_scc2['ip_dst_count'] = 1667
587 expected_cfg.append(expected_scc2)
589 _check_device_udp_flow_config(param, expected_cfg)
592 def test_device_udp_flow_config_doc_example1(caplog):
594 caplog.set_level(logging.INFO)
595 param = __get_udp_params()
596 expected = __get_udp_expected_list()
598 # Multiflow unitary test corresponding to first example in documentation
600 param['udp_src_port'] = 53
601 param['udp_dst_port'] = 53
602 param['ip_src_static'] = True
603 param['flow_count'] = 100
604 param['ip_src_addr'] = '110.0.0.0/8'
605 param['ip_dst_addr'] = '120.0.0.0/8'
609 expected_scc0 = dict(expected)
610 expected_scc0['udp_src_port'] = 53
611 expected_scc0['udp_src_port_max'] = 53
612 expected_scc0['udp_dst_port'] = 53
613 expected_scc0['udp_dst_port_max'] = 53
614 expected_scc0['udp_src_count'] = 1
615 expected_scc0['udp_dst_count'] = 1
616 expected_scc0['ip_src_addr'] = '110.0.0.0'
617 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
618 expected_scc0['ip_src_count'] = 1
619 expected_scc0['ip_dst_addr'] = '120.0.0.0'
620 expected_scc0['ip_dst_addr_max'] = '120.0.0.15'
621 expected_scc0['ip_dst_count'] = 16
622 expected_cfg.append(expected_scc0)
625 expected_scc1 = dict(expected)
626 expected_scc1['udp_src_port'] = 53
627 expected_scc1['udp_src_port_max'] = 53
628 expected_scc1['udp_dst_port'] = 53
629 expected_scc1['udp_dst_port_max'] = 53
630 expected_scc1['udp_src_count'] = 1
631 expected_scc1['udp_dst_count'] = 1
632 expected_scc1['ip_src_addr'] = '110.0.0.1'
633 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
634 expected_scc1['ip_src_count'] = 1
635 expected_scc1['ip_dst_addr'] = '120.0.0.16'
636 expected_scc1['ip_dst_addr_max'] = '120.0.0.32'
637 expected_scc1['ip_dst_count'] = 17
638 expected_cfg.append(expected_scc1)
641 expected_scc2 = dict(expected)
642 expected_scc2['udp_src_port'] = 53
643 expected_scc2['udp_src_port_max'] = 53
644 expected_scc2['udp_dst_port'] = 53
645 expected_scc2['udp_dst_port_max'] = 53
646 expected_scc2['udp_src_count'] = 1
647 expected_scc2['udp_dst_count'] = 1
648 expected_scc2['ip_src_addr'] = '110.0.0.2'
649 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
650 expected_scc2['ip_src_count'] = 1
651 expected_scc2['ip_dst_addr'] = '120.0.0.33'
652 expected_scc2['ip_dst_addr_max'] = '120.0.0.49'
653 expected_scc2['ip_dst_count'] = 17
654 expected_cfg.append(expected_scc2)
656 _check_device_udp_flow_config(param, expected_cfg)
657 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
660 def test_device_udp_flow_config_doc_example2(caplog):
662 caplog.set_level(logging.INFO)
663 param = __get_udp_params()
664 expected = __get_udp_expected_list()
666 # Multiflow unitary test corresponding to second example in documentation
668 param['udp_src_port'] = 53
669 param['udp_dst_port'] = 53
670 param['ip_src_static'] = True
671 param['ip_addrs_step'] = 'random'
672 param['flow_count'] = 100
673 param['ip_src_addr'] = '110.0.0.0/8'
674 param['ip_dst_addr'] = '120.0.0.0/8'
678 expected_scc0 = dict(expected)
679 expected_scc0['udp_src_port'] = 53
680 expected_scc0['udp_src_port_max'] = 53
681 expected_scc0['udp_dst_port'] = 53
682 expected_scc0['udp_dst_port_max'] = 53
683 expected_scc0['udp_src_count'] = 1
684 expected_scc0['udp_dst_count'] = 1
685 expected_scc0['ip_src_addr'] = '110.0.0.0'
686 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
687 expected_scc0['ip_src_count'] = 1
688 expected_scc0['ip_dst_addr'] = '120.0.0.0'
689 expected_scc0['ip_dst_addr_max'] = '120.0.0.15'
690 expected_scc0['ip_dst_count'] = 16
691 expected_cfg.append(expected_scc0)
694 expected_scc1 = dict(expected)
695 expected_scc1['udp_src_port'] = 53
696 expected_scc1['udp_src_port_max'] = 53
697 expected_scc1['udp_dst_port'] = 53
698 expected_scc1['udp_dst_port_max'] = 53
699 expected_scc1['udp_src_count'] = 1
700 expected_scc1['udp_dst_count'] = 1
701 expected_scc1['ip_src_addr'] = '110.0.0.1'
702 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
703 expected_scc1['ip_src_count'] = 1
704 expected_scc1['ip_dst_addr'] = '120.0.0.16'
705 expected_scc1['ip_dst_addr_max'] = '120.0.0.32'
706 expected_scc1['ip_dst_count'] = 17
707 expected_cfg.append(expected_scc1)
710 expected_scc2 = dict(expected)
711 expected_scc2['udp_src_port'] = 53
712 expected_scc2['udp_src_port_max'] = 53
713 expected_scc2['udp_dst_port'] = 53
714 expected_scc2['udp_dst_port_max'] = 53
715 expected_scc2['udp_src_count'] = 1
716 expected_scc2['udp_dst_count'] = 1
717 expected_scc2['ip_src_addr'] = '110.0.0.2'
718 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
719 expected_scc2['ip_src_count'] = 1
720 expected_scc2['ip_dst_addr'] = '120.0.0.33'
721 expected_scc2['ip_dst_addr_max'] = '120.0.0.49'
722 expected_scc2['ip_dst_count'] = 17
723 expected_cfg.append(expected_scc2)
725 _check_device_udp_flow_config(param, expected_cfg)
726 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
729 def test_device_udp_flow_config_doc_example3(caplog):
731 param = __get_udp_params()
732 expected = __get_udp_expected_list()
734 # Multiflow unitary test corresponding to third example in documentation
736 param['udp_src_port'] = 53
737 param['udp_dst_port'] = 53
738 param['ip_src_static'] = True
739 param['ip_addrs_step'] = '0.0.0.5'
740 param['flow_count'] = 100
741 param['ip_src_addr'] = '110.0.0.0/8'
742 param['ip_dst_addr'] = '120.0.0.0/8'
746 expected_scc0 = dict(expected)
747 expected_scc0['udp_src_port'] = 53
748 expected_scc0['udp_src_port_max'] = 53
749 expected_scc0['udp_dst_port'] = 53
750 expected_scc0['udp_dst_port_max'] = 53
751 expected_scc0['udp_src_count'] = 1
752 expected_scc0['udp_dst_count'] = 1
753 expected_scc0['ip_src_addr'] = '110.0.0.0'
754 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
755 expected_scc0['ip_src_count'] = 1
756 expected_scc0['ip_dst_addr'] = '120.0.0.0'
757 expected_scc0['ip_dst_addr_max'] = '120.0.0.75'
758 expected_scc0['ip_dst_count'] = 16
759 expected_cfg.append(expected_scc0)
762 expected_scc1 = dict(expected)
763 expected_scc1['udp_src_port'] = 53
764 expected_scc1['udp_src_port_max'] = 53
765 expected_scc1['udp_dst_port'] = 53
766 expected_scc1['udp_dst_port_max'] = 53
767 expected_scc1['udp_src_count'] = 1
768 expected_scc1['udp_dst_count'] = 1
769 expected_scc1['ip_src_addr'] = '110.0.0.5'
770 expected_scc1['ip_src_addr_max'] = '110.0.0.5'
771 expected_scc1['ip_src_count'] = 1
772 expected_scc1['ip_dst_addr'] = '120.0.0.80'
773 expected_scc1['ip_dst_addr_max'] = '120.0.0.160'
774 expected_scc1['ip_dst_count'] = 17
775 expected_cfg.append(expected_scc1)
778 expected_scc2 = dict(expected)
779 expected_scc2['udp_src_port'] = 53
780 expected_scc2['udp_src_port_max'] = 53
781 expected_scc2['udp_dst_port'] = 53
782 expected_scc2['udp_dst_port_max'] = 53
783 expected_scc2['udp_src_count'] = 1
784 expected_scc2['udp_dst_count'] = 1
785 expected_scc2['ip_src_addr'] = '110.0.0.10'
786 expected_scc2['ip_src_addr_max'] = '110.0.0.10'
787 expected_scc2['ip_src_count'] = 1
788 expected_scc2['ip_dst_addr'] = '120.0.0.165'
789 expected_scc2['ip_dst_addr_max'] = '120.0.0.245'
790 expected_scc2['ip_dst_count'] = 17
791 expected_cfg.append(expected_scc2)
793 caplog.set_level(logging.INFO)
794 _check_device_udp_flow_config(param, expected_cfg)
795 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
798 def test_device_udp_flow_config_doc_example4(caplog):
800 param = __get_udp_params()
801 expected = __get_udp_expected_list()
803 # Multiflow unitary test corresponding to fourth example in documentation
805 param['udp_src_port'] = [10, 14]
806 param['udp_dst_port'] = [20, 25]
807 param['ip_src_static'] = True
808 param['ip_addrs_step'] = '0.0.0.1'
809 param['udp_port_step'] = 'random'
810 param['flow_count'] = 100
811 param['ip_src_addr'] = '110.0.0.0/29'
812 param['ip_dst_addr'] = '120.0.0.0/30'
816 expected_scc0 = dict(expected)
817 expected_scc0['udp_src_port'] = 10
818 expected_scc0['udp_src_port_max'] = 14
819 expected_scc0['udp_dst_port'] = 20
820 expected_scc0['udp_dst_port_max'] = 25
821 expected_scc0['udp_src_count'] = 5
822 expected_scc0['udp_dst_count'] = 6
823 expected_scc0['ip_src_addr'] = '110.0.0.0'
824 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
825 expected_scc0['ip_src_count'] = 1
826 expected_scc0['ip_dst_addr'] = '120.0.0.0'
827 expected_scc0['ip_dst_addr_max'] = '120.0.0.0'
828 expected_scc0['ip_dst_count'] = 1
829 expected_cfg.append(expected_scc0)
832 expected_scc1 = dict(expected)
833 expected_scc1['udp_src_port'] = 10
834 expected_scc1['udp_src_port_max'] = 14
835 expected_scc1['udp_dst_port'] = 20
836 expected_scc1['udp_dst_port_max'] = 25
837 expected_scc1['udp_src_count'] = 5
838 expected_scc1['udp_dst_count'] = 6
839 expected_scc1['ip_src_addr'] = '110.0.0.1'
840 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
841 expected_scc1['ip_src_count'] = 1
842 expected_scc1['ip_dst_addr'] = '120.0.0.1'
843 expected_scc1['ip_dst_addr_max'] = '120.0.0.1'
844 expected_scc1['ip_dst_count'] = 1
845 expected_cfg.append(expected_scc1)
848 expected_scc2 = dict(expected)
849 expected_scc2['udp_src_port'] = 10
850 expected_scc2['udp_src_port_max'] = 14
851 expected_scc2['udp_dst_port'] = 20
852 expected_scc2['udp_dst_port_max'] = 25
853 expected_scc2['udp_src_count'] = 5
854 expected_scc2['udp_dst_count'] = 6
855 expected_scc2['ip_src_addr'] = '110.0.0.2'
856 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
857 expected_scc2['ip_src_count'] = 1
858 expected_scc2['ip_dst_addr'] = '120.0.0.2'
859 expected_scc2['ip_dst_addr_max'] = '120.0.0.2'
860 expected_scc2['ip_dst_count'] = 1
861 expected_cfg.append(expected_scc2)
862 caplog.set_level(logging.INFO)
863 _check_device_udp_flow_config(param, expected_cfg)
864 assert "Current values of ip_addrs_step and/or udp_port_step properties" in caplog.text
865 assert "udp_port_step='1' (previous value: udp_port_step='random'" in caplog.text
868 def test_device_udp_flow_config_no_random_steps_overridden(caplog):
870 param = __get_udp_params()
871 expected = __get_udp_expected_list()
873 # Multiflow unitary test corresponding to fifth example in documentation
875 param['udp_src_port'] = [10, 14]
876 param['udp_dst_port'] = [20, 25]
877 param['ip_src_static'] = True
878 param['ip_addrs_step'] = 'random'
879 param['udp_port_step'] = 'random'
880 param['flow_count'] = 100
881 param['ip_src_addr'] = '110.0.0.0/29'
882 param['ip_dst_addr'] = '120.0.0.0/30'
886 expected_scc0 = dict(expected)
887 expected_scc0['udp_src_port'] = 10
888 expected_scc0['udp_src_port_max'] = 14
889 expected_scc0['udp_dst_port'] = 20
890 expected_scc0['udp_dst_port_max'] = 25
891 expected_scc0['udp_src_count'] = 5
892 expected_scc0['udp_dst_count'] = 6
893 expected_scc0['ip_src_addr'] = '110.0.0.0'
894 expected_scc0['ip_src_addr_max'] = '110.0.0.0'
895 expected_scc0['ip_src_count'] = 1
896 expected_scc0['ip_dst_addr'] = '120.0.0.0'
897 expected_scc0['ip_dst_addr_max'] = '120.0.0.0'
898 expected_scc0['ip_dst_count'] = 1
899 expected_cfg.append(expected_scc0)
902 expected_scc1 = dict(expected)
903 expected_scc1['udp_src_port'] = 10
904 expected_scc1['udp_src_port_max'] = 14
905 expected_scc1['udp_dst_port'] = 20
906 expected_scc1['udp_dst_port_max'] = 25
907 expected_scc1['udp_src_count'] = 5
908 expected_scc1['udp_dst_count'] = 6
909 expected_scc1['ip_src_addr'] = '110.0.0.1'
910 expected_scc1['ip_src_addr_max'] = '110.0.0.1'
911 expected_scc1['ip_src_count'] = 1
912 expected_scc1['ip_dst_addr'] = '120.0.0.1'
913 expected_scc1['ip_dst_addr_max'] = '120.0.0.1'
914 expected_scc1['ip_dst_count'] = 1
915 expected_cfg.append(expected_scc1)
918 expected_scc2 = dict(expected)
919 expected_scc2['udp_src_port'] = 10
920 expected_scc2['udp_src_port_max'] = 14
921 expected_scc2['udp_dst_port'] = 20
922 expected_scc2['udp_dst_port_max'] = 25
923 expected_scc2['udp_src_count'] = 5
924 expected_scc2['udp_dst_count'] = 6
925 expected_scc2['ip_src_addr'] = '110.0.0.2'
926 expected_scc2['ip_src_addr_max'] = '110.0.0.2'
927 expected_scc2['ip_src_count'] = 1
928 expected_scc2['ip_dst_addr'] = '120.0.0.2'
929 expected_scc2['ip_dst_addr_max'] = '120.0.0.2'
930 expected_scc2['ip_dst_count'] = 1
931 expected_cfg.append(expected_scc2)
932 caplog.set_level(logging.INFO)
933 _check_device_udp_flow_config(param, expected_cfg)
934 assert "Current values of ip_addrs_step and/or udp_port_step properties" not in caplog.text
938 refcfg = {1: 100, 2: {21: 100, 22: 200}, 3: None}
939 res1 = {1: 10, 2: {21: 100, 22: 200}, 3: None}
940 res2 = {1: 100, 2: {21: 1000, 22: 200}, 3: None}
941 res3 = {1: 100, 2: {21: 100, 22: 200}, 3: "abc"}
942 assert config_loads("{}", refcfg) == refcfg
943 assert config_loads("{1: 10}", refcfg) == res1
944 assert config_loads("{2: {21: 1000}}", refcfg) == res2
945 assert config_loads('{3: "abc"}', refcfg) == res3
948 # pairs of input string and expected subset (None if identical)
951 ["{2: {21: 100, 30: 50}}", "{2: {30: 50}}"],
952 ["{2: {0: 1, 1: 2}, 5: 5}", None],
953 ["{1: 'abc', 2: {21: 0}}", "{1: 'abc'}"],
956 for fail_pair in fail_pairs:
957 with pytest.raises(Exception) as e_info:
958 config_loads(fail_pair[0], refcfg)
959 expected = fail_pair[1]
961 expected = fail_pair[0]
962 assert expected in str(e_info)
965 flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0,
966 'extra_specs': {'hw:cpu_policy': 'dedicated'}}}
967 new_flavor = {'flavor': {'vcpus': 2, 'ram': 8192, 'disk': 0,
968 'extra_specs': {'hw:cpu_policy': 'dedicated', 'hw:numa_nodes': 2}}}
969 assert config_loads("{'flavor': {'extra_specs': {'hw:numa_nodes': 2}}}", flavor,
970 whitelist_keys=['alpha', 'extra_specs']) == new_flavor
974 logger = logging.getLogger('fluent-logger')
976 class FluentdConfig(dict):
977 def __getattr__(self, attr):
978 return self.get(attr)
982 'logging_tag': 'nfvbench',
983 'result_tag': 'resultnfvbench',
988 'logging_tag': 'nfvbench',
989 'result_tag': 'resultnfvbench',
995 'result_tag': 'resultnfvbench',
1000 'logging_tag': 'nfvbench',
1007 handler = FluentLogHandler(fluentd_configs=fluentd_configs)
1008 logger.addHandler(handler)
1009 logger.setLevel(logging.INFO)
1011 logger.warning('test %d', 100)
1014 raise Exception("test")
1016 logger.exception("got exception")
1018 def assert_ndr_pdr(stats, ndr, ndr_dr, pdr, pdr_dr):
1019 assert stats['ndr']['rate_percent'] == ndr
1020 assert stats['ndr']['stats']['overall']['drop_percentage'] == ndr_dr
1021 assert_equivalence(pdr, stats['pdr']['rate_percent'])
1022 assert_equivalence(pdr_dr, stats['pdr']['stats']['overall']['drop_percentage'])
1024 def _get_dummy_tg_config(chain_type, rate, scc=1, fc=10, step_ip='0.0.0.1',
1025 ip0='10.0.0.0/8', ip1='20.0.0.0/8',
1026 step_udp='1', src_udp=None, dst_udp=None, ip_src_static=True):
1028 'traffic_generator': {'host_name': 'nfvbench_tg',
1029 'default_profile': 'dummy',
1030 'generator_profile': [{'name': 'dummy',
1033 'intf_speed': '10Gbps',
1034 'interfaces': [{'port': 0, 'pci': '0.0'},
1035 {'port': 1, 'pci': '0.0'}]}],
1036 'ip_addrs_step': step_ip,
1037 'ip_addrs': [ip0, ip1],
1038 'ip_src_static': ip_src_static,
1039 'tg_gateway_ip_addrs': ['1.1.0.100', '2.2.0.100'],
1040 'tg_gateway_ip_addrs_step': step_ip,
1041 'gateway_ip_addrs': ['1.1.0.2', '2.2.0.2'],
1042 'gateway_ip_addrs_step': step_ip,
1043 'mac_addrs_left': None,
1044 'mac_addrs_right': None,
1045 'udp_src_port': src_udp,
1046 'udp_dst_port': dst_udp,
1047 'udp_port_step': step_udp},
1048 'traffic': {'profile': 'profile_64',
1049 'bidirectional': True},
1050 'traffic_profile': [{'name': 'profile_64', 'l2frame_size': ['64']}],
1051 'generator_profile': None,
1052 'service_chain': chain_type,
1053 'service_chain_count': scc,
1055 'vlan_tagging': True,
1061 'check_traffic_time_sec': 200,
1062 'generic_poll_sec': 2,
1063 'measurement': {'NDR': 0.001, 'PDR': 0.1, 'load_epsilon': 0.1},
1064 'l2_loopback': False,
1066 'mbuf_factor': None,
1067 'disable_hdrh': None,
1069 'service_mode': False,
1070 'no_flow_stats': False,
1071 'no_latency_stats': False,
1072 'no_latency_streams': False,
1073 'intf_speed': '10Gbps',
1074 'periodic_gratuitous_arp': False,
1075 'gratuitous_arp_pps': 1
1078 def _get_traffic_client(user_info=None):
1079 config = _get_dummy_tg_config('PVP', 'ndr_pdr')
1080 config['vxlan'] = False
1081 config['mpls'] = False
1082 config['ndr_run'] = True
1083 config['pdr_run'] = True
1084 config['generator_profile'] = 'dummy'
1085 config['single_run'] = False
1087 config['user_info'] = user_info
1088 traffic_client = TrafficClient(config)
1089 traffic_client.start_traffic_generator()
1090 traffic_client.set_traffic('64', True)
1091 return traffic_client
1093 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1094 def test_ndr_at_lr():
1095 """Test NDR at line rate."""
1096 traffic_client = _get_traffic_client()
1097 tg = traffic_client.gen
1098 # this is a perfect sut with no loss at LR
1099 tg.set_response_curve(lr_dr=0, ndr=100, max_actual_tx=100, max_11_tx=100)
1100 # tx packets should be line rate for 64B and no drops...
1101 assert tg.get_tx_pps_dropped_pps(100) == (LR_64B_PPS, 0)
1102 # NDR and PDR should be at 100%
1103 # traffic_client.ensure_end_to_end()
1104 results = traffic_client.get_ndr_and_pdr()
1105 assert_ndr_pdr(results, 200.0, 0.0, 200.0, 0.0)
1107 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1108 def test_ndr_at_50():
1109 """Test NDR at 50% line rate.
1111 This is a sut with an NDR of 50% and linear drop rate after NDR up to 20% drops at LR
1112 (meaning that if you send 100% TX, you will only receive 80% RX)
1113 the tg requested TX/actual TX ratio is up to 50%, after 50%
1114 is linear up 80% actuak TX when requesting 100%
1116 traffic_client = _get_traffic_client()
1117 tg = traffic_client.gen
1119 tg.set_response_curve(lr_dr=20, ndr=50, max_actual_tx=80, max_11_tx=50)
1120 # tx packets should be half line rate for 64B and no drops...
1121 assert tg.get_tx_pps_dropped_pps(50) == (LR_64B_PPS / 2, 0)
1122 # at 100% TX requested, actual TX is 80% where the drop rate is 3/5 of 20% of the actual TX
1123 assert tg.get_tx_pps_dropped_pps(100) == (int(LR_64B_PPS * 0.8),
1124 int(LR_64B_PPS * 0.8 * 0.6 * 0.2))
1125 results = traffic_client.get_ndr_and_pdr()
1126 assert_ndr_pdr(results, 100.0, 0.0, 100.781, 0.09374)
1128 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1129 def test_ndr_pdr_low_cpu():
1130 """Test NDR and PDR with too low cpu.
1132 This test is for the case where the TG is underpowered and cannot send fast enough for the NDR
1133 true NDR=40%, actual TX at 50% = 30%, actual measured DR is 0%
1134 The ndr/pdr should bail out with a warning and a best effort measured NDR of 30%
1136 traffic_client = _get_traffic_client()
1137 tg = traffic_client.gen
1138 tg.set_response_curve(lr_dr=50, ndr=40, max_actual_tx=60, max_11_tx=0)
1139 # tx packets should be 30% at requested half line rate for 64B and no drops...
1140 assert tg.get_tx_pps_dropped_pps(50) == (int(LR_64B_PPS * 0.3), 0)
1141 results = traffic_client.get_ndr_and_pdr()
1144 # pp = pprint.PrettyPrinter(indent=4)
1145 # pp.pprint(results)
1147 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1148 def test_ndr_at_lr_sdn_gw_encapsulation():
1149 """Test NDR at line rate with traffic gen outside SUT and connected via SDN GW."""
1150 user_info = {'extra_encapsulation_bytes': 28}
1151 traffic_client = _get_traffic_client(user_info)
1152 tg = traffic_client.gen
1153 # this is a perfect sut with no loss at LR
1154 tg.set_response_curve(lr_dr=0, ndr=100, max_actual_tx=100, max_11_tx=100)
1155 # tx packets should be line rate for 64B and no drops...
1156 assert tg.get_tx_pps_dropped_pps(100) == (LR_64B_PPS, 0)
1157 # NDR and PDR should be at 100%
1158 # traffic_client.ensure_end_to_end()
1159 results = traffic_client.get_ndr_and_pdr()
1160 assert results['ndr']['stats']['theoretical_tx_rate_bps'] == 15000000000.0
1161 assert_ndr_pdr(results, 200.0, 0.0, 200.0, 0.0)
1163 @patch.object(TrafficClient, 'skip_sleep', lambda x: True)
1164 def test_no_openstack():
1165 """Test nfvbench using main."""
1166 config = _get_dummy_tg_config('EXT', '1000pps')
1167 config.openrc_file = None
1168 config.vlans = [[100], [200]]
1169 config['traffic_generator']['mac_addrs_left'] = ['00:00:00:00:00:00']
1170 config['traffic_generator']['mac_addrs_right'] = ['00:00:00:00:01:00']
1171 del config['generator_profile']
1173 sys.argv = [old_argv[0], '-c', json.dumps(config)]
1174 nfvbench.nfvbench.main()