batch_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package nebula
  2. import (
  3. "net/netip"
  4. "testing"
  5. )
  6. func TestSendBatchBookkeeping(t *testing.T) {
  7. b := newSendBatch(4, 32)
  8. if b.Len() != 0 || b.Cap() != 4 {
  9. t.Fatalf("fresh batch: len=%d cap=%d", b.Len(), b.Cap())
  10. }
  11. ap := netip.MustParseAddrPort("10.0.0.1:4242")
  12. for i := 0; i < 4; i++ {
  13. slot := b.Next()
  14. if slot == nil {
  15. t.Fatalf("slot %d: Next returned nil before cap", i)
  16. }
  17. if cap(slot) != 32 || len(slot) != 0 {
  18. t.Fatalf("slot %d: got len=%d cap=%d want len=0 cap=32", i, len(slot), cap(slot))
  19. }
  20. // Write a marker byte.
  21. slot = append(slot, byte(i), byte(i+1), byte(i+2))
  22. b.Commit(len(slot), ap)
  23. }
  24. if b.Next() != nil {
  25. t.Fatalf("Next should return nil when full")
  26. }
  27. if b.Len() != 4 {
  28. t.Fatalf("Len=%d want 4", b.Len())
  29. }
  30. for i, buf := range b.bufs {
  31. if len(buf) != 3 || buf[0] != byte(i) {
  32. t.Errorf("buf %d: %x", i, buf)
  33. }
  34. if b.dsts[i] != ap {
  35. t.Errorf("dst %d: got %v want %v", i, b.dsts[i], ap)
  36. }
  37. }
  38. // Reset returns empty and Next works again.
  39. b.Reset()
  40. if b.Len() != 0 {
  41. t.Fatalf("after Reset Len=%d want 0", b.Len())
  42. }
  43. slot := b.Next()
  44. if slot == nil || cap(slot) != 32 {
  45. t.Fatalf("after Reset Next nil or wrong cap: %v cap=%d", slot == nil, cap(slot))
  46. }
  47. }
  48. func TestBatchSegmentable(t *testing.T) {
  49. ap := netip.MustParseAddrPort("10.0.0.1:4242")
  50. other := netip.MustParseAddrPort("10.0.0.2:4242")
  51. mk := func(addrs []netip.AddrPort, sizes []int) *sendBatch {
  52. b := newSendBatch(len(addrs), 64)
  53. for i, a := range addrs {
  54. s := b.Next()
  55. for j := 0; j < sizes[i]; j++ {
  56. s = append(s, byte(j))
  57. }
  58. b.Commit(len(s), a)
  59. }
  60. return b
  61. }
  62. t.Run("uniform same dst", func(t *testing.T) {
  63. b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 10})
  64. seg, ok := batchSegmentable(b)
  65. if !ok || seg != 10 {
  66. t.Fatalf("got seg=%d ok=%v", seg, ok)
  67. }
  68. })
  69. t.Run("last segment short ok", func(t *testing.T) {
  70. b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 4})
  71. seg, ok := batchSegmentable(b)
  72. if !ok || seg != 10 {
  73. t.Fatalf("got seg=%d ok=%v", seg, ok)
  74. }
  75. })
  76. t.Run("mixed dst rejected", func(t *testing.T) {
  77. b := mk([]netip.AddrPort{ap, other, ap}, []int{10, 10, 10})
  78. if _, ok := batchSegmentable(b); ok {
  79. t.Fatalf("expected rejection for mixed dst")
  80. }
  81. })
  82. t.Run("mid-batch short rejected", func(t *testing.T) {
  83. b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 4, 10})
  84. if _, ok := batchSegmentable(b); ok {
  85. t.Fatalf("expected rejection for short mid-batch")
  86. }
  87. })
  88. t.Run("mid-batch longer rejected", func(t *testing.T) {
  89. b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 11, 10})
  90. if _, ok := batchSegmentable(b); ok {
  91. t.Fatalf("expected rejection for longer mid-batch")
  92. }
  93. })
  94. t.Run("last longer rejected", func(t *testing.T) {
  95. b := mk([]netip.AddrPort{ap, ap, ap}, []int{10, 10, 11})
  96. if _, ok := batchSegmentable(b); ok {
  97. t.Fatalf("expected rejection for longer last segment")
  98. }
  99. })
  100. t.Run("first zero rejected", func(t *testing.T) {
  101. b := mk([]netip.AddrPort{ap, ap}, []int{0, 10})
  102. if _, ok := batchSegmentable(b); ok {
  103. t.Fatalf("expected rejection for zero first")
  104. }
  105. })
  106. }
  107. func TestSendBatchSlotsDoNotOverlap(t *testing.T) {
  108. b := newSendBatch(3, 8)
  109. ap := netip.MustParseAddrPort("10.0.0.1:80")
  110. // Fill three slots, each with its own sentinel byte.
  111. for i := 0; i < 3; i++ {
  112. s := b.Next()
  113. s = append(s, byte(0xA0+i), byte(0xB0+i))
  114. b.Commit(len(s), ap)
  115. }
  116. for i, buf := range b.bufs {
  117. if buf[0] != byte(0xA0+i) || buf[1] != byte(0xB0+i) {
  118. t.Errorf("slot %d corrupted: %x", i, buf)
  119. }
  120. }
  121. }