package timer_test import ( "testing" "github.com/nspcc-dev/neofs-node/pkg/morph/timer" "github.com/stretchr/testify/require" ) func tickN(t *timer.BlockTimer, n uint32) { for i := uint32(0); i < n; i++ { t.Tick() } } func TestBlockTimer(t *testing.T) { blockDur := uint32(10) baseCallCounter := uint32(0) bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) require.NoError(t, bt.Reset()) intervalNum := uint32(7) tickN(bt, intervalNum*blockDur) require.Equal(t, intervalNum, uint32(baseCallCounter)) // add half-interval handler halfCallCounter := uint32(0) bt.OnDelta(1, 2, func() { halfCallCounter++ }) // add double interval handler doubleCallCounter := uint32(0) bt.OnDelta(2, 1, func() { doubleCallCounter++ }) require.NoError(t, bt.Reset()) baseCallCounter = 0 intervalNum = 20 tickN(bt, intervalNum*blockDur) require.Equal(t, intervalNum, uint32(halfCallCounter)) require.Equal(t, intervalNum, uint32(baseCallCounter)) require.Equal(t, intervalNum/2, uint32(doubleCallCounter)) } func TestDeltaPulse(t *testing.T) { blockDur := uint32(9) baseCallCounter := uint32(0) bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) deltaCallCounter := uint32(0) div := uint32(3) bt.OnDelta(1, div, func() { deltaCallCounter++ }, timer.WithPulse()) require.NoError(t, bt.Reset()) intervalNum := uint32(7) tickN(bt, intervalNum*blockDur) require.Equal(t, intervalNum, uint32(baseCallCounter)) require.Equal(t, intervalNum*div, uint32(deltaCallCounter)) } func TestDeltaReset(t *testing.T) { blockDur := uint32(6) baseCallCounter := 0 bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) detlaCallCounter := 0 bt.OnDelta(1, 3, func() { detlaCallCounter++ }) require.NoError(t, bt.Reset()) tickN(bt, 6) require.Equal(t, 1, baseCallCounter) require.Equal(t, 1, detlaCallCounter) require.NoError(t, bt.Reset()) tickN(bt, 3) require.Equal(t, 2, detlaCallCounter) } func TestNewOneTickTimer(t *testing.T) { blockDur := uint32(1) baseCallCounter := 0 bt := timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) require.NoError(t, bt.Reset()) tickN(bt, 10) require.Equal(t, 1, baseCallCounter) // happens once no matter what t.Run("zero duration", func(t *testing.T) { blockDur = uint32(0) baseCallCounter = 0 bt = timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) require.NoError(t, bt.Reset()) tickN(bt, 10) require.Equal(t, 1, baseCallCounter) }) t.Run("delta without pulse", func(t *testing.T) { blockDur = uint32(10) baseCallCounter = 0 bt = timer.NewOneTickTimer(timer.StaticBlockMeter(blockDur), func() { baseCallCounter++ }) detlaCallCounter := 0 bt.OnDelta(1, 10, func() { detlaCallCounter++ }) require.NoError(t, bt.Reset()) tickN(bt, 10) require.Equal(t, 1, baseCallCounter) require.Equal(t, 1, detlaCallCounter) tickN(bt, 10) // 10 more ticks must not affect counters require.Equal(t, 1, baseCallCounter) require.Equal(t, 1, detlaCallCounter) }) }