cosmos-sdk/simsx/reporter_test.go

220 lines
5.8 KiB
Go

package simsx
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
)
func TestSimulationReporterToLegacy(t *testing.T) {
myErr := errors.New("my-error")
myMsg := testdata.NewTestMsg([]byte{1})
specs := map[string]struct {
setup func() SimulationReporter
expOp simtypes.OperationMsg
expErr error
}{
"init only": {
setup: func() SimulationReporter { return NewBasicSimulationReporter() },
expOp: simtypes.NewOperationMsgBasic("", "", "", false),
expErr: errors.New("operation aborted before msg was executed"),
},
"success result": {
setup: func() SimulationReporter {
r := NewBasicSimulationReporter().WithScope(myMsg)
r.Success(myMsg, "testing")
return r
},
expOp: simtypes.NewOperationMsgBasic("TestMsg", "/testpb.TestMsg", "testing", true),
},
"error result": {
setup: func() SimulationReporter {
r := NewBasicSimulationReporter().WithScope(myMsg)
r.Fail(myErr, "testing")
return r
},
expOp: simtypes.NewOperationMsgBasic("TestMsg", "/testpb.TestMsg", "testing", false),
expErr: myErr,
},
"last error wins": {
setup: func() SimulationReporter {
r := NewBasicSimulationReporter().WithScope(myMsg)
r.Fail(errors.New("other-err"), "testing1")
r.Fail(myErr, "testing2")
return r
},
expOp: simtypes.NewOperationMsgBasic("TestMsg", "/testpb.TestMsg", "testing1, testing2", false),
expErr: myErr,
},
"skipped ": {
setup: func() SimulationReporter {
r := NewBasicSimulationReporter().WithScope(myMsg)
r.Skip("testing")
return r
},
expOp: simtypes.NoOpMsg("TestMsg", "/testpb.TestMsg", "testing"),
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
r := spec.setup()
assert.Equal(t, spec.expOp, r.ToLegacyOperationMsg())
require.Equal(t, spec.expErr, r.Close())
})
}
}
func TestSimulationReporterTransitions(t *testing.T) {
specs := map[string]struct {
setup func(r SimulationReporter)
expStatus ReporterStatus
expPanic bool
}{
"undefined->skipped": {
setup: func(r SimulationReporter) {
r.Skip("testing")
},
expStatus: skipped,
},
"skipped->skipped": {
setup: func(r SimulationReporter) {
r.Skip("testing1")
r.Skip("testing2")
},
expStatus: skipped,
},
"skipped->completed": {
setup: func(r SimulationReporter) {
r.Skip("testing1")
r.Success(nil, "testing2")
},
expStatus: completed,
},
"completed->completed": {
setup: func(r SimulationReporter) {
r.Success(nil, "testing1")
r.Fail(nil, "testing2")
},
expStatus: completed,
},
"completed->completed2": {
setup: func(r SimulationReporter) {
r.Fail(nil, "testing1")
r.Success(nil, "testing2")
},
expStatus: completed,
},
"completed->skipped: rejected": {
setup: func(r SimulationReporter) {
r.Success(nil, "testing1")
r.Skip("testing2")
},
expPanic: true,
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
r := NewBasicSimulationReporter()
if !spec.expPanic {
spec.setup(r)
assert.Equal(t, uint32(spec.expStatus), r.status.Load())
return
}
require.Panics(t, func() {
spec.setup(r)
})
})
}
}
func TestSkipHook(t *testing.T) {
myHook := func() (SkipHookFn, *bool) {
var hookCalled bool
return func(args ...any) {
hookCalled = true
}, &hookCalled
}
fn, myHookCalled := myHook()
r := NewBasicSimulationReporter(fn)
r.Skip("testing")
require.True(t, *myHookCalled)
// and with nested reporter
fn, myHookCalled = myHook()
r = NewBasicSimulationReporter(fn)
fn2, myOtherHookCalled := myHook()
r2 := r.WithScope(testdata.NewTestMsg([]byte{1}), fn2)
r2.Skipf("testing %d", 2)
assert.True(t, *myHookCalled)
assert.True(t, *myOtherHookCalled)
}
func TestReporterSummary(t *testing.T) {
specs := map[string]struct {
do func(t *testing.T, r SimulationReporter)
expSummary map[string]int
expReasons map[string]map[string]int
}{
"skipped": {
do: func(t *testing.T, r SimulationReporter) { //nolint:thelper // not a helper
r2 := r.WithScope(testdata.NewTestMsg([]byte{1}))
r2.Skip("testing")
require.NoError(t, r2.Close())
},
expSummary: map[string]int{"TestMsg_skipped": 1},
expReasons: map[string]map[string]int{"/testpb.TestMsg": {"testing": 1}},
},
"success result": {
do: func(t *testing.T, r SimulationReporter) { //nolint:thelper // not a helper
msg := testdata.NewTestMsg([]byte{1})
r2 := r.WithScope(msg)
r2.Success(msg)
require.NoError(t, r2.Close())
},
expSummary: map[string]int{"TestMsg_completed": 1},
expReasons: map[string]map[string]int{},
},
"error result": {
do: func(t *testing.T, r SimulationReporter) { //nolint:thelper // not a helper
msg := testdata.NewTestMsg([]byte{1})
r2 := r.WithScope(msg)
r2.Fail(errors.New("testing"))
require.Error(t, r2.Close())
},
expSummary: map[string]int{"TestMsg_completed": 1},
expReasons: map[string]map[string]int{},
},
"multiple skipped": {
do: func(t *testing.T, r SimulationReporter) { //nolint:thelper // not a helper
r2 := r.WithScope(testdata.NewTestMsg([]byte{1}))
r2.Skip("testing1")
require.NoError(t, r2.Close())
r3 := r.WithScope(testdata.NewTestMsg([]byte{2}))
r3.Skip("testing2")
require.NoError(t, r3.Close())
},
expSummary: map[string]int{"TestMsg_skipped": 2},
expReasons: map[string]map[string]int{
"/testpb.TestMsg": {"testing1": 1, "testing2": 1},
},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
r := NewBasicSimulationReporter()
// when
spec.do(t, r)
gotSummary := r.Summary()
// then
require.Equal(t, spec.expSummary, gotSummary.counts)
require.Equal(t, spec.expReasons, gotSummary.skipReasons)
})
}
}