diff --git a/pkg/innerring/blocktimer.go b/pkg/innerring/blocktimer.go index 6a4dee8015..ad69f207b1 100644 --- a/pkg/innerring/blocktimer.go +++ b/pkg/innerring/blocktimer.go @@ -25,6 +25,10 @@ type ( newEpochHandler func() + containerEstimationStopper interface { + StopEstimation(p container.StopEstimationPrm) error + } + epochTimerArgs struct { l *logger.Logger @@ -32,8 +36,8 @@ type ( newEpochHandlers []newEpochHandler - cnrWrapper *container.Client // to invoke stop container estimation - epoch epochState // to specify which epoch to stop, and epoch duration + cnrWrapper containerEstimationStopper // to invoke stop container estimation + epoch epochState // to specify which epoch to stop, and epoch duration stopEstimationDMul uint32 // X: X/Y of epoch in blocks stopEstimationDDiv uint32 // Y: X/Y of epoch in blocks diff --git a/pkg/innerring/blocktimer_test.go b/pkg/innerring/blocktimer_test.go new file mode 100644 index 0000000000..e1a79c2a8c --- /dev/null +++ b/pkg/innerring/blocktimer_test.go @@ -0,0 +1,167 @@ +package innerring + +import ( + "testing" + + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" + "github.com/stretchr/testify/require" +) + +func TestEpochTimer(t *testing.T) { + t.Parallel() + alphaState := &testAlphabetState{isAlphabet: true} + neh := &testNewEpochHandler{} + cnrStopper := &testContainerEstStopper{} + epochState := &testEpochState{ + counter: 99, + duration: 10, + } + collectHandler := &testEventHandler{} + distributeHandler := &testEventHandler{} + + args := &epochTimerArgs{ + l: test.NewLogger(t, true), + alphabetState: alphaState, + newEpochHandlers: []newEpochHandler{neh.Handle}, + cnrWrapper: cnrStopper, + epoch: epochState, + stopEstimationDMul: 2, + stopEstimationDDiv: 10, + collectBasicIncome: subEpochEventHandler{ + handler: collectHandler.Handle, + durationMul: 3, + durationDiv: 10, + }, + distributeBasicIncome: subEpochEventHandler{ + handler: distributeHandler.Handle, + durationMul: 4, + durationDiv: 10, + }, + } + et := newEpochTimer(args) + err := et.Reset() + require.NoError(t, err, "failed to reset timer") + + et.Tick(100) + require.Equal(t, 0, neh.called, "invalid new epoch handler calls") + require.Equal(t, 0, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 0, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 0, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(101) + require.Equal(t, 0, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 0, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 0, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(102) + require.Equal(t, 0, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 0, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(103) + require.Equal(t, 0, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + + var h uint32 + for h = 104; h < 109; h++ { + et.Tick(h) + require.Equal(t, 0, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + } + + et.Tick(109) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(110) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(111) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 1, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(112) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 2, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 1, distributeHandler.called, "invalid distribute basic income calls") + + et.Tick(113) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 2, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 2, distributeHandler.called, "invalid distribute basic income calls") + + for h = 114; h < 119; h++ { + et.Tick(h) + require.Equal(t, 1, neh.called, "invalid new epoch handler calls") + require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 2, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 2, distributeHandler.called, "invalid distribute basic income calls") + } + et.Tick(120) + require.Equal(t, 2, neh.called, "invalid new epoch handler calls") + require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls") + require.Equal(t, 2, collectHandler.called, "invalid collect basic income calls") + require.Equal(t, 2, distributeHandler.called, "invalid distribute basic income calls") +} + +type testAlphabetState struct { + isAlphabet bool +} + +func (s *testAlphabetState) IsAlphabet() bool { + return s.isAlphabet +} + +type testNewEpochHandler struct { + called int +} + +func (h *testNewEpochHandler) Handle() { + h.called++ +} + +type testContainerEstStopper struct { + called int +} + +func (s *testContainerEstStopper) StopEstimation(_ container.StopEstimationPrm) error { + s.called++ + return nil +} + +type testEpochState struct { + counter uint64 + duration uint64 +} + +func (s *testEpochState) EpochCounter() uint64 { + return s.counter +} +func (s *testEpochState) EpochDuration() uint64 { + return s.duration +} + +type testEventHandler struct { + called int +} + +func (h *testEventHandler) Handle(e event.Event) { + h.called++ +}