從零開始玩轉 PerfDogService---------Demo 解析篇

不二發表於2020-10-16

1.Demo資料夾

當下載好PerfDogService後資料夾是這個樣子的。
在這裡插入圖片描述
檔案說明:

PerfDogService.exe: Service啟動檔案,一般不用手工啟動,自動化指令碼會自動啟動此程式。
perfdog.proto: grpc介面和protobuf結構體的定義檔案
demo/python: python3的demo,依賴庫grpcio和protobuf
demo/java: java的demo,依賴庫grpc-netty-shaded, grpc-protobuf, grpc-stub
PerfDogService.jar: 服務所依賴的jar包

我們先不管其他,只專注於demo資料夾;
展開後是Java和Python兩種語言的Demo,我們本次只分析改造Python的
在這裡插入圖片描述
Python的Demo只有三個檔案在這裡插入圖片描述
Demo.py: 我們程式的執行入口,同時我們主要操作的也是這個檔案;
perfdog_pb2.py: 此檔案是由協議緩衝區編譯器生成,也就是由perfdog.proto這個檔案生成的。我們不要修改它。
perfdog_pb2_grpc.py: 此檔案是gRPC Python協議編譯器外掛生成,也不要修改它
這裡簡單介紹下==協議緩衝區==
協議緩衝區是是一種與語言無關,平臺無關的資料序列化結構化機制;
只需要一次構造資料,然後就可以使用生成的特殊原始碼輕鬆地使用各種語言在各種資料流中寫入和讀取結構化資料;

舉個例子:
你用python語言,你辛辛苦苦用python定義好了一堆字典啦或者Class啦或者其他什麼資料,你想給隔壁老李用,然而老李用java啊,這時候隔壁小王也需要用,然而小王用C++啊,各種語言不能直接呼叫。這個時候通過協議緩衝區這種機制,先把你的資料編譯生成一種特殊的原始碼,老李和小王就可以呼叫這份原始碼了。

2.Demo.py檔案解析

在這裡插入圖片描述

其實全篇只有一個Run函式,而且官方寫的註釋也比較清晰了,我們就來簡單看下吧
在這裡插入圖片描述
0到3其實沒什麼好說的了,就是喚起PerfDogService服務,通過令牌和伺服器建立了一個連線,其中stub除了建立連線還有好多其他的方法
在這裡插入圖片描述
接下來看看第四步
在這裡插入圖片描述

deviceEventIterator這裡是一個可迭代物件,存放著當前所有的連線裝置,例如Android啦,Ios,模擬器啦等等;

在這裡插入圖片描述
我們最常用的應該是device,這裡儲存著被測機型的uid,名字等。這裡的uid就是當前連線裝置的唯一標識,如果你安裝了ADB,可以在控制檯輸入ADB devices檢視你當期連線的裝置資訊,例如這樣:
在這裡插入圖片描述
5其實就是開始初始化裝置
6是開始獲取當前被測裝置的所有安裝的應用,應用儲存在apps這個物件裡,這也是一個可迭代物件,
迭代apps可以獲取到每個app,以及每個app的名字,包名,版本,Icon,是不是系統App,subVersion等等。
在這裡插入圖片描述

第7步這裡實際上是獲取了當前被測裝置的硬體資訊,例如像CPU,型號,安卓版本之類的等等在這裡插入圖片描述
第8步這裡開始選擇要蒐集的效能資料指標都有哪些,我這裡多加了一個CPU Core的使用率
第9步就開始蒐集效能資料了
在這裡插入圖片描述
採集效能資料資訊實際上通過多執行緒的方式進行的,所以Sleep(20)就是採集20s的資料
在這裡插入圖片描述
10和11就是新增不同時間段的註釋
在這裡插入圖片描述
第12步是兩個操作
1.上傳整個資料到雲端
2.匯出第5秒到20秒的資料到本地,其中匯出路徑可以自己更改(outputDirectory)
在這裡插入圖片描述
13最後停止測試,不過其實程式沒停止,如果此時你啟動Perfdog客戶端,可能會顯示這個錯誤。
在這裡插入圖片描述
此時去Kill掉這個java進城就可以了。
在這裡插入圖片描述

3.Demo簡單修改

由於我個人的需求1是不想每次配置都挨行程式碼修改,2是為後續搭建自定義的雲效能測試平臺做鋪墊,所以簡單修改了下程式碼:原始碼未刪,僅是註釋掉了,方便做對比;
1.提取常用配置
2.需要提前配置好需要測試的對應裝置
3.需要提前配置好要測試的APP(配置APP的名字)
4.只上傳一份資料到雲端,
5.儲存到本地的資料不會從中間擷取某段時間了。

# -*- coding: utf-8 -*-
import subprocess
import time
import traceback

import grpc
import perfdog_pb2_grpc
import perfdog_pb2
import threading
class Config():
PERFDOGSERVER_PATH=r'C:\Users\Administrator\Desktop\perfdog\PerfDogService.exe' #PerfDogService的路徑
TOKEN='XXXXXXXXXXXXXXXXXXXX '#token
DEVICES_UID="813QEDTE228ZK" #需要測試的手機序列號
APP_NAME="天氣" #需要測試的app名字
TEST_TIMER=11 #需要測試時長
LABEL="this is a label" #label內容
NOTE="this is a note" #note內容
CASENAME="天氣測試資料" #用例描述 ,會覆蓋相同用例名字的資料
SAVEDATA_BEGINTIME=1 #匯出到本地資料的開始時間()
SAVEDATA_ENDTIME=20 #匯出到本地資料的結束時間(秒)
OUTPUT="F:\\perfdog_service_output\\" #匯出檔案所儲存的目錄,
SAVEDATA_TYPE=perfdog_pb2.EXPORT_TO_JSON #匯出檔案所儲存的型別,



# 第一次執行demo前需要通過pip安裝grpcio(1.23.0)protobuf(3.10.0)
def run():
try:
# 在程式碼裡啟動PerfDogService或手動啟動PerfDogService
print("0.啟動PerfDogService")
# 1.**************************填入PerfDogService的路徑
perfDogService = subprocess.Popen(Config.PERFDOGSERVER_PATH)
# 等待PerfDogService啟動完畢
time.sleep(5)
print("1.通過ip和埠連線到PerfDog Service")
options = [('grpc.max_receive_message_length', 100 * 1024 * 1024)]
channel = grpc.insecure_channel('127.0.0.1:23456', options=options)
print("2.新建一個stub,通過這個stub物件可以呼叫所有伺服器提供的介面")
stub = perfdog_pb2_grpc.PerfDogServiceStub(channel)
print("3.通過令牌登入,令牌可以在官網申請")
userInfo = stub.loginWithToken(perfdog_pb2.Token(token=Config.TOKEN))
print("UserInfo:\n", userInfo)
print("4.啟動裝置監聽器監聽裝置,每當裝置插入和移除時會收到一個DeviceEvent")
deviceEventIterator = stub.startDeviceMonitor(perfdog_pb2.Empty())
for deviceEvent in deviceEventIterator:
# DeviceEvent中獲取到device物件,device物件會在後面的介面中用到
device = deviceEvent.device

print("當前devices: ",device," **** ",deviceEvent)
# time.sleep(20000)
if deviceEvent.eventType == perfdog_pb2.ADD and device.uid==Config.DEVICES_UID:
print("裝置[%s:%s]插入\n" % (device.uid, perfdog_pb2.DEVICE_CONTYPE.Name(device.conType)))
# 每臺手機會返回兩個conType不同的裝置物件(USB的和WIFI),如果是測有線,取其中的USB物件
if device.conType == perfdog_pb2.USB:
print("5.初始化裝置[%s:%s]\n" % (device.uid, perfdog_pb2.DEVICE_CONTYPE.Name(device.conType)))
stub.initDevice(device)
print("6.獲取app列表")
appList = stub.getAppList(device)
#
apps = appList.app
app_index = 0
for app in apps:
print('%s: %s->%s' % (app_index, app.label, app.packageName))
if app.label==Config.APP_NAME:
app_select=app_index
break
else:
app_index += 1
app_select=None
if app_select is None:app_select = int(input("未安裝輸入APP,請選擇要測試App: "))

app = apps[app_select]

print("7.獲取裝置的詳細資訊")
deviceInfo = stub.getDeviceInfo(device)
print("8.開啟效能資料項")
stub.enablePerfDataType(
perfdog_pb2.EnablePerfDataTypeReq(device=device, type=perfdog_pb2.NETWORK_USAGE))
stub.enablePerfDataType(
perfdog_pb2.EnablePerfDataTypeReq(device=device, type=perfdog_pb2.NORMALIZED_CPU_CORE_USAGE))



print("9.開始收集[%s:%s]的效能資料\n" % (app.label, app.packageName))
print(stub.startTestApp(perfdog_pb2.StartTestAppReq(device=device, app=app)))

req = perfdog_pb2.OpenPerfDataStreamReq(device=device)
perfDataIterator = stub.openPerfDataStream(req)

def perf_data_process():
for perfData in perfDataIterator:
print(perfData)

threading.Thread(target=perf_data_process).start()
# 採集一些資料
time.sleep(Config.TEST_TIMER)
print("10.設定label")
stub.setLabel(perfdog_pb2.SetLabelReq(device=device, label="I am a label"))
time.sleep(3)
print("11.新增批註")
stub.addNote(perfdog_pb2.AddNoteReq(device=device, time=5000, note="I am a note"))
print("12.上傳和匯出所有資料")
saveResult = stub.saveData(perfdog_pb2.SaveDataReq(
device=device,
caseName=Config.CASENAME, # webcaseexcel的名字
uploadToServer=True, # 上傳到perfdog伺服器
exportToFile=True, # 儲存到本地
outputDirectory=Config.OUTPUT,
dataExportFormat=Config.SAVEDATA_TYPE
))

print("儲存結果:\n", saveResult)
# print("12.上傳和匯出第5秒到20秒的資料")
# stub.saveData(perfdog_pb2.SaveDataReq(
# device=device,
# beginTime=5000, # 指定開始時間
# endTime=20000, # 指定結束時間
# caseName="case2", # webcaseexcel的名字
# uploadToServer=True, # 上傳到perfdog伺服器
# exportToFile=True, # 儲存到本地
# outputDirectory="F:\\perfdog_service_output\\",
# dataExportFormat=perfdog_pb2.EXPORT_TO_EXCEL
# ))
print("13.停止測試")
stub.stopTest(perfdog_pb2.StopTestReq(device=device))
print("over")
break
elif deviceEvent.eventType == perfdog_pb2.REMOVE:
print("裝置[%s:%s]移除\n" % (device.uid, perfdog_pb2.DEVICE_CONTYPE.Name(device.conType)))
except Exception as e:
traceback.print_exc()

if __name__ == '__main__':
run()
#

相關文章