Skip to content

Commit

Permalink
Factor out duplicate code in the backup-providers (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 authored Jun 12, 2024
1 parent 95a63a7 commit bf401eb
Show file tree
Hide file tree
Showing 19 changed files with 189 additions and 137 deletions.
14 changes: 7 additions & 7 deletions api/v1/backup.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions api/v1/database.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions api/v1/initializer.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions cmd/internal/backup/providers/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package common

import (
"fmt"
"sort"

"github.com/metal-stack/backup-restore-sidecar/cmd/internal/backup/providers"
)

// Sort the given list of backup versions
func Sort(versions []*providers.BackupVersion) {
sort.Slice(versions, func(i, j int) bool {
return versions[i].Date.After(versions[j].Date)
})
}

// Latest returns latest backup version
func Latest(versions []*providers.BackupVersion) *providers.BackupVersion {
Sort(versions)
if len(versions) == 0 {
return nil
}
return versions[0]
}

// Latest returns the backup version at given version
func Get(versions []*providers.BackupVersion, version string) (*providers.BackupVersion, error) {
for _, backup := range versions {
if version == backup.Version {
return backup, nil
}
}
return nil, fmt.Errorf("version %q not found", version)
}
71 changes: 71 additions & 0 deletions cmd/internal/backup/providers/common/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package common

import (
"reflect"
"testing"
"time"

"github.com/metal-stack/backup-restore-sidecar/cmd/internal/backup/providers"
"github.com/stretchr/testify/require"
)

func TestSort(t *testing.T) {
now := time.Now()
tests := []struct {
name string
versions []*providers.BackupVersion
wantedVersions []*providers.BackupVersion
}{
{
name: "mixed",
versions: []*providers.BackupVersion{
{Name: "2.tgz", Date: now.Add(2 * time.Hour)},
{Name: "1.tgz", Date: now.Add(1 * time.Hour)},
{Name: "5.tgz", Date: now.Add(5 * time.Hour)},
{Name: "0.tgz", Date: now},
{Name: "3.tgz", Date: now.Add(3 * time.Hour)},
},
wantedVersions: []*providers.BackupVersion{
{Name: "0.tgz", Date: now},
{Name: "1.tgz", Date: now.Add(1 * time.Hour)},
{Name: "2.tgz", Date: now.Add(2 * time.Hour)},
{Name: "3.tgz", Date: now.Add(3 * time.Hour)},
{Name: "5.tgz", Date: now.Add(5 * time.Hour)},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Sort(tt.versions)
require.ElementsMatch(t, tt.versions, tt.wantedVersions)
})
}
}

func TestLatest(t *testing.T) {
now := time.Now()
newestBackup := &providers.BackupVersion{Name: "5.tgz", Date: now.Add(5 * time.Hour)}
tests := []struct {
name string
versions []*providers.BackupVersion
want *providers.BackupVersion
}{
{
versions: []*providers.BackupVersion{
{Name: "2.tgz", Date: now.Add(2 * time.Hour)},
{Name: "0.tgz", Date: now},
{Name: "1.tgz", Date: now.Add(1 * time.Hour)},
newestBackup,
{Name: "3.tgz", Date: now.Add(3 * time.Hour)},
},
want: newestBackup,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Latest(tt.versions); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Latest() = %v, want %v", got, tt.want)
}
})
}
}
4 changes: 3 additions & 1 deletion cmd/internal/backup/providers/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ type BackupProvider interface {
}

type BackupVersions interface {
// Latest returns the most recent backup
Latest() *BackupVersion
Sort(versions []*BackupVersion, asc bool)
// List returns all backups sorted by date descending, e.g. the newest backup comes first
List() []*BackupVersion
// Get a backup at the specified version
Get(version string) (*BackupVersion, error)
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/internal/backup/providers/gcp/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (b *BackupProviderGCP) ListBackups(ctx context.Context) (providers.BackupVe
objectAttrs = append(objectAttrs, attrs)
}

return BackupVersionsGCP{
return backupVersionsGCP{
objectAttrs: objectAttrs,
}, nil
}
37 changes: 9 additions & 28 deletions cmd/internal/backup/providers/gcp/versions.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
package gcp

import (
"fmt"
"sort"
"strconv"

"cloud.google.com/go/storage"
"github.com/metal-stack/backup-restore-sidecar/cmd/internal/backup/providers"
"github.com/metal-stack/backup-restore-sidecar/cmd/internal/backup/providers/common"
)

type BackupVersionsGCP struct {
type backupVersionsGCP struct {
objectAttrs []*storage.ObjectAttrs
}

func (b BackupVersionsGCP) Latest() *providers.BackupVersion {
result := b.List()
if len(result) == 0 {
return nil
}
return result[0]
func (b backupVersionsGCP) Latest() *providers.BackupVersion {
return common.Latest(b.List())
}

func (b BackupVersionsGCP) List() []*providers.BackupVersion {
func (b backupVersionsGCP) List() []*providers.BackupVersion {
var result []*providers.BackupVersion

tmp := make(map[int64]bool)
tmp := make(map[int64]bool, len(result))
for _, attr := range b.objectAttrs {
ok := tmp[attr.Generation]
if !ok {
Expand All @@ -37,25 +32,11 @@ func (b BackupVersionsGCP) List() []*providers.BackupVersion {
}
}

b.Sort(result, false)
common.Sort(result)

return result
}

func (b BackupVersionsGCP) Sort(versions []*providers.BackupVersion, asc bool) {
sort.Slice(versions, func(i, j int) bool {
if asc {
return versions[i].Date.Before(versions[j].Date)
}
return versions[i].Date.After(versions[j].Date)
})
}

func (b BackupVersionsGCP) Get(version string) (*providers.BackupVersion, error) {
for _, backup := range b.List() {
if version == backup.Version {
return backup, nil
}
}
return nil, fmt.Errorf("version %q not found", version)
func (b backupVersionsGCP) Get(version string) (*providers.BackupVersion, error) {
return common.Get(b.List(), version)
}
2 changes: 1 addition & 1 deletion cmd/internal/backup/providers/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (b *BackupProviderLocal) ListBackups(_ context.Context) (providers.BackupVe
files = append(files, info)
}

return BackupVersionsLocal{
return backupVersionsLocal{
files: files,
}, nil
}
6 changes: 2 additions & 4 deletions cmd/internal/backup/providers/local/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func Test_BackupProviderLocal(t *testing.T) {
for i := range backupAmount {
backupName := p.GetNextBackupName(ctx) + ".tar.gz"
backupPath := path.Join(constants.UploadDir, backupName)
backupContent := fmt.Sprintf("precious data %d", i)
backupContent := fmt.Sprintf("precious data %d", i+1)

err = afero.WriteFile(fs, backupPath, []byte(backupContent), 0600)
require.NoError(t, err)
Expand Down Expand Up @@ -102,8 +102,6 @@ func Test_BackupProviderLocal(t *testing.T) {
require.Len(t, allVersions, amount)

for i, v := range allVersions {
v := v

assert.True(t, strings.HasSuffix(v.Name, ".tar.gz"))
assert.NotZero(t, v.Date)

Expand Down Expand Up @@ -139,7 +137,7 @@ func Test_BackupProviderLocal(t *testing.T) {
gotContent, err := afero.ReadFile(fs, downloadPath)
require.NoError(t, err)

require.Equal(t, fmt.Sprintf("precious data %d", backupAmount-1), string(gotContent))
require.Equal(t, fmt.Sprintf("precious data %d", backupAmount), string(gotContent))

// cleaning up after test
err = fs.Remove(downloadPath)
Expand Down
Loading

0 comments on commit bf401eb

Please sign in to comment.