From cd33f01840548240cc4f2da13bfe9ae1a0678dc1 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Mon, 10 Oct 2022 14:06:31 +0800 Subject: [PATCH] feat: integrage ios performance monitor --- examples/uitest/demo_douyin_live.json | 4 ++ examples/uitest/demo_douyin_live.yaml | 5 +- examples/uitest/demo_douyin_test.go | 10 ++- go.mod | 2 +- go.sum | 4 +- hrp/internal/uixt/ext.go | 14 +++- hrp/internal/uixt/ios_device.go | 93 +++++++++++++++++++++++++-- hrp/internal/uixt/ocr_on.go | 2 +- hrp/internal/version/VERSION | 2 +- hrp/session.go | 7 +- hrp/step.go | 21 +++++- hrp/step_ios_ui.go | 1 + httprunner/__init__.py | 2 +- pyproject.toml | 2 +- 14 files changed, 150 insertions(+), 19 deletions(-) diff --git a/examples/uitest/demo_douyin_live.json b/examples/uitest/demo_douyin_live.json index e9dd2f84..7bc7efab 100644 --- a/examples/uitest/demo_douyin_live.json +++ b/examples/uitest/demo_douyin_live.json @@ -6,6 +6,10 @@ }, "ios": [ { + "perf_options": { + "sys_cpu": true, + "sys_mem": true + }, "port": 8700, "mjpeg_port": 8800, "log_on": true diff --git a/examples/uitest/demo_douyin_live.yaml b/examples/uitest/demo_douyin_live.yaml index b1eccd04..e20f426c 100644 --- a/examples/uitest/demo_douyin_live.yaml +++ b/examples/uitest/demo_douyin_live.yaml @@ -3,7 +3,10 @@ config: variables: app_name: 抖音 ios: - - port: 8700 + - perf_options: + sys_cpu: true + sys_mem: true + port: 8700 mjpeg_port: 8800 log_on: true teststeps: diff --git a/examples/uitest/demo_douyin_test.go b/examples/uitest/demo_douyin_test.go index ff42eb86..4d3215bb 100644 --- a/examples/uitest/demo_douyin_test.go +++ b/examples/uitest/demo_douyin_test.go @@ -14,7 +14,15 @@ func TestIOSDouyinLive(t *testing.T) { WithVariables(map[string]interface{}{ "app_name": "抖音", }). - SetIOS(hrp.WithLogOn(true), hrp.WithWDAPort(8700), hrp.WithWDAMjpegPort(8800)), + SetIOS( + hrp.WithLogOn(true), + hrp.WithWDAPort(8700), + hrp.WithWDAMjpegPort(8800), + hrp.WithPerfOptions( + hrp.WithPerfSystemCPU(true), + hrp.WithPerfSystemMem(true), + ), + ), TestSteps: []hrp.IStep{ hrp.NewStep("启动抖音"). IOS(). diff --git a/go.mod b/go.mod index 8fa0c5ce..5a7a6797 100644 --- a/go.mod +++ b/go.mod @@ -88,4 +88,4 @@ require ( ) // replace github.com/httprunner/funplugin => ../funplugin -replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7 +replace github.com/electricbubble/gidevice => github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739 diff --git a/go.sum b/go.sum index 8b05a05a..52334bbd 100644 --- a/go.sum +++ b/go.sum @@ -96,8 +96,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7 h1:rxaa937c9aj3Yu4M2UZb5CLAgmPu5XXpXQEfKKSWkEw= -github.com/debugtalk/gidevice v0.6.3-0.20221008035433-d79086a752a7/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o= +github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739 h1:rMcmtiJJh28z0ILZxdq0C6A2kbobdr4zu9CtxiS6GVY= +github.com/debugtalk/gidevice v0.6.3-0.20221009112329-b36169c16739/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o= github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ= github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/electricbubble/gadb v0.0.7 h1:fxvVLVNs3IFKuYAEXDF2tDZUjT9jNCltoTSirjM5dgo= diff --git a/hrp/internal/uixt/ext.go b/hrp/internal/uixt/ext.go index bf7b6422..66666754 100644 --- a/hrp/internal/uixt/ext.go +++ b/hrp/internal/uixt/ext.go @@ -131,8 +131,10 @@ type DriverExt struct { frame *bytes.Buffer doneMjpegStream chan bool scale float64 - StartTime time.Time // used to associate screenshots name - ScreenShots []string // save screenshots path + StartTime time.Time // used to associate screenshots name + ScreenShots []string // save screenshots path + perfStop chan struct{} // stop performance monitor + perfData []string // save perf data CVArgs } @@ -154,6 +156,14 @@ func extend(driver WebDriver) (dExt *DriverExt, err error) { return dExt, nil } +func (dExt *DriverExt) GetPerfData() []string { + if dExt.perfStop == nil { + return nil + } + close(dExt.perfStop) + return dExt.perfData +} + func (dExt *DriverExt) takeScreenShot() (raw *bytes.Buffer, err error) { // wait for action done time.Sleep(500 * time.Millisecond) diff --git a/hrp/internal/uixt/ios_device.go b/hrp/internal/uixt/ios_device.go index 95228062..bfe4d3ce 100644 --- a/hrp/internal/uixt/ios_device.go +++ b/hrp/internal/uixt/ios_device.go @@ -92,6 +92,28 @@ func InitWDAClient(device *IOSDevice) (*DriverExt, error) { } } + if device.PerfOptions != nil { + data, err := iosDevice.d.PerfStart(device.perfOpitons()...) + if err != nil { + return nil, err + } + + driverExt.perfStop = make(chan struct{}) + // start performance monitor + go func() { + for { + select { + case <-driverExt.perfStop: + iosDevice.d.PerfStop() + return + case d := <-data: + fmt.Println(string(d)) + driverExt.perfData = append(driverExt.perfData, string(d)) + } + } + }() + } + driverExt.UUID = iosDevice.UUID() return driverExt, nil } @@ -122,6 +144,15 @@ func WithLogOn(logOn bool) IOSDeviceOption { } } +func WithPerfOptions(options ...giDevice.PerfOption) IOSDeviceOption { + return func(device *IOSDevice) { + device.PerfOptions = &giDevice.PerfOptions{} + for _, option := range options { + option(device.PerfOptions) + } + } +} + func IOSDevices(udid ...string) (devices []giDevice.Device, err error) { var usbmux giDevice.Usbmux if usbmux, err = giDevice.NewUsbmux(); err != nil { @@ -171,11 +202,12 @@ func NewIOSDevice(options ...IOSDeviceOption) (device *IOSDevice, err error) { } type IOSDevice struct { - d giDevice.Device - UDID string `json:"udid,omitempty" yaml:"udid,omitempty"` - Port int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port - MjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port - LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"` + d giDevice.Device + PerfOptions *giDevice.PerfOptions `json:"perf_options,omitempty" yaml:"perf_options,omitempty"` + UDID string `json:"udid,omitempty" yaml:"udid,omitempty"` + Port int `json:"port,omitempty" yaml:"port,omitempty"` // WDA remote port + MjpegPort int `json:"mjpeg_port,omitempty" yaml:"mjpeg_port,omitempty"` // WDA remote MJPEG port + LogOn bool `json:"log_on,omitempty" yaml:"log_on,omitempty"` } func (dev *IOSDevice) UUID() string { @@ -240,6 +272,57 @@ func (dev *IOSDevice) opitons() (deviceOptions []IOSDeviceOption) { return } +func (dev *IOSDevice) perfOpitons() (perfOptions []giDevice.PerfOption) { + if dev.PerfOptions == nil { + return + } + + // system + if dev.PerfOptions.SysCPU { + perfOptions = append(perfOptions, giDevice.WithPerfSystemCPU(true)) + } + if dev.PerfOptions.SysMem { + perfOptions = append(perfOptions, giDevice.WithPerfSystemMem(true)) + } + if dev.PerfOptions.SysDisk { + perfOptions = append(perfOptions, giDevice.WithPerfSystemDisk(true)) + } + if dev.PerfOptions.SysNetwork { + perfOptions = append(perfOptions, giDevice.WithPerfSystemNetwork(true)) + } + if dev.PerfOptions.FPS { + perfOptions = append(perfOptions, giDevice.WithPerfFPS(true)) + } + if dev.PerfOptions.Network { + perfOptions = append(perfOptions, giDevice.WithPerfNetwork(true)) + } + + // process + if dev.PerfOptions.BundleID != "" { + perfOptions = append(perfOptions, + giDevice.WithPerfBundleID(dev.PerfOptions.BundleID)) + } + if dev.PerfOptions.Pid != 0 { + perfOptions = append(perfOptions, + giDevice.WithPerfPID(dev.PerfOptions.Pid)) + } + + // config + if dev.PerfOptions.OutputInterval != 0 { + perfOptions = append(perfOptions, + giDevice.WithPerfOutputInterval(dev.PerfOptions.OutputInterval)) + } + if dev.PerfOptions.SystemAttributes != nil { + perfOptions = append(perfOptions, + giDevice.WithPerfSystemAttributes(dev.PerfOptions.SystemAttributes...)) + } + if dev.PerfOptions.ProcessAttributes != nil { + perfOptions = append(perfOptions, + giDevice.WithPerfProcessAttributes(dev.PerfOptions.ProcessAttributes...)) + } + return +} + // NewHTTPDriver creates new remote HTTP client, this will also start a new session. func (dev *IOSDevice) NewHTTPDriver(capabilities Capabilities) (driver WebDriver, err error) { localPort, err := getFreePort() diff --git a/hrp/internal/uixt/ocr_on.go b/hrp/internal/uixt/ocr_on.go index fe0620c9..28ff5826 100644 --- a/hrp/internal/uixt/ocr_on.go +++ b/hrp/internal/uixt/ocr_on.go @@ -55,7 +55,7 @@ func (s *veDEMOCRService) getOCRResult(imageBuf []byte) ([]OCRResult, error) { return nil, fmt.Errorf("close body writer error: %v", err) } - url, _ := base64.StdEncoding.DecodeString("aHR0cHM6Ly9odWJibGUuYnl0ZWRhbmNlLm5ldC92aWRlby9hcGkvdjEvYWxnb3JpdGhtL29jcg==") + url, _ := base64.StdEncoding.DecodeString("aHR0cHM6Ly9ndGZ0YXNrLmJ5dGVkYW5jZS5jb20vYXBpL3YxL2FsZ29yaXRobS9vY3I=") req, err := http.NewRequest("POST", string(url), bodyBuf) if err != nil { return nil, fmt.Errorf("construct request error: %v", err) diff --git a/hrp/internal/version/VERSION b/hrp/internal/version/VERSION index 3d9f5b5f..17e3a2ee 100644 --- a/hrp/internal/version/VERSION +++ b/hrp/internal/version/VERSION @@ -1 +1 @@ -v4.3.0-beta-10081235 \ No newline at end of file +v4.3.0-beta-10101409 \ No newline at end of file diff --git a/hrp/session.go b/hrp/session.go index d04f5a9e..0a3b7fb5 100644 --- a/hrp/session.go +++ b/hrp/session.go @@ -5,7 +5,6 @@ import ( "time" "github.com/gorilla/websocket" - "github.com/pkg/errors" "github.com/rs/zerolog/log" ) @@ -162,8 +161,8 @@ func (r *SessionRunner) GetSummary() (*TestCaseSummary, error) { caseSummary.InOut.ExportVars = exportVars caseSummary.InOut.ConfigVars = r.parsedConfig.Variables - // add WDA/UIA logs to summary for uuid, client := range r.hrpRunner.uiClients { + // add WDA/UIA logs to summary log, err := client.Driver.StopCaptureLog() if err != nil { return caseSummary, err @@ -172,6 +171,10 @@ func (r *SessionRunner) GetSummary() (*TestCaseSummary, error) { "uuid": uuid, "content": log, } + + // stop performance monitor + logs["performance"] = client.GetPerfData() + caseSummary.Logs = append(caseSummary.Logs, logs) } diff --git a/hrp/step.go b/hrp/step.go index 13b6da61..86f773fd 100644 --- a/hrp/step.go +++ b/hrp/step.go @@ -1,6 +1,10 @@ package hrp -import "github.com/httprunner/httprunner/v4/hrp/internal/uixt" +import ( + giDevice "github.com/electricbubble/gidevice" + + "github.com/httprunner/httprunner/v4/hrp/internal/uixt" +) type StepType string @@ -24,6 +28,21 @@ var ( WithIgnoreNotFoundError = uixt.WithIgnoreNotFoundError ) +var ( + WithPerfSystemCPU = giDevice.WithPerfSystemCPU + WithPerfSystemMem = giDevice.WithPerfSystemMem + WithPerfSystemDisk = giDevice.WithPerfSystemDisk + WithPerfSystemNetwork = giDevice.WithPerfSystemNetwork + WithPerfGPU = giDevice.WithPerfGPU + WithPerfFPS = giDevice.WithPerfFPS + WithPerfNetwork = giDevice.WithPerfNetwork + WithPerfBundleID = giDevice.WithPerfBundleID + WithPerfPID = giDevice.WithPerfPID + WithPerfOutputInterval = giDevice.WithPerfOutputInterval + WithPerfProcessAttributes = giDevice.WithPerfProcessAttributes + WithPerfSystemAttributes = giDevice.WithPerfSystemAttributes +) + type StepResult struct { Name string `json:"name" yaml:"name"` // step name StepType StepType `json:"step_type" yaml:"step_type"` // step type, testcase/request/transaction/rendezvous diff --git a/hrp/step_ios_ui.go b/hrp/step_ios_ui.go index d482c0e1..8e09c74f 100644 --- a/hrp/step_ios_ui.go +++ b/hrp/step_ios_ui.go @@ -15,6 +15,7 @@ var ( WithWDAPort = uixt.WithWDAPort WithWDAMjpegPort = uixt.WithWDAMjpegPort WithLogOn = uixt.WithLogOn + WithPerfOptions = uixt.WithPerfOptions ) type IOSStep struct { diff --git a/httprunner/__init__.py b/httprunner/__init__.py index f3da2174..f5f861d1 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "v4.3.0-beta-10081235" +__version__ = "v4.3.0-beta-10101409" __description__ = "One-stop solution for HTTP(S) testing." diff --git a/pyproject.toml b/pyproject.toml index 6e10cef3..bb226013 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "v4.3.0-beta-10081235" +version = "v4.3.0-beta-10101409" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md"