go-ceph/rados/operation_test.go
John Mulligan c96da54878 rados: add test cases for basic operation types
Signed-off-by: John Mulligan <jmulligan@redhat.com>
2021-01-12 14:47:30 +00:00

120 lines
2.7 KiB
Go

package rados
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestOperationError(t *testing.T) {
oe := OperationError{
kind: readOp,
OpError: fmt.Errorf("bad mojo %v", 77),
StepErrors: map[int]error{
1: fmt.Errorf("limit exceeded"),
3: fmt.Errorf("weirdness"),
},
}
assert.Error(t, oe)
estr := oe.Error()
assert.Contains(t, estr, "read operation error")
assert.Contains(t, estr, "op=bad mojo 77")
assert.Contains(t, estr, "Step#1=limit exceeded")
assert.Contains(t, estr, "Step#3=weirdness")
oe = OperationError{
kind: writeOp,
StepErrors: map[int]error{
0: fmt.Errorf("unlucky"),
},
}
assert.Error(t, oe)
estr = oe.Error()
assert.Contains(t, estr, "write operation error")
assert.NotContains(t, estr, "op=")
assert.Contains(t, estr, "Step#0=unlucky")
}
type fooStep struct {
updateCount int
freeCount int
failMe error
}
func (fs *fooStep) update() error {
fs.updateCount++
return fs.failMe
}
func (fs *fooStep) free() {
fs.freeCount++
}
func TestOpStepFinalizer(t *testing.T) {
// this confirms that given a valid op step the finalizer helper
// function calls the free method of the interface
fs := &fooStep{}
opStepFinalizer(fs)
opStepFinalizer(fs)
assert.Equal(t, 2, fs.freeCount)
// this should not panic
opStepFinalizer(nil)
}
func TestOperationType(t *testing.T) {
t.Run("stepErrors", func(t *testing.T) {
o := &operation{}
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{failMe: fmt.Errorf("yow")})
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{failMe: fmt.Errorf("ouch")})
err := o.update(readOp, 0)
if assert.Error(t, err) {
oe := err.(OperationError)
assert.NoError(t, oe.OpError)
assert.Len(t, oe.StepErrors, 2)
assert.Contains(t, oe.StepErrors, 1)
assert.Contains(t, oe.StepErrors, 4)
}
})
t.Run("opError", func(t *testing.T) {
o := &operation{}
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{})
err := o.update(readOp, 5)
if assert.Error(t, err) {
oe := err.(OperationError)
assert.Error(t, oe.OpError)
assert.Len(t, oe.StepErrors, 0)
}
})
t.Run("noErrors", func(t *testing.T) {
o := &operation{}
o.steps = append(o.steps, &fooStep{})
o.steps = append(o.steps, &fooStep{})
err := o.update(readOp, 0)
assert.NoError(t, err)
x := 0
for i := range o.steps {
x += o.steps[i].(*fooStep).updateCount
}
assert.Equal(t, 2, x)
o.free()
x = 0
for i := range o.steps {
x += o.steps[i].(*fooStep).updateCount
}
assert.Equal(t, 2, x)
})
}