fix bugs in GetBackupVolumeSnapshots and add test

Signed-off-by: Steve Kriss <steve@heptio.com>
pull/951/head
Steve Kriss 2018-10-17 15:10:42 -06:00
parent 17b3a3b073
commit cf2c27141b
2 changed files with 81 additions and 1 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package persistence
import (
"compress/gzip"
"encoding/json"
"io"
"io/ioutil"
@ -233,17 +234,51 @@ func (s *objectBackupStore) GetBackupMetadata(name string) (*arkv1api.Backup, er
return backupObj, nil
}
func keyExists(objectStore cloudprovider.ObjectStore, bucket, prefix, key string) (bool, error) {
keys, err := objectStore.ListObjects(bucket, prefix)
if err != nil {
return false, err
}
var found bool
for _, existing := range keys {
if key == existing {
found = true
break
}
}
return found, nil
}
func (s *objectBackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Snapshot, error) {
key := s.layout.getBackupVolumeSnapshotsKey(name)
// if the volumesnapshots file doesn't exist, we don't want to return an error, since
// a legacy backup or a backup with no snapshots would not have this file, so check for
// its existence before attempting to get its contents.
ok, err := keyExists(s.objectStore, s.bucket, s.layout.getBackupDir(name), key)
if err != nil {
return nil, errors.WithStack(err)
}
if !ok {
return nil, nil
}
res, err := s.objectStore.GetObject(s.bucket, key)
if err != nil {
return nil, err
}
defer res.Close()
gzr, err := gzip.NewReader(res)
if err != nil {
return nil, errors.WithStack(err)
}
defer gzr.Close()
var volumeSnapshots []*volume.Snapshot
if err := json.NewDecoder(res).Decode(&volumeSnapshots); err != nil {
if err := json.NewDecoder(gzr).Decode(&volumeSnapshots); err != nil {
return nil, errors.Wrap(err, "error decoding object data")
}

View File

@ -18,6 +18,8 @@ package persistence
import (
"bytes"
"compress/gzip"
"encoding/json"
"errors"
"io"
"io/ioutil"
@ -38,6 +40,7 @@ import (
cloudprovidermocks "github.com/heptio/ark/pkg/cloudprovider/mocks"
"github.com/heptio/ark/pkg/util/encode"
arktest "github.com/heptio/ark/pkg/util/test"
"github.com/heptio/ark/pkg/volume"
)
type objectBackupStoreTestHarness struct {
@ -304,6 +307,48 @@ func TestPutBackup(t *testing.T) {
}
}
func TestGetBackupVolumeSnapshots(t *testing.T) {
harness := newObjectBackupStoreTestHarness("test-bucket", "")
// volumesnapshots file not found should not error
harness.objectStore.PutObject(harness.bucket, "backups/test-backup/ark-backup.json", newStringReadSeeker("foo"))
res, err := harness.GetBackupVolumeSnapshots("test-backup")
assert.NoError(t, err)
assert.Nil(t, res)
// volumesnapshots file containing invalid data should error
harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-volumesnapshots.json.gz", newStringReadSeeker("foo"))
res, err = harness.GetBackupVolumeSnapshots("test-backup")
assert.NotNil(t, err)
// volumesnapshots file containing gzipped json data should return correctly
snapshots := []*volume.Snapshot{
{
Spec: volume.SnapshotSpec{
BackupName: "test-backup",
PersistentVolumeName: "pv-1",
},
},
{
Spec: volume.SnapshotSpec{
BackupName: "test-backup",
PersistentVolumeName: "pv-2",
},
},
}
obj := new(bytes.Buffer)
gzw := gzip.NewWriter(obj)
require.NoError(t, json.NewEncoder(gzw).Encode(snapshots))
require.NoError(t, gzw.Close())
require.NoError(t, harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-volumesnapshots.json.gz", obj))
res, err = harness.GetBackupVolumeSnapshots("test-backup")
assert.NoError(t, err)
assert.EqualValues(t, snapshots, res)
}
func TestGetBackupContents(t *testing.T) {
harness := newObjectBackupStoreTestHarness("test-bucket", "")