网络测试仪A11)实现100/50/25GE Media config的切换,使得Loki-100G-5S-2P测试板卡能够链接在50GbE模式下进行流量测试
介绍Python API实现Media config的切换,使得Loki-100G-5S-2P测试板卡那个链接在50GbE模式下进行流量测试
## ValkyrieManager软件手动切换流程介绍,传送门https://www.cnblogs.com/xena/p/12104486.html
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))
SocketDrivers.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)
TestUtilsL23.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.