mirror of
https://github.com/luxfi/p2p.git
synced 2026-10-30 15:22:55 +00:00
121 lines
3.4 KiB
Go
121 lines
3.4 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package throttling
|
|
|
|
import (
|
|
"context"
|
|
"github.com/luxfi/metric"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/luxfi/ids"
|
|
)
|
|
|
|
// Test inboundMsgBufferThrottler
|
|
func TestMsgBufferThrottler(t *testing.T) {
|
|
require := require.New(t)
|
|
throttler, err := newInboundMsgBufferThrottler(metric.NewNoOp().Registry(), 3)
|
|
require.NoError(err)
|
|
|
|
nodeID1, nodeID2 := ids.GenerateTestNodeID(), ids.GenerateTestNodeID()
|
|
// Acquire shouldn't block for first 3
|
|
throttler.Acquire(context.Background(), nodeID1)
|
|
throttler.Acquire(context.Background(), nodeID1)
|
|
throttler.Acquire(context.Background(), nodeID1)
|
|
require.Len(throttler.nodeToNumProcessingMsgs, 1)
|
|
require.Equal(uint64(3), throttler.nodeToNumProcessingMsgs[nodeID1])
|
|
|
|
// Acquire shouldn't block for other node
|
|
throttler.Acquire(context.Background(), nodeID2)
|
|
throttler.Acquire(context.Background(), nodeID2)
|
|
throttler.Acquire(context.Background(), nodeID2)
|
|
require.Len(throttler.nodeToNumProcessingMsgs, 2)
|
|
require.Equal(uint64(3), throttler.nodeToNumProcessingMsgs[nodeID1])
|
|
require.Equal(uint64(3), throttler.nodeToNumProcessingMsgs[nodeID2])
|
|
|
|
// Acquire should block for 4th acquire
|
|
done := make(chan struct{})
|
|
go func() {
|
|
throttler.Acquire(context.Background(), nodeID1)
|
|
done <- struct{}{}
|
|
}()
|
|
select {
|
|
case <-done:
|
|
require.FailNow("should block on acquiring")
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
|
|
throttler.release(nodeID1)
|
|
// fourth acquire should be unblocked
|
|
<-done
|
|
require.Len(throttler.nodeToNumProcessingMsgs, 2)
|
|
require.Equal(uint64(3), throttler.nodeToNumProcessingMsgs[nodeID2])
|
|
|
|
// Releasing from other node should have no effect
|
|
throttler.release(nodeID2)
|
|
throttler.release(nodeID2)
|
|
throttler.release(nodeID2)
|
|
|
|
// Release remaining 3 acquires
|
|
throttler.release(nodeID1)
|
|
throttler.release(nodeID1)
|
|
throttler.release(nodeID1)
|
|
require.Empty(throttler.nodeToNumProcessingMsgs)
|
|
}
|
|
|
|
// Test inboundMsgBufferThrottler when an acquire is cancelled
|
|
func TestMsgBufferThrottlerContextCancelled(t *testing.T) {
|
|
require := require.New(t)
|
|
throttler, err := newInboundMsgBufferThrottler(metric.NewNoOp().Registry(), 3)
|
|
require.NoError(err)
|
|
|
|
vdr1Context, vdr1ContextCancelFunc := context.WithCancel(context.Background())
|
|
nodeID1 := ids.GenerateTestNodeID()
|
|
// Acquire shouldn't block for first 3
|
|
throttler.Acquire(vdr1Context, nodeID1)
|
|
throttler.Acquire(vdr1Context, nodeID1)
|
|
throttler.Acquire(vdr1Context, nodeID1)
|
|
require.Len(throttler.nodeToNumProcessingMsgs, 1)
|
|
require.Equal(uint64(3), throttler.nodeToNumProcessingMsgs[nodeID1])
|
|
|
|
// Acquire should block for 4th acquire
|
|
done := make(chan struct{})
|
|
go func() {
|
|
throttler.Acquire(vdr1Context, nodeID1)
|
|
done <- struct{}{}
|
|
}()
|
|
select {
|
|
case <-done:
|
|
require.FailNow("should block on acquiring")
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
|
|
// Acquire should block for 5th acquire
|
|
done2 := make(chan struct{})
|
|
go func() {
|
|
throttler.Acquire(vdr1Context, nodeID1)
|
|
done2 <- struct{}{}
|
|
}()
|
|
select {
|
|
case <-done2:
|
|
require.FailNow("should block on acquiring")
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
|
|
// Unblock fifth acquire
|
|
vdr1ContextCancelFunc()
|
|
select {
|
|
case <-done2:
|
|
case <-time.After(50 * time.Millisecond):
|
|
require.FailNow("cancelling context should unblock Acquire")
|
|
}
|
|
select {
|
|
case <-done:
|
|
case <-time.After(50 * time.Millisecond):
|
|
require.FailNow("should be blocked")
|
|
}
|
|
}
|