Add a lot more testing
This commit is contained in:
parent
512d924f0c
commit
57afeab4ca
76
job.go
76
job.go
@ -14,10 +14,11 @@ import (
|
||||
const WorkDirPerms = 0o666
|
||||
|
||||
var (
|
||||
ErrNoJobsFound = errors.New("no jobs found and at least one job is required")
|
||||
ErrMissingField = errors.New("missing config field")
|
||||
ErrMissingBlock = errors.New("missing config block")
|
||||
ErrMutuallyExclusive = errors.New("mutually exclusive values not valid")
|
||||
ErrNoJobsFound = errors.New("no jobs found and at least one job is required")
|
||||
ErrMissingField = errors.New("missing config field")
|
||||
ErrMissingBlock = errors.New("missing config block")
|
||||
ErrMutuallyExclusive = errors.New("mutually exclusive values not valid")
|
||||
ErrInvalidConfigValue = errors.New("invalid config value")
|
||||
)
|
||||
|
||||
type TaskConfig struct {
|
||||
@ -128,11 +129,20 @@ func (t JobTaskMySQL) Filename() string {
|
||||
|
||||
func (t JobTaskMySQL) Validate() error {
|
||||
if invalidChars := "'\";"; strings.ContainsAny(t.Name, invalidChars) {
|
||||
return fmt.Errorf("mysql task %s has an invalid name. The name may not contain %s", t.Name, invalidChars)
|
||||
return fmt.Errorf(
|
||||
"mysql task %s has an invalid name. The name may not contain %s: %w",
|
||||
t.Name,
|
||||
invalidChars,
|
||||
ErrInvalidConfigValue,
|
||||
)
|
||||
}
|
||||
|
||||
if len(t.Tables) > 0 && t.Database == "" {
|
||||
return fmt.Errorf("mysql task %s is invalid. Must specify a database to use tables: %w", t.Name, ErrMissingField)
|
||||
return fmt.Errorf(
|
||||
"mysql task %s is invalid. Must specify a database to use tables: %w",
|
||||
t.Name,
|
||||
ErrMissingField,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -206,7 +216,12 @@ func (t JobTaskSqlite) Filename() string {
|
||||
|
||||
func (t JobTaskSqlite) Validate() error {
|
||||
if invalidChars := "'\";"; strings.ContainsAny(t.Name, invalidChars) {
|
||||
return fmt.Errorf("sqlite task %s has an invalid name. The name may not contain %s", t.Name, invalidChars)
|
||||
return fmt.Errorf(
|
||||
"sqlite task %s has an invalid name. The name may not contain %s: %w",
|
||||
t.Name,
|
||||
invalidChars,
|
||||
ErrInvalidConfigValue,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -217,7 +232,7 @@ func (t JobTaskSqlite) GetPreTask() ExecutableTask {
|
||||
name: t.Name,
|
||||
env: nil,
|
||||
OnBackup: fmt.Sprintf(
|
||||
"sqlite3 %s '.backup $RESTIC_JOB_DIR/%s'",
|
||||
"sqlite3 '%s' '.backup $RESTIC_JOB_DIR/%s'",
|
||||
t.Path, t.Filename(),
|
||||
),
|
||||
OnRestore: "",
|
||||
@ -429,17 +444,6 @@ func (j Job) JobDir() string {
|
||||
return cwd
|
||||
}
|
||||
|
||||
/*
|
||||
* func NewTaskConfig(jobDir string, jobLogger *log.Logger, restic *ResticCmd, taskName string) TaskConfig {
|
||||
* return TaskConfig{
|
||||
* JobDir: jobDir,
|
||||
* Logger: GetChildLogger(jobLogger, taskName),
|
||||
* Restic: restic,
|
||||
* Env: nil,
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
func (j Job) RunBackup() error {
|
||||
logger := GetLogger(j.Name)
|
||||
restic := j.NewRestic()
|
||||
@ -524,37 +528,3 @@ func (c Config) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/***
|
||||
|
||||
job "My App" {
|
||||
schedule = "* * * * *"
|
||||
config {
|
||||
repo = "s3://..."
|
||||
passphrase = "foo"
|
||||
}
|
||||
|
||||
task "Dump mysql" {
|
||||
mysql {
|
||||
hostname = "foo"
|
||||
username = "bar"
|
||||
}
|
||||
}
|
||||
|
||||
task "Create biz file" {
|
||||
on_backup {
|
||||
body = <<EOF
|
||||
echo foo > /biz.txt
|
||||
EOF
|
||||
}
|
||||
}
|
||||
|
||||
task "Backup data files" {
|
||||
files = [
|
||||
"/foo/bar",
|
||||
"/biz.txt",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
***/
|
||||
|
122
job_test.go
122
job_test.go
@ -173,3 +173,125 @@ func TestJobTaskScript(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJobTaskMySQL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type TaskGenerator interface {
|
||||
Validate() error
|
||||
GetPreTask() main.ExecutableTask
|
||||
GetPostTask() main.ExecutableTask
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
task TaskGenerator
|
||||
validationErr error
|
||||
preBackup string
|
||||
postBackup string
|
||||
preRestore string
|
||||
postRestore string
|
||||
}{
|
||||
{
|
||||
name: "mysql simple",
|
||||
// nolint:exhaustivestruct
|
||||
task: main.JobTaskMySQL{Name: "simple"},
|
||||
validationErr: nil,
|
||||
preBackup: "mysqldump --result-file './simple.sql'",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "mysql < './simple.sql'",
|
||||
},
|
||||
{
|
||||
name: "mysql invalid name",
|
||||
// nolint:exhaustivestruct
|
||||
task: main.JobTaskMySQL{Name: "it's invalid;"},
|
||||
validationErr: main.ErrInvalidConfigValue,
|
||||
preBackup: "",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "",
|
||||
},
|
||||
{
|
||||
name: "mysql tables no database",
|
||||
// nolint:exhaustivestruct
|
||||
task: main.JobTaskMySQL{
|
||||
Name: "name",
|
||||
Tables: []string{"table1", "table2"},
|
||||
},
|
||||
validationErr: main.ErrMissingField,
|
||||
preBackup: "",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "",
|
||||
},
|
||||
{
|
||||
name: "mysql all options",
|
||||
task: main.JobTaskMySQL{
|
||||
Name: "simple",
|
||||
Hostname: "host",
|
||||
Username: "user",
|
||||
Password: "pass",
|
||||
Database: "db",
|
||||
Tables: []string{"table1", "table2"},
|
||||
},
|
||||
validationErr: nil,
|
||||
preBackup: "mysqldump --result-file './simple.sql' --host host --user user --password pass db table1 table2",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "mysql --host host --user user --password pass < './simple.sql'",
|
||||
},
|
||||
// Sqlite
|
||||
{
|
||||
name: "sqlite simple",
|
||||
|
||||
task: main.JobTaskSqlite{Name: "simple", Path: "database.db"},
|
||||
validationErr: nil,
|
||||
preBackup: "sqlite3 'database.db' '.backup $RESTIC_JOB_DIR/simple.db.bak'",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "cp '$RESTIC_JOB_DIR/simple.db.bak' 'database.db'",
|
||||
},
|
||||
{
|
||||
name: "sqlite invalid name",
|
||||
|
||||
task: main.JobTaskSqlite{Name: "it's invalid;", Path: "database.db"},
|
||||
validationErr: main.ErrInvalidConfigValue,
|
||||
preBackup: "",
|
||||
postBackup: "",
|
||||
preRestore: "",
|
||||
postRestore: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
testCase := c
|
||||
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validateErr := testCase.task.Validate()
|
||||
if !errors.Is(validateErr, testCase.validationErr) {
|
||||
t.Errorf("unexpected validation result. expected: %v, actual: %v", testCase.validationErr, validateErr)
|
||||
}
|
||||
|
||||
if validateErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if preTask, ok := testCase.task.GetPreTask().(main.JobTaskScript); ok {
|
||||
AssertEqual(t, "incorrect pre-backup", testCase.preBackup, preTask.OnBackup)
|
||||
AssertEqual(t, "incorrect pre-restore", testCase.preRestore, preTask.OnRestore)
|
||||
} else {
|
||||
t.Error("pre task was not a JobTaskScript")
|
||||
}
|
||||
|
||||
if postTask, ok := testCase.task.GetPostTask().(main.JobTaskScript); ok {
|
||||
AssertEqual(t, "incorrect post-backup", testCase.postBackup, postTask.OnBackup)
|
||||
AssertEqual(t, "incorrect post-restore", testCase.postRestore, postTask.OnRestore)
|
||||
} else {
|
||||
t.Error("post task was not a JobTaskScript")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,16 @@ import (
|
||||
"github.com/go-test/deep"
|
||||
)
|
||||
|
||||
func AssertEqual(t *testing.T, message string, expected, actual interface{}) bool {
|
||||
t.Helper()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("%s. expected: %v, actual: %v", message, expected, actual)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func TestMergeEnvMap(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user