999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

Python在光收發模塊測試腳本中的實現

2024-09-15 00:00:00羅震
物聯網技術 2024年6期

摘 要:光收發模塊固件開發需根據不同的客戶需求而定制,使得測試用例不斷增加,因此長時間的壓力測試也日益增多,為了節省測試用例編寫時間,提出了用Python語言編寫光收發模塊固件測試腳本的方法。文中介紹了基于Python調用動態鏈接庫、構建測試環境、編寫測試用例腳本等內容。結果表明,選用Python易于編寫測試用例,提高了測試效率。

關鍵詞:光收發模塊;Python;測試腳本;動態鏈接庫;ctypes;SFF-8472

中圖分類號:TP311 文獻標識碼:A 文章編號:2095-1302(2024)06-0-03

0 引 言

光收發模塊是光通信系統的重要組成部分,是光纖通信系統中光電轉化的器件。本地終端將待傳輸的電信號由光收發模塊的電/光(E/O)轉換為適宜傳輸的光信號發送到光纖鏈路中,再由遠方終端的另一個模塊把接收的光信號經光收發模塊的光/電(O/E)轉換為電信號輸出給遠方終端主機,從而實現異地終端通信[1]。光收發模塊要滿足MSA協議的數字診斷監測和監控信號實時監測[2]、模擬量溫度補償以及系統I2C和突發Trigger中斷處理要求,因此固件(Firmware)測試是很重要的環節。

光模塊固件功能和性能測試是嚴謹、細致的工作,在固件交付給硬件工程師調測之前必須完成全面測試。具體測試方法主要包括白盒測試和黑盒測試。黑盒測試可稱為功能測試、數據驅動測試或基于需求說明的測試,是在完全不考慮程序內部結構和內部特性的情況下,檢查輸入與輸出之間的關系是否符合要求[3]。我們在完成固件白盒測試的條件下,黑盒測試主要是為滿足不同用戶對MSA多源協議的開放區域和加密區域需求以及面對潛在資源訪問沖突風險而進行的測試。如果采用人工手動測試,往往按照測試用例步驟反復操作,工作量很大,并且單調重復的工作容易出錯;其次,系統壓力測試、性能測試需要模擬用戶系統測試場景;最后,固件是否能長時間可靠運行也非手工測試可以執行。因此,需要軟件開發人員開發自動化測試方案。光模塊的自動化測試有幾種形式,最常見的是基于傳統的文本語言軟件開發環境,常用的有LabWindows/CVI、VB、VC++、C#等;一種是基于圖形化語言軟件開發環境,常用的有NI的LabVIEW編寫的GUI程序測試,或使用工具命令語言TCL編寫腳本測試[4]。軟件測試中,腳本技術的引入是實現軟件測試自動化技術的有效手段[5],Python易學易用,有更多模塊庫的支持,在編寫測試腳本中具有很大優勢。

Python是一種面向對象的解釋性高級編程語言,具有動態語義[6]。Python的優點是易讀易維護、可擴展、可移植、擁有豐富的庫支撐[7]。Python是開發腳本的絕佳工具,Python的最大缺點是其整體性能。作為一種解釋性語言,Python比一些編譯語言(如C)慢。在一些重視速度的任務中,會影響測試性能。但可以把Python腳本編寫優勢與其他語言的優勢融合,使用Python開發自動測試腳本,同時對于性能關鍵型和特定設備的驅動程序代碼則仍使用其他語言,比如C,通過調用C語言編寫的動態庫來克服其缺點。可以用Python的擴展工具ctypes。ctypes最初是Thomas Heller開發的一個項目,但現在包含在標準庫中,雖然存在一些限制,但這可能是訪問C語言代碼的最簡單方式之一,只需將庫導入就可使用。

1 光收發模塊測試接口

訪問光收發模塊監控量接口時遵循多元協議,即SFF-8472協議。xPon的OLT和ONU使用SFF-8472協議實現對光鏈路的測量和診斷[8]。A0和A2地址值是SFF-8472規定的從設備地址值,每個地址可訪問256 B數據,如圖1所示[9]。A2地址還可通過127字段來選擇擴展頁,其中128到255頁供光模塊生產商使用,一般用來調試接口或存儲數據。

2 搭建Python自動化測試腳本環境

2.1 Python調用動態鏈接庫的方法

Python調用C語言編寫動態鏈接庫,不僅要兼容C接口的調用習慣,還要兼容C語言的數據類型。而ctypes庫已經做了這兩方面工作,使得調用動態鏈接庫非常方便。ctypes導出cdll以及Windows下的windll和oledll對象,用于加載動態鏈接庫。通過訪問這3個對象的屬性,就可以調用動態鏈接庫的函數。cdll加載使用標準cdecl調用約定導出函數的庫,而windll庫使用stdcall調用約定函數。oledll使用stdcall調用約定,且返回值是Windows中返回的HRESULT值[10]。在Python程序中添加import ctype語句就可以導入ctypes庫。

2.2 cdll庫的加載

測試腳本需要加載2種不同調用約定方式的動態鏈接庫,一種是cdll,另一種是windll。按cdll調用約定的動態鏈接庫ATEAPI.dll是測試板驅動程序,主要由USB訪問、I2C讀寫、測試板電源控制等底層操作函數組成,該動態鏈接庫的加載如下:

self.objdll = ctypes.cdll.LoadLibrary(\".\ATEAPI.dll\")

2.2.1 測試板類的設計

可以設計一個類,在類中加載動態鏈接庫ATEAPI.dll,并增加屬性和方法,便于測試腳本調用,具體代碼如下:

class cTestEvb:

def __init__(self, devusbindex=0):

self.devUsbIndex = devusbindex

# load dll

self.objdll = ctypes.cdll.LoadLibrary(\".\ATEAPI.dll\")

# use property

def setUsbDevice(self, devusbindex):

self.devUsbIndex = devusbindex

def getUsbDevice(self):

return self.devUsbIndex

devusbindex = property(setUsbDevice, getUsbDevice)

# Open USB Device

def openUsbDevice(self):

usbHandle = None

usbHandle = self.objdll.AteOpenDevice(self.devUsbIndex)

if usbHandle != None:

print(\"Open USB device {}\".format(self.devUsbIndex))

self.objdll.AteCloseDevice(usbHandle)

# Slot Power On

def AteAllPowerOn(self):

self.objdll.AteSffPowerOn(self.devUsbIndex)

self.objdll.AteSfpPowerOn(self.devUsbIndex)

def AteAllPowerOff(self):

self.objdll.AteSffPowerOff(self.devUsbIndex)

self.objdll.AteSfpPowerOff(self.devUsbIndex)

在編寫測試腳本程序時,首先創建類的對象,然后打開USB設備和測試板電源,代碼如下:

testEvb = cTestEvb(devUsbIndex)

testEvb.openUsbDevice()

testEvb.AteAllPowerOn()

2.3 windll庫的加載

另一個動態鏈接庫是CommandIndex.dll,該庫可以完成一些測試命令的解析,通過在測試腳本輸入命令的方式測試光模塊,比直接操作光模塊A2擴展頁中的寄存器更加方便快捷,因為這樣無需反復查看固件工程師編寫的Memory map文件,只需輸入命令,經過CommandIndex.dll解析命令轉換為一幀含有包頭、包尾、累加和校驗的數據包。光模塊接收這幀數據并解析命令后調用對應函數或讀寫數據,再將讀數據打包,返回上位機。CommandIndex.dll的接口函數AteCmdSer完成命令輸入與數據輸出,函數原型如下:

__declspec(dllexport) int __stdcall AteCmdSer(char* ArgIn, char* ArgOut);

ArgIn命令以字符串輸入,ArgOut數據以字符串輸出。

AteCmdSer函數負責接收輸入命令、解析命令、執行命令(執行時調用測試板動態鏈接庫ATEAPI.dll的驅動程序),返回結果。

CommandIndex.dll按照stdcall調用約定,所以按如下語句加載動態庫:

cmdservdll=ctypes.windll.LoadLibrary(\".\CommandIndex.dll\")

2.3.1 定義和注冊回調函數

在光模塊測試中,光模塊與外界唯一的通信接口是I2C總線,不論任何命令,最終發給光模塊的數據均以I2C總線為載體,而CommandIndex.dll是通用鏈接庫,ATEAPI.dll是測試板專用鏈接庫,因此針對不同的測試板或設備需要指定I2C讀寫的調用函數,然后將I2C讀函數和I2C寫函數的指針傳遞給CommandIndex.dll,即注冊這2個回調函數。定義I2C讀函數和I2C寫函數,可以看到調用ATEAPI.dll的I2C讀寫函數:

def I2C_Read(nDev, nReg, nLen, pbyBuf):

pbyValBuff = ctypes.c_ubyte * 256

pbyVal = pbyValBuff()

wRes = testEvb.objdll.AteIicRandomRead(devusbindex, devSffChannel, nDev, nReg, nLen, pbyVal)

if 0 == wRes:

for i in range(nLen):

pbyBuf[i] = pbyVal[i]

return wRes

def I2C_Write(nDev, nReg, nLen, pbyDat):

pbyValBuff = ctypes.c_ubyte * 256

pbyVal = pbyValBuff()

for i in range(nLen):

pbyVal[i % 256] = pbyDat[i]

byRes = testEvb.objdll.AteIicRandomWrite(devusbindex, devSffChannel, nDev, nReg, nLen, ctypes.byref(pbyVal))

return byRes

ctypes允許從Python調用函數創建C可調用函數指針,有時稱為回調函數。首先,必須為回調函數創建一個類。該類知道調用約定、返回類型以及該函數將接收的參數數量和類型。CFUNCTYPE()函數使用cdecl調用約定為回調函數創建類型。在Windows下,WINFUNCTYPE()函數使用stdcall調用約定為回調函數創建類型。調用這2個工廠函數時,將結果類型作為第一個參數,回調函數預期的參數類型作為剩余參數。

由于dll中調用約定是stdcall,所以使用WINFUNCTYPE()

作為回調函數創建類型:

I2C_Read_FUNC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_ubyte))

I2C_Write_FUNC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_ubyte))

接下來調用動態鏈接庫CommandIndex.dll中的RegistCallBackFunciton進行注冊,注冊函數原型如下:

__declspec(dllexport) int __stdcall RegistCallBackFunciton(char* ArgIn, pBkFun pFun);

將回調函數指針以及對應的命令作為參數注冊:

_i2c_write_func = I2C_Write_FUNC(I2C_Write)

cmdType = b\"I2C_WRITE\"

cmdservdll.RegistCallBackFunciton(ctypes.string_at(cmdType), _i2c_write_func)

i2c_read_func = I2C_Read_FUNC(I2C_Read)

cmdType = b'I2C_READ'

cmdservdll.RegistCallBackFunciton(ctypes.string_at(cmdType), _i2c_read_func)

至此,我們就架起了測試腳本命令和測試板I2C讀寫的橋梁。

2.3.2 命令實現舉例

例如要讀固件版本的命令是“MCU_GET_VERSION()”,我們可以這樣設計代碼:

strCmdIn = create_string_buffer(b'MCU_GET_VERSION()')

strCmdOutBuff = ctypes.c_ubyte*64

strCmdOut = strCmdOutBuff()

strFwVer = []

retStauts = cmdservdll. AteCmdSer (strCmdIn, strCmdOut)

if 0 == retStauts:

strFwVer = [chr(strCmdOut[item]) for item in range(len(strCmdOut)) if 0 != strCmdOut[item]]

else:

print(\"Can't get firmware version, stop test ! \")

sys.exit()

strFwVer = ''.join(strFwVer)

字符串格式為固件編號_版本號_編譯時間,讀出結果如下所示:

FEP91_1.3_20220426115813

3 編寫Python測試腳本

完成Python測試腳本測試環境的搭建后,可以很快編寫出測試用例腳本,以一個讀寫SFF-8472協議中的A2地址值0到96字段的壓力測試為例,流程如圖2所示。

該壓力測試腳本可以自行設定測試次數,我們以測試

10次為例演示測試腳本的過程和結果,如圖3所示。

4 結 語

本文提出了一種新穎的自動化腳本測試—采用Python編寫光收發模塊自動化測試腳本,詳細描述了如何搭建Python語言測試腳本的使用環境,并演示了自動化腳本的編寫以及運行結果。經實際工作證明,針對不同的測試需求,能夠快速開發出測試腳本,提高測試效率,較好應對客戶定制光模塊固件所帶來的需求變化。后續我們考慮充分利用Python強大的程序庫的支持,尤其在字符串處理、數據可視化、圖表輸出等方面,對測試結果進行數據分析,為定位固件bug、性能分析提供強有力的支撐。

參考文獻

[1]胡慶紅. SFP光收發模塊測試平臺的研究與設計[D].武漢:武漢理工大學,2013.

[2]蘇友章,周劍揚,郭元章.基于通用MCU的智能SFP光模塊設計[J].福建電腦,2009,25(3):134-135.

[3]劉戈.嵌入式軟件測試[J].長嶺技術,2006(2):3.

[4]李志報,袁亮.基于Tcl/Tk語言的自動化測試平臺的實現[J].電子技術應用,2013,39(1):59-61.

[5]于以序,何艷敏,左雪梅,等.實時嵌入式軟件測試研究[J].中國測試技術,2004,30(5):3-6.

[6][挪] Magnus Lie HetLand. Python基礎教程[M]. 3版.袁國忠,譯. 北京:人民郵電出版社,2018.

[7]百度百科. Python(計算機編程語言)[EB/OL]. [2023-05-25].https://baike.baidu.com/item/Python/407313?fr=aladdin.

[8]吳承英,吳航,張志強.光接入網實用技術[M].北京:人民郵電出版社,2019.

[9] SINA.SFF-8472-R12.4.pdf [EB/OL].[2021-03-31].https://www.snia.org/technology-communities/sff/specifications.

[10] Python官方網站. ctypes-A foreign function library for Python[EB/OL]. [2023-06-07]. https://docs.python.org/3/library/ctypes.html.

作者簡介:羅 震(1972—),男,工程碩士,工程師,主要從事光通信行業光收發模塊固件開發工作。

主站蜘蛛池模板: 亚洲av综合网| 国产成年女人特黄特色大片免费| 色老头综合网| 国产在线一区二区视频| 国产一级在线播放| 国产一区二区网站| 国产精品尤物铁牛tv| 免费一级毛片| 国产精品永久在线| 色妞永久免费视频| 精品无码国产自产野外拍在线| 国产h视频免费观看| 国产大片喷水在线在线视频| 亚洲AV无码一二区三区在线播放| 亚洲精品手机在线| 99久久这里只精品麻豆| 欧美亚洲网| 999精品免费视频| 久久精品丝袜高跟鞋| 欧美精品高清| 亚洲综合极品香蕉久久网| 亚洲成人动漫在线观看| 欧日韩在线不卡视频| 国产网站免费看| 亚洲天堂啪啪| 新SSS无码手机在线观看| 超清无码熟妇人妻AV在线绿巨人| 一边摸一边做爽的视频17国产| 91无码网站| 亚洲欧洲日韩久久狠狠爱| 热99re99首页精品亚洲五月天| 国产人免费人成免费视频| 五月天久久综合国产一区二区| 日韩最新中文字幕| 日本国产精品一区久久久| 国产精品久久自在自线观看| 国产一级裸网站| 无码在线激情片| 国产精品入口麻豆| 国产swag在线观看| 国产黄色片在线看| 永久免费精品视频| 亚洲综合久久成人AV| 欧美亚洲激情| 91精品国产91久无码网站| 精品人妻一区二区三区蜜桃AⅤ| 日韩在线第三页| 大香网伊人久久综合网2020| 在线综合亚洲欧美网站| 久久五月视频| 好紧太爽了视频免费无码| 国产欧美成人不卡视频| 亚洲av中文无码乱人伦在线r| 欧美a√在线| 在线精品欧美日韩| 国产一级一级毛片永久| 刘亦菲一区二区在线观看| 又爽又大又光又色的午夜视频| 幺女国产一级毛片| 亚洲成年人网| 国产91视频观看| 高h视频在线| 欧美色伊人| 在线观看国产黄色| 在线观看免费人成视频色快速| 免费毛片a| 国产日韩欧美精品区性色| 日本国产在线| 亚洲欧美国产五月天综合| 亚洲天堂网站在线| 欧美不卡二区| 伊人福利视频| 丁香五月婷婷激情基地| 国产日本视频91| 国产人成在线视频| 欧美日本一区二区三区免费| 亚洲日韩高清在线亚洲专区| 日本午夜视频在线观看| 亚洲第一成网站| 67194在线午夜亚洲| 91久久夜色精品国产网站| 亚洲国产AV无码综合原创|