Raise an error when an unknown job is requested
Some checks failed
continuous-integration/drone/push Build is failing

Fixes #1
This commit is contained in:
IamTheFij 2022-11-04 14:31:54 -07:00
parent 917438471e
commit 3103fbde29
2 changed files with 116 additions and 18 deletions

70
main.go
View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"log" "log"
@ -15,7 +16,8 @@ import (
var ( var (
// version of restic-scheduler being run. // version of restic-scheduler being run.
version = "dev" version = "dev"
ErrJobNotFound = errors.New("jobs not found")
) )
func ParseConfig(path string) ([]Job, error) { func ParseConfig(path string) ([]Job, error) {
@ -92,6 +94,12 @@ func ReadJobs(paths []string) ([]Job, error) {
type Set map[string]bool type Set map[string]bool
func (s Set) Contains(key string) bool {
_, contains := s[key]
return contains
}
func NewSetFrom(l []string) Set { func NewSetFrom(l []string) Set {
s := make(Set) s := make(Set)
for _, l := range l { for _, l := range l {
@ -101,30 +109,44 @@ func NewSetFrom(l []string) Set {
return s return s
} }
func runBackupJobs(jobs []Job, names []string) error { /// FilterJobs filters a list of jobs by a list of names
func FilterJobs(jobs []Job, names []string) ([]Job, error) {
nameSet := NewSetFrom(names) nameSet := NewSetFrom(names)
_, runAll := nameSet["all"] if nameSet.Contains("all") {
return jobs, nil
}
filteredJobs := []Job{}
for _, job := range jobs { for _, job := range jobs {
if _, found := nameSet[job.Name]; runAll || found { if nameSet.Contains(job.Name) {
if err := job.RunBackup(); err != nil { filteredJobs = append(filteredJobs, job)
return err
} delete(nameSet, job.Name)
}
}
var err error
if len(nameSet) > 0 {
err = fmt.Errorf("%w: %v", ErrJobNotFound, nameSet)
}
return filteredJobs, err
}
func RunBackupJobs(jobs []Job) error {
for _, job := range jobs {
if err := job.RunBackup(); err != nil {
return err
} }
} }
return nil return nil
} }
func runRestoreJobs(jobs []Job, names []string) error { func RunRestoreJobs(jobs []Job) error {
nameSet := NewSetFrom(names)
_, runAll := nameSet["all"]
for _, job := range jobs { for _, job := range jobs {
if _, found := nameSet[job.Name]; runAll || found { if err := job.RunRestore(); err != nil {
if err := job.RunRestore(); err != nil { return err
return err
}
} }
} }
@ -161,13 +183,25 @@ func main() {
} }
// Run specified backup jobs // Run specified backup jobs
if err := runBackupJobs(jobs, strings.Split(*backup, ",")); err != nil { backupJobNames := strings.Split(*backup, ",")
backupJobs, filterJobErr := FilterJobs(jobs, backupJobNames)
if err := RunBackupJobs(backupJobs); err != nil {
log.Fatalf("Failed running backup jobs: %v", err) log.Fatalf("Failed running backup jobs: %v", err)
} }
if filterJobErr != nil {
log.Fatalf("Unkown backup job: %v", err)
}
// Run specified restore jobs // Run specified restore jobs
if err := runRestoreJobs(jobs, strings.Split(*restore, ",")); err != nil { restoreJobNames := strings.Split(*restore, ",")
log.Fatalf("Failed running backup jobs: %v", err) restoreJobs, filterJobErr := FilterJobs(jobs, restoreJobNames)
if err := RunRestoreJobs(restoreJobs); err != nil {
log.Fatalf("Failed running restore jobs: %v", err)
}
if filterJobErr != nil {
log.Fatalf("Unkown restore job: %v", err)
} }
// Exit if only running once // Exit if only running once

View File

@ -1,8 +1,10 @@
package main_test package main_test
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"reflect"
"testing" "testing"
main "git.iamthefij.com/iamthefij/restic-scheduler" main "git.iamthefij.com/iamthefij/restic-scheduler"
@ -38,3 +40,65 @@ func TestReadJobs(t *testing.T) {
t.Error("Expected read jobs but found none") t.Error("Expected read jobs but found none")
} }
} }
func TestRunJobs(t *testing.T) {
t.Parallel()
validJob := main.Job{
Name: "Valid job",
Schedule: "@daily",
Config: ValidResticConfig(),
Tasks: []main.JobTask{},
Backup: main.BackupFilesTask{Paths: []string{"/test"}}, // nolint:exhaustivestruct
Forget: nil,
MySQL: []main.JobTaskMySQL{},
Sqlite: []main.JobTaskSqlite{},
}
cases := []struct {
name string
jobs []main.Job
names []string
expected []main.Job
expectedError error
}{
{
name: "Found job",
jobs: []main.Job{validJob},
names: []string{"Valid job"},
expected: []main.Job{validJob},
expectedError: nil,
},
{
name: "Run all",
jobs: []main.Job{validJob},
names: []string{"all"},
expected: []main.Job{validJob},
expectedError: nil,
},
{
name: "Extra, missing job",
jobs: []main.Job{validJob},
names: []string{"Valid job", "Not Found"},
expected: []main.Job{validJob},
expectedError: main.ErrJobNotFound,
},
}
for _, c := range cases {
testCase := c
t.Run(testCase.name+" backup", func(t *testing.T) {
t.Parallel()
jobs, err := main.FilterJobs(testCase.jobs, testCase.names)
if !reflect.DeepEqual(jobs, testCase.expected) {
t.Errorf("expected %v but found %v", testCase.expected, jobs)
}
if !errors.Is(err, testCase.expectedError) {
t.Errorf("expected %v but found %v", testCase.expectedError, err)
}
})
}
}