You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
7.7 KiB
293 lines
7.7 KiB
package main_test |
|
|
|
import ( |
|
"errors" |
|
"log" |
|
"os" |
|
"path/filepath" |
|
"testing" |
|
"time" |
|
|
|
main "git.iamthefij.com/iamthefij/restic-scheduler" |
|
) |
|
|
|
func TestNoOpts(t *testing.T) { |
|
t.Parallel() |
|
|
|
args := main.NoOpts{}.ToArgs() |
|
expected := []string{} |
|
|
|
AssertEqual(t, "no opts returned some opts", expected, args) |
|
} |
|
|
|
func TestGlobalOptions(t *testing.T) { |
|
t.Parallel() |
|
|
|
args := main.ResticGlobalOpts{ |
|
CaCertFile: "file", |
|
CacheDir: "directory", |
|
PasswordFile: "file", |
|
TLSClientCertFile: "file", |
|
LimitDownload: 1, |
|
LimitUpload: 1, |
|
VerboseLevel: 1, |
|
CleanupCache: true, |
|
NoCache: true, |
|
NoLock: true, |
|
}.ToArgs() |
|
|
|
expected := []string{ |
|
"--cacert", "file", |
|
"--cache-dir", "directory", |
|
"--password-file", "file", |
|
"--tls-client-cert", "file", |
|
"--limit-download", "1", |
|
"--limit-upload", "1", |
|
"--verbose", "1", |
|
"--cleanup-cache", |
|
"--no-cache", |
|
"--no-lock", |
|
} |
|
|
|
AssertEqual(t, "args didn't match", expected, args) |
|
} |
|
|
|
func TestBackupOpts(t *testing.T) { |
|
t.Parallel() |
|
|
|
args := main.BackupOpts{ |
|
Exclude: []string{"file1", "file2"}, |
|
Include: []string{"directory"}, |
|
Tags: []string{"thing"}, |
|
Host: "steve", |
|
}.ToArgs() |
|
|
|
expected := []string{ |
|
"--exclude", "file1", |
|
"--exclude", "file2", |
|
"--include", "directory", |
|
"--tag", "thing", |
|
"--host", "steve", |
|
} |
|
|
|
AssertEqual(t, "args didn't match", expected, args) |
|
} |
|
|
|
func TestRestoreOpts(t *testing.T) { |
|
t.Parallel() |
|
|
|
args := main.RestoreOpts{ |
|
Exclude: []string{"file1", "file2"}, |
|
Include: []string{"directory"}, |
|
Host: []string{"steve"}, |
|
Tags: []string{"thing"}, |
|
Path: "directory", |
|
Target: "directory", |
|
Verify: true, |
|
}.ToArgs() |
|
|
|
expected := []string{ |
|
"--exclude", "file1", |
|
"--exclude", "file2", |
|
"--include", "directory", |
|
"--host", "steve", |
|
"--tag", "thing", |
|
"--path", "directory", |
|
"--target", "directory", |
|
"--verify", |
|
} |
|
|
|
AssertEqual(t, "args didn't match", expected, args) |
|
} |
|
|
|
func TestForgetOpts(t *testing.T) { |
|
t.Parallel() |
|
|
|
args := main.ForgetOpts{ |
|
KeepLast: 1, |
|
KeepHourly: 1, |
|
KeepDaily: 1, |
|
KeepWeekly: 1, |
|
KeepMonthly: 1, |
|
KeepYearly: 1, |
|
KeepWithin: 1 * time.Second, |
|
KeepWithinHourly: 1 * time.Second, |
|
KeepWithinDaily: 1 * time.Second, |
|
KeepWithinWeekly: 1 * time.Second, |
|
KeepWithinMonthly: 1 * time.Second, |
|
KeepWithinYearly: 1 * time.Second, |
|
Tags: []main.TagList{ |
|
{"thing1", "thing2"}, |
|
{"otherthing"}, |
|
}, |
|
KeepTags: []main.TagList{{"thing"}}, |
|
Prune: true, |
|
}.ToArgs() |
|
|
|
expected := []string{ |
|
"--keep-last", "1", |
|
"--keep-hourly", "1", |
|
"--keep-daily", "1", |
|
"--keep-weekly", "1", |
|
"--keep-monthly", "1", |
|
"--keep-yearly", "1", |
|
"--keep-within", "1s", |
|
"--keep-within-hourly", "1s", |
|
"--keep-within-daily", "1s", |
|
"--keep-within-weekly", "1s", |
|
"--keep-within-monthly", "1s", |
|
"--keep-within-yearly", "1s", |
|
"--tag", "thing1,thing2", |
|
"--tag", "otherthing", |
|
"--keep-tag", "thing", |
|
"--prune", |
|
} |
|
|
|
AssertEqual(t, "args didn't match", expected, args) |
|
} |
|
|
|
func TestBuildEnv(t *testing.T) { |
|
t.Parallel() |
|
|
|
cases := []struct { |
|
name string |
|
cmd main.Restic |
|
expected []string |
|
}{ |
|
{ |
|
name: "No Env", |
|
cmd: main.Restic{}, // nolint:exhaustivestruct |
|
expected: os.Environ(), |
|
}, |
|
{ |
|
name: "SetEnv", |
|
cmd: main.Restic{ // nolint:exhaustivestruct |
|
Env: map[string]string{"TestKey": "Value"}, |
|
}, |
|
expected: append(os.Environ(), "TestKey=Value"), |
|
}, |
|
{ |
|
name: "SetEnv", |
|
cmd: main.Restic{ // nolint:exhaustivestruct |
|
Passphrase: "Shhhhhhhh!!", |
|
}, |
|
expected: append(os.Environ(), "RESTIC_PASSWORD=Shhhhhhhh!!"), |
|
}, |
|
} |
|
|
|
for _, c := range cases { |
|
c := c |
|
|
|
t.Run(c.name, func(t *testing.T) { |
|
t.Parallel() |
|
|
|
AssertEqual(t, "args didn't match", c.expected, c.cmd.BuildEnv()) |
|
}) |
|
} |
|
} |
|
|
|
func TestResticInterface(t *testing.T) { |
|
t.Parallel() |
|
|
|
if testing.Short() { |
|
t.Skip("Skip integration test when running short tests") |
|
} |
|
|
|
dataDir := t.TempDir() |
|
repoDir := t.TempDir() |
|
cacheDir := t.TempDir() |
|
restoreTarget := t.TempDir() |
|
|
|
dataFile := filepath.Join(dataDir, "test.txt") |
|
restoredDataFile := filepath.Join(restoreTarget, dataFile) |
|
|
|
restic := main.Restic{ |
|
Logger: log.New(os.Stderr, t.Name()+":", log.Lmsgprefix), |
|
Repo: repoDir, |
|
Env: map[string]string{}, |
|
Passphrase: "Correct.Horse.Battery.Staple", |
|
// nolint:exhaustivestruct |
|
GlobalOpts: &main.ResticGlobalOpts{ |
|
CacheDir: cacheDir, |
|
}, |
|
Cwd: dataDir, |
|
} |
|
|
|
// Write test file to the data dir |
|
err := os.WriteFile(dataFile, []byte("testing"), 0644) |
|
AssertEqualFail(t, "unexpected error writing to test file", nil, err) |
|
|
|
// Make sure no existing repo is found |
|
_, err = restic.ReadSnapshots() |
|
if err == nil || !errors.Is(err, main.ErrRepoNotFound) { |
|
AssertEqualFail(t, "didn't get expected error for backup", main.ErrRepoNotFound, err) |
|
} |
|
|
|
// Try to backup when repo is not initialized |
|
err = restic.Backup([]string{dataDir}, main.BackupOpts{}) // nolint:exhaustivestruct |
|
if !errors.Is(err, main.ErrRepoNotFound) { |
|
AssertEqualFail(t, "unexpected error creating making backup", nil, err) |
|
} |
|
|
|
// Init repo |
|
err = restic.EnsureInit() |
|
AssertEqualFail(t, "unexpected error initializing repo", nil, err) |
|
|
|
// Verify it can be reinitialized with no issues |
|
err = restic.EnsureInit() |
|
AssertEqualFail(t, "unexpected error reinitializing repo", nil, err) |
|
|
|
// Backup for real this time |
|
err = restic.Backup([]string{dataDir}, main.BackupOpts{Tags: []string{"test"}}) // nolint:exhaustivestruct |
|
AssertEqualFail(t, "unexpected error creating making backup", nil, err) |
|
|
|
// Check snapshots |
|
expectedHostname, _ := os.Hostname() |
|
snapshots, err := restic.ReadSnapshots() |
|
AssertEqualFail(t, "unexpected error reading snapshots", nil, err) |
|
AssertEqual(t, "unexpected number of snapshots", 1, len(snapshots)) |
|
|
|
AssertEqual(t, "unexpected snapshot value: hostname", expectedHostname, snapshots[0].Hostname) |
|
AssertEqual(t, "unexpected snapshot value: paths", []string{dataDir}, snapshots[0].Paths) |
|
AssertEqual(t, "unexpected snapshot value: tags", []string{"test"}, snapshots[0].Tags) |
|
|
|
// Backup again |
|
err = restic.Backup([]string{dataDir}, main.BackupOpts{}) // nolint:exhaustivestruct |
|
AssertEqualFail(t, "unexpected error creating making second backup", nil, err) |
|
|
|
// Check for second backup |
|
snapshots, err = restic.ReadSnapshots() |
|
AssertEqualFail(t, "unexpected error reading second snapshots", nil, err) |
|
AssertEqual(t, "unexpected number of snapshots", 2, len(snapshots)) |
|
|
|
// Forget one backup |
|
err = restic.Forget(main.ForgetOpts{KeepLast: 1, Prune: true}) // nolint:exhaustivestruct |
|
AssertEqualFail(t, "unexpected error forgetting snapshot", nil, err) |
|
|
|
// Check forgotten snapshot |
|
snapshots, err = restic.ReadSnapshots() |
|
AssertEqualFail(t, "unexpected error reading post forget snapshots", nil, err) |
|
AssertEqual(t, "unexpected number of snapshots", 1, len(snapshots)) |
|
|
|
// Check restic repo |
|
err = restic.Check() |
|
AssertEqualFail(t, "unexpected error checking repo", nil, err) |
|
|
|
// Change the data file |
|
err = os.WriteFile(dataFile, []byte("unexpected"), 0644) |
|
AssertEqualFail(t, "unexpected error writing to test file", nil, err) |
|
|
|
// Check that data wrote |
|
value, err := os.ReadFile(dataFile) |
|
AssertEqualFail(t, "unexpected error reading from test file", nil, err) |
|
AssertEqualFail(t, "incorrect value in test file (we expect the unexpected!)", "unexpected", string(value)) |
|
|
|
// Restore files |
|
err = restic.Restore("latest", main.RestoreOpts{Target: restoreTarget}) // nolint:exhaustivestruct |
|
AssertEqualFail(t, "unexpected error restoring latest snapshot", nil, err) |
|
|
|
// Check restored values |
|
value, err = os.ReadFile(restoredDataFile) |
|
AssertEqualFail(t, "unexpected error reading from test file", nil, err) |
|
AssertEqualFail(t, "incorrect value in test file", "testing", string(value)) |
|
}
|
|
|