Package: chimera-core
Xena OpenAutomation Chimera CoreXOA Chimera Core provides a set of high-level APIs to administer Xena's network impairment emulator,Chimerafor test automation.IntroductionThe XOA Chimera Core is a Python library that provides a user-friendly and powerful interface for automating network impairment emulation tasks using Xena Networks Emulator,Chimera.The XOA Chimera Core is designed to be easy to use and integrate with other automation tools and frameworks. It provides a comprehensive set of methods and classes for interacting with Chimera, including the ability to create and run complex impairment scenarios.The XOA Chimera Core simplifies the process of automating network impairment emulation tasks. It provides a simple, yet powerful, interface for interacting with Chimera using the Python programming language. With the XOA Chimera Core, testing professionals can easily create and execute network impairment scenarios, analyze traffic, and perform detailed analysis of 5G ORAN, all while leveraging the power and flexibility of the Python programming language.Overall, the XOA Chimera Core is a valuable tool for anyone looking to automate their network emulation tasks using Xena Chimera. With its simple, yet powerful, interface and support for the Python programming language, the XOA Chimera Core provides a set of flexible and extensible APIs for automating network emulation and improving the quality of network infrastructure.Chimera is a network impairment emulator that makes it easy to introduce consistent, accurate, well-defined and repeatable impairments (e.g. packet manipulation, packet drop, latency and jitter) to traffic between DUTs in the lab. All rates from 10GE to 100GE are supported by a single 2-slot test module.Chimera is ideal for NEMs who want to optimize Quality of Experience (QoE) for customers by ensuring equipment can handle acceptable levels of impairment. Service providers, enterprises, and government agencies can also use Chimera to validate Quality of Service (QoS) for voice, video, and data traffic being sent across their networks.Chimera can be installed as a test module in a ValkyrieBay chassis for seamless integration withValkyrieManager. This provides a simple way to impair traffic being generated by Valkyrie from within the same UI - a unique feature for Chimera. Or it is available in a compact chassis for use as a standalone solution for emulating impairment on traffic between two DUTs.Chimera can also be controlled usingXOA CLI, a simple and easy to use command-line-interface scripting API making test automation easy and fast. The result is a cost-effective and powerful network impairment emulator solution for benchmarking, stress testing/negative testing, "what-if" testing, and regression testing.IMPORTANTFor a brief product overview, go toChimera Fact Sheet.For complete details of how to use Chimera, go toChimera User Manual.For detailed technical specifications, go toChimera Data Sheet.DocumentationThe user documentation is hosted:Xena OpenAutomation Chimera Core DocumentationInstallationInstall UsingpipMake sure Pythonpipis installed on you system. If you are using virtualenv, then pip is already installed into environments created by virtualenv, and using sudo is not needed. If you do not have pip installed, download this file:https://bootstrap.pypa.io/get-pip.pyand runpython get-pip.py.To install the latest, use pip to install from pypi:~/>pipinstallchimera-coreTo upgrade to the latest, use pip to upgrade from pypi:~/>pipinstallchimera-core--upgradeInstall From Source CodeMake sure these packages are installedwheel,setuptoolson your system.Installsetuptoolsusing pip:~/>pipinstallwheelsetuptoolsTo install source of python packages:/xoa_driver>pythonsetup.pyinstallTo build.whlfile for distribution:/xoa_driver>pythonsetup.pybdist_wheelQuick StartGet Python pip if not already installed (Downloadhttps://bootstrap.pypa.io/get-pip.py):python get-pip.pyInstall the latest chimera-core:pip install chimera-core -UWrite Python code to manage with Xena testers:importasynciofromfunctoolsimportpartialfromtypingimportListfromipaddressimportIPv4Address,IPv6Addressfromloguruimportloggerfromchimera_core.controllerimportMainControllerfromchimera_core.typesimportdistributions,enums,datasetCHASSIS_IP="10.20.1.252"USERNAME="chimera-core"MODULE_IDX=11PORT_IDX=0FLOW_IDX=1asyncdefmy_awesome_func(stop_event:asyncio.Event):# create credential objectcredentials=dataset.Credentials(product=dataset.EProductType.VALKYRIE,host=CHASSIS_IP)#----------------------------------------------# 1. Connect to Valkyrie chassis and select port# ---------------------------------------------# region Connect to Valkyrie chassis and select port# create chimera core controller objectcontroller=awaitMainController()# add chimera emulator into the chassis inventory and get the IDtester_id=awaitcontroller.add_tester(credentials=credentials)# create tester objecttester=awaitcontroller.use_tester(tester_id,username=USERNAME,reserve=False,debug=False)# create module objectmodule=awaittester.use_module(module_id=MODULE_IDX,reserve=False)# free the module in case it is reserved by othersawaitmodule.free(should_free_sub_resources=True)awaitmodule.reserve()# create port object and reserver the portport=awaittester.use_port(module_id=MODULE_IDX,port_id=PORT_IDX,reserve=False)# reserve the portawaitport.reserve()# reset portawaitport.reset()# endregion#----------------------------------------------# 2. Configure Chimera port# ---------------------------------------------# region Configure Chimera portport_config=awaitport.config.get()port_config.comment="My Chimera Port"port_config.set_autoneg_on()port_config.set_autoneg_off()port_config.set_fcs_error_mode_discard()port_config.set_fcs_error_mode_pass()port_config.set_link_flap(enable=enums.OnOff.ON,duration=100,period=1000,repetition=0)port_config.set_link_flap_off()port_config.set_pma_error_pulse(enable=enums.OnOff.ON,duration=100,period=1000,repetition=0,coeff=100,exp=-4)port_config.set_pma_error_pulse_off()port_config.set_impairment_off()port_config.set_impairment_on()awaitport.config.set(port_config)# endregion#----------------------------------------------# 3. Configure flow's basic filter on a port# ---------------------------------------------# region Flow configuration + basic filter on a port# Configure flow propertiesflow=port.flows[FLOW_IDX]flow_config=awaitflow.get()flow_config.comment="On VLAN 111"awaitflow.set(config=flow_config)# Initialize shadow filter on the flowshadow_filter=flow.shadow_filterawaitshadow_filter.init()awaitshadow_filter.clear()# Configure shadow filter to BASIC modebasic_filter=awaitshadow_filter.use_basic_mode()basic_filter_config=awaitbasic_filter.get()awaitbasic_filter.set(basic_filter_config)awaitshadow_filter.enable()awaitshadow_filter.apply()# Configure flow propertiesflow=port.flows[FLOW_IDX]flow_config=awaitflow.get()flow_config.comment="On VLAN 111"awaitflow.set(config=flow_config)# Initialize shadow filter on the flowshadow_filter=flow.shadow_filterawaitshadow_filter.init()awaitshadow_filter.clear()# Gaussian distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Gaussian(mean=1,sd=1)dist.continuous()# Set distribution and start impairment Latency & Jitterlatency_jitter_config=awaitflow.latency_jitter.get()latency_jitter_config.set_distribution(dist)awaitflow.latency_jitter.start(latency_jitter_config)awaitflow.latency_jitter.stop(latency_jitter_config)#------------------# Ethernet subfilter#------------------# Use and configure basic-mode shadow filter's Ethernet subfilterethernet_subfilter=basic_filter_config.layer_2.use_ethernet()ethernet_subfilter.exclude()ethernet_subfilter.include()ethernet_subfilter.src_addr.on(value=dataset.Hex("AAAAAAAAAAAA"),mask=dataset.Hex("FFFFFFFFFFFF"))ethernet_subfilter.dest_addr.on(value=dataset.Hex("BBBBBBBBBBBB"),mask=dataset.Hex("FFFFFFFFFFFF"))#------------------# Layer 2+ subfilter#------------------# Not use basic-mode shadow filter's Layer 2+ subfilterlayer_2_plus_subfilter=basic_filter_config.layer_2_plus.use_none()# Use and configure basic-mode shadow filter's Layer2+ subfilter (One VLAN tag)layer_2_plus_subfilter=basic_filter_config.layer_2_plus.use_1_vlan_tag()layer_2_plus_subfilter.off()layer_2_plus_subfilter.exclude()layer_2_plus_subfilter.include()layer_2_plus_subfilter.tag_inner.on(value=1234,mask=dataset.Hex("FFF"))layer_2_plus_subfilter.pcp_inner.on(value=3,mask=dataset.Hex("7"))# Use and configure basic-mode shadow filter's Layer2+ subfilter (Two VLAN tag)layer_2_plus_subfilter=basic_filter_config.layer_2_plus.use_2_vlan_tags()layer_2_plus_subfilter.off()layer_2_plus_subfilter.exclude()layer_2_plus_subfilter.include()layer_2_plus_subfilter.tag_inner.on(value=1234,mask=dataset.Hex("FFF"))layer_2_plus_subfilter.pcp_inner.on(value=3,mask=dataset.Hex("7"))layer_2_plus_subfilter.tag_outer.on(value=2345,mask=dataset.Hex("FFF"))layer_2_plus_subfilter.pcp_outer.on(value=0,mask=dataset.Hex("7"))# Use and configure basic-mode shadow filter's Layer2+ subfilter (MPLS)layer_2_plus_subfilter=basic_filter_config.layer_2_plus.use_mpls()layer_2_plus_subfilter.off()layer_2_plus_subfilter.exclude()layer_2_plus_subfilter.include()layer_2_plus_subfilter.label.on(value=1000,mask=dataset.Hex("FFFFF"))layer_2_plus_subfilter.toc.on(value=0,mask=dataset.Hex("7"))#------------------# Layer 3 subfilter#------------------# Not use basic-mode shadow filter's Layer 3 subfilterlayer_3_subfilter=basic_filter_config.layer_3.use_none()# Use and configure basic-mode shadow filter's Layer 3 subfilter (IPv4)layer_3_subfilter=basic_filter_config.layer_3.use_ipv4()layer_3_subfilter.off()layer_3_subfilter.exclude()layer_3_subfilter.include()layer_3_subfilter.src_addr.on(value=IPv4Address("10.0.0.2"),mask=dataset.Hex("FFFFFFFF"))layer_3_subfilter.dest_addr.on(value=IPv4Address("11.0.0.2"),mask=dataset.Hex("FFFFFFFF"))layer_3_subfilter.dscp.on(value=0,mask=dataset.Hex("FC"))# Use and configure basic-mode shadow filter's Layer 3 subfilter (IPv6)layer_3_subfilter=basic_filter_config.layer_3.use_ipv6()layer_3_subfilter.exclude()layer_3_subfilter.include()layer_3_subfilter.src_addr.on(value=IPv6Address("2001::2"),mask=dataset.Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))layer_3_subfilter.dest_addr.on(value=IPv6Address("2002::2"),mask=dataset.Hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))#------------------# Layer 4 subfilter#------------------# Not use basic-mode shadow filter's Layer 4 subfilterlayer_4_subfilter=basic_filter_config.layer_4.use_none()# Use and configure basic-mode shadow filter's Layer 4 subfilter (TCP)layer_4_subfilter=basic_filter_config.layer_4.use_tcp()layer_4_subfilter.off()layer_4_subfilter.exclude()layer_4_subfilter.include()layer_4_subfilter.src_port.on(value=1234,mask=dataset.Hex("FFFF"))layer_4_subfilter.dest_port.on(value=80,mask=dataset.Hex("FFFF"))# Use and configure basic-mode shadow filter's Layer 4 subfilter (UDP)layer_4_subfilter=basic_filter_config.layer_4.use_udp()layer_4_subfilter.off()layer_4_subfilter.exclude()layer_4_subfilter.include()layer_4_subfilter.src_port.on(value=1234,mask=dataset.Hex("FFFF"))layer_4_subfilter.dest_port.on(value=80,mask=dataset.Hex("FFFF"))#------------------# Layer Xena subfilter#------------------# Not use basic-mode shadow filter's Layer Xena subfilterlayer_xena_subfilter=basic_filter_config.layer_xena.use_none()# Use and configure basic-mode shadow filter's Layer 4 subfilter (TCP)layer_xena_subfilter=basic_filter_config.layer_xena.use_tpld()layer_xena_subfilter.exclude()layer_xena_subfilter.include()layer_xena_subfilter[0].on(tpld_id=2)layer_xena_subfilter[0].off()layer_xena_subfilter[1].on(tpld_id=4)layer_xena_subfilter[1].off()layer_xena_subfilter[2].on(tpld_id=6)layer_xena_subfilter[2].off()layer_xena_subfilter[3].on(tpld_id=8)layer_xena_subfilter[3].off()layer_xena_subfilter[4].on(tpld_id=10)layer_xena_subfilter[4].off()layer_xena_subfilter[5].on(tpld_id=20)layer_xena_subfilter[5].off()layer_xena_subfilter[6].on(tpld_id=40)layer_xena_subfilter[6].off()layer_xena_subfilter[7].on(tpld_id=60)layer_xena_subfilter[7].off()layer_xena_subfilter[8].on(tpld_id=80)layer_xena_subfilter[8].off()layer_xena_subfilter[9].on(tpld_id=100)layer_xena_subfilter[9].off()layer_xena_subfilter[10].on(tpld_id=102)layer_xena_subfilter[10].off()layer_xena_subfilter[11].on(tpld_id=104)layer_xena_subfilter[11].off()layer_xena_subfilter[12].on(tpld_id=106)layer_xena_subfilter[12].off()layer_xena_subfilter[13].on(tpld_id=108)layer_xena_subfilter[13].off()layer_xena_subfilter[14].on(tpld_id=110)layer_xena_subfilter[14].off()layer_xena_subfilter[15].on(tpld_id=200)layer_xena_subfilter[15].off()#------------------# Layer Any subfilter#------------------# Not use basic-mode shadow filter's Layer Any subfilterlayer_any_subfilter=basic_filter_config.layer_any.use_none()# Use and configure basic-mode shadow filter's Layer 4 subfilter (TCP)layer_any_subfilter=basic_filter_config.layer_any.use_any_field()layer_any_subfilter.off()layer_any_subfilter.exclude()layer_any_subfilter.include()layer_any_subfilter.on(position=0,value=dataset.Hex("112233445566"),mask=dataset.Hex("112233445566"))# Enable and apply the basic filter settingsawaitbasic_filter.set(basic_filter_config)awaitshadow_filter.enable()awaitshadow_filter.apply()# endregion#----------------------------------------------# 4. Configure flow's extended filter on a port# ---------------------------------------------# region Flow configuration + extended filter on a port# Configure flow propertiesflow=port.flows[FLOW_IDX]flow_config=awaitflow.get()flow_config.comment="On VLAN 111"awaitflow.set(config=flow_config)# Initialize shadow filter on the flowshadow_filter=flow.shadow_filterawaitshadow_filter.init()awaitshadow_filter.clear()# Configure shadow filter to EXTENDED modeextended_filter=awaitshadow_filter.use_extended_mode()extended_filter_config=awaitextended_filter.get()ethernet=dataset.ProtocolSegement(protocol_type=dataset.ProtocolOption.ETHERNET,value='000001111',mask='1110000',)ipv4_1=dataset.ProtocolSegement(protocol_type=dataset.ProtocolOption.IP,value='000001111',mask='1110000',)ipv4_2=dataset.ProtocolSegement(protocol_type=dataset.ProtocolOption.IP,value='000001111',mask='1110000',)extended_filter_config.protocol_segments=(ethernet,ipv4_1,ipv4_2)awaitextended_filter.set(extended_filter_config)awaitshadow_filter.enable()awaitshadow_filter.apply()# endregion#----------------------------------------------# 5. Configure impairment - Drop# ---------------------------------------------# region Configure impairment - Drop# Fixed Burst distribution for impairment Dropdist=distributions.drop.FixedBurst(burst_size=5)dist.repeat(period=5)dist.one_shot()# Random Burst distribution for impairment Dropdist=distributions.drop.RandomBurst(minimum=1,maximum=10,probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Fixed Rate distribution for impairment Dropdist=distributions.drop.FixedRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Bit Error Rate distribution for impairment Dropdist=distributions.drop.BitErrorRate(coefficient=1,exponent=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Random Rate distribution for impairment Dropdist=distributions.drop.RandomRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gilbert Elliot distribution for impairment Dropdist=distributions.drop.GilbertElliot(good_state_impair_prob=0,good_state_trans_prob=0,bad_state_impair_prob=0,bad_state_trans_prob=0)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Uniform distribution for impairment Dropdist=distributions.drop.Uniform(minimum=1,maximum=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gaussian distribution for impairment Dropdist=distributions.drop.Gaussian(mean=1,sd=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Poisson distribution for impairment Dropdist=distributions.drop.Poisson(lamda=9)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gamma distribution for impairment Dropdist=distributions.drop.Gamma(shape=1,scale=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Custom distribution for impairment Dropdata_x=[0,1]*256custom_distribution=awaitport.custom_distributions.add(linear=False,entry_count=len(data_x),data_x=data_x,comment="Example Custom Distribution")dist=distributions.drop.Custom(custom_distribution=custom_distribution)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Set distribution and start impairment Dropdrop_config=awaitflow.drop.get()drop_config.set_distribution(dist)awaitflow.drop.start(drop_config)awaitflow.drop.stop(drop_config)# endregion#----------------------------------------------# 6. Configure impairment - Misordering# ---------------------------------------------# region Configure impairment - Misordering# Fixed Burst distribution for impairment Misorderingdist=distributions.misordering.FixedBurst(burst_size=1)dist.repeat(period=5)dist.one_shot()# Fixed Rate distribution for impairment Misorderingdist=distributions.misordering.FixedRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Set distribution and start impairment Misorderingmisordering_config=awaitflow.misordering.get()misordering_config.depth=1misordering_config.set_distribution(dist)awaitflow.misordering.start(misordering_config)awaitflow.misordering.stop(misordering_config)# endregion#----------------------------------------------# 7. Configure impairment - Latency & Jitter# ---------------------------------------------# region Configure impairment - Latency & Jitter# Fixed Burst distribution for impairment Latency & Jitterdist=distributions.latency_jitter.ConstantDelay(delay=100)# Random Burst distribution for impairment Latency & Jitterdist=distributions.latency_jitter.AccumulateBurst(burst_delay=1300)dist.repeat(period=1)dist.one_shot()# Step distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Step(min=1300,max=77000)dist.continuous()# Uniform distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Uniform(minimum=1,maximum=1)dist.continuous()# Gaussian distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Gaussian(mean=1,sd=1)dist.continuous()# Poisson distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Poisson(lamda=9)dist.continuous()# Gamma distribution for impairment Latency & Jitterdist=distributions.latency_jitter.Gamma(shape=1,scale=1)dist.continuous()# Custom distribution for impairment Latency & Jitterdata_x=[0,1]*256custom_distribution=awaitport.custom_distributions.add(linear=False,entry_count=len(data_x),data_x=data_x,comment="Example Custom Distribution")dist=distributions.latency_jitter.Custom(custom_distribution=custom_distribution)dist.continuous()# Set distribution and start impairment Latency & Jitterlatency_jitter_config=awaitflow.latency_jitter.get()latency_jitter_config.set_distribution(dist)awaitflow.latency_jitter.start(latency_jitter_config)awaitflow.latency_jitter.stop(latency_jitter_config)# endregion#----------------------------------------------# 8. Configure impairment - Duplication# ---------------------------------------------# region Configure impairment - Duplication# Fixed Burst distribution for impairment Duplicationdist=distributions.duplication.FixedBurst(burst_size=5)dist.repeat(period=5)dist.one_shot()# Random Burst distribution for impairment Duplicationdist=distributions.duplication.RandomBurst(minimum=1,maximum=10,probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Fixed Rate distribution for impairment Duplicationdist=distributions.duplication.FixedRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Bit Error Rate distribution for impairment Duplicationdist=distributions.duplication.BitErrorRate(coefficient=1,exponent=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Random Rate distribution for impairment Duplicationdist=distributions.duplication.RandomRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gilbert Elliot distribution for impairment Duplicationdist=distributions.duplication.GilbertElliot(good_state_impair_prob=0,good_state_trans_prob=0,bad_state_impair_prob=0,bad_state_trans_prob=0)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Uniform distribution for impairment Duplicationdist=distributions.duplication.Uniform(minimum=1,maximum=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gaussian distribution for impairment Duplicationdist=distributions.duplication.Gaussian(mean=1,sd=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Poisson distribution for impairment Duplicationdist=distributions.duplication.Poisson(lamda=9)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gamma distribution for impairment Duplicationdist=distributions.duplication.Gamma(shape=1,scale=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Custom distribution for impairment Duplicationdata_x=[0,1]*256custom_distribution=awaitport.custom_distributions.add(linear=False,entry_count=len(data_x),data_x=data_x,comment="Example Custom Distribution")dist=distributions.duplication.Custom(custom_distribution=custom_distribution)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Set distribution and start impairment Duplicationduplication_config=awaitflow.duplication.get()duplication_config.set_distribution(dist)awaitflow.duplication.start(duplication_config)awaitflow.duplication.stop(duplication_config)# endregion#----------------------------------------------# 9. Configure impairment - Corruption# ---------------------------------------------# region Configure impairment - Corruption# Fixed Burst distribution for impairment Corruptiondist=distributions.corruption.FixedBurst(burst_size=5)dist.repeat(period=5)dist.one_shot()# Random Burst distribution for impairment Corruptiondist=distributions.corruption.RandomBurst(minimum=1,maximum=10,probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Fixed Rate distribution for impairment Corruptiondist=distributions.corruption.FixedRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Bit Error Rate distribution for impairment Corruptiondist=distributions.corruption.BitErrorRate(coefficient=1,exponent=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Random Rate distribution for impairment Corruptiondist=distributions.corruption.RandomRate(probability=10_000)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gilbert Elliot distribution for impairment Corruptiondist=distributions.corruption.GilbertElliot(good_state_impair_prob=0,good_state_trans_prob=0,bad_state_impair_prob=0,bad_state_trans_prob=0)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Uniform distribution for impairment Corruptiondist=distributions.corruption.Uniform(minimum=1,maximum=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gaussian distribution for impairment Corruptiondist=distributions.corruption.Gaussian(mean=1,sd=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Poisson distribution for impairment Corruptiondist=distributions.corruption.Poisson(lamda=9)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Gamma distribution for impairment Corruptiondist=distributions.corruption.Gamma(shape=1,scale=1)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Custom distribution for impairment Corruptiondata_x=[0,1]*256custom_distribution=awaitport.custom_distributions.add(linear=False,entry_count=len(data_x),data_x=data_x,comment="Example Custom Distribution")dist=distributions.corruption.Custom(custom_distribution=custom_distribution)dist.repeat_pattern(duration=1,period=1)dist.continuous()# Set distribution and start impairment Corruptioncorruption_config=awaitflow.corruption.get()corruption_config.corruption_type=enums.CorruptionType.ETHcorruption_config.corruption_type=enums.CorruptionType.IPcorruption_config.corruption_type=enums.CorruptionType.TCPcorruption_config.corruption_type=enums.CorruptionType.UDPcorruption_config.set_distribution(dist)awaitflow.corruption.start(corruption_config)awaitflow.corruption.stop(corruption_config)# endregion#----------------------------------------------# 10. Configure bandwidth control - Policer# ---------------------------------------------# region Configure bandwidth control - Policer# Set and start bandwidth control Policerpolicer_config=awaitflow.policer.get()policer_config.set_control_mode(mode=enums.PolicerMode.L1)policer_config.set_control_on_l1()policer_config.set_control_mode(mode=enums.PolicerMode.L2)policer_config.set_control_on_l2()policer_config.mode=enums.PolicerMode.L1policer_config.mode=enums.PolicerMode.L2policer_config.cir=10_000policer_config.cbs=1_000policer_config.set_on_off(on_off=enums.OnOff.ON)policer_config.set_on()policer_config.set_on_off(on_off=enums.OnOff.OFF)policer_config.set_off()awaitflow.policer.start(policer_config)awaitflow.policer.stop(policer_config)# endregion#----------------------------------------------# 11. Configure bandwidth control - Shaper# ---------------------------------------------# region Configure bandwidth control - Shaper# Set and start bandwidth control Shapershaper_config=awaitflow.shaper.get()shaper_config.set_control_mode(mode=enums.PolicerMode.L1)shaper_config.set_control_on_l1()shaper_config.set_control_mode(mode=enums.PolicerMode.L2)shaper_config.set_control_on_l2()shaper_config.mode=enums.PolicerMode.L1shaper_config.mode=enums.PolicerMode.L2shaper_config.cir=10_000shaper_config.cbs=1_000shaper_config.buffer_size=1_000shaper_config.set_on_off(on_off=enums.OnOff.ON)shaper_config.set_on()shaper_config.set_on_off(on_off=enums.OnOff.OFF)shaper_config.set_off()awaitflow.shaper.start(shaper_config)awaitflow.shaper.stop(shaper_config)# endregion#----------------------------------------------# 12. Flow statistics# ---------------------------------------------# region Flow Statisticsrx_total=awaitflow.statistics.rx.total.get()rx_total.byte_countrx_total.packet_countrx_total.l2_bpsrx_total.ppstx_total=awaitflow.statistics.tx.total.get()tx_total.byte_counttx_total.packet_counttx_total.l2_bpstx_total.ppsflow_drop_total=awaitflow.statistics.total.dropped.get()flow_drop_total.pkt_drop_count_totalflow_drop_total.pkt_drop_count_programmedflow_drop_total.pkt_drop_count_bandwidthflow_drop_total.pkt_drop_count_otherflow_drop_total.pkt_drop_ratio_totalflow_drop_total.pkt_drop_ratio_programmedflow_drop_total.pkt_drop_ratio_bandwidthflow_drop_total.pkt_drop_ratio_otherflow_corrupted_total=awaitflow.statistics.total.corrupted.get()flow_corrupted_total.fcs_corrupted_pkt_countflow_corrupted_total.fcs_corrupted_pkt_ratioflow_corrupted_total.ip_corrupted_pkt_countflow_corrupted_total.ip_corrupted_pkt_ratioflow_corrupted_total.tcp_corrupted_pkt_countflow_corrupted_total.tcp_corrupted_pkt_ratioflow_corrupted_total.total_corrupted_pkt_countflow_corrupted_total.total_corrupted_pkt_ratioflow_corrupted_total.udp_corrupted_pkt_countflow_corrupted_total.udp_corrupted_pkt_ratioflow_delayed_total=awaitflow.statistics.total.delayed.get()flow_delayed_total.pkt_countflow_delayed_total.ratioflow_jittered_total=awaitflow.statistics.total.jittered.get()flow_jittered_total.pkt_countflow_jittered_total.ratioflow_duplicated_total=awaitflow.statistics.total.duplicated.get()flow_duplicated_total.pkt_countflow_duplicated_total.ratioflow_misordered_total=awaitflow.statistics.total.misordered.get()flow_misordered_total.pkt_countflow_misordered_total.ratioawaitflow.statistics.tx.clear.set()awaitflow.statistics.rx.clear.set()awaitflow.statistics.clear.set()# endregion#----------------------------------------------# 13. Port statistics# ---------------------------------------------# region Port Statisticsport_drop=awaitport.config.statistics.dropped.get()port_drop.pkt_drop_count_totalport_drop.pkt_drop_count_programmedport_drop.pkt_drop_count_bandwidthport_drop.pkt_drop_count_otherport_drop.pkt_drop_ratio_totalport_drop.pkt_drop_ratio_programmedport_drop.pkt_drop_ratio_bandwidthport_drop.pkt_drop_ratio_otherport_corrupted=awaitport.config.statistics.corrupted.get()port_corrupted.fcs_corrupted_pkt_countport_corrupted.fcs_corrupted_pkt_ratioport_corrupted.ip_corrupted_pkt_countport_corrupted.ip_corrupted_pkt_ratioport_corrupted.tcp_corrupted_pkt_countport_corrupted.tcp_corrupted_pkt_ratioport_corrupted.total_corrupted_pkt_countport_corrupted.total_corrupted_pkt_ratioport_corrupted.udp_corrupted_pkt_countport_corrupted.udp_corrupted_pkt_ratioport_delayed=awaitport.config.statistics.delayed.get()port_delayed.pkt_countport_delayed.ratioport_jittered=awaitport.config.statistics.jittered.get()port_jittered.pkt_countport_jittered.ratioport_duplicated=awaitport.config.statistics.duplicated.get()port_duplicated.pkt_countport_duplicated.ratioport_misordered=awaitport.config.statistics.misordered.get()port_misordered.pkt_countport_misordered.ratioawaitport.config.statistics.clear.set()# endregionasyncdefmain()->None:stop_event=asyncio.Event()awaitmy_awesome_func(stop_event=stop_event)if__name__=="__main__":asyncio.run(main())FOR TESTING BEYOND THE STANDARD.