go-ceph/rbd/admin/msschedule_test.go

269 lines
7.2 KiB
Go
Raw Normal View History

//go:build !nautilus
// +build !nautilus
package admin
import (
"errors"
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/ceph/go-ceph/internal/commands"
)
var ssList1 = `
{
"4": {
"name": "rbd/",
"schedule": [
{
"interval": "70m",
"start_time": null
},
{
"interval": "30m",
"start_time": null
}
]
},
"4//106ff127efdc": {
"name": "rbd/jumpy",
"schedule": [
{
"interval": "99m",
"start_time": null
}
]
}
}
`
var ssList2 = `
{
"4": {
"name": "rbd/",
"schedule": [
{
"interval": "80m",
"start_time": null
}
]
},
"4//104f1d296736": {
"name": "rbd/baz",
"schedule": [
{
"interval": "1d",
"start_time": "14:00:00-05:00"
}
]
}
}
`
var sStatus1 = `
{
"scheduled_images": []
}
`
var sStatus2 = `
{
"scheduled_images": [
{
"image": "rbd/foo",
"schedule_time": "2021-03-02 16:30:00"
}
]
}
`
var sStatus3 = `
{
"scheduled_images": [
{
"image": "rbd/bar",
"schedule_time": "2021-03-02 16:00:00"
},
{
"image": "rbd/foo",
"schedule_time": "2021-03-02 16:30:00"
}
]
}
`
func TestParseMirrorSnapshotScheduleList(t *testing.T) {
t.Run("list1", func(t *testing.T) {
r := commands.NewResponse([]byte(ssList1), "", nil)
l, err := parseMirrorSnapshotScheduleList(r)
assert.NoError(t, err)
if assert.Len(t, l, 2) {
s1 := l[0]
s2 := l[1]
if s1.Name != "rbd/" {
// just swap them. it shouldn't matter to the test if the map has
// changed the order.
s1, s2 = s2, s1
}
assert.Equal(t, "rbd/", s1.Name)
assert.Equal(t, "4", s1.LevelSpecID)
if assert.Len(t, s1.Schedule, 2) {
assert.EqualValues(t, "70m", s1.Schedule[0].Interval)
assert.EqualValues(t, "", s1.Schedule[0].StartTime)
assert.EqualValues(t, "30m", s1.Schedule[1].Interval)
assert.EqualValues(t, "", s1.Schedule[1].StartTime)
}
assert.Equal(t, "rbd/jumpy", s2.Name)
assert.Equal(t, "4//106ff127efdc", s2.LevelSpecID)
if assert.Len(t, s2.Schedule, 1) {
assert.EqualValues(t, "99m", s2.Schedule[0].Interval)
assert.EqualValues(t, "", s2.Schedule[0].StartTime)
}
}
})
t.Run("list2", func(t *testing.T) {
r := commands.NewResponse([]byte(ssList2), "", nil)
l, err := parseMirrorSnapshotScheduleList(r)
assert.NoError(t, err)
if assert.Len(t, l, 2) {
s1 := l[0]
s2 := l[1]
if s1.Name != "rbd/" {
// just swap them. it shouldn't matter to the test if the map has
// changed the order.
s1, s2 = s2, s1
}
assert.Equal(t, "rbd/", s1.Name)
assert.Equal(t, "4", s1.LevelSpecID)
if assert.Len(t, s1.Schedule, 1) {
assert.EqualValues(t, "80m", s1.Schedule[0].Interval)
assert.EqualValues(t, "", s1.Schedule[0].StartTime)
}
assert.Equal(t, "rbd/baz", s2.Name)
assert.Equal(t, "4//104f1d296736", s2.LevelSpecID)
if assert.Len(t, s2.Schedule, 1) {
assert.EqualValues(t, "1d", s2.Schedule[0].Interval)
assert.EqualValues(t, "14:00:00-05:00", s2.Schedule[0].StartTime)
}
}
})
t.Run("empty", func(t *testing.T) {
r := commands.NewResponse([]byte("{}"), "", nil)
l, err := parseMirrorSnapshotScheduleList(r)
assert.NoError(t, err)
assert.Len(t, l, 0)
})
t.Run("error", func(t *testing.T) {
r := commands.NewResponse([]byte{}, "", errors.New("yikes"))
l, err := parseMirrorSnapshotScheduleList(r)
assert.Error(t, err)
assert.Len(t, l, 0)
})
}
func TestParseMirrorSnapshotScheduleStatus(t *testing.T) {
t.Run("status1", func(t *testing.T) {
r := commands.NewResponse([]byte(sStatus1), "", nil)
s, err := parseMirrorSnapshotScheduleStatus(r)
assert.NoError(t, err)
assert.Len(t, s, 0)
})
t.Run("status2", func(t *testing.T) {
r := commands.NewResponse([]byte(sStatus2), "", nil)
s, err := parseMirrorSnapshotScheduleStatus(r)
assert.NoError(t, err)
if assert.Len(t, s, 1) {
assert.Equal(t, "rbd/foo", s[0].Image)
assert.Contains(t, s[0].ScheduleTime, "16:30")
}
})
t.Run("status3", func(t *testing.T) {
r := commands.NewResponse([]byte(sStatus3), "", nil)
s, err := parseMirrorSnapshotScheduleStatus(r)
assert.NoError(t, err)
if assert.Len(t, s, 2) {
assert.Equal(t, "rbd/bar", s[0].Image)
assert.Contains(t, s[0].ScheduleTime, "16:00")
assert.Equal(t, "rbd/foo", s[1].Image)
assert.Contains(t, s[1].ScheduleTime, "16:30")
}
})
t.Run("error", func(t *testing.T) {
r := commands.NewResponse([]byte{}, "", errors.New("zrkk"))
s, err := parseMirrorSnapshotScheduleStatus(r)
assert.Error(t, err)
assert.Len(t, s, 0)
})
}
func TestMirrorSnapshotScheduleAddRemove(t *testing.T) {
ensureDefaultPool(t)
ra := getAdmin(t)
scheduler := ra.MirrorSnashotSchedule()
t.Run("noStartTime", func(t *testing.T) {
err := scheduler.Add(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), NoStartTime)
assert.NoError(t, err)
err = scheduler.Remove(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), NoStartTime)
assert.NoError(t, err)
})
t.Run("startTime", func(t *testing.T) {
stime := StartTime("12:00:00")
err := scheduler.Add(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), stime)
assert.NoError(t, err)
err = scheduler.Remove(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), stime)
assert.NoError(t, err)
})
t.Run("badStartTime", func(t *testing.T) {
stime := StartTime("henry")
err := scheduler.Add(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), stime)
assert.Error(t, err)
})
}
func TestMirrorSnapshotScheduleList(t *testing.T) {
ensureDefaultPool(t)
ra := getAdmin(t)
// assume a pool of "rbd" exists?
scheduler := ra.MirrorSnashotSchedule()
err := scheduler.Add(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), NoStartTime)
assert.NoError(t, err)
defer func() {
err = scheduler.Remove(NewLevelSpec(defaultPoolName, "", ""), Interval("1d"), NoStartTime)
assert.NoError(t, err)
}()
slist, err := scheduler.List(NewLevelSpec(defaultPoolName, "", ""))
assert.NoError(t, err)
if assert.Len(t, slist, 1) {
assert.Equal(t, "rbd/", slist[0].Name)
if assert.Len(t, slist[0].Schedule, 1) {
assert.Equal(t, Interval("1d"), slist[0].Schedule[0].Interval)
}
}
err = scheduler.Add(NewLevelSpec(defaultPoolName, "", ""), Interval("8h"), NoStartTime)
assert.NoError(t, err)
defer func() {
err = scheduler.Remove(NewLevelSpec(defaultPoolName, "", ""), Interval("8h"), NoStartTime)
assert.NoError(t, err)
}()
slist, err = scheduler.List(NewLevelSpec(defaultPoolName, "", ""))
assert.NoError(t, err)
if assert.Len(t, slist, 1) {
assert.Equal(t, "rbd/", slist[0].Name)
if assert.Len(t, slist[0].Schedule, 2) {
// ceph doesn't return the list in a "stable" order so we just
// take the lazy approach and sort by the interval value
sched := slist[0].Schedule
sort.Slice(sched, func(i, j int) bool {
return sched[i].Interval < sched[j].Interval
})
assert.Equal(t, Interval("1d"), sched[0].Interval)
assert.Equal(t, Interval("8h"), sched[1].Interval)
}
}
}