diff --git a/common/create_bug.go b/common/create_bug.go
new file mode 100644
index 0000000..7075ab6
--- /dev/null
+++ b/common/create_bug.go
@@ -0,0 +1,88 @@
+package common
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/imroc/req/v3"
+ "github.com/tidwall/gjson"
+)
+
+const API_tbapi = "http://qa.flatincbr.work:5354"
+
+type BugInfo struct {
+ ProjectName string `json:"project_name"` // tb项目名称
+ ProjectID string `json:"project_id"` // tb项目id
+ ExecutorID string `json:"executor_id"` // tb缺陷的处理人
+ Title string `json:"title"` // tb缺陷的标题
+ Content string `json:"content"` // tb缺陷的备注
+ InvolveMembers []string `json:"involve_members"` // tb缺陷的参与人
+ Pf string `json:"pf"` // 所属平台,除了adr/ios其它不处理
+}
+
+func NewBug(project_name string) BugInfo {
+ var v BugInfo
+ v.ProjectName = project_name
+ return v
+}
+
+// 指定执行者
+func (b *BugInfo) SetExecutor(id string) *BugInfo {
+ b.ExecutorID = id
+ return b
+}
+
+// 指定参与者
+func (b *BugInfo) SetInvolveMember(id ...string) *BugInfo {
+ b.InvolveMembers = id
+ return b
+}
+
+// 设置标题
+func (b *BugInfo) SetTitle(title string) *BugInfo {
+ b.Title = title
+ return b
+}
+
+// 设置备注内容
+func (b *BugInfo) SetContent(content string) *BugInfo {
+ b.Content = content
+ return b
+}
+
+// 设置所属平台:adr/ios
+func (b *BugInfo) SetPlatform(pf string) *BugInfo {
+ b.Pf = pf
+ return b
+}
+
+func (b *BugInfo) Create() (string, error) {
+ // buf, err := json.Marshal(b)
+ // if err != nil {
+ // fmt.Println("序列化失败:", err)
+ // return "", err
+ // }
+ // fmt.Println(string(buf))
+
+ client := req.C().
+ SetTimeout(10 * time.Second)
+ resp, err := client.R().
+ SetBodyJsonMarshal(b).
+ Post(API_tbapi + "/api/tb/v2/bug/create")
+ if err != nil {
+ fmt.Println("Teambition提单失败:", err)
+ return "", err
+ }
+ if resp.IsErrorState() {
+ fmt.Println("Teambition提单失败:", resp.StatusCode, resp.String())
+ return "", err
+ }
+ bug_id := gjson.Get(resp.String(), "data").String()
+ if len(bug_id) == 0 {
+ return "", errors.New("请求成功,但返回bug_id为空")
+ }
+ fmt.Println("Teambition提单成功, id =", bug_id)
+
+ return bug_id, nil
+}
diff --git a/docs/docs.go b/docs/docs.go
index 1171a6a..f039307 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -959,6 +959,35 @@ const docTemplate = `{
}
}
},
+ "/api/monkey/v2/task/get_anomalies": {
+ "get": {
+ "description": "通过任务id获取Monkey异常信息",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "tags": [
+ "Monkey相关 /api/monkey/v2/"
+ ],
+ "summary": "获取Monkey异常信息",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "任务id",
+ "name": "task_id",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "返回任务结果",
+ "schema": {
+ "$ref": "#/definitions/models.Response"
+ }
+ }
+ }
+ }
+ },
"/api/monkey/v2/task/handle/set": {
"post": {
"description": "更新Monkey任务跟进状态",
@@ -995,6 +1024,59 @@ const docTemplate = `{
}
}
},
+ "/api/monkey/v2/task/store_anomaly": {
+ "post": {
+ "description": "上报Monkey异常",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "tags": [
+ "Monkey相关 /api/monkey/v2/"
+ ],
+ "summary": "上报Monkey异常",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "任务id",
+ "name": "task_id",
+ "in": "formData",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "crash_log_list",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "activity_name_info",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "device_name",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "status",
+ "in": "formData"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "返回更新后的任务信息",
+ "schema": {
+ "$ref": "#/definitions/models.Response"
+ }
+ }
+ }
+ }
+ },
"/api/project/v1/app": {
"get": {
"description": "根据应用名称app_name获取应用信息",
diff --git a/docs/swagger.json b/docs/swagger.json
index 5965983..7b7d818 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -947,6 +947,35 @@
}
}
},
+ "/api/monkey/v2/task/get_anomalies": {
+ "get": {
+ "description": "通过任务id获取Monkey异常信息",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "tags": [
+ "Monkey相关 /api/monkey/v2/"
+ ],
+ "summary": "获取Monkey异常信息",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "任务id",
+ "name": "task_id",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "返回任务结果",
+ "schema": {
+ "$ref": "#/definitions/models.Response"
+ }
+ }
+ }
+ }
+ },
"/api/monkey/v2/task/handle/set": {
"post": {
"description": "更新Monkey任务跟进状态",
@@ -983,6 +1012,59 @@
}
}
},
+ "/api/monkey/v2/task/store_anomaly": {
+ "post": {
+ "description": "上报Monkey异常",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "tags": [
+ "Monkey相关 /api/monkey/v2/"
+ ],
+ "summary": "上报Monkey异常",
+ "parameters": [
+ {
+ "type": "integer",
+ "description": "任务id",
+ "name": "task_id",
+ "in": "formData",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "crash_log_list",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "activity_name_info",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "device_name",
+ "in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "要更新的任务状态",
+ "name": "status",
+ "in": "formData"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "返回更新后的任务信息",
+ "schema": {
+ "$ref": "#/definitions/models.Response"
+ }
+ }
+ }
+ }
+ },
"/api/project/v1/app": {
"get": {
"description": "根据应用名称app_name获取应用信息",
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index fefdf8f..c5e3761 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -635,6 +635,25 @@ paths:
summary: 获取Monkey任务的执行命令
tags:
- Monkey相关 /api/monkey/v2/
+ /api/monkey/v2/task/get_anomalies:
+ get:
+ consumes:
+ - application/x-www-form-urlencoded
+ description: 通过任务id获取Monkey异常信息
+ parameters:
+ - description: 任务id
+ in: query
+ name: task_id
+ required: true
+ type: integer
+ responses:
+ "200":
+ description: 返回任务结果
+ schema:
+ $ref: '#/definitions/models.Response'
+ summary: 获取Monkey异常信息
+ tags:
+ - Monkey相关 /api/monkey/v2/
/api/monkey/v2/task/handle/set:
post:
consumes:
@@ -659,6 +678,41 @@ paths:
summary: 更新任务跟进状态
tags:
- Monkey相关 /api/monkey/v2/
+ /api/monkey/v2/task/store_anomaly:
+ post:
+ consumes:
+ - application/x-www-form-urlencoded
+ description: 上报Monkey异常
+ parameters:
+ - description: 任务id
+ in: formData
+ name: task_id
+ required: true
+ type: integer
+ - description: 要更新的任务状态
+ in: formData
+ name: crash_log_list
+ type: string
+ - description: 要更新的任务状态
+ in: formData
+ name: activity_name_info
+ type: string
+ - description: 要更新的任务状态
+ in: formData
+ name: device_name
+ type: string
+ - description: 要更新的任务状态
+ in: formData
+ name: status
+ type: string
+ responses:
+ "200":
+ description: 返回更新后的任务信息
+ schema:
+ $ref: '#/definitions/models.Response'
+ summary: 上报Monkey异常
+ tags:
+ - Monkey相关 /api/monkey/v2/
/api/project/v1/app:
get:
consumes:
diff --git a/go.mod b/go.mod
index bfbbc04..c9a3b49 100644
--- a/go.mod
+++ b/go.mod
@@ -54,6 +54,9 @@ require (
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/tidwall/gjson v1.14.4 // indirect
+ github.com/tidwall/match v1.1.1 // indirect
+ github.com/tidwall/pretty 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
diff --git a/go.sum b/go.sum
index 7f0b8d0..f75eb84 100644
--- a/go.sum
+++ b/go.sum
@@ -164,6 +164,12 @@ github.com/swaggo/gin-swagger v1.5.2/go.mod h1:Cbj/MlHApPOjZdf4joWFXLLgmZVPyh54G
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
github.com/swaggo/swag v1.8.4 h1:oGB351qH1JqUqK1tsMYEE5qTBbPk394BhsZxmUfebcI=
github.com/swaggo/swag v1.8.4/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
+github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
+github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
+github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
diff --git a/models/monkey_anomaly.go b/models/monkey_anomaly.go
new file mode 100644
index 0000000..9ae8033
--- /dev/null
+++ b/models/monkey_anomaly.go
@@ -0,0 +1,33 @@
+package models
+
+import (
+ "autogo/global"
+ "encoding/json"
+ "fmt"
+)
+
+type MonkeyAnomaly struct {
+ global.MODEL
+ TaskId int `json:"task_id"`
+ Udid string `json:"udid"`
+ AnomalyInfos string `json:"-" gorm:"anomaly_infos"`
+ Anomalies []string `json:"anomalies" gorm:"-"`
+ CoverdPages string `json:"coverd_pages"`
+ Logs string `json:"logs"`
+}
+
+func (m *MonkeyAnomaly) TableName() string {
+ return "monkey_anomalies"
+}
+
+func (m *MonkeyAnomaly) JsonReady() {
+ var strs []string
+ if len(m.AnomalyInfos) > 3 {
+ err := json.Unmarshal([]byte(m.AnomalyInfos), &strs)
+ if err != nil {
+ fmt.Println("[JsonReady]", "序列化失败")
+ return
+ }
+ m.Anomalies = strs
+ }
+}
diff --git a/models/monkey_task.go b/models/monkey_task.go
index cd72f0d..1601fca 100644
--- a/models/monkey_task.go
+++ b/models/monkey_task.go
@@ -66,7 +66,7 @@ func (task *MonkeyTask) Cmd(udid string, filename string) string {
// }
// cmd_str += " >> /home/app/logs/task_output/task_" + cast.ToString(task.Id) + ".log 2>&1"
case "ios":
- cmd_str = "docker run -d --rm --name monkey_task_" + cast.ToString(task.Id) + "_" + udid + " "
+ cmd_str = "docker run -d --rm --net=host --name monkey_task_" + cast.ToString(task.Id) + "_" + udid + " "
cmd_str += "-e TASK_ID=" + cast.ToString(task.Id) + " "
cmd_str += "-e BUNDLE_ID=" + task.PackageName + " "
cmd_str += "-e RUNTIME=" + cast.ToString(task.RunTime) + " "
diff --git a/monkey/anomaly.go b/monkey/anomaly.go
new file mode 100644
index 0000000..42e68f4
--- /dev/null
+++ b/monkey/anomaly.go
@@ -0,0 +1,161 @@
+package monkey
+
+import (
+ "autogo/common"
+ "autogo/controllers"
+ "autogo/dbsql"
+ "autogo/models"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+ "github.com/spf13/cast"
+)
+
+type anomaly struct {
+ TaskId int `json:"task_id"`
+ Udid string `json:"udid"`
+ Anomalies []string `json:"anomalies"`
+ CoverdPages []string `json:"coverd_pages"`
+ Logs []string `json:"logs"`
+}
+
+// @Tags Monkey相关 /api/monkey/v2/
+// @Summary 上报Monkey异常
+// @Description 上报Monkey异常
+// @accept x-www-form-urlencoded
+// @Param task_id formData int true "任务id"
+// @Param crash_log_list formData string false "要更新的任务状态"
+// @Param activity_name_info formData string false "要更新的任务状态"
+// @Param device_name formData string false "要更新的任务状态"
+// @Param status formData string false "要更新的任务状态"
+// @Success 200 {object} models.Response "返回更新后的任务信息"
+// @Router /api/monkey/v2/task/store_anomaly [post]
+func StoreMonkeyAnomaly(c *gin.Context) {
+ rsp := controllers.NewResponse()
+
+ var ano anomaly
+ err := c.ShouldBindJSON(&ano)
+ if err != nil {
+ c.JSON(http.StatusOK, rsp.Error("json解析失败: "+err.Error()))
+ return
+ }
+
+ var res models.MonkeyAnomaly
+ res.TaskId = cast.ToInt(ano.TaskId)
+ if res.TaskId < 1 {
+ rsp.Error("task_id error:" + c.PostForm("task_id"))
+ c.JSON(http.StatusOK, rsp)
+ return
+ }
+ if len(ano.Anomalies) > 0 {
+ buf, _ := json.Marshal(ano.Anomalies)
+ res.Anomalies = ano.Anomalies
+ res.AnomalyInfos = string(buf)
+ }
+ if len(ano.CoverdPages) > 0 {
+ res.CoverdPages = strings.Join(ano.CoverdPages, ",")
+ }
+ res.Udid = ano.Udid
+ if len(ano.Logs) > 0 {
+ res.Logs = strings.Join(ano.Logs, ",")
+ }
+
+ db, err := dbsql.GetConn(dbsql.DSN)
+ if err != nil {
+ rsp.Error(err.Error())
+ c.JSON(http.StatusOK, rsp)
+ return
+ }
+ defer dbsql.Close(db)
+ db.Table(res.TableName()).Model(models.MonkeyAnomaly{}).Create(&res)
+ if res.ID < 1 {
+ rsp.Error("保存Monkey异常失败")
+ c.JSON(http.StatusOK, rsp)
+ return
+ }
+
+ rsp.Success()
+ rsp.Data = res
+ c.JSON(http.StatusOK, rsp)
+
+ go createTbBug(res)
+}
+
+// @Tags Monkey相关 /api/monkey/v2/
+// @Summary 获取Monkey异常信息
+// @Description 通过任务id获取Monkey异常信息
+// @accept x-www-form-urlencoded
+// @Param task_id query int true "任务id"
+// @Success 200 {object} models.Response "返回任务结果"
+// @Router /api/monkey/v2/task/get_anomalies [get]
+func GetMonkeyAnomaliesByTaskId(c *gin.Context) {
+ rsp := controllers.NewResponse()
+
+ var list []models.MonkeyAnomaly
+ db, err := dbsql.GetConn(dbsql.DSN)
+ if err != nil {
+ rsp.Error(err.Error())
+ c.JSON(http.StatusOK, rsp)
+ return
+ }
+ defer dbsql.Close(db)
+ db.Where("task_id = ?", c.Query("task_id")).Find(&list)
+ for i, _ := range list {
+ list[i].JsonReady()
+ }
+
+ rsp.Success()
+ rsp.Data = list
+ c.JSON(http.StatusOK, rsp)
+}
+
+func createTbBug(ano models.MonkeyAnomaly) {
+ db, err := dbsql.GetConn(dbsql.DSN)
+ if err != nil {
+ fmt.Println("[createTbBug]", err)
+ return
+ }
+ defer dbsql.Close(db)
+
+ var task models.MonkeyTask
+ db.Model(models.MonkeyTask{}).Where("id = ?", ano.TaskId).Last(&task)
+ if task.Id < 1 {
+ fmt.Println("[createTbBug]", "没有找到monkey任务,id -", ano.TaskId)
+ return
+ }
+
+ content := ""
+ content += "**关联Monkey报告:** [点击查看](http://qa.flatincbr.work/#/monkey/result/" + cast.ToString(ano.TaskId) + ")" + "\n\n
\n\n"
+ content += "**上报时间:**" + ano.CreateTime.Format("2006-01-02 15:04:05") + "\n\n
\n\n"
+ content += "**应用版本:**" + task.Version + "\n\n
\n\n"
+ content += "**信息预览:**" + "\n\n"
+ for _, v := range ano.Anomalies {
+ for i, vv := range strings.Split(v, "\n") {
+ content += "> " + vv + "\n"
+ if i > 10 {
+ break
+ }
+ }
+ content += "> " + "——————————————————————" + "\n"
+ }
+ content += "> " + "(...更多请查看Monkey报告)" + "\n"
+ content += "\n"
+
+ bug := common.NewBug("crushu") //task.Project
+ bug.SetExecutor("62733beb6918b259138d7577").
+ SetInvolveMember("62733beb6918b259138d7577").
+ SetTitle("【Monkey测试】任务id=" + cast.ToString(task.Id) + "发生异常").
+ SetPlatform(task.Platform).
+ SetContent(content)
+
+ id, err := bug.Create()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Println("缺陷创建成功:", "https://www.teambition.com/task/"+id)
+
+}
diff --git a/monkey/task.go b/monkey/task.go
index 728598f..c5b8af8 100644
--- a/monkey/task.go
+++ b/monkey/task.go
@@ -455,7 +455,19 @@ func StopMonkeyTask(c *gin.Context) {
list := GetTaskFromDocker(task_id)
for _, v := range list {
StopDockerContainer(v.Name)
- db.Table("device").Model(models.Device{}).Where("udid = ?", v.Device).Update("status", "online")
+ }
+
+ // 重置设备状态
+ var task models.MonkeyTask
+ db.Table(task.TableName()).Model(models.MonkeyTask{}).Where("id = ?", task_id).Last(&task)
+ if strings.Contains(task.Devices, ",") {
+ // 多台设备
+ for _, v := range strings.Split(task.Devices, ",") {
+ db.Table("device").Model(models.Device{}).Where("udid = ?", v).Update("status", "online")
+ }
+ } else if len(task.Devices) > 1 {
+ // 有一台设备
+ db.Table("device").Model(models.Device{}).Where("udid = ?", task.Devices).Update("status", "online")
}
db.Table("monkey_task").Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("status", "CANCEL")
diff --git a/test/test.go b/test/cli/test.go
similarity index 75%
rename from test/test.go
rename to test/cli/test.go
index 76af90d..2e446c7 100644
--- a/test/test.go
+++ b/test/cli/test.go
@@ -1,231 +1,255 @@
-package main
-
-import (
- "autogo/common"
- "autogo/dbsql"
- "autogo/device"
- "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 {
- fmt.Println(err)
- return
- }
-
- lines := strings.Split(string(output), "\n")
- for i, line := range lines {
- if i == 0 {
- continue // skip header line
- }
- fields := strings.Fields(line)
- if len(fields) >= 7 {
- fmt.Printf("Container ID: %s, Name: %s\n", fields[0], fields[len(fields)-1])
- getRuntime(fields[0])
- }
- }
- 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 命令获取容器创建时间
- cmd := exec.Command("docker", "inspect", "-f", "{{.Created}}", containerID)
- output, err := cmd.Output()
- if err != nil {
- fmt.Println(err)
- return
- }
-
- // 将输出结果转换为时间格式
- createdTime, err := time.Parse(time.RFC3339Nano, strings.TrimSpace(string(output)))
- if err != nil {
- fmt.Println(err)
- return
- }
-
- // 计算容器已经运行的时间
- uptime := time.Since(createdTime)
-
- // 将容器运行时间转换为秒级时间戳输出
- uptimeInSeconds := int64(uptime.Seconds())
- fmt.Printf("Container %s has been running for %d seconds\n", containerID, uptimeInSeconds)
-}
-
-func sib() {
- if device.CheckSib() {
- fmt.Println("sib已安装")
- fmt.Println(device.GetIOSDevices())
- } else {
- fmt.Println("sib未安装")
- }
-}
-
-func tmp1() {
- dbsql.DSN = dbsql.DSN_local
- db, err := dbsql.GetConn(dbsql.DSN)
- if err != nil {
- fmt.Println(err)
- return
- }
- defer dbsql.Close(db)
- var task models.MonkeyTask
- db.Last(&task)
- common.PushMonkeyResult(task)
- return
- // dbsql.DSN = dbsql.DSN_local
- // db, err := dbsql.GetConn(dbsql.DSN)
- // if err != nil {
- // fmt.Println(err)
- // return
- // }
- // defer dbsql.Close(db)
-
- var list []models.MonkeyTask
- db.Model(models.MonkeyTask{}).Order("id DESC").Find(&list)
- for _, v := range list {
- if v.PackageURL != "" {
- app, err := common.GetBranch(v.PackageName, v.PackageURL)
- if err != nil {
- fmt.Println(v.Id, "-", err, "||", v.PackageURL)
- err = nil
- } else {
- fmt.Println(v.Id, "-", app.Branch)
- db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("version", app.Version+"_"+app.VersionCode)
- }
- }
- }
-}
-
-func Dir() {
- err := monkey.CreateDir("files")
- if err != nil {
- fmt.Println(err)
- }
- err = monkey.CreateDir("files/1")
- if err != nil {
- fmt.Println(err)
- }
- err = monkey.CreateAndWriteFile("files/1/2.txt", []byte("hidiuniduini"))
- if err != nil {
- 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"`
-}
+package main
+
+import (
+ "autogo/common"
+ "autogo/dbsql"
+ "autogo/device"
+ "autogo/models"
+ "autogo/monkey"
+ "autogo/test"
+ "fmt"
+ "net/http"
+ "os/exec"
+ "strings"
+ "time"
+
+ "github.com/imroc/req/v3"
+ "github.com/spf13/cast"
+)
+
+func main() {
+ test.GetMonkeyResult()
+ return
+
+ db, err := dbsql.GetConn(dbsql.DSN_local)
+ if err != nil {
+ return
+ }
+ defer dbsql.Close(db)
+ var list []models.MonkeyTask
+ db.Model(models.MonkeyTask{}).Where("crash_count > 0 AND is_del = 0").Find(&list)
+ str := ""
+ for _, v := range list {
+ str += "\"" + cast.ToString(v.Id) + "\" "
+ }
+ fmt.Println(str)
+
+ return
+ buglyHelper()
+ return
+ cmd := exec.Command("docker", "ps")
+ output, err := cmd.Output()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ lines := strings.Split(string(output), "\n")
+ for i, line := range lines {
+ if i == 0 {
+ continue // skip header line
+ }
+ fields := strings.Fields(line)
+ if len(fields) >= 7 {
+ fmt.Printf("Container ID: %s, Name: %s\n", fields[0], fields[len(fields)-1])
+ getRuntime(fields[0])
+ }
+ }
+ 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=3&rows=10&sortField=matchCount&appId=447d39aea1&fsn=8799e426-34c8-4a75-bd0d-1e186509eb5e`
+ client := req.C().
+ SetTimeout(5 * time.Second)
+ resp, err := client.R().
+ SetCookies(cookies()...).
+ SetHeader("X-Token", "957369952").
+ 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", "bugly-session=s%3AqQZzQXsgw0wv_lFKAOT88ND_yh_B1f6H.au%2F78LCSHj5zhwqe%2FljmOXGP7TBW3yHnMwypYesrn34;bugly_session=eyJpdiI6InV1R3R0TmZ2S01HTkVBSGpucThXZXc9PSIsInZhbHVlIjoiam1lM3o1cVJISjNyZVJ6U3JJYzhmK1M1UVJiUlhCS1wvRTh6T1d4XC93NDdiY3FITVNJQXRpVFd6Y1BBV1wvZTBhOWR0MHBxNTlRdGNYdExoS2VWK2swckE9PSIsIm1hYyI6IjliMDExNTdmMzgyODFmNTEyYzVmMGQ3MGMxYTdjOTZmMDNjYzVjYzlkYzcxMmVjNmUyMzk4YWE2OTRmNzY4NzAifQ%3D%3D;").
+ 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
+ }
+ if len(rsp.Ret.IssueList) > 0 {
+ fmt.Println(len(rsp.Ret.IssueList))
+ } else {
+ fmt.Println(resp.String())
+ }
+
+}
+
+func cookies() []*http.Cookie {
+ var cookies []*http.Cookie
+ // var c1 http.Cookie
+ // c1.Name = "bugly-session"
+ // c1.Value = "s:qQZzQXsgw0wv_lFKAOT88ND_yh_B1f6H.au/78LCSHj5zhwqe/ljmOXGP7TBW3yHnMwypYesrn34"
+ // cookies = append(cookies, &c1)
+
+ var c3 http.Cookie
+ c3.Name = "bugly_session"
+ c3.Value = "eyJpdiI6InV1R3R0TmZ2S01HTkVBSGpucThXZXc9PSIsInZhbHVlIjoiam1lM3o1cVJISjNyZVJ6U3JJYzhmK1M1UVJiUlhCS1wvRTh6T1d4XC93NDdiY3FITVNJQXRpVFd6Y1BBV1wvZTBhOWR0MHBxNTlRdGNYdExoS2VWK2swckE9PSIsIm1hYyI6IjliMDExNTdmMzgyODFmNTEyYzVmMGQ3MGMxYTdjOTZmMDNjYzVjYzlkYzcxMmVjNmUyMzk4YWE2OTRmNzY4NzAifQ=="
+ cookies = append(cookies, &c3)
+ return cookies
+}
+
+func getRuntime(containerID string) {
+
+ // 执行 docker inspect 命令获取容器创建时间
+ cmd := exec.Command("docker", "inspect", "-f", "{{.Created}}", containerID)
+ output, err := cmd.Output()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ // 将输出结果转换为时间格式
+ createdTime, err := time.Parse(time.RFC3339Nano, strings.TrimSpace(string(output)))
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ // 计算容器已经运行的时间
+ uptime := time.Since(createdTime)
+
+ // 将容器运行时间转换为秒级时间戳输出
+ uptimeInSeconds := int64(uptime.Seconds())
+ fmt.Printf("Container %s has been running for %d seconds\n", containerID, uptimeInSeconds)
+}
+
+func sib() {
+ if device.CheckSib() {
+ fmt.Println("sib已安装")
+ fmt.Println(device.GetIOSDevices())
+ } else {
+ fmt.Println("sib未安装")
+ }
+}
+
+func tmp1() {
+ dbsql.DSN = dbsql.DSN_local
+ db, err := dbsql.GetConn(dbsql.DSN)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ defer dbsql.Close(db)
+ var task models.MonkeyTask
+ db.Last(&task)
+ common.PushMonkeyResult(task)
+ return
+ // dbsql.DSN = dbsql.DSN_local
+ // db, err := dbsql.GetConn(dbsql.DSN)
+ // if err != nil {
+ // fmt.Println(err)
+ // return
+ // }
+ // defer dbsql.Close(db)
+
+ var list []models.MonkeyTask
+ db.Model(models.MonkeyTask{}).Order("id DESC").Find(&list)
+ for _, v := range list {
+ if v.PackageURL != "" {
+ app, err := common.GetBranch(v.PackageName, v.PackageURL)
+ if err != nil {
+ fmt.Println(v.Id, "-", err, "||", v.PackageURL)
+ err = nil
+ } else {
+ fmt.Println(v.Id, "-", app.Branch)
+ db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("version", app.Version+"_"+app.VersionCode)
+ }
+ }
+ }
+}
+
+func Dir() {
+ err := monkey.CreateDir("files")
+ if err != nil {
+ fmt.Println(err)
+ }
+ err = monkey.CreateDir("files/1")
+ if err != nil {
+ fmt.Println(err)
+ }
+ err = monkey.CreateAndWriteFile("files/1/2.txt", []byte("hidiuniduini"))
+ if err != nil {
+ 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"`
+}
diff --git a/test/monkey_result.go b/test/monkey_result.go
new file mode 100644
index 0000000..63ddc55
--- /dev/null
+++ b/test/monkey_result.go
@@ -0,0 +1,71 @@
+package test
+
+import (
+ "autogo/common"
+ "autogo/dbsql"
+ "autogo/models"
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ "github.com/spf13/cast"
+)
+
+func GetMonkeyResult() {
+ var res models.MonkeyResult
+ dbsql.SetDSN("Flatincbr.com")
+ db, err := dbsql.GetConn(dbsql.DSN_local)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ defer dbsql.Close(db)
+ db.Model(models.MonkeyResult{}).Last(&res)
+
+ var strs []string
+ json.Unmarshal([]byte(res.CrashLogs), &strs)
+ if len(strs) > 0 {
+ res.CrashLogList = strs
+ }
+ json.Unmarshal([]byte(res.ActivityNameInfo), &strs)
+ if len(strs) > 0 {
+ res.ActivityList = strs
+ }
+ json.Unmarshal([]byte(res.Logs), &strs)
+ if len(strs) > 0 {
+ res.LogList = strs
+ }
+
+ var task models.MonkeyTask
+ db.Table(task.TableName()).Model(models.MonkeyTask{}).Where("id = ?", res.TaskId).Last(&task)
+
+ // buf, _ := json.Marshal(res)
+ content := ""
+ content += "**关联Monkey报告:** [点击查看](http://qa.flatincbr.work/#/monkey/result/" + cast.ToString(res.TaskId) + ")" + "\n\n
\n\n"
+ content += "**上报时间:**" + res.CreateTime.Format("2006-01-02 15:04:05") + "\n\n
\n\n"
+ content += "**应用版本:**" + task.Version + "\n\n
\n\n"
+ content += "**信息预览:**" + "\n\n"
+ for i, v := range strings.Split(res.CrashLogList[0], "\n") {
+ content += "> " + v + "\n"
+ if i > 10 {
+ break
+ }
+ }
+ content += "> " + "(...更多请查看Monkey报告)" + "\n"
+ content += "\n"
+ // fmt.Println(content)
+
+ bug := common.NewBug("crushu")
+ bug.SetExecutor("62733beb6918b259138d7577").
+ SetInvolveMember("62733beb6918b259138d7577").
+ SetTitle("【Monkey测试】测试缺陷标题byProjectName").
+ SetPlatform("adr").
+ SetContent(content)
+
+ id, err := bug.Create()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Println("缺陷创建成功:", "https://www.teambition.com/task/"+id)
+}