Spirent TestCenter 自动化中文版教程(八)门道初探之基础实践(路由转发)

文摘   科技   2024-01-09 11:44   北京  


引言


通过前面的文章我们已经了解了PortDeviceStream BlockGenerator在自动化中的使用方法,他们像一颗颗精巧的积木一样构成了Spirent TestCenter的基本元素。那么他们是怎样相互衔接的呢,现在我们通过一个小实验,来寻找答案吧。

往期文章

Spirent TestCenter 自动化中文版教程(一)书山有路之Hello World!

Spirent TestCenter 自动化中文版教程(二)门道初探之port基础

Spirent TestCenter 自动化中文版教程(三):门道初探之port技巧

Spirent TestCenter自动化中文教程(四):门道初探之调试技巧

Spirent TestCenter 自动化中文版教程(五):门道初探之StreamBlock基础

Spirent TestCenter 自动化中文版教程(六)门道初探之Device和绑定流

Spirent TestCenter 自动化中文版教程(七)门道初探之Generator基础

测试说明
1
测试目的
通过自动化的方式验证待测设备的路由转发功能。

2
测试拓扑

3
测试要求
  1. 待测设备可以是任何具备路由转发功能的网络设备;
  2. Gateway_1/2参考配置:1.1.1.1/27,2.2.2.2/27。

4
预期结果
待测设备成功转发来自Iface_1/2的流量,并且无丢包。
测试步骤


  1. 加载Spirent TestCenter自动化进程;
  2. 定义测试用例、测试床参数;
  3. 创建Port Handle,连接STC机框;
  4. 创建Device Handle,引用测试床参数;
  5. 创建Streamblock,配置发包策略;
  6. 通过ARP获取待测设备的MAC地址;
  7. 转发流量、获取统计并判定结果;
  8. 保存测试例配置文件,断开机框连接。

01

加载Spirent TestCenter自动化进程
指定STC Tcl库的路径是开启Spirent TestCenter自动化的一把钥匙,通常我们会把这一行放在脚本的置顶位置。
# 指定Spirent TestCenter Tcl库的路径,加载自动化进程source {C:\Program Files\Spirent Communications\Spirent TestCenter 5.45\Spirent TestCenter Application\SpirentTestCenter.tcl}
02


定义测试用例、测试床参数
测试用例参数:测试例名称、测试例配置文件名称、测试例结果。
测试床参数STC测试端口Iface_1/2的机框IP地址和槽位编号、以及对应的子网和网关参数。
# 测试例名称:Routing_Forwardingset testcase_name "Routing Forwarding"set testcase_result "Unknow"puts "Start test case: $testcase_name"
# 获取本自动化脚本的目录,并在该目录下定义配置文件set case_path [file dirname [file normalize [info script] ] ]set conf_file "$case_path/${testcase_name}.xml"
# Spirnet TestCenter Chassis的地址及其端口位置和子网信息set Iface_1(Subnet) 1.1.1.10/27set Iface_2(Subnet) 2.2.2.20/27
set Iface_1(Gateway) 1.1.1.1set Iface_2(Gateway) 2.2.2.2
set Iface_1(Location) //10.61.32.98/3/11set Iface_2(Location) //10.61.32.98/3/12

03



创建Port Handle,连接STC机框


在当前的Project中,分别在STC测试端口Iface_1/2下创建端口对象,名称为:Port_1/2。连接STC机框。
# 在当前的Project下,创建端口对象set Case_Project [stc::create project]puts "Creat test case project: $Case_Project."
set Port_1 [stc::create port \ -under $Case_Project \ -location $Iface_1(Location) \ -name Port_1 ] set Port_2 [stc::create port \ -under $Case_Project \ -location $Iface_2(Location) \ -name Port_2 ]puts "Create port handle: [stc::get $Port_1 -name] at $Iface_1(Location), and [stc::get $Port_2 -name] at $Iface_1(Location)."# 若占用端口失败,则退出进程try { puts "Reserving port: [stc::get $Port_1 -name], [stc::get $Port_2 -name]." stc::perform AttachPortsCommand stc::apply stc::sleep 5 puts "Successed to reserve port: [stc::get $Port_1 -name], [stc::get $Port_2 -name], continue..."} on error {} { puts "Failed to reserve port: [stc::get $Port_1 -name], [stc::get $Port_2 -name], exit." exit}
如果端口已经被占用,则占用端口失败,并退出自动化进程。此时,我们需要将已被占用的端口释放或选择占用其他可用的端口。

04



创建Device Handle,引用测试床参数


Port_1中依次创建DeviceEthIIIfIpv4If对象。在Ipv4If对象中配置对应的IP地址、掩码和网关。
# 创建Emulated Deviceset Device_1 [stc::create "EmulatedDevice" \        -under $Case_Project \    -AffiliatedPort $Port_1 \        -Name Device_1 ]set EthIIIf_1 [stc::create "EthIIIf" \        -under $Device_1 \        -Name Eth_1]set Ipv4If_1 [stc::create "Ipv4If" \        -under $Device_1 \        -StackedOnEndpoint-targets " $EthIIIf_1 " \        -Address [lindex [split $Iface_1(Subnet) "/"]  0] \        -PrefixLength [lindex  [split $Iface_1(Subnet) "/"]  1] \        -Gateway $Iface_1(Gateway) \        -Name IPv4_1]stc::config $Device_1 -TopLevelIf-targets " $Ipv4If_1 "stc::config $Device_1 -PrimaryIf-targets " $Ipv4If_1 "
其中,stc::config $Device_1 -TopLevelIf-targets "$Ipv4If_1"
stc::config $Device_1 -PrimaryIf-targets "$Ipv4If_1"对应了Spirent TestCenter Client GUISelect Encapsulation的配置。
值得说明的是,在Spirent TestCenter Client GUI中通过“All Devices> “Add”的方法创建Device对象的时候,在“Configure Devices”界面多个端口的IPv4 addressIPv4 gateway是通过“Address Step”的方法配置的。因此当上述计算结果与实际有出入时,可在添加Device完毕后,进行手动修改。
之后,按照同样的方法创建并配置Device_2
set Device_2 [stc::create "EmulatedDevice" \        -under $Case_Project \    -AffiliatedPort $Port_2 \        -Name Device_2 ]set EthIIIf_2 [stc::create "EthIIIf" \        -under $Device_2 \        -Name Eth_2]set Ipv4If_2 [stc::create "Ipv4If" \        -under $Device_2 \        -StackedOnEndpoint-targets " $EthIIIf_2 " \        -Address [lindex  [split $Iface_2(Subnet) "/"]  0] \        -PrefixLength [lindex  [split $Iface_2(Subnet) "/"]  1] \        -Gateway $Iface_2(Gateway) \        -Name IPv4_2]stc::config $Device_2 -TopLevelIf-targets " $Ipv4If_2 "stc::config $Device_2 -PrimaryIf-targets " $Ipv4If_2 "

05



创建Streamblock,配置发包策略


分别在Port_1/2中创建Streamblock_1/2,并配置其发包策略为:Bursts
# 创建Bound Stream Blockset Streamblock_1 [stc::create "StreamBlock" \        -under $Port_1 \        -Name Streamblock_1 ]stc::config $Streamblock_1 -SrcBinding-targets " $Ipv4If_1 "stc::config $Streamblock_1 -DstBinding-targets " $Ipv4If_2 "
set Streamblock_2 [stc::create "StreamBlock" \ -under $Port_2 \ -Name Streamblock_2 ]stc::config $Streamblock_2 -SrcBinding-targets " $Ipv4If_2 "stc::config $Streamblock_2 -DstBinding-targets " $Ipv4If_1 "
# 配置Port_1发送1000个报文,Port_2发送2000个报文set Generator_1 [lindex [stc::get $Port_1 -children-Generator] 0]set GeneratorConfig_1 [lindex [stc::get $Generator_1 -children-GeneratorConfig] 0]stc::config $GeneratorConfig_1 \ -Duration "1000" \ -DurationMode "BURSTS"
set Generator_2 [lindex [stc::get $Port_2 -children-Generator] 0]set GeneratorConfig_2 [lindex [stc::get $Generator_2 -children-GeneratorConfig] 0]stc::config $GeneratorConfig_2 \ -Duration "2000" \ -DurationMode "BURSTS"stc::applyputs "Creat bound stream block: [stc::get $Streamblock_1 -Name] at: [stc::get $Port_1 -name], [stc::get $Streamblock_2 -Name] at: [stc::get $Port_2 -name]."
Spirent TestCenter Client GUI中的效果如下图所示:

06



通过ARP获取待测设备的MAC地址



若此时我们通过stc::get $Streamblock_1 -IsArpResolved和stc::get $Streamblock_2 -IsArpResolved查看两条Stream Block的ARP状态,发现它们的返回值均为false。
IsArpResolved对应STC Client GUI中Stream Blocks 的Arp Status。如下图所示:
由于Iface_1/2分别位于不同的子网,所以此时Spirent TestCenter无法正确的将报文发送至网关设备。
如果采用手工测试的方法,我们可以点击在GUI界面的工具栏点击“Start ARP/ND”按钮之后,只需稍等片刻即可成功获取网关的MAC地址。那么在自动化中该怎么做呢?
我们也可以借助stc::help的方法查看与arp有关的命令,并依次查看他们的使用方法。例如:通过stc::help list commands *arp*检索与arp有关的命令时,找到了ArpNdStart。
再次通过stc::help ArpNdStart查看该命令的使用方法时,在它的可修改属性(Writable Attributes)中找到了Handlelist,此时你也许已经对如何使用ArpNdStart有了一些朦胧的想法。

如果你仍然有些不知所措的话,那么还记得我们说过的学习API重要的三分文档吗?在Spirent_TestCenter_Automation_Obj_Ref.pdf的Page 261中对获取ARP的方法进行了说明。


也可以参考
Spirent_TestCenter_Automation_Prog_Guide.pdf的Page: 121的使用方法。
我们来依葫芦画瓢,按照上述方法获取ARP,会怎样呢?
# 通过ARP学习GatewayA/B的MAC,若失败则退出自动化进程puts "Reserving MAC address by ARP."stc::perform ArpNdStart -HandleList [list $Port_1 $Port_2]stc::sleep 5if {([stc::get $Streamblock_1 -IsArpResolved] == true ) && ([stc::get $Streamblock_2 -IsArpResolved] == true )} {        puts "ARP successfully reserved MAC address, continue..."} else {        puts "Failed to reserve MAC address, exit."        exit}
BINGO!!!成功啦。

此时,不仅

stc::get $Streamblock_1 -IsArpResolved和

stc::get $Streamblock_2 -IsArpResolved的返回值均为true。

并且通过
stc::get $Ipv4If_1 -GatewayMac和
stc::get $Ipv4If_2 -GatewayMac两条命令,也成功获取了Gateway_1/2的MAC地址。
总之,在自动化开发的过程中当你不知所措时,应当善于利用stc::help和API文档的帮助。另外,关于ARP的更多用法我们还会在后续的文章中向大家介绍。
07



转发流量、获取统计并判定结果


接下来就是熟悉的发送流量、查看统计结果、保存测试例配置啦。
# 订阅 StreamBlock 结果stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype TxStreamResults stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype RxStreamSummaryResults# 清除当前统计stc::perform ResultsClearAllstc::apply
# 启动流量puts "Start traffic."stc::perform GeneratorStart# 等待流量转发完毕while {([stc::get $Streamblock_1 -RunningState] != "STOPPED") || ([stc::get $Streamblock_2 -RunningState] != "STOPPED")} { stc::sleep 1}puts "Traffic stoped."stc::sleep 5
# 获取统计array set Streamblock_1_Tx_Result [stc::get $Streamblock_1.TxStreamResults]array set Streamblock_1_Rx_Result [stc::get $Streamblock_1.RxStreamSummaryResults]array set Streamblock_2_Tx_Result [stc::get $Streamblock_2.TxStreamResults]array set Streamblock_2_Rx_Result [stc::get $Streamblock_2.RxStreamSummaryResults]
puts "Stream Block Name: [stc::get $Streamblock_1 -Name], StreamID: $Streamblock_1_Tx_Result(-StreamId), Receive Port: $Streamblock_1_Rx_Result(-RxPort), Sending Frame Count: $Streamblock_1_Tx_Result(-FrameCount), Receive Frame Count: $Streamblock_1_Rx_Result(-FrameCount)"puts "Stream Block Name: [stc::get $Streamblock_2 -Name], StreamID: $Streamblock_2_Tx_Result(-StreamId), Receive Port: $Streamblock_2_Rx_Result(-RxPort), Sending Frame Count: $Streamblock_2_Tx_Result(-FrameCount), Receive Frame Count: $Streamblock_2_Rx_Result(-FrameCount)"# 判定结果if { ($Streamblock_1_Tx_Result(-FrameCount) == $Streamblock_1_Rx_Result(-FrameCount)) && ($Streamblock_2_Tx_Result(-FrameCount) == $Streamblock_2_Rx_Result(-FrameCount)) } { set testcase_result "Pass"} else { set testcase_result "Fail"}puts "Test case: $testcase_name stopped, result: $testcase_result"
结果如下所示:

08



保存测试例配置文件,断开机框连接


# 保存Spirent TestCenter配置文件stc::perform SaveAsXmlCommand -FileName $conf_file# 断开与Spirent TestCenter Port的连接stc::perform detachPorts -portList [list $Port_1 $Port_2]exit



测试例完整代码

# 指定Spirent TestCenter Tcl库的路径,加载自动化进程source {C:\Program Files\Spirent Communications\Spirent TestCenter 5.45\Spirent TestCenter Application\SpirentTestCenter.tcl}# 测试例名称:Routing_Forwardingset testcase_name "Routing Forwarding"set testcase_result "Unknow"puts "Start test case: $testcase_name"# 获取本自动化脚本的目录,并在该目录下定义配置文件set case_path [file dirname [file normalize  [info script] ] ]set conf_file "$case_path/${testcase_name}.xml"# Spirnet TestCenter Chassis的地址及其端口位置和子网信息set Iface_1(Subnet) 1.1.1.10/27set Iface_2(Subnet) 2.2.2.20/27set Iface_1(Gateway) 1.1.1.1set Iface_2(Gateway) 2.2.2.2set Iface_1(Location) //10.61.32.98/3/11set Iface_2(Location) //10.61.32.98/3/12# 在当前的Project下,创建端口对象set Case_Project [stc::create project]puts "Creat test case project: $Case_Project."set Port_1 [stc::create port \                        -under $Case_Project \                        -location $Iface_1(Location) \                        -name Port_1 ]    set Port_2 [stc::create port \                        -under $Case_Project \                        -location $Iface_2(Location) \                        -name Port_2 ]puts "Create port handle: [stc::get $Port_1 -name] at $Iface_1(Location), and [stc::get $Port_2 -name] at $Iface_1(Location)."# 若占用端口失败,则退出进程try {          puts "Reserving port: [stc::get $Port_1 -name], [stc::get $Port_2 -name]."      stc::perform AttachPortsCommand          stc::apply          stc::sleep 5          puts "Successed to reserve port: [stc::get $Port_1 -name], [stc::get $Port_2 -name], continue..."}   on error {} {            puts "Failed to reserve port: [stc::get $Port_1 -name], [stc::get $Port_2 -name], exit."          exit}  # 创建Emulated Device  set Device_1 [stc::create "EmulatedDevice" \                  -under $Case_Project \              -AffiliatedPort $Port_1 \                  -Name Device_1 ]  set EthIIIf_1 [stc::create "EthIIIf" \                          -under $Device_1 \                          -Name Eth_1]  set Ipv4If_1 [stc::create "Ipv4If" \                          -under $Device_1 \                          -StackedOnEndpoint-targets $EthIIIf_1 " \                          -Address [lindex [split $Iface_1(Subnet) "/"]  0] \                          -PrefixLength [lindex  [split $Iface_1(Subnet) "/"]  1] \                          -Gateway $Iface_1(Gateway) \                          -Name IPv4_1]  stc::config $Device_1 -TopLevelIf-targets $Ipv4If_1 "  stc::config $Device_1 -PrimaryIf-targets $Ipv4If_1 "  set Device_2 [stc::create "EmulatedDevice" \                          -under $Case_Project \                      -AffiliatedPort $Port_2 \                          -Name Device_2 ]  set EthIIIf_2 [stc::create "EthIIIf" \                            -under $Device_2 \                            -Name Eth_2]  set Ipv4If_2 [stc::create "Ipv4If" \                          -under $Device_2 \                          -StackedOnEndpoint-targets $EthIIIf_2 " \                          -Address [lindex  [split $Iface_2(Subnet) "/"]  0] \                          -PrefixLength [lindex  [split $Iface_2(Subnet) "/"]  1] \                          -Gateway $Iface_2(Gateway) \                          -Name IPv4_2]  stc::config $Device_2 -TopLevelIf-targets $Ipv4If_2 "  stc::config $Device_2 -PrimaryIf-targets $Ipv4If_2 "  puts "Creat EmulatedDevice:  [stc::get $Device_1 -name], [stc::get $Device_2 -name]"  # 创建Bound Stream Block  set Streamblock_1 [stc::create "StreamBlock" \          -under $Port_1 \          -Name Streamblock_1 ]  stc::config $Streamblock_1 -SrcBinding-targets $Ipv4If_1 "  stc::config $Streamblock_1 -DstBinding-targets $Ipv4If_2 "  set Streamblock_2 [stc::create "StreamBlock" \          -under $Port_2 \          -Name Streamblock_2 ]  stc::config $Streamblock_2 -SrcBinding-targets $Ipv4If_2 "  stc::config $Streamblock_2 -DstBinding-targets $Ipv4If_1 "  # 配置Port_1发送1000个报文,Port_2发送2000个报文  set Generator_1 [lindex [stc::get $Port_1 -children-Generator] 0]  set GeneratorConfig_1 [lindex [stc::get $Generator_1 -children-GeneratorConfig] 0]  stc::config $GeneratorConfig_1 \          -Duration "1000" \          -DurationMode "BURSTS"  set Generator_2 [lindex [stc::get $Port_2 -children-Generator] 0]  set GeneratorConfig_2 [lindex [stc::get $Generator_2 -children-GeneratorConfig] 0]  stc::config $GeneratorConfig_2 \          -Duration "2000" \          -DurationMode "BURSTS"  stc::apply  puts "Creat bound stream block: [stc::get $Streamblock_1 -Name] at: [stc::get $Port_1 -name], [stc::get $Streamblock_2 -Name] at: [stc::get $Port_2 -name]."  # 通过ARP学习GatewayA/B的MAC,若失败则退出自动化进程  puts "Reserving MAC address by ARP."  stc::perform ArpNdStart -HandleList [list $Port_1 $Port_2]  stc::sleep 5  if {([stc::get $Streamblock_1 -IsArpResolved] == true ) && ([stc::get $Streamblock_2 -IsArpResolved] == true )} {          puts "ARP successfully reserved MAC address, continue..."  else {          puts "Failed to reserve MAC address, exit."          exit}  # 订阅 StreamBlock 结果  stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype TxStreamResults   stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype RxStreamSummaryResults  # 清除当前统计  stc::perform ResultsClearAllstc::apply  # 启动流量  puts "Start traffic."  stc::perform GeneratorStart  # 等待流量转发完毕  while {([stc::get $Streamblock_1 -RunningState] != "STOPPED") || ([stc::get $Streamblock_2 -RunningState] != "STOPPED")} {     stc::sleep 1  }  puts "Traffic stoped."  stc::sleep 5  # 获取统计  array set Streamblock_1_Tx_Result [stc::get $Streamblock_1.TxStreamResults]  array set Streamblock_1_Rx_Result [stc::get $Streamblock_1.RxStreamSummaryResults]  array set Streamblock_2_Tx_Result [stc::get $Streamblock_2.TxStreamResults]  array set Streamblock_2_Rx_Result [stc::get $Streamblock_2.RxStreamSummaryResults]  puts  "Stream Block Name: [stc::get $Streamblock_1 -Name], StreamID: $Streamblock_1_Tx_Result(-StreamId), Receive Port: $Streamblock_1_Rx_Result(-RxPort), Sending Frame Count: $Streamblock_1_Tx_Result(-FrameCount), Receive Frame Count: $Streamblock_1_Rx_Result(-FrameCount)"  puts  "Stream Block Name: [stc::get $Streamblock_2 -Name], StreamID: $Streamblock_2_Tx_Result(-StreamId), Receive Port: $Streamblock_2_Rx_Result(-RxPort), Sending Frame Count: $Streamblock_2_Tx_Result(-FrameCount), Receive Frame Count: $Streamblock_2_Rx_Result(-FrameCount)"  # 判定结果  if { ($Streamblock_1_Tx_Result(-FrameCount) == $Streamblock_1_Rx_Result(-FrameCount)) && ($Streamblock_2_Tx_Result(-FrameCount) == $Streamblock_2_Rx_Result(-FrameCount)) } {          set testcase_result "Pass"  } else {          set testcase_result "Fail"  }  puts "Test case: $testcase_name stopped, result: $testcase_result"  # 保存Spirent TestCenter配置文件  stc::perform SaveAsXmlCommand -FileName $conf_file  # 断开与Spirent TestCenter Port的连接  stc::perform detachPorts -portList [list $Port_1 $Port_2]  exit

测试过程及结果



测试小结

本文通过一个小实验回顾了PortDeviceStream Block…的用法,同时了解了有关ARP的使用方法。希望能够对你有所帮助。

关键词:
STC,自动化,基础实践,Tcl脚本,Emulated Device,Bound Stream Block,Traffic Generator,Bursts,ARP,路由转发
联系我们:
思博伦官方网站: www.spirent.cn
技术中心热线:400-810-9529
支持邮箱:support@spirent.com
售后网站:support.spirent.com

版权归思博伦通信科技(北京)有限公司所有,思博伦技术中心(SpirentServices)原创发布,转载请联系授权。

长按识别二维码,关注思博伦技术中心

思博伦技术中心
思博伦技术中心由思博伦全球服务部的技术团队管理和维护。我们致力于提供完善的技术支持,并定期更新。通过我们的微信平台您将获取最新的产品发布信息,全面的产品使用技巧,实用的常见问题解决方案,以及完善的售后服务流程。
 最新文章