feat: 使用docker执行adr monkey任务

master
luziqi 3 years ago
parent 6f0a13f99c
commit 7ba8e1d5d5

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"os/exec" "os/exec"
"strings" "strings"
"time"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"github.com/spf13/cast" "github.com/spf13/cast"
@ -93,16 +94,27 @@ func CheckTaskStatus() {
var list []models.MonkeyTask var list []models.MonkeyTask
db.Model(models.MonkeyTask{}).Where("status = ?", "RUNNING").Find(&list) db.Model(models.MonkeyTask{}).Where("status = ?", "RUNNING").Find(&list)
for i, v := range list { for i, v := range list {
var count int64 // 如果无对应正在运行的容器,判断为【结束】或【异常停止】
db.Model(models.MonkeyActivity{}).Where("task_id = ?", list[i].Id).Count(&count) if len(monkey.GetTaskFromDocker(v.Id)) == 0 {
list[i].CoveredAcitvities = int(count) // 如果预期结束时间(任务开始时间+运行时间) < 当前时间,判断任务为运行正常结束
var pids []models.MonkeyPid if v.UpdateTime+v.RunTime < int(time.Now().Unix()) {
db.Model(models.MonkeyPid{}).Where("task_id = ?", v.Id).Find(&pids) list[i].Status = "FINISH"
if code := checkTaskPids(pids); code != 0 { db.Table(v.TableName()).Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
list[i].Status = "FINISH" } else {
db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status) common.PushCorntaskLog("任务状态似乎异常task_id=" + cast.ToString(v.Id))
common.PushMonkeyResult(v) }
} }
continue
// var count int64
// db.Model(models.MonkeyActivity{}).Where("task_id = ?", list[i].Id).Count(&count)
// list[i].CoveredAcitvities = int(count)
// var pids []models.MonkeyPid
// db.Model(models.MonkeyPid{}).Where("task_id = ?", v.Id).Find(&pids)
// if code := checkTaskPids(pids); code != 0 {
// list[i].Status = "FINISH"
// db.Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
// common.PushMonkeyResult(v)
// }
} }
} }

@ -6,6 +6,9 @@ import (
"autogo/models" "autogo/models"
"autogo/monkey" "autogo/monkey"
"strings" "strings"
"time"
"github.com/spf13/cast"
) )
func CheckMonkeyTasks() { func CheckMonkeyTasks() {
@ -34,15 +37,26 @@ func CheckMonkeyTasks() {
common.PushCorntaskLog("执行Monkey任务" + task.Project + "-" + device.Udid) common.PushCorntaskLog("执行Monkey任务" + task.Project + "-" + device.Udid)
} }
db.Model(models.MonkeyTask{}).Where("status = ? AND is_del = 0", "RUNNING").Find(&list) db.Model(models.MonkeyTask{}).Where("status = ? AND is_del = 0", "RUNNING").Find(&list)
for _, task := range list { for i, v := range list {
var pids []models.MonkeyPid // 如果无对应正在运行的容器,判断为【结束】或【异常停止】
db.Model(models.MonkeyPid{}).Where("task_id = ?", task.Id).Find(&pids) if len(monkey.GetTaskFromDocker(v.Id)) == 0 {
if code := checkTaskPids(pids); code == 0 { // 如果预期结束时间(任务开始时间+运行时间) < 当前时间,判断任务为运行正常结束
task.Status = "RUNNING" if v.UpdateTime+v.RunTime < int(time.Now().Unix()) {
} else if code == 1 { list[i].Status = "FINISH"
task.Status = "FINISH" db.Table(v.TableName()).Model(models.MonkeyTask{}).Where("id = ?", v.Id).Update("status", list[i].Status)
db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", task.Status) common.PushMonkeyResult(v)
common.PushMonkeyResult(task) } else {
common.PushCorntaskLog("任务状态似乎异常task_id=" + cast.ToString(v.Id))
}
} }
// var pids []models.MonkeyPid
// db.Model(models.MonkeyPid{}).Where("task_id = ?", task.Id).Find(&pids)
// if code := checkTaskPids(pids); code == 0 {
// task.Status = "RUNNING"
// } else if code == 1 {
// task.Status = "FINISH"
// db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", task.Status)
// common.PushMonkeyResult(task)
// }
} }
} }

@ -1,6 +1,10 @@
package models package models
import "errors" import (
"errors"
"github.com/spf13/cast"
)
type MonkeyTask struct { type MonkeyTask struct {
Id int `json:"id" gorm:"column:id;type:int(11);primary_key;not null;autoIncrement;comment:主键"` Id int `json:"id" gorm:"column:id;type:int(11);primary_key;not null;autoIncrement;comment:主键"`
@ -31,6 +35,41 @@ func (m *MonkeyTask) TableName() string {
return "monkey_task" return "monkey_task"
} }
func (task *MonkeyTask) Cmd(udid string, filename string) string {
cmd_str := ""
switch task.Platform {
case "adr":
cmd_str = "docker run -d --rm --name monkey_task_" + cast.ToString(task.Id) + "_" + udid + " --net=host "
cmd_str += "-e TASK_ID=" + cast.ToString(task.Id) + " "
cmd_str += "-e PACKAGE=" + task.PackageName + " "
cmd_str += "-e RUN_TIME=" + cast.ToString(task.RunTime) + " "
cmd_str += "-e DEVICE=" + udid + " "
cmd_str += "-v /home/tmp/pkg/" + filename + ":/tmp/test.apk" + " "
cmd_str += "-v /home/app/uat:/home/app/uat" + " "
cmd_str += "monkey-adr"
// cmd_str = "cd /home/app/monkey && nohup python3 main_adr.py" +
// " -task_id " + cast.ToString(task.Id)
// if task.PackageURL != "" {
// cmd_str += " -pkg_path " + filename
// }
// cmd_str += " -package " + task.PackageName
// if task.LaunchActivity != "" {
// cmd_str += " -launch_activity " + task.LaunchActivity
// }
// cmd_str += " -run_time " + cast.ToString(task.RunTime)
// if udid != "" {
// cmd_str += " -device_udid " + udid
// }
// cmd_str += " >> /home/app/logs/task_output/task_" + cast.ToString(task.Id) + ".log 2>&1"
}
return cmd_str
}
func (t *MonkeyTask) Check() error { func (t *MonkeyTask) Check() error {
if t.Project == "" { if t.Project == "" {
return errors.New("task.Project为空") return errors.New("task.Project为空")

@ -18,6 +18,15 @@ import (
// } // }
func RunAndroidMonkeyCmd(task models.MonkeyTask, udid string) { func RunAndroidMonkeyCmd(task models.MonkeyTask, udid string) {
filename := cast.ToString(time.Now().Unix()) + ".apk"
pkg_path := "/home/tmp/pkg/" + filename
log.Debug("正在下载apk", task.PackageURL)
err := exec.Command("wget", task.PackageURL, "-O", pkg_path).Run()
if err != nil {
log.Error(err)
}
log.Debug("下载完毕,安装包路径", pkg_path)
db, err := dbsql.GetConn(dbsql.DSN) db, err := dbsql.GetConn(dbsql.DSN)
if err != nil { if err != nil {
return return
@ -25,27 +34,7 @@ func RunAndroidMonkeyCmd(task models.MonkeyTask, udid string) {
defer dbsql.Close(db) defer dbsql.Close(db)
db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", "INIT") db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Update("status", "INIT")
// python main_adr.py -package music.hising.live.dev -launch_activity sing.lagufun.social.live.ui.activity.SplashActivity // python main_adr.py -package music.hising.live.dev -launch_activity sing.lagufun.social.live.ui.activity.SplashActivity
cmd_content := "cd /home/app/monkey && nohup python3 main_adr.py" + cmd_content := task.Cmd(udid, filename)
" -task_id " + cast.ToString(task.Id)
if task.PackageURL != "" {
pkg_path := "/home/tmp/pkg/" + cast.ToString(time.Now().Unix()) + ".apk"
log.Debug("正在下载apk", task.PackageURL)
err := exec.Command("wget", task.PackageURL, "-O", pkg_path).Run()
if err != nil {
log.Error(err)
}
cmd_content += " -pkg_path " + pkg_path
log.Debug("下载完毕,安装包路径", pkg_path)
}
cmd_content += " -package " + task.PackageName
if task.LaunchActivity != "" {
cmd_content += " -launch_activity " + task.LaunchActivity
}
cmd_content += " -run_time " + cast.ToString(task.RunTime)
if udid != "" {
cmd_content += " -device_udid " + udid
}
cmd_content += " >> /home/app/logs/task_output/task_" + cast.ToString(task.Id) + ".log 2>&1"
db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Last(&task) db.Model(models.MonkeyTask{}).Where("id = ?", task.Id).Last(&task)
if task.Status != "INIT" { if task.Status != "INIT" {

@ -0,0 +1,57 @@
package monkey
import (
"fmt"
"os/exec"
"strings"
"github.com/spf13/cast"
)
type DockerContainer struct {
ID string `json:"id"`
Name string `json:"name"`
Device string `json:"device"`
}
// 根据任务id获取关联容器由于后续可能支持一个任务绑定多个设备执行所以返回数组
func GetTaskFromDocker(task_id int) []DockerContainer {
var list []DockerContainer
cmd := exec.Command("docker", "ps")
output, err := cmd.Output()
if err != nil {
fmt.Println(err)
return list
}
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])
var c DockerContainer
c.ID = fields[0]
c.Name = fields[len(fields)-1]
_strs := strings.Split(c.Name, "_")
c.Device = _strs[len(_strs)-1]
if strings.Contains(c.Name, "monkey_task_"+cast.ToString(task_id)+"_") {
list = append(list, c)
}
}
}
return list
}
func StopDockerContainer(container_name string) bool {
cmd := exec.Command("docker", "stop", "-t", "0", container_name)
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("[docker] Error stopping container:", err)
return false
}
fmt.Println("[docker] Container stopped successfully:", string(out))
return true
}

@ -426,8 +426,33 @@ func UpdateDevices(c *gin.Context) {
// @Router /api/monkey/v1/task/stop [post] // @Router /api/monkey/v1/task/stop [post]
func StopMonkeyTask(c *gin.Context) { func StopMonkeyTask(c *gin.Context) {
var rsp models.Response var rsp models.Response
var pids []int
task_id := cast.ToInt(c.PostForm("task_id"))
if task_id < 1 {
c.JSON(http.StatusOK, rsp.Error("task_id error: "+c.PostForm("task_id")))
return
}
db, err := dbsql.GetConn(dbsql.DSN)
if err != nil {
c.JSON(http.StatusOK, rsp.Error(err.Error()))
return
}
defer dbsql.Close(db)
list := GetTaskFromDocker(task_id)
for _, v := range list {
if StopDockerContainer(v.Name) {
db.Table("monkey_task").Model(models.MonkeyTask{}).Where("id = ?", task_id).Update("status", "CANCEL")
db.Table("device").Model(models.Device{}).Where("udid = ?", v.Device).Update("status", "online")
}
}
rsp.Data = list
c.JSON(http.StatusOK, rsp.Success())
return
var pids []int
if task_id := cast.ToInt(c.PostForm("task_id")); task_id > 0 { if task_id := cast.ToInt(c.PostForm("task_id")); task_id > 0 {
db, err := dbsql.GetConn(dbsql.DSN) db, err := dbsql.GetConn(dbsql.DSN)
if err != nil { if err != nil {

@ -3,12 +3,72 @@ package main
import ( import (
"autogo/common" "autogo/common"
"autogo/dbsql" "autogo/dbsql"
"autogo/device"
"autogo/models" "autogo/models"
"autogo/monkey" "autogo/monkey"
"fmt" "fmt"
"os/exec"
"strings"
"time"
) )
func main() { func main() {
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 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 dbsql.DSN = dbsql.DSN_local
db, err := dbsql.GetConn(dbsql.DSN) db, err := dbsql.GetConn(dbsql.DSN)
if err != nil { if err != nil {
@ -42,7 +102,6 @@ func main() {
} }
} }
} }
// // common.GetBranch("", "")
} }
func Dir() { func Dir() {

Loading…
Cancel
Save