mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-27 00:55:17 +00:00
1275 lines
44 KiB
Go
1275 lines
44 KiB
Go
|
package rcmgr
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"testing"
|
||
|
"testing/quick"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p/core/network"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func checkResources(t *testing.T, rc *resources, st network.ScopeStat) {
|
||
|
t.Helper()
|
||
|
|
||
|
if rc.nconnsIn != st.NumConnsInbound {
|
||
|
t.Fatalf("expected %d inbound conns, got %d", st.NumConnsInbound, rc.nconnsIn)
|
||
|
}
|
||
|
if rc.nconnsOut != st.NumConnsOutbound {
|
||
|
t.Fatalf("expected %d outbound conns, got %d", st.NumConnsOutbound, rc.nconnsOut)
|
||
|
}
|
||
|
if rc.nstreamsIn != st.NumStreamsInbound {
|
||
|
t.Fatalf("expected %d inbound streams, got %d", st.NumStreamsInbound, rc.nstreamsIn)
|
||
|
}
|
||
|
if rc.nstreamsOut != st.NumStreamsOutbound {
|
||
|
t.Fatalf("expected %d outbound streams, got %d", st.NumStreamsOutbound, rc.nstreamsOut)
|
||
|
}
|
||
|
if rc.nfd != st.NumFD {
|
||
|
t.Fatalf("expected %d file descriptors, got %d", st.NumFD, rc.nfd)
|
||
|
}
|
||
|
if rc.memory != st.Memory {
|
||
|
t.Fatalf("expected %d reserved bytes of memory, got %d", st.Memory, rc.memory)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCheckMemory(t *testing.T) {
|
||
|
t.Run("overflows", func(t *testing.T) {
|
||
|
rc := resources{limit: &BaseLimit{
|
||
|
Memory: math.MaxInt64 - 1,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
}}
|
||
|
rc.memory = math.MaxInt64 - 1
|
||
|
require.Error(t, rc.checkMemory(2, network.ReservationPriorityAlways))
|
||
|
|
||
|
rc.memory = 1024
|
||
|
require.NoError(t, rc.checkMemory(1, network.ReservationPriorityAlways))
|
||
|
})
|
||
|
|
||
|
t.Run("negative mem", func(t *testing.T) {
|
||
|
rc := resources{limit: &BaseLimit{
|
||
|
Memory: math.MaxInt64,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
}}
|
||
|
rc.memory = math.MaxInt64
|
||
|
|
||
|
require.Error(t, rc.checkMemory(-1, network.ReservationPriorityAlways))
|
||
|
})
|
||
|
|
||
|
f := func(limit uint64, res uint64, currentMem uint64, priShift uint8) bool {
|
||
|
limit = (limit % math.MaxInt64) + 1
|
||
|
if limit < 1024 {
|
||
|
// We set the min to 1KiB
|
||
|
limit = 1024
|
||
|
}
|
||
|
currentMem = (currentMem % limit) // We can't have reserved more than our limit
|
||
|
res = (res >> 14) // We won't resonably ever have a reservation > 2^50
|
||
|
rc := resources{limit: &BaseLimit{
|
||
|
Memory: int64(limit),
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
}}
|
||
|
rc.memory = int64(currentMem)
|
||
|
|
||
|
priShift = (priShift % 9)
|
||
|
// Check different priorties at 2^0, 2^1,...2^8. This lets our math be correct in the check below (and avoid overflows).
|
||
|
pri := uint8((1 << priShift) - 1)
|
||
|
|
||
|
err := rc.checkMemory(int64(res), pri)
|
||
|
if limit == math.MaxInt64 && err == nil {
|
||
|
// Special case logic
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
return (err != nil) == (uint64(res)+uint64(rc.memory) > (uint64(limit) >> uint64(8-priShift)))
|
||
|
}
|
||
|
|
||
|
require.NoError(t, quick.Check(f, nil))
|
||
|
}
|
||
|
|
||
|
func TestResources(t *testing.T) {
|
||
|
rc := resources{limit: &BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
}}
|
||
|
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
// test checkMemory
|
||
|
if err := rc.checkMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(2048, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(3072, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(4096, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(8192, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(1024, network.ReservationPriorityLow); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(2048, network.ReservationPriorityLow); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(2048, network.ReservationPriorityMedium); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(3072, network.ReservationPriorityMedium); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(3072, network.ReservationPriorityHigh); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := rc.checkMemory(3584, network.ReservationPriorityHigh); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
|
||
|
// test reserveMemory
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := rc.reserveMemory(512, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3584})
|
||
|
|
||
|
if err := rc.reserveMemory(4096, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected memory reservation to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3584})
|
||
|
|
||
|
rc.releaseMemory(2560)
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := rc.reserveMemory(2048, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
rc.releaseMemory(3072)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityLow); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityLow); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityMedium); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityMedium); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := rc.reserveMemory(1024, network.ReservationPriorityHigh); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := rc.reserveMemory(512, network.ReservationPriorityHigh); err == nil {
|
||
|
t.Fatal("expected memory check to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := rc.reserveMemory(512, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{Memory: 3584})
|
||
|
|
||
|
rc.releaseMemory(3584)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
// test addStream
|
||
|
if err := rc.addStream(network.DirInbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
if err := rc.addStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected addStream to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
if err := rc.addStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected addStream to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
rc.removeStream(network.DirInbound)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
if err := rc.addStream(network.DirOutbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
if err := rc.addStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected addStream to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
if err := rc.addStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected addStream to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
rc.removeStream(network.DirOutbound)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
// test addConn
|
||
|
if err := rc.addConn(network.DirInbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
if err := rc.addConn(network.DirInbound, false); err == nil {
|
||
|
t.Fatal("expected addConn to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
rc.removeConn(network.DirInbound, false)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
if err := rc.addConn(network.DirOutbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
if err := rc.addConn(network.DirOutbound, false); err == nil {
|
||
|
t.Fatal("expected addConn to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
rc.removeConn(network.DirOutbound, false)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
|
||
|
if err := rc.addConn(network.DirInbound, true); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
if err := rc.addConn(network.DirOutbound, true); err == nil {
|
||
|
t.Fatal("expected addConn to fail")
|
||
|
}
|
||
|
checkResources(t, &rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
rc.removeConn(network.DirInbound, true)
|
||
|
checkResources(t, &rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeSimple(t *testing.T) {
|
||
|
s := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
s.IncRef()
|
||
|
if s.refCnt != 1 {
|
||
|
t.Fatal("expected refcnt of 1")
|
||
|
}
|
||
|
s.DecRef()
|
||
|
if s.refCnt != 0 {
|
||
|
t.Fatal("expected refcnt of 0")
|
||
|
}
|
||
|
|
||
|
testResourceScopeBasic(t, s)
|
||
|
}
|
||
|
|
||
|
func testResourceScopeBasic(t *testing.T, s *resourceScope) {
|
||
|
if err := s.ReserveMemory(2048, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := s.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := s.ReserveMemory(512, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 3584})
|
||
|
|
||
|
if err := s.ReserveMemory(512, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
if err := s.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
s.ReleaseMemory(4096)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s.AddStream(network.DirInbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
if err := s.AddStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
if err := s.AddStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
s.RemoveStream(network.DirInbound)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s.AddStream(network.DirOutbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
if err := s.AddStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
if err := s.AddStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
s.RemoveStream(network.DirOutbound)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s.AddConn(network.DirInbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
if err := s.AddConn(network.DirInbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
s.RemoveConn(network.DirInbound, false)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s.AddConn(network.DirOutbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
if err := s.AddConn(network.DirOutbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
s.RemoveConn(network.DirOutbound, false)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s.AddConn(network.DirInbound, true); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
if err := s.AddConn(network.DirOutbound, true); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
s.RemoveConn(network.DirInbound, true)
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeTxnBasic(t *testing.T) {
|
||
|
s := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
txn, err := s.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
testResourceScopeBasic(t, txn.(*resourceScope))
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
|
||
|
// check constraint propagation
|
||
|
if err := txn.ReserveMemory(4096, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn.(*resourceScope).rc, network.ScopeStat{Memory: 4096})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
txn.Done()
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
txn.Done() // idempotent
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeTxnZombie(t *testing.T) {
|
||
|
s := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
txn1, err := s.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn2, err := txn1.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := txn2.ReserveMemory(4096, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn2.(*resourceScope).rc, network.ScopeStat{Memory: 4096})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 4096})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
txn1.Done()
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
if err := txn2.ReserveMemory(4096, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
|
||
|
txn2.Done()
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeTxnTree(t *testing.T) {
|
||
|
s := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 1,
|
||
|
StreamsOutbound: 1,
|
||
|
Streams: 1,
|
||
|
ConnsInbound: 1,
|
||
|
ConnsOutbound: 1,
|
||
|
Conns: 1,
|
||
|
FD: 1,
|
||
|
},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
txn1, err := s.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn2, err := txn1.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn3, err := txn1.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn4, err := txn2.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn5, err := txn2.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := txn3.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn3.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := txn4.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn4.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn3.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn2.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := txn5.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn5.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn4.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn3.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn2.(*resourceScope).rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 3072})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := txn1.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &txn5.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn4.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn3.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn2.(*resourceScope).rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 4096})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
if err := txn5.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
if err := txn4.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
if err := txn3.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
if err := txn2.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
checkResources(t, &txn5.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn4.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn3.(*resourceScope).rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &txn2.(*resourceScope).rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &txn1.(*resourceScope).rc, network.ScopeStat{Memory: 4096})
|
||
|
checkResources(t, &s.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
txn1.Done()
|
||
|
checkResources(t, &s.rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeDAG(t *testing.T) {
|
||
|
// A small DAG of scopes
|
||
|
// s1
|
||
|
// +---> s2
|
||
|
// +------------> s5
|
||
|
// +----
|
||
|
// +---> s3 +. \
|
||
|
// | \ -----+-> s4 (a diamond!)
|
||
|
// | ------/
|
||
|
// \
|
||
|
// ------> s6
|
||
|
s1 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 4096,
|
||
|
StreamsInbound: 4,
|
||
|
StreamsOutbound: 4,
|
||
|
Streams: 4,
|
||
|
ConnsInbound: 4,
|
||
|
ConnsOutbound: 4,
|
||
|
Conns: 4,
|
||
|
FD: 4,
|
||
|
},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
s2 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 2048,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 2,
|
||
|
Streams: 2,
|
||
|
ConnsInbound: 2,
|
||
|
ConnsOutbound: 2,
|
||
|
Conns: 2,
|
||
|
FD: 2,
|
||
|
},
|
||
|
[]*resourceScope{s1}, "test", nil, nil,
|
||
|
)
|
||
|
s3 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 2048,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 2,
|
||
|
Streams: 2,
|
||
|
ConnsInbound: 2,
|
||
|
ConnsOutbound: 2,
|
||
|
Conns: 2,
|
||
|
FD: 2,
|
||
|
},
|
||
|
[]*resourceScope{s1}, "test", nil, nil,
|
||
|
)
|
||
|
s4 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 2048,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 2,
|
||
|
Streams: 2,
|
||
|
ConnsInbound: 2,
|
||
|
ConnsOutbound: 2,
|
||
|
Conns: 2,
|
||
|
FD: 2,
|
||
|
},
|
||
|
[]*resourceScope{s2, s3, s1}, "test", nil, nil,
|
||
|
)
|
||
|
s5 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 2048,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 2,
|
||
|
Streams: 2,
|
||
|
ConnsInbound: 2,
|
||
|
ConnsOutbound: 2,
|
||
|
Conns: 2,
|
||
|
FD: 2,
|
||
|
},
|
||
|
[]*resourceScope{s2, s1}, "test", nil, nil,
|
||
|
)
|
||
|
s6 := newResourceScope(
|
||
|
&BaseLimit{
|
||
|
Memory: 2048,
|
||
|
StreamsInbound: 2,
|
||
|
StreamsOutbound: 2,
|
||
|
Streams: 2,
|
||
|
ConnsInbound: 2,
|
||
|
ConnsOutbound: 2,
|
||
|
Conns: 2,
|
||
|
FD: 2,
|
||
|
},
|
||
|
[]*resourceScope{s3, s1}, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
if err := s4.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := s5.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := s6.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := s4.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expcted ReserveMemory to fail")
|
||
|
}
|
||
|
if err := s5.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expcted ReserveMemory to fail")
|
||
|
}
|
||
|
if err := s6.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expcted ReserveMemory to fail")
|
||
|
}
|
||
|
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
s4.ReleaseMemory(1024)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
s5.ReleaseMemory(1024)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
s6.ReleaseMemory(1024)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s4.AddStream(network.DirInbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
if err := s5.AddStream(network.DirInbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
|
||
|
if err := s6.AddStream(network.DirInbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 3})
|
||
|
|
||
|
if err := s4.AddStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
if err := s5.AddStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
if err := s6.AddStream(network.DirInbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 3})
|
||
|
|
||
|
s4.RemoveStream(network.DirInbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 2})
|
||
|
|
||
|
s5.RemoveStream(network.DirInbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsInbound: 1})
|
||
|
|
||
|
s6.RemoveStream(network.DirInbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s4.AddStream(network.DirOutbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
if err := s5.AddStream(network.DirOutbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
|
||
|
if err := s6.AddStream(network.DirOutbound); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 3})
|
||
|
|
||
|
if err := s4.AddStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
if err := s5.AddStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
if err := s6.AddStream(network.DirOutbound); err == nil {
|
||
|
t.Fatal("expected AddStream to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 3})
|
||
|
|
||
|
s4.RemoveStream(network.DirOutbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 2})
|
||
|
|
||
|
s5.RemoveStream(network.DirOutbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumStreamsOutbound: 1})
|
||
|
|
||
|
s6.RemoveStream(network.DirOutbound)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s4.AddConn(network.DirInbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
if err := s5.AddConn(network.DirInbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
|
||
|
if err := s6.AddConn(network.DirInbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 3})
|
||
|
|
||
|
if err := s4.AddConn(network.DirInbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s5.AddConn(network.DirInbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s6.AddConn(network.DirInbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 3})
|
||
|
|
||
|
s4.RemoveConn(network.DirInbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 2})
|
||
|
|
||
|
s5.RemoveConn(network.DirInbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 1})
|
||
|
|
||
|
s6.RemoveConn(network.DirInbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s4.AddConn(network.DirOutbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
if err := s5.AddConn(network.DirOutbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
|
||
|
if err := s6.AddConn(network.DirOutbound, false); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 3})
|
||
|
|
||
|
if err := s4.AddConn(network.DirOutbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s5.AddConn(network.DirOutbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s6.AddConn(network.DirOutbound, false); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 3})
|
||
|
|
||
|
s4.RemoveConn(network.DirOutbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 2})
|
||
|
|
||
|
s5.RemoveConn(network.DirOutbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsOutbound: 1})
|
||
|
|
||
|
s6.RemoveConn(network.DirOutbound, false)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
|
||
|
if err := s4.AddConn(network.DirInbound, true); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
if err := s5.AddConn(network.DirInbound, true); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
|
||
|
if err := s6.AddConn(network.DirInbound, true); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 3, NumFD: 3})
|
||
|
|
||
|
if err := s4.AddConn(network.DirOutbound, true); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s5.AddConn(network.DirOutbound, true); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
if err := s6.AddConn(network.DirOutbound, true); err == nil {
|
||
|
t.Fatal("expected AddConn to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 3, NumFD: 3})
|
||
|
|
||
|
s4.RemoveConn(network.DirInbound, true)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 2, NumFD: 2})
|
||
|
|
||
|
s5.RemoveConn(network.DirInbound, true)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{NumConnsInbound: 1, NumFD: 1})
|
||
|
|
||
|
s6.RemoveConn(network.DirInbound, true)
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
}
|
||
|
|
||
|
func TestResourceScopeDAGTxn(t *testing.T) {
|
||
|
// A small DAG of scopes
|
||
|
// s1
|
||
|
// +---> s2
|
||
|
// +------------> s5
|
||
|
// +----
|
||
|
// +---> s3 +. \
|
||
|
// | \ -----+-> s4 (a diamond!)
|
||
|
// | ------/
|
||
|
// \
|
||
|
// ------> s6
|
||
|
s1 := newResourceScope(
|
||
|
&BaseLimit{Memory: 8192},
|
||
|
nil, "test", nil, nil,
|
||
|
)
|
||
|
s2 := newResourceScope(
|
||
|
&BaseLimit{Memory: 4096 + 2048},
|
||
|
[]*resourceScope{s1}, "test", nil, nil,
|
||
|
)
|
||
|
s3 := newResourceScope(
|
||
|
&BaseLimit{Memory: 4096 + 2048},
|
||
|
[]*resourceScope{s1}, "test", nil, nil,
|
||
|
)
|
||
|
s4 := newResourceScope(
|
||
|
&BaseLimit{Memory: 4096 + 1024},
|
||
|
[]*resourceScope{s2, s3, s1}, "test", nil, nil,
|
||
|
)
|
||
|
s5 := newResourceScope(
|
||
|
&BaseLimit{Memory: 4096 + 1024},
|
||
|
[]*resourceScope{s2, s1}, "test", nil, nil,
|
||
|
)
|
||
|
s6 := newResourceScope(
|
||
|
&BaseLimit{Memory: 4096 + 1024},
|
||
|
[]*resourceScope{s3, s1}, "test", nil, nil,
|
||
|
)
|
||
|
|
||
|
txn4, err := s4.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn5, err := s5.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
txn6, err := s6.BeginSpan()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if err := txn4.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 1024})
|
||
|
|
||
|
if err := txn5.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := txn6.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 3072})
|
||
|
|
||
|
if err := txn4.ReserveMemory(4096, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024 + 4096})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048 + 4096})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048 + 4096})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 3072 + 4096})
|
||
|
|
||
|
if err := txn4.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
if err := txn5.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
if err := txn6.ReserveMemory(1024, network.ReservationPriorityAlways); err == nil {
|
||
|
t.Fatal("expected ReserveMemory to fail")
|
||
|
}
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{Memory: 1024 + 4096})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048 + 4096})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048 + 4096})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 3072 + 4096})
|
||
|
|
||
|
txn4.Done()
|
||
|
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 1024})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 2048})
|
||
|
|
||
|
if err := txn5.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if err := txn6.ReserveMemory(1024, network.ReservationPriorityAlways); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{Memory: 2048})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{Memory: 4096})
|
||
|
|
||
|
txn5.Done()
|
||
|
txn6.Done()
|
||
|
|
||
|
checkResources(t, &s6.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s5.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s4.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s3.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s2.rc, network.ScopeStat{})
|
||
|
checkResources(t, &s1.rc, network.ScopeStat{})
|
||
|
}
|