github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/cron/cron_test.go (about) 1 package cron_test 2 3 import ( 4 "testing" 5 6 "github.com/filecoin-project/go-state-types/abi" 7 "github.com/filecoin-project/go-state-types/big" 8 "github.com/filecoin-project/go-state-types/exitcode" 9 "github.com/stretchr/testify/assert" 10 11 "github.com/filecoin-project/specs-actors/v4/actors/builtin" 12 "github.com/filecoin-project/specs-actors/v4/actors/builtin/cron" 13 "github.com/filecoin-project/specs-actors/v4/support/mock" 14 tutil "github.com/filecoin-project/specs-actors/v4/support/testing" 15 ) 16 17 func TestExports(t *testing.T) { 18 mock.CheckActorExports(t, cron.Actor{}) 19 } 20 21 func TestConstructor(t *testing.T) { 22 actor := cronHarness{cron.Actor{}, t} 23 24 receiver := tutil.NewIDAddr(t, 100) 25 builder := mock.NewBuilder(receiver).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID) 26 27 t.Run("construct with empty entries", func(t *testing.T) { 28 rt := builder.Build(t) 29 30 actor.constructAndVerify(rt) 31 32 var st cron.State 33 rt.GetState(&st) 34 var nilCronEntries = []cron.Entry(nil) 35 assert.Equal(t, nilCronEntries, st.Entries) 36 37 actor.checkState(rt) 38 }) 39 40 t.Run("construct with non-empty entries", func(t *testing.T) { 41 rt := builder.Build(t) 42 43 var entryParams = []cron.EntryParam{ 44 {Receiver: tutil.NewIDAddr(t, 1001), MethodNum: abi.MethodNum(1001)}, 45 {Receiver: tutil.NewIDAddr(t, 1002), MethodNum: abi.MethodNum(1002)}, 46 {Receiver: tutil.NewIDAddr(t, 1003), MethodNum: abi.MethodNum(1003)}, 47 {Receiver: tutil.NewIDAddr(t, 1004), MethodNum: abi.MethodNum(1004)}, 48 } 49 actor.constructAndVerify(rt, entryParams...) 50 51 var st cron.State 52 rt.GetState(&st) 53 expectedEntries := make([]cron.Entry, len(entryParams)) 54 for i, e := range entryParams { 55 expectedEntries[i] = cron.Entry(e) 56 } 57 assert.Equal(t, expectedEntries, st.Entries) 58 59 actor.checkState(rt) 60 }) 61 } 62 63 func TestEpochTick(t *testing.T) { 64 actor := cronHarness{cron.Actor{}, t} 65 66 receiver := tutil.NewIDAddr(t, 100) 67 builder := mock.NewBuilder(receiver).WithCaller(builtin.SystemActorAddr, builtin.SystemActorCodeID) 68 69 t.Run("epoch tick with empty entries", func(t *testing.T) { 70 rt := builder.Build(t) 71 72 var nilCronEntries = []cron.EntryParam(nil) 73 actor.constructAndVerify(rt, nilCronEntries...) 74 actor.epochTickAndVerify(rt) 75 actor.checkState(rt) 76 }) 77 78 t.Run("epoch tick with non-empty entries", func(t *testing.T) { 79 rt := builder.Build(t) 80 81 entry1 := cron.EntryParam{Receiver: tutil.NewIDAddr(t, 1001), MethodNum: abi.MethodNum(1001)} 82 entry2 := cron.EntryParam{Receiver: tutil.NewIDAddr(t, 1002), MethodNum: abi.MethodNum(1002)} 83 entry3 := cron.EntryParam{Receiver: tutil.NewIDAddr(t, 1003), MethodNum: abi.MethodNum(1003)} 84 entry4 := cron.EntryParam{Receiver: tutil.NewIDAddr(t, 1004), MethodNum: abi.MethodNum(1004)} 85 86 actor.constructAndVerify(rt, entry1, entry2, entry3, entry4) 87 // exit code should not matter 88 rt.ExpectSend(entry1.Receiver, entry1.MethodNum, nil, big.Zero(), nil, exitcode.Ok) 89 rt.ExpectSend(entry2.Receiver, entry2.MethodNum, nil, big.Zero(), nil, exitcode.ErrIllegalArgument) 90 rt.ExpectSend(entry3.Receiver, entry3.MethodNum, nil, big.Zero(), nil, exitcode.ErrInsufficientFunds) 91 rt.ExpectSend(entry4.Receiver, entry4.MethodNum, nil, big.Zero(), nil, exitcode.ErrForbidden) 92 actor.epochTickAndVerify(rt) 93 94 actor.checkState(rt) 95 }) 96 97 t.Run("built-in entries", func(t *testing.T) { 98 bie := cron.BuiltInEntries() 99 assert.True(t, len(bie) > 0) 100 }) 101 } 102 103 type cronHarness struct { 104 cron.Actor 105 t testing.TB 106 } 107 108 func (h *cronHarness) constructAndVerify(rt *mock.Runtime, entries ...cron.EntryParam) { 109 params := cron.ConstructorParams{Entries: entries} 110 rt.ExpectValidateCallerAddr(builtin.SystemActorAddr) 111 ret := rt.Call(h.Constructor, ¶ms) 112 assert.Nil(h.t, ret) 113 rt.Verify() 114 } 115 116 func (h *cronHarness) epochTickAndVerify(rt *mock.Runtime) { 117 rt.ExpectValidateCallerAddr(builtin.SystemActorAddr) 118 ret := rt.Call(h.EpochTick, nil) 119 assert.Nil(h.t, ret) 120 rt.Verify() 121 } 122 123 func (h *cronHarness) checkState(rt *mock.Runtime) { 124 var st cron.State 125 rt.GetState(&st) 126 _, msgs := cron.CheckStateInvariants(&st, rt.AdtStore()) 127 assert.True(h.t, msgs.IsEmpty()) 128 }