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) }) }