From d1ecb0f05e19dc89d514427f63f10e4227412931 Mon Sep 17 00:00:00 2001 From: luziqi Date: Mon, 19 Jun 2023 13:58:18 +0800 Subject: [PATCH] update --- common/config.go | 32 ++++++++++--- crontask/corn.go | 3 +- crontask/ios.go | 7 +++ go.mod | 5 +++ go.sum | 14 ++++++ monkey/cli_adr.go | 2 +- monkey/ios.go | 27 ++++++++++- monkey/task_v2.go | 7 ++- test/test.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 198 insertions(+), 10 deletions(-) diff --git a/common/config.go b/common/config.go index 61ec0c0..65d0959 100644 --- a/common/config.go +++ b/common/config.go @@ -41,7 +41,7 @@ func GetBranch(pkg_name string, pkg_url string) (ApkInfo, error) { SetQueryParam("pageSize", "200"). SetQueryParam("sortBy", "utime"). SetQueryParam("orderBy", "DESC"). - Get("http://8.214.100.26:8048/api/admin/pkg-name-list") + Get("http://8.214.100.26:8048/api/app-version/get-apk-list") if err != nil { return _app, err } @@ -52,10 +52,30 @@ func GetBranch(pkg_name string, pkg_url string) (ApkInfo, error) { } return _app, errors.New("没有匹配到对应的包信息") } else { - // iOS先不处理 - _app.Branch = "unknow" - _app.Version = "0.0.0" - _app.VersionCode = "000" - return _app, nil + var rsp RespGetApkInfo + client := req.C() + _, err := client.R(). + SetSuccessResult(&rsp). + SetQueryParam("access_key", ACCRSS_KEY). + SetQueryParam("pkg_name", pkg_name). + SetQueryParam("pageIndex", "1"). + SetQueryParam("pageSize", "200"). + SetQueryParam("sortBy", "utime"). + SetQueryParam("orderBy", "DESC"). + Get("http://8.214.100.26:8048/api/app-version/get-apk-list") + if err != nil { + return _app, err + } + for _, v := range rsp.Data { + if v.Name == filename { + return v, nil + } + } + return _app, errors.New("没有匹配到对应的包信息") + // // iOS先不处理 + // _app.Branch = "unknow" + // _app.Version = "0.0.0" + // _app.VersionCode = "000" + // return _app, nil } } diff --git a/crontask/corn.go b/crontask/corn.go index a163eb7..3b3b4a1 100644 --- a/crontask/corn.go +++ b/crontask/corn.go @@ -72,7 +72,8 @@ func CheckAndroidDevices() { fmt.Println("设备", v.Udid, "已连接但未认证") } case "online": - monkey.KeepDevice(v.Udid) + // 保持亮屏 + monkey.KeepAndroidDevice(v.Udid) } } else { // 数据表中的设备,adb没有获取到,视为离线 diff --git a/crontask/ios.go b/crontask/ios.go index 6767ba3..548b46f 100644 --- a/crontask/ios.go +++ b/crontask/ios.go @@ -21,6 +21,7 @@ func CheckIOSDevices() { db.Model(models.Device{}).Where("platform = ? AND is_del = 0", "ios").Find(&list) for _, v := range list { if vv, ok := m[v.Udid]; ok { + // 数据表中的设备,sib有获取到 if vv.Status != "online" && v.Status != vv.Status { db.Model(models.Device{}).Where("udid = ?", v.Udid).Update("status", vv.Status) fmt.Println("[Crontab]", v.Udid, "连接状态异常:", v.Status) @@ -28,7 +29,13 @@ func CheckIOSDevices() { db.Model(models.Device{}).Where("udid = ?", v.Udid).Update("status", "online") fmt.Println("[Crontab]", v.Udid, "已连接") } + switch v.Status { + case "online": + // 保持亮屏 + // monkey.KeepiOSDevice(v.Udid) + } } else { + // 数据表中的设备,sib没有获取到 if v.Status == "online" || v.Status == "busy" { db.Model(models.Device{}).Where("udid = ?", v.Udid).Update("status", "offline") fmt.Println("[Crontab]", v.Udid, "已离线") diff --git a/go.mod b/go.mod index 95d32ec..bfbbc04 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect + github.com/electricbubble/gidevice v0.6.2 // indirect + github.com/electricbubble/gwda v0.4.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect @@ -38,6 +40,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect @@ -50,6 +53,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.2.0 // indirect github.com/quic-go/qtls-go1-20 v0.1.0 // indirect github.com/quic-go/quic-go v0.32.0 // indirect + github.com/satori/go.uuid v1.2.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.7.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect @@ -61,4 +65,5 @@ require ( google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + howett.net/plist v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index b95f77d..7f0b8d0 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,10 @@ 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/electricbubble/gidevice v0.6.2 h1:eIeCHH7Xn5fTwnUv3qL8c7L4anKIHtjlTBkgr1LDVTc= +github.com/electricbubble/gidevice v0.6.2/go.mod h1:bRHL2M9qgeEKju8KRvKMZUVEg7t5zMnTiG3SJ3QDH5o= +github.com/electricbubble/gwda v0.4.0 h1:+Sbi8WRM8sXh0cXpmY97GiWuR1CNQ/v2tsMUyWxlnV4= +github.com/electricbubble/gwda v0.4.0/go.mod h1:kyzKpP1/iKJ2i4AxmT8sEmSvB8Pz5NcDVwc/m/Jsg6k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= @@ -69,6 +73,7 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imroc/req/v3 v3.32.3 h1:FX3xCN0iWn1wJKHN0EB8l7EjXDTE4j/C8m7zeAb2UH0= github.com/imroc/req/v3 v3.32.3/go.mod h1:cZ+7C3L/AYOr4tLGG16hZF90F1WzAdAdzt1xFSlizXY= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -89,6 +94,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc= +github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -131,6 +138,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -228,6 +237,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -241,3 +252,6 @@ gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM= gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= +howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/monkey/cli_adr.go b/monkey/cli_adr.go index d5be4fc..85181c9 100644 --- a/monkey/cli_adr.go +++ b/monkey/cli_adr.go @@ -111,7 +111,7 @@ func getAndroidDeviceName(udid string) string { return device_name } -func KeepDevice(udid string) error { +func KeepAndroidDevice(udid string) error { //adb shell input keyevent 3 cmd := exec.Command("adb", "-s", udid, "shell", "input", "keyevent", "4") err := cmd.Run() diff --git a/monkey/ios.go b/monkey/ios.go index 0d15e3d..e95a107 100644 --- a/monkey/ios.go +++ b/monkey/ios.go @@ -4,9 +4,12 @@ import ( "autogo/common" "autogo/dbsql" "autogo/models" + "fmt" "os/exec" + "strings" "time" + "github.com/electricbubble/gwda" log "github.com/sirupsen/logrus" "github.com/spf13/cast" ) @@ -19,7 +22,7 @@ func RuniOSMonkeyByDocker(task models.MonkeyTask, udid string) { defer dbsql.Close(db) db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", "INIT") - filename := cast.ToString(time.Now().Unix()) + ".ipa" + filename := cast.ToString(time.Now().UnixMilli()) + ".ipa" pkg_path := "/home/tmp/pkg/" + filename log.Debug("正在下载ipa:", task.PackageURL) err = exec.Command("wget", task.PackageURL, "-O", pkg_path).Run() @@ -44,3 +47,25 @@ func RuniOSMonkeyByDocker(task models.MonkeyTask, udid string) { log.Error(err) } } + +// iOS设备保活,注意需要先启动wda +func KeepiOSDevice(udid string) error { + // 初始化wda驱动和设备信息 + devices, err := gwda.DeviceList() + if err != nil { + fmt.Println() + return err + } + for _, v := range devices { + if strings.EqualFold(v.SerialNumber(), udid) { + fmt.Println("匹配到对应设备 -", udid) + driver, err := gwda.NewUSBDriver(nil, v) + if err != nil { + return err + } + driver.PressButton(gwda.DeviceButtonHome) + return nil + } + } + return nil +} diff --git a/monkey/task_v2.go b/monkey/task_v2.go index 6f9fcbf..f74d8c8 100644 --- a/monkey/task_v2.go +++ b/monkey/task_v2.go @@ -88,7 +88,12 @@ func CreateTaskV2(c *gin.Context) { task.Branch = app.Branch } if task.Version == "" { - task.Version = app.Version + "_" + app.VersionCode + if task.Platform == "ios" { + task.Version = app.Version + "_" + cast.ToString(app.BuildNum) + } else { + task.Version = app.Version + "_" + app.VersionCode + } + } } } diff --git a/test/test.go b/test/test.go index ea98d65..76af90d 100644 --- a/test/test.go +++ b/test/test.go @@ -7,12 +7,17 @@ import ( "autogo/models" "autogo/monkey" "fmt" + "net/http" "os/exec" "strings" "time" + + "github.com/imroc/req/v3" ) func main() { + buglyHelper() + return cmd := exec.Command("docker", "ps") output, err := cmd.Output() if err != nil { @@ -34,6 +39,49 @@ func main() { fmt.Println("end") } +func buglyHelper() { + var rsp BuglyRsp + url := `https://bugly.qq.com/v2/search?start=0&userSearchPage=%2Fv2%2Fworkbench%2Fapps&pid=2&platformId=2&date=last_7_day&sortOrder=desc&useSearchTimes=2&rows=10&sortField=matchCount&appId=447d39aea1&fsn=f0726b64-a3ac-4e0d-a89d-c9148c82a5e6` + client := req.C(). + SetTimeout(5 * time.Second) + resp, err := client.R(). + SetCookies(cookies()...). + SetHeader("X-Token", "536325371"). + SetHeader("Accept", "application/json;charset=utf-8"). + SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36"). + // SetHeader("Cookie", "ptui_loginuin=188107463; RK=vOtUmiA9WS; ptcz=d265861b48af6f48ea0f924ded6af2b654f74146c1dc4d8632cb48e67edf7484; _ga=GA1.2.1584569153.1684823271; _qpsvr_localtk=0.9318772864960871; token-skey=b9694495-0a28-882a-01f9-d038d9e43bc7; token-lifeTime=1686922095; bugly-session=s:xz-9qL2pRzO3Mz8Wu_I7Svl2SLCWJfLE.MqN7buOfwmbUlRkdLauxXaddtaS3lebknTnCdPQOmtw; referrer=eyJpdiI6IkFcLzJDUTlValNtS0lUaGRFdkg3d2pRPT0iLCJ2YWx1ZSI6Ims4YUp6cUxyZlc0N25hOEJ2QWpZUlZQa2RKc1o3N3RiRHZXVVI1MlJLZ1RrSEtaQ2VmY1BtNEhMUjg4QjJSaExnc05cLzdiaGc2SHFtOTgzdnljMmlxUjd3d0FNZWdZdFwvNjdsT2ZYaG84M21Yd25FV1N0UTJyZTd3TDBId3hiQzNhN1wvS2RTZ1ZvdVFDYStKeEIrcGNnWWs1bno3dHdjTkVWdHIrYmRYTWNUb3Z1UGVvMXdoSE50djJBZ05hZ2pXUiIsIm1hYyI6IjgwNDI0ZjI2MjI0ZDFhMDA3MjBhYjQ4MWIwYjJiZTIzY2U5YjNkZjYyNGFkNTA5NGFjN2U4Y2U3ZTQwMDVlYWQifQ==; bugly_session=eyJpdiI6IjNmQzhJamU1cUlVd08yZHdWMkpTcmc9PSIsInZhbHVlIjoiZ3dFUXZUWmZ6XC8rbTZITG1DRVdrdDUrM1p0RE5nemgzeVhJa2huYWhieVB4SVFRMnlyWFFCU2JCQVpmRHNRQjdubnhhRWVJcUd3OEdzSk1zKzF2WGt3PT0iLCJtYWMiOiIwZjc4MGFmMDk1YzUyZTQ4Zjc5MjcwMDMyNGUzNmMxYjE5MjRlNTQ2MjliMzA3NmQyMGVjODRiZDgyMDU2NGQ1In0="). + SetHeader("Accept", "application/json;charset=utf-8"). + SetHeader("Accept-Encoding", "gzip, deflate, br"). + SetHeader("Accept-Language", "zh-CN,zh;q=0.9"). + SetHeader("Connection", "keep-alive"). + SetSuccessResult(&rsp). + // SetResult(&rsp). + Get(url) + if err != nil { + fmt.Println(err) + return + } + if resp.IsErrorState() { + fmt.Println(resp.StatusCode) + return + } + fmt.Println(len(rsp.Ret.IssueList)) +} + +func cookies() []*http.Cookie { + var cookies []*http.Cookie + var c1 http.Cookie + c1.Name = "bugly-session" + c1.Value = "s:xz-9qL2pRzO3Mz8Wu_I7Svl2SLCWJfLE.MqN7buOfwmbUlRkdLauxXaddtaS3lebknTnCdPQOmtw" + cookies = append(cookies, &c1) + + var c3 http.Cookie + c3.Name = "bugly_session" + c3.Value = "eyJpdiI6IlpuTkc5aXcwRHdUR1JGdDhIUmJMbGc9PSIsInZhbHVlIjoiRTZhVmxya3R3Sjl6UzBKQjRLa0EyNXlVV0lVYlNWVnpvVWFrbzVRS0k5am9UK3Y2MHN5czc3XC9JV0ZJNCtBQkdBbW4rZFh5RmFrcWYzODhOanV0OE9BPT0iLCJtYWMiOiI2MmJlYTI2MWE0M2U4NTFlNjJhYzkwZTAyOTQ3MTgxZmYwMTc0ZGJjOGE4MTE0ZjQ1Y2VmN2I5NjJkYTk2ZGY5In0=" + cookies = append(cookies, &c3) + return cookies +} + func getRuntime(containerID string) { // 执行 docker inspect 命令获取容器创建时间 @@ -118,3 +166,66 @@ func Dir() { fmt.Println(err) } } + +type BuglyRsp struct { + Status int `json:"status"` + Msg string `json:"msg"` + Ret struct { + AppID string `json:"appId"` + PlatformID string `json:"platformId"` + IssueList []struct { + IssueID int `json:"issueId"` + IssueHash string `json:"issueHash"` + IssueCount int `json:"issueCount"` + CrashInfo struct { + CrashID string `json:"crashId"` + TagID int `json:"tagId"` + } `json:"crashInfo"` + IssueVersions []struct { + Version string `json:"version"` + Count int `json:"count"` + DeviceCount int `json:"deviceCount"` + } `json:"issueVersions"` + FtName string `json:"ftName"` + IssueDocMap struct { + ID string `json:"id"` + IssueID int `json:"issueId"` + Status int `json:"status"` + Count int `json:"count"` + SysCount int `json:"sysCount"` + ProductVersion string `json:"productVersion"` + DeviceCount int `json:"deviceCount"` + SysDeviceCount int `json:"sysDeviceCount"` + LastUpdateTime string `json:"lastUpdateTime"` + FirstUploadTime string `json:"firstUploadTime"` + LastUploadTime string `json:"lastUploadTime"` + ExpName string `json:"expName"` + ExpFingure string `json:"expFingure"` + IsSystemStack int `json:"isSystemStack"` + KeyStack string `json:"keyStack"` + Type string `json:"type"` + AverageBattery float64 `json:"averageBattery"` + AverageMemory float64 `json:"averageMemory"` + AverageSD float64 `json:"averageSD"` + AverageStorage float64 `json:"averageStorage"` + CrossVersionIssueID int `json:"crossVersionIssueId"` + VersionIssueIds []int `json:"versionIssueIds"` + SubIssueVersions string `json:"subIssueVersions"` + ExpMessage string `json:"expMessage"` + RootCount int `json:"rootCount"` + SysRootCount int `json:"sysRootCount"` + ExpAddr string `json:"expAddr"` + RefSdkAppID string `json:"refSdkAppId"` + RefSdkIssueID string `json:"refSdkIssueId"` + CrashRecordCount int `json:"crashRecordCount"` + } `json:"issueDocMap"` + CrossVersionIssueID int `json:"crossVersionIssueId"` + EsCount int `json:"esCount"` + EsDeviceCount int `json:"esDeviceCount"` + } `json:"issueList"` + NumFound int `json:"numFound"` + CrashNums int `json:"crashNums"` + AnrNums int `json:"anrNums"` + ErrorNums int `json:"errorNums"` + } `json:"ret"` +}