| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- package nebula
- import (
- "net/netip"
- "testing"
- )
- func TestSendBatchBookkeeping(t *testing.T) {
- b := newSendBatch(4, 32)
- if b.Len() != 0 || b.Cap() != 4 {
- t.Fatalf("fresh batch: len=%d cap=%d", b.Len(), b.Cap())
- }
- ap := netip.MustParseAddrPort("10.0.0.1:4242")
- for i := 0; i < 4; i++ {
- slot := b.Next()
- if slot == nil {
- t.Fatalf("slot %d: Next returned nil before cap", i)
- }
- if cap(slot) != 32 || len(slot) != 0 {
- t.Fatalf("slot %d: got len=%d cap=%d want len=0 cap=32", i, len(slot), cap(slot))
- }
- // Write a marker byte.
- slot = append(slot, byte(i), byte(i+1), byte(i+2))
- b.Commit(len(slot), ap)
- }
- if b.Next() != nil {
- t.Fatalf("Next should return nil when full")
- }
- if b.Len() != 4 {
- t.Fatalf("Len=%d want 4", b.Len())
- }
- for i, buf := range b.bufs {
- if len(buf) != 3 || buf[0] != byte(i) {
- t.Errorf("buf %d: %x", i, buf)
- }
- if b.dsts[i] != ap {
- t.Errorf("dst %d: got %v want %v", i, b.dsts[i], ap)
- }
- }
- // Reset returns empty and Next works again.
- b.Reset()
- if b.Len() != 0 {
- t.Fatalf("after Reset Len=%d want 0", b.Len())
- }
- slot := b.Next()
- if slot == nil || cap(slot) != 32 {
- t.Fatalf("after Reset Next nil or wrong cap: %v cap=%d", slot == nil, cap(slot))
- }
- }
- func TestBatchSegmentable(t *testing.T) {
- ap := netip.MustParseAddrPort("10.0.0.1:4242")
- other := netip.MustParseAddrPort("10.0.0.2:4242")
- mk := func(addrs []netip.AddrPort, sizes []int) *sendBatch {
- b := newSendBatch(len(addrs), 64)
- for i, a := range addrs {
- s := b.Next()
- for j := 0; j < sizes[i]; j++ {
- s = append(s, byte(j))
- }
- b.Commit(len(s), a)
- }
- return b
- }
- t.Run("uniform same dst", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 10})
- seg, ok := batchSegmentable(b)
- if !ok || seg != 10 {
- t.Fatalf("got seg=%d ok=%v", seg, ok)
- }
- })
- t.Run("last segment short ok", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 4})
- seg, ok := batchSegmentable(b)
- if !ok || seg != 10 {
- t.Fatalf("got seg=%d ok=%v", seg, ok)
- }
- })
- t.Run("mixed dst rejected", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, other, ap}, []int{10, 10, 10})
- if _, ok := batchSegmentable(b); ok {
- t.Fatalf("expected rejection for mixed dst")
- }
- })
- t.Run("mid-batch short rejected", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 4, 10})
- if _, ok := batchSegmentable(b); ok {
- t.Fatalf("expected rejection for short mid-batch")
- }
- })
- t.Run("mid-batch longer rejected", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 11, 10})
- if _, ok := batchSegmentable(b); ok {
- t.Fatalf("expected rejection for longer mid-batch")
- }
- })
- t.Run("last longer rejected", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 11})
- if _, ok := batchSegmentable(b); ok {
- t.Fatalf("expected rejection for longer last segment")
- }
- })
- t.Run("first zero rejected", func(t *testing.T) {
- b := mk([]netip.AddrPort{ap, ap}, []int{0, 10})
- if _, ok := batchSegmentable(b); ok {
- t.Fatalf("expected rejection for zero first")
- }
- })
- }
- func TestSendBatchSlotsDoNotOverlap(t *testing.T) {
- b := newSendBatch(3, 8)
- ap := netip.MustParseAddrPort("10.0.0.1:80")
- // Fill three slots, each with its own sentinel byte.
- for i := 0; i < 3; i++ {
- s := b.Next()
- s = append(s, byte(0xA0+i), byte(0xB0+i))
- b.Commit(len(s), ap)
- }
- for i, buf := range b.bufs {
- if buf[0] != byte(0xA0+i) || buf[1] != byte(0xB0+i) {
- t.Errorf("slot %d corrupted: %x", i, buf)
- }
- }
- }
|