mirror of https://github.com/ceph/go-ceph
270 lines
7.4 KiB
Go
270 lines
7.4 KiB
Go
package rbd
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGroupSnapshots(t *testing.T) {
|
|
// tests are done as subtests to avoid creating pools, images, etc
|
|
// over and over again.
|
|
conn := radosConnect(t)
|
|
require.NotNil(t, conn)
|
|
defer conn.Shutdown()
|
|
|
|
poolname := GetUUID()
|
|
err := conn.MakePool(poolname)
|
|
require.NoError(t, err)
|
|
defer conn.DeletePool(poolname)
|
|
|
|
ioctx, err := conn.OpenIOContext(poolname)
|
|
require.NoError(t, err)
|
|
defer ioctx.Destroy()
|
|
|
|
// create a group, some images, and add images to the group
|
|
gname := "snapme"
|
|
err = GroupCreate(ioctx, gname)
|
|
assert.NoError(t, err)
|
|
|
|
options := NewRbdImageOptions()
|
|
assert.NoError(t,
|
|
options.SetUint64(ImageOptionOrder, uint64(testImageOrder)))
|
|
|
|
name1 := GetUUID()
|
|
err = CreateImage(ioctx, name1, testImageSize, options)
|
|
require.NoError(t, err)
|
|
|
|
name2 := GetUUID()
|
|
err = CreateImage(ioctx, name2, testImageSize, options)
|
|
require.NoError(t, err)
|
|
|
|
err = GroupImageAdd(ioctx, gname, ioctx, name1)
|
|
assert.NoError(t, err)
|
|
err = GroupImageAdd(ioctx, gname, ioctx, name2)
|
|
assert.NoError(t, err)
|
|
|
|
t.Run("groupSnapCreateRemove", func(t *testing.T) {
|
|
err := GroupSnapCreate(ioctx, gname, "snap1")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapRemove(ioctx, gname, "snap1")
|
|
assert.NoError(t, err)
|
|
})
|
|
t.Run("groupSnapRename", func(t *testing.T) {
|
|
err := GroupSnapCreate(ioctx, gname, "snap2a")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapRename(ioctx, gname, "fred", "wilma")
|
|
assert.Error(t, err)
|
|
err = GroupSnapRename(ioctx, gname, "snap2a", "snap2b")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapRemove(ioctx, gname, "snap2a")
|
|
assert.Error(t, err, "remove of old name: expect error")
|
|
err = GroupSnapRemove(ioctx, gname, "snap2b")
|
|
assert.NoError(t, err, "remove of current name: expect success")
|
|
})
|
|
t.Run("groupSnappList", func(t *testing.T) {
|
|
err := GroupSnapCreate(ioctx, gname, "snap1")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapCreate(ioctx, gname, "snap2")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapCreate(ioctx, gname, "snap3")
|
|
assert.NoError(t, err)
|
|
|
|
gsl, err := GroupSnapList(ioctx, gname)
|
|
assert.NoError(t, err)
|
|
if assert.Len(t, gsl, 3) {
|
|
names := []string{}
|
|
for _, gsi := range gsl {
|
|
assert.Equal(t, GroupSnapStateComplete, gsi.State)
|
|
names = append(names, gsi.Name)
|
|
}
|
|
assert.Contains(t, names, "snap1")
|
|
assert.Contains(t, names, "snap2")
|
|
assert.Contains(t, names, "snap3")
|
|
}
|
|
|
|
err = GroupSnapRemove(ioctx, gname, "snap3")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapRemove(ioctx, gname, "snap2")
|
|
assert.NoError(t, err)
|
|
err = GroupSnapRename(ioctx, gname, "snap1", "snap1a")
|
|
|
|
gsl, err = GroupSnapList(ioctx, gname)
|
|
assert.NoError(t, err)
|
|
if assert.Len(t, gsl, 1) {
|
|
assert.Equal(t, GroupSnapStateComplete, gsl[0].State)
|
|
assert.Equal(t, "snap1a", gsl[0].Name)
|
|
}
|
|
|
|
err = GroupSnapRemove(ioctx, gname, "snap1a")
|
|
assert.NoError(t, err)
|
|
|
|
gsl, err = GroupSnapList(ioctx, gname)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, gsl, 0)
|
|
})
|
|
t.Run("groupSnapGetInfo", func(t *testing.T) {
|
|
err := GroupSnapCreate(ioctx, gname, "snapDetails")
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
err = GroupSnapRemove(ioctx, gname, "snapDetails")
|
|
assert.NoError(t, err)
|
|
}()
|
|
|
|
info, err := GroupSnapGetInfo(ioctx, gname, "snapDetails")
|
|
if errors.Is(err, ErrNotImplemented) {
|
|
t.Skipf("GroupSnapGetInfo is not supported: %v", err)
|
|
}
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, GroupSnapStateComplete, info.State)
|
|
|
|
names := make([]string, len(info.Snapshots))
|
|
for i, snap := range info.Snapshots {
|
|
names[i] = snap.Name
|
|
}
|
|
assert.Contains(t, names, name1)
|
|
assert.Contains(t, names, name2)
|
|
})
|
|
t.Run("groupSnapRollback", func(t *testing.T) {
|
|
img, err := OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("HELLO WORLD"), 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
snapname := "snap1"
|
|
err = GroupSnapCreate(ioctx, gname, snapname)
|
|
assert.NoError(t, err)
|
|
|
|
img, err = OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("GOODBYE WORLD"), 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
img, err = OpenImage(ioctx, name2, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("2222222222222"), 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
err = GroupSnapRollback(ioctx, gname, snapname)
|
|
assert.NoError(t, err)
|
|
|
|
b := make([]byte, 8)
|
|
img, err = OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.ReadAt(b, 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("HELLO WO"), b)
|
|
|
|
img, err = OpenImage(ioctx, name2, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.ReadAt(b, 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("\x00\x00\x00\x00\x00\x00\x00\x00"), b)
|
|
|
|
err = GroupSnapRemove(ioctx, gname, snapname)
|
|
assert.NoError(t, err)
|
|
})
|
|
t.Run("groupSnapRollbackWithProgress", func(t *testing.T) {
|
|
img, err := OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("SAY CHEESE"), 0)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("AND SMILE_"), 10240)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
snapname := "snap2r"
|
|
err = GroupSnapCreate(ioctx, gname, snapname)
|
|
assert.NoError(t, err)
|
|
|
|
img, err = OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("GOODBYE WORLD"), 0)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("_THIS_IS_ALL_"), 10240)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("I_HAVE_TO_SAY"), 11240)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
img, err = OpenImage(ioctx, name2, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.WriteAt([]byte("3333333333333"), 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
|
|
cc := 0
|
|
cb := func(_, total uint64, v interface{}) int {
|
|
cc++
|
|
val := v.(int)
|
|
assert.Equal(t, 0, val)
|
|
assert.Equal(t, uint64(1), total)
|
|
return 0
|
|
}
|
|
err = GroupSnapRollbackWithProgress(ioctx, gname, snapname, cb, 0)
|
|
assert.NoError(t, err)
|
|
assert.GreaterOrEqual(t, cc, 2)
|
|
|
|
b := make([]byte, 8)
|
|
img, err = OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.ReadAt(b, 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("SAY CHEE"), b)
|
|
|
|
img, err = OpenImage(ioctx, name2, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
_, err = img.ReadAt(b, 0)
|
|
assert.NoError(t, err)
|
|
err = img.Close()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []byte("\x00\x00\x00\x00\x00\x00\x00\x00"), b)
|
|
|
|
err = GroupSnapRemove(ioctx, gname, snapname)
|
|
assert.NoError(t, err)
|
|
})
|
|
t.Run("invalidIOContext", func(t *testing.T) {
|
|
assert.Panics(t, func() {
|
|
GroupSnapCreate(nil, gname, "foo")
|
|
})
|
|
assert.Panics(t, func() {
|
|
GroupSnapRemove(nil, gname, "foo")
|
|
})
|
|
assert.Panics(t, func() {
|
|
GroupSnapRename(nil, gname, "foo", "bar")
|
|
})
|
|
assert.Panics(t, func() {
|
|
GroupSnapList(nil, gname)
|
|
})
|
|
assert.Panics(t, func() {
|
|
GroupSnapRollback(nil, gname, "foo")
|
|
})
|
|
assert.Panics(t, func() {
|
|
cb := func(_, _ uint64, _ interface{}) int { return 0 }
|
|
GroupSnapRollbackWithProgress(nil, gname, "foo", cb, nil)
|
|
})
|
|
})
|
|
t.Run("invalidCallback", func(t *testing.T) {
|
|
err := GroupSnapRollbackWithProgress(ioctx, gname, "foo", nil, nil)
|
|
assert.Error(t, err)
|
|
})
|
|
}
|