mirror of https://github.com/shunfei/cronsun
Add test and crontab checker.
parent
a18f5ac3fc
commit
18717c0e78
|
@ -4,14 +4,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/shunfei/cronsun"
|
"github.com/shunfei/cronsun"
|
||||||
|
cron2 "github.com/shunfei/cronsun/node/cron"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,47 +32,41 @@ var ImportCmd = &cobra.Command{
|
||||||
Use: "import",
|
Use: "import",
|
||||||
Short: `it will load the job from the crontab, but you must to confirm you can execute 'crontab -l'`,
|
Short: `it will load the job from the crontab, but you must to confirm you can execute 'crontab -l'`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
ea := NewExitAction()
|
|
||||||
|
|
||||||
var nodeInclude []string
|
var nodeInclude []string
|
||||||
|
|
||||||
if len(importNodes) > 0 {
|
if len(importNodes) > 0 {
|
||||||
nodeInclude = strings.Split(importNodes, spliter)
|
nodeInclude = strings.Split(importNodes, spliter)
|
||||||
}
|
}
|
||||||
|
|
||||||
crons := loadCrons()
|
ea := NewExitAction()
|
||||||
|
crons, err := loadCrons()
|
||||||
|
if err != nil {
|
||||||
|
ea.Exit("load crontab failed,err:%s", err.Error())
|
||||||
|
}
|
||||||
total := len(crons)
|
total := len(crons)
|
||||||
var successCount int
|
var successCount int
|
||||||
|
|
||||||
ea.After = func() {
|
ea.After = func() {
|
||||||
fmt.Printf("total:%d,success:%d,failed:%d\n", total, successCount, total-successCount)
|
fmt.Printf("total:%d,success:%d,failed:%d\n", total, successCount, total-successCount)
|
||||||
cmd.Help()
|
if err := cmd.Help(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
|
|
||||||
for _, cron := range crons {
|
for _, cron := range crons {
|
||||||
job := cronsun.Job{}
|
job := cronsun.Job{}
|
||||||
job.ID = cronsun.NextID()
|
job.ID = cronsun.NextID()
|
||||||
job.Command = cron.cmd
|
job.Command = cron.cmd
|
||||||
|
|
||||||
jr := &cronsun.JobRule{
|
jr := &cronsun.JobRule{
|
||||||
Timer: "* " + cron.timer,
|
Timer: "* " + cron.timer,
|
||||||
}
|
}
|
||||||
|
|
||||||
jr.NodeIDs = nodeInclude
|
jr.NodeIDs = nodeInclude
|
||||||
|
|
||||||
job.Name = fmt.Sprintf("crontab-%d", rand.Intn(1000))
|
job.Name = fmt.Sprintf("crontab-%d", rand.Intn(1000))
|
||||||
job.Group = "crontab"
|
job.Group = "crontab"
|
||||||
job.Rules = append(job.Rules, jr)
|
job.Rules = append(job.Rules, jr)
|
||||||
// 默认先暂停
|
// 默认先暂停
|
||||||
job.Pause = true
|
job.Pause = true
|
||||||
|
|
||||||
if err := job.Check(); err != nil {
|
if err := job.Check(); err != nil {
|
||||||
ea.Exit("job check error:%s", err.Error())
|
ea.Exit("job check error:%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := json.Marshal(job)
|
b, err := json.Marshal(job)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ea.Exit("json marshal error:%s", err.Error())
|
ea.Exit("json marshal error:%s", err.Error())
|
||||||
|
@ -83,31 +76,46 @@ var ImportCmd = &cobra.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ea.Exit("etcd put error:%s", err.Error())
|
ea.Exit("etcd put error:%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
successCount++
|
successCount++
|
||||||
|
|
||||||
fmt.Printf("crontab-%s %s has import to the cronsun, the job id is:%s\n", cron.timer, cron.cmd, job.ID)
|
fmt.Printf("crontab-%s %s has import to the cronsun, the job id is:%s\n", cron.timer, cron.cmd, job.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("import fininsh,success:%d\n", successCount)
|
fmt.Printf("import fininsh,succes:%d\n", successCount)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadCrons() []cron {
|
func checkCrons(crons []string) (invalid []string) {
|
||||||
var crons []cron
|
for _, item := range crons {
|
||||||
|
item = strings.TrimSpace(item)
|
||||||
cmd := exec.Command("crontab", "-l")
|
if item != "" && !strings.HasPrefix(item, "#") {
|
||||||
|
expr := strings.Fields(item)
|
||||||
|
expr = expr[:5]
|
||||||
|
_, err := cron2.ParseStandard(strings.Join(expr, " "))
|
||||||
|
if err != nil {
|
||||||
|
invalid = append(invalid, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCrons() (crons []cron, err error) {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
cmd := exec.Command("crontab", "-l")
|
||||||
cmd.Stdout = &b
|
cmd.Stdout = &b
|
||||||
cmd.Stderr = &b
|
cmd.Stderr = &b
|
||||||
|
err = cmd.Run()
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result := strings.Split(b.String(), "\n")
|
result := strings.Split(b.String(), "\n")
|
||||||
|
invalid := checkCrons(result)
|
||||||
|
if len(invalid) > 0 {
|
||||||
|
title := fmt.Sprintf("There are %d invalid cron expression,please check them at first.\n", len(invalid))
|
||||||
|
err = fmt.Errorf(title + strings.Join(invalid, "\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, item := range result {
|
for _, item := range result {
|
||||||
item = strings.TrimSpace(item)
|
item = strings.TrimSpace(item)
|
||||||
|
@ -118,6 +126,5 @@ func loadCrons() []cron {
|
||||||
crons = append(crons, cron{timer, cmd})
|
crons = append(crons, cron{timer, cmd})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
return crons
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckCrons(t *testing.T) {
|
||||||
|
crontab := `
|
||||||
|
*/1 * * * * /usr/bine/echo hello
|
||||||
|
* * * * * /usr/bin/ls
|
||||||
|
* & * * * /usr/bin/php -v
|
||||||
|
* * * * /usr/bin/go run main.go
|
||||||
|
`
|
||||||
|
invalidCrons := checkCrons(strings.Split(crontab, "\n"))
|
||||||
|
if len(invalidCrons) != 2 {
|
||||||
|
t.Error("should have 2 cron expression,but get none.")
|
||||||
|
}
|
||||||
|
if invalidCrons[0] != "* & * * * /usr/bin/php -v" ||
|
||||||
|
invalidCrons[1] != "* * * * /usr/bin/go run main.go" {
|
||||||
|
t.Error("invalid cron expression should * & * * * /usr/bin/php -v and * * * * /usr/bin/go run main.go.")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue