2021-04-15 13:50:34 +00:00
|
|
|
package timer_test
|
2021-01-21 16:32:41 +00:00
|
|
|
|
|
|
|
import (
|
2024-11-20 07:53:33 +00:00
|
|
|
"errors"
|
2021-01-21 16:32:41 +00:00
|
|
|
"testing"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/timer"
|
2021-01-21 16:32:41 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2021-04-15 13:50:34 +00:00
|
|
|
func tickN(t *timer.BlockTimer, n uint32) {
|
2024-10-30 11:42:09 +00:00
|
|
|
for range n {
|
2022-03-30 10:16:41 +00:00
|
|
|
t.Tick(0)
|
2021-01-21 16:32:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// This test emulates inner ring handling of a new epoch and a new block.
|
2022-04-04 07:07:33 +00:00
|
|
|
// "resetting" consists of ticking the current height as well and invoking `Reset`.
|
|
|
|
func TestIRBlockTimer_Reset(t *testing.T) {
|
|
|
|
var baseCounter [2]int
|
|
|
|
blockDur := uint32(3)
|
|
|
|
|
|
|
|
bt1 := timer.NewBlockTimer(
|
|
|
|
func() (uint32, error) { return blockDur, nil },
|
|
|
|
func() { baseCounter[0]++ })
|
|
|
|
bt2 := timer.NewBlockTimer(
|
|
|
|
func() (uint32, error) { return blockDur, nil },
|
|
|
|
func() { baseCounter[1]++ })
|
|
|
|
|
|
|
|
require.NoError(t, bt1.Reset())
|
|
|
|
require.NoError(t, bt2.Reset())
|
|
|
|
|
|
|
|
run := func(bt *timer.BlockTimer, direct bool) {
|
|
|
|
if direct {
|
|
|
|
bt.Tick(1)
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
bt.Tick(1)
|
|
|
|
} else {
|
|
|
|
bt.Tick(1)
|
|
|
|
bt.Tick(1)
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
}
|
|
|
|
bt.Tick(2)
|
|
|
|
bt.Tick(3)
|
|
|
|
}
|
|
|
|
|
|
|
|
run(bt1, true)
|
|
|
|
run(bt2, false)
|
|
|
|
require.Equal(t, baseCounter[0], baseCounter[1])
|
|
|
|
}
|
|
|
|
|
2024-11-20 07:53:33 +00:00
|
|
|
func TestBlockTimer_ResetChangeDuration(t *testing.T) {
|
|
|
|
var dur uint32 = 2
|
|
|
|
var err error
|
|
|
|
var counter int
|
|
|
|
|
|
|
|
bt := timer.NewBlockTimer(
|
|
|
|
func() (uint32, error) { return dur, err },
|
|
|
|
func() { counter++ })
|
|
|
|
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
|
|
|
|
tickN(bt, 2)
|
|
|
|
require.Equal(t, 1, counter)
|
|
|
|
|
|
|
|
t.Run("return error", func(t *testing.T) {
|
|
|
|
dur = 5
|
|
|
|
err = errors.New("my awesome error")
|
|
|
|
require.ErrorIs(t, bt.Reset(), err)
|
|
|
|
|
|
|
|
tickN(bt, 2)
|
|
|
|
require.Equal(t, 2, counter)
|
|
|
|
})
|
|
|
|
t.Run("change duration", func(t *testing.T) {
|
|
|
|
dur = 5
|
|
|
|
err = nil
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
|
|
|
|
tickN(bt, 5)
|
|
|
|
require.Equal(t, 3, counter)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-01-21 16:32:41 +00:00
|
|
|
func TestBlockTimer(t *testing.T) {
|
|
|
|
blockDur := uint32(10)
|
|
|
|
baseCallCounter := uint32(0)
|
|
|
|
|
2021-04-15 13:50:34 +00:00
|
|
|
bt := timer.NewBlockTimer(timer.StaticBlockMeter(blockDur), func() {
|
2021-01-21 16:32:41 +00:00
|
|
|
baseCallCounter++
|
|
|
|
})
|
|
|
|
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
|
|
|
|
intervalNum := uint32(7)
|
|
|
|
|
|
|
|
tickN(bt, intervalNum*blockDur)
|
|
|
|
|
|
|
|
require.Equal(t, intervalNum, uint32(baseCallCounter))
|
2021-01-28 16:10:21 +00:00
|
|
|
}
|
2021-07-21 14:28:59 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
})
|
|
|
|
}
|
2022-03-30 10:16:41 +00:00
|
|
|
|
|
|
|
func TestBlockTimer_TickSameHeight(t *testing.T) {
|
2024-11-20 07:43:38 +00:00
|
|
|
var baseCounter int
|
2022-03-30 10:16:41 +00:00
|
|
|
|
|
|
|
blockDur := uint32(2)
|
|
|
|
bt := timer.NewBlockTimer(
|
|
|
|
func() (uint32, error) { return blockDur, nil },
|
|
|
|
func() { baseCounter++ })
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
|
2024-11-20 07:43:38 +00:00
|
|
|
check := func(t *testing.T, h uint32, base int) {
|
2024-08-30 16:20:55 +00:00
|
|
|
for range 2 * int(blockDur) {
|
2022-03-30 10:16:41 +00:00
|
|
|
bt.Tick(h)
|
|
|
|
require.Equal(t, base, baseCounter)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-20 07:43:38 +00:00
|
|
|
check(t, 1, 0)
|
|
|
|
check(t, 2, 1)
|
|
|
|
check(t, 3, 1)
|
|
|
|
check(t, 4, 2)
|
2022-03-30 10:16:41 +00:00
|
|
|
|
|
|
|
t.Run("works the same way after `Reset()`", func(t *testing.T) {
|
|
|
|
t.Run("same block duration", func(t *testing.T) {
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
baseCounter = 0
|
|
|
|
|
2024-11-20 07:43:38 +00:00
|
|
|
check(t, 1, 0)
|
|
|
|
check(t, 2, 1)
|
|
|
|
check(t, 3, 1)
|
|
|
|
check(t, 4, 2)
|
2022-03-30 10:16:41 +00:00
|
|
|
})
|
|
|
|
t.Run("different block duration", func(t *testing.T) {
|
|
|
|
blockDur = 3
|
|
|
|
|
|
|
|
require.NoError(t, bt.Reset())
|
|
|
|
baseCounter = 0
|
2024-11-20 07:43:38 +00:00
|
|
|
|
|
|
|
check(t, 1, 0)
|
|
|
|
check(t, 2, 0)
|
|
|
|
check(t, 3, 1)
|
|
|
|
check(t, 4, 1)
|
|
|
|
check(t, 5, 1)
|
|
|
|
check(t, 6, 2)
|
2022-03-30 10:16:41 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|