mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-30 18:35:18 +00:00
251 lines
6.4 KiB
Go
251 lines
6.4 KiB
Go
|
package rcmgr
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"math"
|
||
|
"runtime"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestFileDescriptorCounting(t *testing.T) {
|
||
|
if runtime.GOOS == "windows" {
|
||
|
t.Skip("can't read file descriptors on Windows")
|
||
|
}
|
||
|
n := getNumFDs()
|
||
|
require.NotZero(t, n)
|
||
|
require.Less(t, n, int(1e7))
|
||
|
}
|
||
|
|
||
|
func TestScaling(t *testing.T) {
|
||
|
base := BaseLimit{
|
||
|
Streams: 100,
|
||
|
StreamsInbound: 200,
|
||
|
StreamsOutbound: 400,
|
||
|
Conns: 10,
|
||
|
ConnsInbound: 20,
|
||
|
ConnsOutbound: 40,
|
||
|
FD: 1,
|
||
|
Memory: 1 << 20,
|
||
|
}
|
||
|
|
||
|
t.Run("no scaling if no increase is defined", func(t *testing.T) {
|
||
|
cfg := ScalingLimitConfig{ServiceBaseLimit: base}
|
||
|
scaled := cfg.Scale(8<<30, 100)
|
||
|
require.Equal(t, base, scaled.serviceDefault)
|
||
|
})
|
||
|
|
||
|
t.Run("scaling", func(t *testing.T) {
|
||
|
cfg := ScalingLimitConfig{
|
||
|
TransientBaseLimit: base,
|
||
|
TransientLimitIncrease: BaseLimitIncrease{
|
||
|
Streams: 1,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 3,
|
||
|
Conns: 4,
|
||
|
ConnsInbound: 5,
|
||
|
ConnsOutbound: 6,
|
||
|
Memory: 7,
|
||
|
FDFraction: 0.5,
|
||
|
},
|
||
|
}
|
||
|
scaled := cfg.Scale(128<<20+4<<30, 1000)
|
||
|
require.Equal(t, 500, scaled.transient.FD)
|
||
|
require.Equal(t, base.Streams+4, scaled.transient.Streams)
|
||
|
require.Equal(t, base.StreamsInbound+4*2, scaled.transient.StreamsInbound)
|
||
|
require.Equal(t, base.StreamsOutbound+4*3, scaled.transient.StreamsOutbound)
|
||
|
require.Equal(t, base.Conns+4*4, scaled.transient.Conns)
|
||
|
require.Equal(t, base.ConnsInbound+4*5, scaled.transient.ConnsInbound)
|
||
|
require.Equal(t, base.ConnsOutbound+4*6, scaled.transient.ConnsOutbound)
|
||
|
require.Equal(t, base.Memory+4*7, scaled.transient.Memory)
|
||
|
})
|
||
|
|
||
|
t.Run("scaling and using the base amounts", func(t *testing.T) {
|
||
|
cfg := ScalingLimitConfig{
|
||
|
TransientBaseLimit: base,
|
||
|
TransientLimitIncrease: BaseLimitIncrease{
|
||
|
Streams: 1,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 3,
|
||
|
Conns: 4,
|
||
|
ConnsInbound: 5,
|
||
|
ConnsOutbound: 6,
|
||
|
Memory: 7,
|
||
|
FDFraction: 0.01,
|
||
|
},
|
||
|
}
|
||
|
scaled := cfg.Scale(1, 10)
|
||
|
require.Equal(t, 1, scaled.transient.FD)
|
||
|
require.Equal(t, base.Streams, scaled.transient.Streams)
|
||
|
require.Equal(t, base.StreamsInbound, scaled.transient.StreamsInbound)
|
||
|
require.Equal(t, base.StreamsOutbound, scaled.transient.StreamsOutbound)
|
||
|
require.Equal(t, base.Conns, scaled.transient.Conns)
|
||
|
require.Equal(t, base.ConnsInbound, scaled.transient.ConnsInbound)
|
||
|
require.Equal(t, base.ConnsOutbound, scaled.transient.ConnsOutbound)
|
||
|
require.Equal(t, base.Memory, scaled.transient.Memory)
|
||
|
})
|
||
|
|
||
|
t.Run("scaling limits in maps", func(t *testing.T) {
|
||
|
cfg := ScalingLimitConfig{
|
||
|
ServiceLimits: map[string]baseLimitConfig{
|
||
|
"A": {
|
||
|
BaseLimit: BaseLimit{Streams: 10, Memory: 100, FD: 9},
|
||
|
},
|
||
|
"B": {
|
||
|
BaseLimit: BaseLimit{Streams: 20, Memory: 200, FD: 10},
|
||
|
BaseLimitIncrease: BaseLimitIncrease{Streams: 2, Memory: 3, FDFraction: 0.4},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
scaled := cfg.Scale(128<<20+4<<30, 1000)
|
||
|
|
||
|
require.Len(t, scaled.service, 2)
|
||
|
require.Contains(t, scaled.service, "A")
|
||
|
require.Equal(t, 10, scaled.service["A"].Streams)
|
||
|
require.Equal(t, int64(100), scaled.service["A"].Memory)
|
||
|
require.Equal(t, 9, scaled.service["A"].FD)
|
||
|
|
||
|
require.Contains(t, scaled.service, "B")
|
||
|
require.Equal(t, 20+4*2, scaled.service["B"].Streams)
|
||
|
require.Equal(t, int64(200+4*3), scaled.service["B"].Memory)
|
||
|
require.Equal(t, 400, scaled.service["B"].FD)
|
||
|
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestReadmeExample(t *testing.T) {
|
||
|
scalingLimits := ScalingLimitConfig{
|
||
|
SystemBaseLimit: BaseLimit{
|
||
|
ConnsInbound: 64,
|
||
|
ConnsOutbound: 128,
|
||
|
Conns: 128,
|
||
|
StreamsInbound: 512,
|
||
|
StreamsOutbound: 1024,
|
||
|
Streams: 1024,
|
||
|
Memory: 128 << 20,
|
||
|
FD: 256,
|
||
|
},
|
||
|
SystemLimitIncrease: BaseLimitIncrease{
|
||
|
ConnsInbound: 32,
|
||
|
ConnsOutbound: 64,
|
||
|
Conns: 64,
|
||
|
StreamsInbound: 256,
|
||
|
StreamsOutbound: 512,
|
||
|
Streams: 512,
|
||
|
Memory: 256 << 20,
|
||
|
FDFraction: 1,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
limitConf := scalingLimits.Scale(4<<30, 1000)
|
||
|
|
||
|
require.Equal(t, 384, limitConf.system.Conns)
|
||
|
require.Equal(t, 1000, limitConf.system.FD)
|
||
|
}
|
||
|
|
||
|
func TestJSONMarshalling(t *testing.T) {
|
||
|
bl := ResourceLimits{
|
||
|
Streams: DefaultLimit,
|
||
|
StreamsInbound: 10,
|
||
|
StreamsOutbound: BlockAllLimit,
|
||
|
Conns: 10,
|
||
|
// ConnsInbound: DefaultLimit,
|
||
|
ConnsOutbound: Unlimited,
|
||
|
Memory: Unlimited64,
|
||
|
}
|
||
|
|
||
|
jsonEncoded, err := json.Marshal(bl)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, string(jsonEncoded), `{"StreamsInbound":10,"StreamsOutbound":"blockAll","Conns":10,"ConnsOutbound":"unlimited","Memory":"unlimited"}`)
|
||
|
|
||
|
// Roundtrip
|
||
|
var blDecoded ResourceLimits
|
||
|
err = json.Unmarshal(jsonEncoded, &blDecoded)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Equal(t, bl, blDecoded)
|
||
|
}
|
||
|
|
||
|
func TestJSONRoundTripInt64(t *testing.T) {
|
||
|
bl := ResourceLimits{
|
||
|
Memory: math.MaxInt64,
|
||
|
}
|
||
|
|
||
|
jsonEncoded, err := json.Marshal(bl)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Equal(t, string(jsonEncoded), `{"Memory":"9223372036854775807"}`)
|
||
|
|
||
|
// Roundtrip
|
||
|
var blDecoded ResourceLimits
|
||
|
err = json.Unmarshal(jsonEncoded, &blDecoded)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Equal(t, bl, blDecoded)
|
||
|
}
|
||
|
|
||
|
func TestRoundTripFromConcreteAndBack(t *testing.T) {
|
||
|
l := PartialLimitConfig{
|
||
|
System: ResourceLimits{
|
||
|
Conns: 1234,
|
||
|
Memory: 54321,
|
||
|
},
|
||
|
|
||
|
ServiceDefault: ResourceLimits{
|
||
|
Conns: 2,
|
||
|
},
|
||
|
|
||
|
Service: map[string]ResourceLimits{
|
||
|
"foo": {
|
||
|
Conns: 3,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
concrete := l.Build(InfiniteLimits)
|
||
|
|
||
|
// Roundtrip
|
||
|
fromConcrete := concrete.ToPartialLimitConfig().Build(InfiniteLimits)
|
||
|
require.Equal(t, concrete, fromConcrete)
|
||
|
}
|
||
|
|
||
|
func TestSerializeJSON(t *testing.T) {
|
||
|
bl := BaseLimit{
|
||
|
Streams: 10,
|
||
|
}
|
||
|
|
||
|
out, err := json.Marshal(bl)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, "{\"Streams\":10}", string(out))
|
||
|
|
||
|
bli := BaseLimitIncrease{
|
||
|
Streams: 10,
|
||
|
}
|
||
|
|
||
|
out, err = json.Marshal(bli)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, "{\"Streams\":10}", string(out))
|
||
|
}
|
||
|
|
||
|
func TestWhatIsZeroInResourceLimits(t *testing.T) {
|
||
|
l := ResourceLimits{
|
||
|
Streams: BlockAllLimit,
|
||
|
Memory: BlockAllLimit64,
|
||
|
}
|
||
|
|
||
|
out, err := json.Marshal(l)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, `{"Streams":"blockAll","Memory":"blockAll"}`, string(out))
|
||
|
|
||
|
l2 := ResourceLimits{}
|
||
|
err = json.Unmarshal([]byte(`{"Streams":0,"Memory":0}`), &l2)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, l, l2)
|
||
|
|
||
|
l3 := ResourceLimits{}
|
||
|
err = json.Unmarshal([]byte(`{"Streams":0,"Memory":"0"}`), &l3)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, l, l3)
|
||
|
}
|