实现Media config的切换,使得Loki-100G-5S-2P测试板卡可以链接在50GbE模式下进行流量测试
实现Media config的切换,使得测试板卡那个链接在50GbE模式下进行流量测试
main.py
# coding=UTF-8
import time, json, random, queue, types, sys, socket, math, os
from binascii import hexlify
from TestUtilsL23 import XenaScriptTools
#########################################
##############Descripting################
## Aurthor: Zohn Yang ##
## Date : 2019-12-9 ##
## Email : szy@xenanetworks.com ##
## Software : Pyhton 3.7.4 ##
#########################################
def runtest(xm, ports, rate, size, duration):
##Print message
module = str(ports[0])[0:1]
print("Start the scripting...")
##RELEASE THE ports and modules, relinquish other users.
xm.Send(module + ' M_RESERVATION RELEASE')
xm.Send(module + ' M_RESERVATION relinquish')
xm.Send(ports[0] + ' P_RESERVATION RELEASE')
xm.Send(ports[0] + ' P_RESERVATION relinquish')
xm.Send(ports[1] + ' P_RESERVATION RELEASE')
xm.Send(ports[1] + ' P_RESERVATION relinquish')
##Reserve the module
xm.Send(module + ' M_RESERVATION RESERVE')
##set port speed mode into 4*50G
print("Set the mode into 50G...")
#xm.SendExpectOK(module + ' M_CFPCONFIGEXT 2 100000 100000')
#xm.SendExpectOK(module + ' M_CFPCONFIGEXT 8 25000 25000 25000 25000 25000 25000 25000 25000')
xm.SendExpectOK(module + ' M_CFPCONFIGEXT 4 50000 50000 50000 50000')
time.sleep(5)
xm.Send(module + ' M_RESERVATION RELEASE')
print("Successful...")
##Release the port and then Reserve the ports
print ("Resever the port...")
xm.Send(ports[0] + ' P_RESERVATION RESERVE')
xm.Send(ports[1] + ' P_RESERVATION RESERVE')
##RESET PORTS
xm.Send(ports[0] + ' P_RESET')
xm.Send(ports[1] + ' P_RESET')
time.sleep(1)
MAC1= '000000000002'
MAC2= '000000000001'
IP1 = '192.168.100.100'
IP2 = '192.168.100.101'
IP1 = hexlify(socket.inet_aton(IP1)).decode()
IP2 = hexlify(socket.inet_aton(IP2)).decode()
hearder1 = '0x' + str(MAC2) + str(MAC1) + '08004500002E000000007FFFF0B6' + str(IP1) + str(IP2)
hearder2 = '0x' + str(MAC1) + str(MAC2) + '08004500002E000000007FFFF0B6' + str(IP2) + str(IP1)
print("Start to configure the streams...")
##Create the streams in port 0
##Create the SID index of stream
xm.SendExpectOK(ports[0] + " PS_CREATE [0]")
##Create the TPLD index of stream
xm.SendExpectOK(ports[0] + " PS_TPLDID [0] 0")
##Configure the packet size
xm.SendExpectOK(ports[0] + " PS_PACKETLENGTH [0]" + size)
##Configure the packet type
xm.SendExpectOK(ports[0] + " PS_HEADERPROTOCOL [0] ETHERNET IP")
##Configure the packet header
xm.SendExpectOK(ports[0] + " PS_PACKETHEADER [0] "+ str(hearder1))
##Enable streams
xm.SendExpectOK(ports[0] + " PS_ENABLE [0] on")
##Configure the stream rate
xm.SendExpectOK(ports[0] + " PS_RATEFRACTION [0] " + str(int(rate)*10000))
##Create the streams in port 1
xm.SendExpectOK(ports[1] + " PS_CREATE [1]")
xm.SendExpectOK(ports[1] + " PS_TPLDID [1] 1")
xm.SendExpectOK(ports[1] + " PS_PACKETLENGTH [1]" + size)
xm.SendExpectOK(ports[1] + " PS_HEADERPROTOCOL [1] ETHERNET IP")
xm.SendExpectOK(ports[1] + " PS_PACKETHEADER [1] "+ str(hearder2))
xm.SendExpectOK(ports[1] + " PS_ENABLE [1] on")
xm.SendExpectOK(ports[1] + " PS_RATEFRACTION [1] " + str(int(rate)*10000))
print("Start the traffic...")
#####START TRAFFIC
xm.SendExpectOK(ports[0] + ' P_TRAFFIC ON')
xm.SendExpectOK(ports[1] + ' P_TRAFFIC ON')
time.sleep(int(duration))
xm.SendExpectOK(ports[0] + ' P_TRAFFIC OFF')
xm.SendExpectOK(ports[1] + ' P_TRAFFIC OFF')
print("Stop the traffic and collect the result...")
xm.Send(ports[0] + ' P_RESERVATION RELEASE')
xm.Send(ports[1] + ' P_RESERVATION RELEASE')
time.sleep(2)
####Get traffic result
##Get the TX and RX result
TX1 = (filter(xm, ports[0] + ' PT_STREAM [0] ?'))[3]
TX2 = (filter(xm, ports[1] + ' PT_STREAM [1] ?'))[3]
RX1 = (filter(xm, ports[1] + ' PR_TPLDTRAFFIC [0] ?'))[3]
RX2 = (filter(xm, ports[0] + ' PR_TPLDTRAFFIC [1] ?'))[3]
##Get the latency
latency1 = (filter(xm, ports[1] + ' PR_TPLDLATENCY [0] ?'))[1]
latency2 = (filter(xm, ports[0] + ' PR_TPLDLATENCY [1] ?'))[1]
##Get the error
error1 = filter(xm, ports[1] + ' PR_TPLDERRORS[1] ?')
error2 = filter(xm, ports[0] + ' PR_TPLDERRORS[0] ?')
##Get the FCS
FCS1 = (filter(xm, ports[0] + ' PR_EXTRA ?'))[0]
FCS2 = (filter(xm, ports[1] + ' PR_EXTRA ?'))[0]
##Caculate the lost
Lost1 = int(TX1) - int(RX1)
Lost2 = int(TX2) - int(RX2)
##print the result
print()
print ('----------------------------------------------------------------------------------------------------')
print ('Stream1 | TX: ' + str(TX1) + ' | RX: ' + str(RX1) + ' | Lost :' + str(Lost1) + ' | FCS: ' + str(FCS2) + ' | Misoder Error: ' + error1[2] + ' | Payload Errors: ' + error1[3])
print ('----------------------------------------------------------------------------------------------------')
print ('Stream2 | TX: ' + str(TX2) + ' | RX: ' + str(RX2) + ' | Lost :' + str(Lost2) + ' | FCS: ' + str(FCS1) + ' | Misoder Error: ' + error2[2] + ' | Payload Errors: ' + error2[3])
print ('----------------------------------------------------------------------------------------------------')
print ('Ending.......')
def filter(xm, cmd):
getvalue = xm.Send(cmd)
getvalue = getvalue.split(' ')[-1]
getvalue = getvalue.split(' ')
return getvalue
def main(argv):
with open('config.txt','r+') as f:
configs = f.readlines()
config_dict = {}
for conf in configs:
parsed = conf.strip('\n').split(':')
if len(parsed) > 1:
config_dict[parsed[0]] = parsed[1]
ip_address = config_dict.get('ip_address')
print(ip_address)
ports = config_dict.get('ports').split(' ')
print(ports)
rate = config_dict.get('rate')
size = config_dict.get('size')
duration = config_dict.get('duration')
xm = XenaScriptTools(ip_address)
print('Start to connect to the chassis...')
xm.LogonSetOwner("xena", "python_test_1")
print('Logon successful...')
runtest(xm, ports, rate, size, duration)
if __name__ == '__main__':
sys.exit(main(sys.argv))
SockeDrives.py
import socket
import sys
class SimpleSocket(object):
def __init__(self, hostname, port = 22611, timeout = 20):
hostname = hostname.encode()
self.hostname = hostname
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
sys.stderr.write("[Socket connection error] Cannot connect to %s, error: %s\n" % (hostname, msg[0]))
sys.exit(1)
self.sock.settimeout(timeout)
try:
self.sock.connect((hostname, port))
except socket.error as msg:
sys.stderr.write("[Socket connection error] Cannot connect to %s, error: %s\n" % (hostname, msg[0]))
sys.exit(2)
def __del__(self):
self.sock.close()
def SendCommand(self, cmd):
cmd = cmd.encode()
self.sock.send(cmd + b'\n')
def Ask(self, cmd):
cmd = cmd.encode()
self.sock.send(cmd + b'\n')
return self.sock.recv(2048)
def set_keepalives(self):
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 2)
TestUtisL23.py
import os, sys, time, threading, inspect, types
from SocketDrivers import SimpleSocket
LOGFILE = "XENALOG"
RESET = " p_reset"
RESERVATION = " p_reservation ?"
RESERVE = " p_reservation reserve"
RELINQUISH = " p_reservation relinquish"
RELEASE = " p_reservation release"
TRAFFIC_ON = " p_traffic on"
TRAFFIC_OFF = " p_traffic off"
TCLEAR = " pt_clear"
RCLEAR = " pr_clear"
DELETE = " ps_delete"
LIMIT = " P_TXTIMELIMIT"
COMMENT_START = ';'
def errexit(msg):
#print (str(msg) + ", exiting...]")
sys.exit()
## Keepalive thread to ensure tcp connection is kept open
# do not edit this
class KeepAliveThread(threading.Thread):
message = ''
def __init__(self, connection, interval = 10):
threading.Thread.__init__(self)
self.connection = connection
self.interval = interval
self.finished = threading.Event()
self.setDaemon(True)
print ('[KeepAliveThread] Thread initiated, interval %d seconds' % (self.interval))
def stop (self):
self.finished.set()
self.join()
def run (self):
while not self.finished.isSet():
self.finished.wait(self.interval)
self.connection.Ask(self.message)
## Low level driver for TCPIP based queried
# do not edit this
class XenaSocketDriver(SimpleSocket):
def __init__(self, hostname, port = 22611):
SimpleSocket.__init__(self, hostname = hostname, port = port)
SimpleSocket.set_keepalives(self)
self.access_semaphor = threading.Semaphore(1)
def SendCommand(self, cmd):
self.access_semaphor.acquire()
SimpleSocket.SendCommand(self, cmd)
self.access_semaphor.release()
def Ask(self, cmd):
self.access_semaphor.acquire()
reply = SimpleSocket.Ask(self, cmd).strip(b'\n')
self.access_semaphor.release()
return reply
## Xena supplied class example for Scripting via Python
# feel free to add functions below
#
class XenaScriptTools:
def __init__(self, ip):
self.ip = ip
self.debug = 0
self.halt = 1
self.log = 0
self.cmds = []
self.logf = os.environ.get(LOGFILE)
if self.logf != None:
self.log = 1
self.driver= XenaSocketDriver(ip)
def __del__(self):
if self.log:
lf = open(log.txt, 'w')
for cmd in self.cmds:
lf.write(cmd + "\n")
lf.close()
return
## Enable debug - prints commands and errors
def debugOn(self):
self.debug = 1
return
## Disable debug (default) - no printed output
def debugOff(self):
self.debug = 0
return
def debugMsg(self, msg):
if self.debug == 1:
print ("message")
print (msg)
def logCmd(self, cmd):
if self.log == 1:
self.cmds.append(cmd)
## Enable halt on error - calls sys.exit(1) upon error
def haltOn(self):
self.halt = 1
return
## Disable halt on error (default)
def haltOff(self):
self.halt = 0
return
## Print diagnostics msg and halt
def errexit(self, msg):
if self.halt == 1:
#print
#print (msg + ", exiting...]")
print
sys.exit(1)
###############################################
## Send and Expect primitives
###############################################
## Send command and return response
def Send(self, cmd):
res = self.driver.Ask(cmd)
self.debugMsg("Send() : " + cmd)
res = res.decode()
self.debugMsg("Send() received: " + res)
self.logCmd(cmd)
return res
## Send command and expect response (typically <OK>)
def SendExpect(self, cmd, resp):
self.debugMsg("SendExpect("+resp+"): " + cmd)
self.logCmd(cmd)
res = self.driver.Ask(cmd).decode()
if res.rstrip('\n') == resp:
return True;
else:
self.debugMsg("SendExpect() failed")
self.debugMsg(" Expected: " + resp)
if type(res) != type(str()):
res = res.decode()
self.debugMsg(" Received: " + res)
self.errexit("Test result :Failed;[Send:" + str(cmd) + "; Received: " + str(res))
return False
def SendExpectSync(self, cmd, resp):
self.debugMsg("SendExpect("+resp+"): " + cmd)
self.logCmd(cmd)
res = self.driver.Ask(cmd).decode()
sync = res.rstrip('\n').split(' ')[-1]
if sync == resp:
return True;
else:
self.debugMsg("SendExpect() failed")
self.debugMsg(" Expected: " + resp)
self.debugMsg(" Received: " + res)
self.errexit("Test result :Failed;[Port " + str(res))
return False
## Send commands and expect <OK>
def SendExpectOK(self, cmd):
return self.SendExpect(cmd, "<OK>")
def SendExpectSyncOK(self, cmd):
return self.SendExpectSync(cmd, "IN_SYNC")
## Send command and match response with specified string
def SendAndMatch(self, cmd, str):
self.debugMsg("SendAndMatch() : " + cmd)
self.logCmd(cmd)
res = self.driver.Ask(cmd)
if res.find(str) != -1:
return True
else:
self.debugMsg("SendAndMatch() failed")
self.debugMsg(" Expected: " + str)
self.debugMsg(" Got : " + res)
print ("Test result :Failed;[测试异常,请重新测试]"),
self.errexit("Halting in line %d" % (inspect.currentframe().f_back.f_lineno))
return False
###############################################
## Xena Scripting API specific commands
###############################################
##############################
# Chassis and Logon Commands
##############################
## Logon
def Logon(self, pwd):
self.SendExpectOK("c_logon \"" + pwd + "\"")
## Logon and set owner
def LogonSetOwner(self, pwd, owner):
self.Logon(pwd)
self.SendExpectOK("c_owner \"" + owner + "\"")
## Logon to chassis, set user name and password, then reserve ports
def LogonAndReserve(self, ports, pwd, owner):
if type(ports) == type(str()):
ports = [ports]
self.LogonSetOwner(pwd, owner)
self.PortReserve(ports)
# Reserve chassis, release or relinquish first if necessary
def ChassisReserve(self):
self.ChassisRelease()
self.SendExpectOK("C_RESERVATION reserve")
# Reserve chassis, release or relinquish first if necessary
def ChassisRelease(self):
res = self.Send("C_RESERVATION ?").split()[1]
if res.find("RESERVED_BY_YOU") != -1:
self.debugMsg("Chassis is reserved by me - release")
self.SendExpectOK("C_RESERVATION release")
elif res.find("RESERVED_BY_OTHER") != -1:
self.debugMsg("Chassis is reserved by other - relinquish")
self.SendExpectOK("C_RESERVATION relinquish")
elif res.find("RELEASED") != -1:
self.debugMsg("Chassis is released - do nothing")
else:
self.errexit("Halting in line %d" % (inspect.currentframe().f_back.f_lineno))
##############################
# Misc Commands
##############################
def Comment(self, text):
self.Send("; ######################################")
text = text.decode()
self.Send("; " + text)
self.Send("; ######################################")
##############################
# Port Commands
##############################
## Reserve a port - if port is reserved, release or relinquish, then reserve
def PortReserve(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.Send(port + RESERVATION)
if res.find("RESERVED_BY_OTHER") != -1:
self.debugMsg("Port " + port + " is reserved by other - relinquish")
self.SendExpectOK(port + RELINQUISH)
self.SendExpectOK(port + RESERVE)
elif res.find("RESERVED_BY_YOU") != -1:
self.debugMsg("Port " + port + " is reserved by me - do nothing")
else:
self.SendExpectOK(port + RESERVE)
def PortRelease(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.Send(port + RESERVATION)
if res.find("RESERVED_BY_YOU") != -1:
self.SendExpectOK(port + RELEASE)
def PortRelinquish(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.Send(port + RESERVATION)
if res.find("RESERVED_BY_OTHER") != -1:
self.Send(port + RELINQUISH)
def PortSyncCheck(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.SendExpectSyncOK(port + " P_RECEIVESYNC ?")
## Start traffic on ports
def PortTrafficStart(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.SendExpectOK(port + TRAFFIC_ON)
##Start learning mac address
def Statisticsclear(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.SendExpectOK(port + TCLEAR)
res = self.SendExpectOK(port + RCLEAR)
## Stop traffic on ports
def PortTrafficStop(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.SendExpectOK(port + TRAFFIC_OFF)
## Reset ports
def Portreset(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.SendExpectOK(port + RESET)
def get_module_port_prefix(self, moduleIndex, portIndex):
return "%d/%d" % (moduleIndex, portIndex)
def load_script(self, filename, moduleIndex, portIndex, israwlines=False):
module_port_prefix = self.get_module_port_prefix(moduleIndex, portIndex)
self.PortReserve(module_port_prefix)
if not israwlines:
self.driver.SendCommand(module_port_prefix)
line_number = 0;
send_count = 0;
for line in open(filename, 'r'):
command = line.strip('\n')
line_number += 1
if command.startswith(COMMENT_START):
continue
success = self.SendExpectOK(command.strip('\n'))
if not success:
print ('[XenaManager] Error in script at line: %d, [%s]' % (line_number, command))
print ('[XenaManager] Load interrupted!')
return
send_count += 1
if send_count % 100 == 0:
print ("\r[XenaManager] (Sent %d commands ...)" % send_count),
print ("\r[XenaManager] Script '%s' (%d commands) loaded succesfully." % (filename, send_count))
##Streams configuration
def StreamsDelete(self, ports):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
i = 0
for i in range(24):
res = self.Send(port + DELETE + '[' + str(i) + ']')
i += 1
def Porttimelimit(self, ports, packettime):
if type(ports) == type(str()):
ports = [ports]
for port in ports:
res = self.Send(port + " P_TXTIMELIMIT " + packettime + "000000")
config.json
ip_address:176.22.65.118
ports:7/0 7/2
rate:100
size:FIXED 64 1518
duration:20
运行结果
Microsoft Windows [版本 10.0.17763.914]
(c) 2018 Microsoft Corporation。保留所有权利。
D:\Xena_Python\50G Media type>python main.py config.txt
176.22.65.118
['7/0', '7/2']
Start to connect to the chassis...
Logon successful...
Start the scripting...
Set the mode into 50G...
Successful...
Resever the port...
Start to configure the streams...
Start the traffic...
Stop the traffic and collect the result...
----------------------------------------------------------------------------------------------------
Stream1 | TX: 1531076544 | RX: 1531076544 | Lost :0 | FCS: 0 | Misoder Error: 0 | Payload Errors: 0
----------------------------------------------------------------------------------------------------
Stream2 | TX: 1528691904 | RX: 1528691904 | Lost :0 | FCS: 0 | Misoder Error: 0 | Payload Errors: 0
----------------------------------------------------------------------------------------------------
Ending.......
专注有线以太网测试100年!(还差87年)
--Xena Networks.