From 5c793dcaba35a36fe6204a7522d4126acd393aa9 Mon Sep 17 00:00:00 2001 From: Umputun Date: Fri, 29 Dec 2017 19:22:48 -0600 Subject: [PATCH] extract and test makeBackup --- app/migrator/migrator.go | 37 +++++++++++++++++++++++------------ app/migrator/migrator_test.go | 34 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/app/migrator/migrator.go b/app/migrator/migrator.go index baeb1243..c478cdd9 100644 --- a/app/migrator/migrator.go +++ b/app/migrator/migrator.go @@ -61,29 +61,42 @@ func ImportComments(p ImportParams) error { return importer.Import(fh, p.SiteID) } -// AutoBackup runs daily export to local files +// AutoBackup runs daily export to local files, keeps up to keepMax backups for given siteID func AutoBackup(exporter Exporter, backupLocation string, siteID string, keepMax int) { log.Print("[INFO] activate auto-backup") tick := time.NewTicker(24 * time.Hour) for range tick.C { - log.Print("[DEBUG] make backup") - fh, err := os.Create(fmt.Sprintf("%s/backup-%s-%s.gz", backupLocation, siteID, time.Now().Format("20060102"))) + _, err := makeBackup(exporter, backupLocation, siteID) if err != nil { - log.Printf("[WARN] can't create backup file, %s", err) + log.Printf("[WARN] auto-backup for %s failed, %s", siteID, err) continue } - gz := gzip.NewWriter(fh) - - if err = exporter.Export(gz, siteID); err != nil { - log.Printf("[WARN] export failed, %+v", err) - } - _ = gz.Close() - _ = fh.Close() - removeOldBackupFiles(backupLocation, siteID, keepMax) } } +func makeBackup(exporter Exporter, backupLocation string, siteID string) (string, error) { + log.Printf("[DEBUG] make backup for %s", siteID) + backupFile := fmt.Sprintf("%s/backup-%s-%s.gz", backupLocation, siteID, time.Now().Format("20060102")) + fh, err := os.Create(backupFile) + if err != nil { + return "", errors.Wrapf(err, "can't create backup file %s", backupFile) + } + gz := gzip.NewWriter(fh) + + if err = exporter.Export(gz, siteID); err != nil { + return "", errors.Wrapf(err, "export failed for %s", siteID) + } + if err = gz.Close(); err != nil { + return "", errors.Wrapf(err, "can't close gz for %s", backupFile) + } + if err = fh.Close(); err != nil { + return "", errors.Wrapf(err, "can't close file handler for %s", backupFile) + } + log.Printf("[DEBUG] created backup file %s", backupFile) + return backupFile, nil +} + func removeOldBackupFiles(backupLocation string, siteID string, keepMax int) { files, err := ioutil.ReadDir(backupLocation) if err != nil { diff --git a/app/migrator/migrator_test.go b/app/migrator/migrator_test.go index 8e1db7e7..3ab19664 100644 --- a/app/migrator/migrator_test.go +++ b/app/migrator/migrator_test.go @@ -2,19 +2,21 @@ package migrator import ( "fmt" + "io" "io/ioutil" "os" "testing" + "time" "github.com/stretchr/testify/assert" ) func TestMigrator_RemoveOldBackupFiles(t *testing.T) { - loc := "tmp/remark-backups.test" + loc := "/tmp/remark-backups.test" defer os.RemoveAll(loc) os.MkdirAll(loc, 0700) - for i := 0; i < 10; i++ { + for i := 1; i <= 10; i++ { fname := fmt.Sprintf("%s/backup-site1-201712%02d.gz", loc, i) err := ioutil.WriteFile(fname, []byte("blah"), 0600) assert.Nil(t, err) @@ -24,7 +26,29 @@ func TestMigrator_RemoveOldBackupFiles(t *testing.T) { ff, err := ioutil.ReadDir(loc) assert.Nil(t, err) assert.Equal(t, 3, len(ff), "should keep 3 files only") - assert.Equal(t, "backup-site1-20171207.gz", ff[0].Name()) - assert.Equal(t, "backup-site1-20171208.gz", ff[1].Name()) - assert.Equal(t, "backup-site1-20171209.gz", ff[2].Name()) + assert.Equal(t, "backup-site1-20171208.gz", ff[0].Name()) + assert.Equal(t, "backup-site1-20171209.gz", ff[1].Name()) + assert.Equal(t, "backup-site1-20171210.gz", ff[2].Name()) +} + +func TestMigrator_MakeBackup(t *testing.T) { + loc := "/tmp/remark-backups.test" + defer os.RemoveAll(loc) + os.MkdirAll(loc, 0700) + + fname, err := makeBackup(&mockExporter{}, loc, "site1") + assert.NoError(t, err) + expFile := fmt.Sprintf("/tmp/remark-backups.test/backup-site1-%s.gz", time.Now().Format("20060102")) + assert.Equal(t, expFile, fname) + + fi, err := os.Lstat(expFile) + assert.NoError(t, err) + assert.Equal(t, int64(52), fi.Size()) +} + +type mockExporter struct{} + +func (mock *mockExporter) Export(w io.Writer, siteID string) error { + w.Write([]byte("some export blah blah 1234567890")) + return nil }