|
|
package monkey
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"goqs/controllers"
|
|
|
"goqs/dbsql"
|
|
|
"goqs/models"
|
|
|
"net/http"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
"github.com/spf13/cast"
|
|
|
)
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 新建Monkey任务
|
|
|
// @Description 新建Monkey任务,创建成功后将会发送指令到monkey服务,初始status为WAITTING-等待中
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param project formData string false "项目名"
|
|
|
// @Param package_url formData string false "测试包下载链接"
|
|
|
// @Param package_name formData string true "应用包名"
|
|
|
// @Param launch_activity formData string false "启动activity页"
|
|
|
// @Param platform formData string true "平台adr/ios"
|
|
|
// @Param run_time formData string false "运行时间(s),默认两小时(7200s)"
|
|
|
// @Param creator formData string false "任务创建者"
|
|
|
// @Param mode formData string false "调用服务的方式,0-cli模式/1-api模式,默认cli"
|
|
|
// @Success 200 {object} models.Response "返回创建的任务id"
|
|
|
// @Router /api/monkey/v1/create_task [post]
|
|
|
func CreateTask(c *gin.Context) {
|
|
|
rsp := controllers.NewResponse()
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if err != nil {
|
|
|
rsp.Error(err.Error())
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
|
|
|
var task models.MonkeyTask
|
|
|
task.Project = c.PostForm("project")
|
|
|
task.PackageURL = c.PostForm("package_url")
|
|
|
task.PackageName = c.PostForm("package_name")
|
|
|
task.LaunchActivity = c.PostForm("launch_activity")
|
|
|
task.Platform = c.PostForm("platform")
|
|
|
task.RunTime = cast.ToInt(c.DefaultPostForm("run_time", "7200"))
|
|
|
task.Creator = c.PostForm("creator")
|
|
|
task.Status = "WAITTING"
|
|
|
|
|
|
// || task.Creator == ""
|
|
|
if task.PackageName == "" || task.LaunchActivity == "" ||
|
|
|
task.Platform == "" ||
|
|
|
task.RunTime <= 10 {
|
|
|
rsp.Error("get formdata error")
|
|
|
rsp.Data = task
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var devices []models.Device
|
|
|
is_online := false
|
|
|
db.Model(models.Device{}).Where("project = ?", task.Project).Find(&devices)
|
|
|
if len(devices) < 1 {
|
|
|
rsp.Error("该产品没有注册设备,请检查")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
m := GetAndroidDevices()
|
|
|
for _, v := range devices {
|
|
|
if _, ok := m[v.Udid]; ok {
|
|
|
is_online = true
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
if !is_online {
|
|
|
rsp.Error("该产品没有设备在线,请检查")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
db.Model(models.MonkeyTask{}).Create(&task)
|
|
|
if db.Error != nil {
|
|
|
rsp.Error(db.Error.Error())
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = task
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
|
|
|
go runAndroidMonkeyCmd(task)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 更新Monkey任务状态
|
|
|
// @Description 更新Monkey任务状态,进行中为RUNNING,已完成为FINIASHED,如有错误为ERROR
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param task_id formData int true "任务id"
|
|
|
// @Param status formData string false "要更新的任务状态"
|
|
|
// @Success 200 {object} models.Response "返回更新后的任务信息"
|
|
|
// @Router /api/monkey/v1/task/status [post]
|
|
|
func UpdateTaskStatus(c *gin.Context) {
|
|
|
rsp := controllers.NewResponse()
|
|
|
|
|
|
task_id := cast.ToInt(c.PostForm("task_id"))
|
|
|
status := c.PostForm("status")
|
|
|
if task_id <= 0 {
|
|
|
rsp.Error("task_id error")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if err != nil {
|
|
|
rsp.Error(err.Error())
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
|
|
|
var task models.MonkeyTask
|
|
|
db.Where("id = ?", task_id).Find(&task)
|
|
|
if task.Id <= 0 {
|
|
|
rsp.Error("任务不存在")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
task.Status = status
|
|
|
db.Save(&task)
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = task
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 更新Monkey任务崩溃数量
|
|
|
// @Description 更新Monkey任务崩溃数量
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param task_id formData int true "任务id"
|
|
|
// @Param crash_count formData string false "要更新的崩溃数量"
|
|
|
// @Success 200 {object} models.Response "返回更新后的任务信息"
|
|
|
// @Router /api/monkey/v1/task/crash_count [post]
|
|
|
func UpdateTaskCrashCount(c *gin.Context) {
|
|
|
rsp := controllers.NewResponse()
|
|
|
|
|
|
task_id := cast.ToInt(c.PostForm("task_id"))
|
|
|
// crash_count := cast.ToInt(c.DefaultPostForm("crash_count", "0"))
|
|
|
if task_id <= 0 {
|
|
|
rsp.Error("task_id error")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
// if crash_count <= 0 {
|
|
|
// rsp.Error("crash_count 错误或等于0,不更新")
|
|
|
// c.JSON(http.StatusOK, rsp)
|
|
|
// return
|
|
|
// }
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if err != nil {
|
|
|
rsp.Error(err.Error())
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
var count int64
|
|
|
db.Model(models.MonkeyResult{}).Where("task_id = ?", task_id).Count(&count)
|
|
|
|
|
|
// var task models.MonkeyTask
|
|
|
// db.Where("id = ?", task_id).Find(&task)
|
|
|
// if task.Id <= 0 {
|
|
|
// rsp.Error("任务不存在")
|
|
|
// c.JSON(http.StatusOK, rsp)
|
|
|
// return
|
|
|
// }
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("crash_count", count)
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = count
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 获取任务列表
|
|
|
// @Description 获取任务列表
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param page_size query int false "每页大小,默认为10"
|
|
|
// @Param page_index query int false "第几页,默认为第一页"
|
|
|
// @Success 200 {object} models.Response "返回更新后的任务信息"
|
|
|
// @Router /api/monkey/v1/tasks [get]
|
|
|
func GetTasks(c *gin.Context) {
|
|
|
var rsp models.Response
|
|
|
var p models.Page
|
|
|
|
|
|
pageIndex, err := strconv.Atoi(c.DefaultQuery("page_index", "1"))
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
p.Index = pageIndex
|
|
|
pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
p.Size = pageSize
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
|
|
|
var list []models.MonkeyTask
|
|
|
|
|
|
db = db.Model(&models.MonkeyTask{})
|
|
|
var lenght int64
|
|
|
db = db.Where("is_del = 0").Count(&lenght)
|
|
|
db = dbsql.SetPageQuery(db, pageIndex, pageSize)
|
|
|
db.Order("id desc").Find(&list)
|
|
|
// lenght = len(list)
|
|
|
dbsql.Close(db)
|
|
|
|
|
|
db, _ = dbsql.GetConn(dbsql.DSN)
|
|
|
for i, v := range list {
|
|
|
var count int64
|
|
|
db.Model(models.MonkeyActivity{}).Where("task_id = ?", list[i].Id).Count(&count)
|
|
|
list[i].CoveredAcitvities = int(count)
|
|
|
// 如果状态在 进行中 or 取消中,则检查进程状态
|
|
|
if v.Status == "RUNNING" || v.Status == "CANCELING" {
|
|
|
var pids []models.MonkeyPid
|
|
|
db.Model(models.MonkeyPid{}).Where("task_id = ?", v.Id).Find(&pids)
|
|
|
if code := checkTaskPids(pids); code == 0 {
|
|
|
list[i].Status = "RUNNING"
|
|
|
} else if code == 1 {
|
|
|
if v.Status == "CANCELING" {
|
|
|
list[i].Status = "CANCEL"
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
|
|
|
} else if v.Status == "RUNNING" {
|
|
|
list[i].Status = "FINISH"
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
dbsql.Close(db)
|
|
|
|
|
|
if p.Size >= int(lenght) {
|
|
|
p.MaxPage = 1
|
|
|
} else {
|
|
|
p.MaxPage = int64(lenght/int64(p.Size) + 1)
|
|
|
}
|
|
|
p.List = list
|
|
|
p.Total = int(lenght)
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = p
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 获取monkey任务信息
|
|
|
// @Description 根据id获取monkey任务信息
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param id query int false "任务id"
|
|
|
// @Success 200 {object} models.Response "返回monkey任务信息"
|
|
|
// @Router /api/monkey/v1/task [get]
|
|
|
func GetTaskById(c *gin.Context) {
|
|
|
var rsp models.Response
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
|
|
|
var data models.MonkeyTask
|
|
|
|
|
|
db = db.Model(&models.MonkeyTask{})
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", c.DefaultQuery("id", "0")).Last(&data)
|
|
|
dbsql.Close(db)
|
|
|
|
|
|
db, _ = dbsql.GetConn(dbsql.DSN)
|
|
|
var count int64
|
|
|
db.Where("task_id = ?", data.Id).Count(&count)
|
|
|
data.CoveredAcitvities = int(count)
|
|
|
dbsql.Close(db)
|
|
|
|
|
|
if data.Id < 1 {
|
|
|
rsp.Error("查找不到monkey任务信息,id=" + c.Query("id"))
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = data
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 上传Logcat日志
|
|
|
// @Description 上传Logcat日志
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Success 200 {object} models.Response "返回成功或失败"
|
|
|
// @Router /webdav/monkey/task/:id/:filename [put]
|
|
|
func TaskReport(c *gin.Context) {
|
|
|
|
|
|
fmt.Println(c.Request.Header)
|
|
|
data, err := c.GetRawData()
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
|
c.String(http.StatusOK, "OK")
|
|
|
return
|
|
|
}
|
|
|
fmt.Println(len(data))
|
|
|
CreateDir("./files")
|
|
|
CreateDir("./files/monkey")
|
|
|
CreateDir("./files/monkey/log")
|
|
|
CreateDir("./files/monkey/log/" + c.Param("id"))
|
|
|
CreateAndWriteFile("./files//monkey/log/"+c.Param("id")+"/"+c.Param("filename"), data)
|
|
|
c.String(http.StatusOK, "OK")
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 上报进程id
|
|
|
// @Description 上传进程id并关联到任务
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param task_id formData int true "任务id"
|
|
|
// @Param pid formData int true "进程id"
|
|
|
// @Success 200 {object} models.Response "返回成功或失败"
|
|
|
// @Router /api/monkey/v1/task/pid [post]
|
|
|
func UpdatePids(c *gin.Context) {
|
|
|
var rsp models.Response
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
var obj models.MonkeyPid
|
|
|
if task_id := cast.ToInt(c.PostForm("task_id")); task_id > 0 {
|
|
|
obj.TaskId = task_id
|
|
|
} else {
|
|
|
rsp.Error("task_id获取失败")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
if pid := cast.ToInt(c.PostForm("pid")); pid > 0 {
|
|
|
obj.PId = pid
|
|
|
} else {
|
|
|
rsp.Error("pid获取失败")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
db.Create(&obj)
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = obj
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 上报运行设备
|
|
|
// @Description 上报运行设备Udid,调用后追加到指定任务的设备字段中
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param task_id formData int true "任务id"
|
|
|
// @Param udid formData string true "设备udid"
|
|
|
// @Success 200 {object} models.Response "返回成功或失败"
|
|
|
// @Router /api/monkey/v1/task/update_devices [post]
|
|
|
func UpdateDevices(c *gin.Context) {
|
|
|
var rsp models.Response
|
|
|
|
|
|
task_id := cast.ToInt(c.PostForm("task_id"))
|
|
|
if task_id < 1 {
|
|
|
rsp.Error("task_id获取失败")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
udid := c.PostForm("udid")
|
|
|
if udid == "" {
|
|
|
rsp.Error("pid获取失败")
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
|
|
|
var data models.MonkeyTask
|
|
|
|
|
|
db = db.Model(&models.MonkeyTask{})
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Last(&data)
|
|
|
|
|
|
// 处理
|
|
|
if strings.Contains(data.Devices, ",") || len(data.Devices) > 0 {
|
|
|
data.Devices += "," + udid
|
|
|
} else {
|
|
|
data.Devices = udid
|
|
|
}
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("devices", data.Devices)
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = data
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|
|
|
|
|
|
// @Tags Monkey相关 /api/monkey/v1/
|
|
|
// @Summary 停止monkey任务
|
|
|
// @Description 停止monkey任务,杀死所有关联任务的进程id
|
|
|
// @accept x-www-form-urlencoded
|
|
|
// @Param task_id formData int true "任务id"
|
|
|
// @Success 200 {object} models.Response "返回成功或失败"
|
|
|
// @Router /api/monkey/v1/task/stop [post]
|
|
|
func StopMonkeyTask(c *gin.Context) {
|
|
|
var rsp models.Response
|
|
|
var pids []int
|
|
|
|
|
|
if task_id := cast.ToInt(c.PostForm("task_id")); task_id > 0 {
|
|
|
db, err := dbsql.GetConn(dbsql.DSN)
|
|
|
if rsp.CheckErr(err) {
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
return
|
|
|
}
|
|
|
defer dbsql.Close(db)
|
|
|
db.Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("status", "CANCELING")
|
|
|
var list []models.MonkeyPid
|
|
|
db.Where("task_id = ? and is_del = 0", task_id).Find(&list)
|
|
|
for _, v := range list {
|
|
|
killPid(v.PId)
|
|
|
pids = append(pids, v.PId)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
rsp.Success()
|
|
|
rsp.Data = pids
|
|
|
c.JSON(http.StatusOK, rsp)
|
|
|
}
|