mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-11-11 02:35:18 +00:00
170 lines
6.4 KiB
Go
170 lines
6.4 KiB
Go
|
package rcmgr
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/json"
|
||
|
"os"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func withMemoryLimit(l BaseLimit, m int64) BaseLimit {
|
||
|
l2 := l
|
||
|
l2.Memory = m
|
||
|
return l2
|
||
|
}
|
||
|
|
||
|
func TestLimitConfigParserBackwardsCompat(t *testing.T) {
|
||
|
// Tests that we can parse the old limit config format.
|
||
|
in, err := os.Open("limit_config_test.backwards-compat.json")
|
||
|
require.NoError(t, err)
|
||
|
defer in.Close()
|
||
|
|
||
|
defaultScaledLimits := DefaultLimits
|
||
|
defaultScaledLimits.AddServiceLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
defaultScaledLimits.AddProtocolPeerLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
defaults := defaultScaledLimits.AutoScale()
|
||
|
cfg, err := readLimiterConfigFromJSON(in, defaults)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Equal(t, int64(65536), cfg.system.Memory)
|
||
|
require.Equal(t, defaults.system.Streams, cfg.system.Streams)
|
||
|
require.Equal(t, defaults.system.StreamsInbound, cfg.system.StreamsInbound)
|
||
|
require.Equal(t, defaults.system.StreamsOutbound, cfg.system.StreamsOutbound)
|
||
|
require.Equal(t, 16, cfg.system.Conns)
|
||
|
require.Equal(t, 8, cfg.system.ConnsInbound)
|
||
|
require.Equal(t, 16, cfg.system.ConnsOutbound)
|
||
|
require.Equal(t, 16, cfg.system.FD)
|
||
|
|
||
|
require.Equal(t, defaults.transient, cfg.transient)
|
||
|
require.Equal(t, int64(8765), cfg.serviceDefault.Memory)
|
||
|
|
||
|
require.Contains(t, cfg.service, "A")
|
||
|
require.Equal(t, withMemoryLimit(cfg.serviceDefault, 8192), cfg.service["A"])
|
||
|
require.Contains(t, cfg.service, "B")
|
||
|
require.Equal(t, cfg.serviceDefault, cfg.service["B"])
|
||
|
require.Contains(t, cfg.service, "C")
|
||
|
require.Equal(t, defaults.service["C"], cfg.service["C"])
|
||
|
|
||
|
require.Equal(t, int64(4096), cfg.peerDefault.Memory)
|
||
|
peerID, err := peer.Decode("12D3KooWPFH2Bx2tPfw6RLxN8k2wh47GRXgkt9yrAHU37zFwHWzS")
|
||
|
require.NoError(t, err)
|
||
|
require.Contains(t, cfg.peer, peerID)
|
||
|
require.Equal(t, int64(4097), cfg.peer[peerID].Memory)
|
||
|
}
|
||
|
|
||
|
func TestLimitConfigParser(t *testing.T) {
|
||
|
in, err := os.Open("limit_config_test.json")
|
||
|
require.NoError(t, err)
|
||
|
defer in.Close()
|
||
|
|
||
|
defaultScaledLimits := DefaultLimits
|
||
|
defaultScaledLimits.AddServiceLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
defaultScaledLimits.AddProtocolPeerLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
defaults := defaultScaledLimits.AutoScale()
|
||
|
cfg, err := readLimiterConfigFromJSON(in, defaults)
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
require.Equal(t, int64(65536), cfg.system.Memory)
|
||
|
require.Equal(t, defaults.system.Streams, cfg.system.Streams)
|
||
|
require.Equal(t, defaults.system.StreamsInbound, cfg.system.StreamsInbound)
|
||
|
require.Equal(t, defaults.system.StreamsOutbound, cfg.system.StreamsOutbound)
|
||
|
require.Equal(t, 16, cfg.system.Conns)
|
||
|
require.Equal(t, 8, cfg.system.ConnsInbound)
|
||
|
require.Equal(t, 16, cfg.system.ConnsOutbound)
|
||
|
require.Equal(t, 16, cfg.system.FD)
|
||
|
|
||
|
require.Equal(t, defaults.transient, cfg.transient)
|
||
|
require.Equal(t, int64(8765), cfg.serviceDefault.Memory)
|
||
|
|
||
|
require.Contains(t, cfg.service, "A")
|
||
|
require.Equal(t, withMemoryLimit(cfg.serviceDefault, 8192), cfg.service["A"])
|
||
|
require.Contains(t, cfg.service, "B")
|
||
|
require.Equal(t, cfg.serviceDefault, cfg.service["B"])
|
||
|
require.Contains(t, cfg.service, "C")
|
||
|
require.Equal(t, defaults.service["C"], cfg.service["C"])
|
||
|
|
||
|
require.Equal(t, int64(4096), cfg.peerDefault.Memory)
|
||
|
peerID, err := peer.Decode("12D3KooWPFH2Bx2tPfw6RLxN8k2wh47GRXgkt9yrAHU37zFwHWzS")
|
||
|
require.NoError(t, err)
|
||
|
require.Contains(t, cfg.peer, peerID)
|
||
|
require.Equal(t, int64(4097), cfg.peer[peerID].Memory)
|
||
|
|
||
|
// Roundtrip
|
||
|
limitConfig := cfg.ToPartialLimitConfig()
|
||
|
jsonBytes, err := json.Marshal(&limitConfig)
|
||
|
require.NoError(t, err)
|
||
|
cfgAfterRoundTrip, err := readLimiterConfigFromJSON(bytes.NewReader(jsonBytes), defaults)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, limitConfig, cfgAfterRoundTrip.ToPartialLimitConfig())
|
||
|
}
|
||
|
|
||
|
func TestLimitConfigRoundTrip(t *testing.T) {
|
||
|
// Tests that we can roundtrip a PartialLimitConfig to a ConcreteLimitConfig and back.
|
||
|
in, err := os.Open("limit_config_test.json")
|
||
|
require.NoError(t, err)
|
||
|
defer in.Close()
|
||
|
|
||
|
defaults := DefaultLimits
|
||
|
defaults.AddServiceLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
defaults.AddProtocolPeerLimit("C", DefaultLimits.ServiceBaseLimit, BaseLimitIncrease{})
|
||
|
concreteCfg, err := readLimiterConfigFromJSON(in, defaults.AutoScale())
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Roundtrip
|
||
|
limitConfig := concreteCfg.ToPartialLimitConfig()
|
||
|
// Using InfiniteLimits because it's different then the defaults used above.
|
||
|
// If anything was marked "default" in the round trip, it would show up as a
|
||
|
// difference here.
|
||
|
concreteCfgRT := limitConfig.Build(InfiniteLimits)
|
||
|
require.Equal(t, concreteCfg, concreteCfgRT)
|
||
|
}
|
||
|
|
||
|
func TestDefaultsDontChange(t *testing.T) {
|
||
|
concrete := DefaultLimits.Scale(8<<30, 16<<10) // 8GB, 16k fds
|
||
|
jsonBytes, err := json.MarshalIndent(concrete.ToPartialLimitConfig(), "", " ")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Uncomment to update the defaults file
|
||
|
// err = os.WriteFile("limit_config_test_default.json", jsonBytes, 0644)
|
||
|
// require.NoError(t, err)
|
||
|
|
||
|
defaultsFromFile, err := os.ReadFile("limit_config_test_default.json")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// replace crlf with lf because of windows
|
||
|
defaultsFromFile = bytes.ReplaceAll(defaultsFromFile, []byte("\r\n"), []byte("\n"))
|
||
|
jsonBytes = bytes.ReplaceAll(jsonBytes, []byte("\r\n"), []byte("\n"))
|
||
|
|
||
|
require.Equal(t, string(defaultsFromFile), string(jsonBytes))
|
||
|
}
|
||
|
|
||
|
func TestReadmeLimitConfigSerialization(t *testing.T) {
|
||
|
noisyNeighbor, _ := peer.Decode("QmVvtzcZgCkMnSFf2dnrBPXrWuNFWNM9J3MpZQCvWPuVZf")
|
||
|
cfg := PartialLimitConfig{
|
||
|
System: ResourceLimits{
|
||
|
// Allow unlimited outbound streams
|
||
|
StreamsOutbound: Unlimited,
|
||
|
},
|
||
|
Peer: map[peer.ID]ResourceLimits{
|
||
|
noisyNeighbor: {
|
||
|
// No inbound connections from this peer
|
||
|
ConnsInbound: BlockAllLimit,
|
||
|
// But let me open connections to them
|
||
|
Conns: DefaultLimit,
|
||
|
ConnsOutbound: DefaultLimit,
|
||
|
// No inbound streams from this peer
|
||
|
StreamsInbound: BlockAllLimit,
|
||
|
// And let me open unlimited (by me) outbound streams (the peer may have their own limits on me)
|
||
|
StreamsOutbound: Unlimited,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
jsonBytes, err := json.Marshal(&cfg)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, `{"Peer":{"QmVvtzcZgCkMnSFf2dnrBPXrWuNFWNM9J3MpZQCvWPuVZf":{"StreamsInbound":"blockAll","StreamsOutbound":"unlimited","ConnsInbound":"blockAll"}},"System":{"StreamsOutbound":"unlimited"}}`, string(jsonBytes))
|
||
|
}
|