引言
通过前面的文章我们已经了解了Port、Device、Stream Block、Generator在自动化中的使用方法,他们像一颗颗精巧的积木一样构成了Spirent TestCenter的基本元素。那么他们是怎样相互衔接的呢,现在我们通过一个小实验,来寻找答案吧。
往期文章
Spirent TestCenter 自动化中文版教程(一)书山有路之Hello World!
Spirent TestCenter 自动化中文版教程(二)门道初探之port基础
Spirent TestCenter 自动化中文版教程(三):门道初探之port技巧
Spirent TestCenter自动化中文教程(四):门道初探之调试技巧
Spirent TestCenter 自动化中文版教程(五):门道初探之StreamBlock基础
待测设备可以是任何具备路由转发功能的网络设备; Gateway_1/2参考配置:1.1.1.1/27,2.2.2.2/27。
加载Spirent TestCenter自动化进程; 定义测试用例、测试床参数; 创建Port Handle,连接STC机框; 创建Device Handle,引用测试床参数; 创建Streamblock,配置发包策略; 通过ARP获取待测设备的MAC地址; 转发流量、获取统计并判定结果; 保存测试例配置文件,断开机框连接。
# 指定Spirent TestCenter Tcl库的路径,加载自动化进程
source {C:\Program Files\Spirent Communications\Spirent TestCenter 5.45\Spirent TestCenter Application\SpirentTestCenter.tcl}
# 测试例名称:Routing_Forwarding
set 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/27
set Iface_2(Subnet) 2.2.2.20/27
set Iface_1(Gateway) 1.1.1.1
set Iface_2(Gateway) 2.2.2.2
set Iface_1(Location) //10.61.32.98/3/11
set 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 "
# 创建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]."
如果你仍然有些不知所措的话,那么还记得我们说过的学习API重要的三分文档吗?在Spirent_TestCenter_Automation_Obj_Ref.pdf的Page 261中对获取ARP的方法进行了说明。
# 通过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
}
此时,不仅
stc::get $Streamblock_1 -IsArpResolved和
stc::get $Streamblock_2 -IsArpResolved的返回值均为true。
# 订阅 StreamBlock 结果
stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype TxStreamResults
stc::subscribe -Parent $Case_Project -ConfigType StreamBlock -resulttype RxStreamSummaryResults
# 清除当前统计
stc::perform ResultsClearAll
stc::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
# 指定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/27
set Iface_2(Subnet) 2.2.2.20/27
set Iface_1(Gateway) 1.1.1.1
set Iface_2(Gateway) 2.2.2.2
set Iface_1(Location) //10.61.32.98/3/11
set 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