bits_test.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package nebula
  2. import (
  3. "testing"
  4. "github.com/slackhq/nebula/test"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. func TestBits(t *testing.T) {
  8. l := test.NewLogger()
  9. b := NewBits(10)
  10. // make sure it is the right size
  11. assert.Len(t, b.bits, 10)
  12. // This is initialized to zero - receive one. This should work.
  13. assert.True(t, b.Check(l, 1))
  14. u := b.Update(l, 1)
  15. assert.True(t, u)
  16. assert.EqualValues(t, 1, b.current)
  17. g := []bool{false, true, false, false, false, false, false, false, false, false}
  18. assert.Equal(t, g, b.bits)
  19. // Receive two
  20. assert.True(t, b.Check(l, 2))
  21. u = b.Update(l, 2)
  22. assert.True(t, u)
  23. assert.EqualValues(t, 2, b.current)
  24. g = []bool{false, true, true, false, false, false, false, false, false, false}
  25. assert.Equal(t, g, b.bits)
  26. // Receive two again - it will fail
  27. assert.False(t, b.Check(l, 2))
  28. u = b.Update(l, 2)
  29. assert.False(t, u)
  30. assert.EqualValues(t, 2, b.current)
  31. // Jump ahead to 15, which should clear everything and set the 6th element
  32. assert.True(t, b.Check(l, 15))
  33. u = b.Update(l, 15)
  34. assert.True(t, u)
  35. assert.EqualValues(t, 15, b.current)
  36. g = []bool{false, false, false, false, false, true, false, false, false, false}
  37. assert.Equal(t, g, b.bits)
  38. // Mark 14, which is allowed because it is in the window
  39. assert.True(t, b.Check(l, 14))
  40. u = b.Update(l, 14)
  41. assert.True(t, u)
  42. assert.EqualValues(t, 15, b.current)
  43. g = []bool{false, false, false, false, true, true, false, false, false, false}
  44. assert.Equal(t, g, b.bits)
  45. // Mark 5, which is not allowed because it is not in the window
  46. assert.False(t, b.Check(l, 5))
  47. u = b.Update(l, 5)
  48. assert.False(t, u)
  49. assert.EqualValues(t, 15, b.current)
  50. g = []bool{false, false, false, false, true, true, false, false, false, false}
  51. assert.Equal(t, g, b.bits)
  52. // make sure we handle wrapping around once to the current position
  53. b = NewBits(10)
  54. assert.True(t, b.Update(l, 1))
  55. assert.True(t, b.Update(l, 11))
  56. assert.Equal(t, []bool{false, true, false, false, false, false, false, false, false, false}, b.bits)
  57. // Walk through a few windows in order
  58. b = NewBits(10)
  59. for i := uint64(0); i <= 100; i++ {
  60. assert.True(t, b.Check(l, i), "Error while checking %v", i)
  61. assert.True(t, b.Update(l, i), "Error while updating %v", i)
  62. }
  63. }
  64. func TestBitsDupeCounter(t *testing.T) {
  65. l := test.NewLogger()
  66. b := NewBits(10)
  67. b.lostCounter.Clear()
  68. b.dupeCounter.Clear()
  69. b.outOfWindowCounter.Clear()
  70. assert.True(t, b.Update(l, 1))
  71. assert.Equal(t, int64(0), b.dupeCounter.Count())
  72. assert.False(t, b.Update(l, 1))
  73. assert.Equal(t, int64(1), b.dupeCounter.Count())
  74. assert.True(t, b.Update(l, 2))
  75. assert.Equal(t, int64(1), b.dupeCounter.Count())
  76. assert.True(t, b.Update(l, 3))
  77. assert.Equal(t, int64(1), b.dupeCounter.Count())
  78. assert.False(t, b.Update(l, 1))
  79. assert.Equal(t, int64(0), b.lostCounter.Count())
  80. assert.Equal(t, int64(2), b.dupeCounter.Count())
  81. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  82. }
  83. func TestBitsOutOfWindowCounter(t *testing.T) {
  84. l := test.NewLogger()
  85. b := NewBits(10)
  86. b.lostCounter.Clear()
  87. b.dupeCounter.Clear()
  88. b.outOfWindowCounter.Clear()
  89. assert.True(t, b.Update(l, 20))
  90. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  91. assert.True(t, b.Update(l, 21))
  92. assert.True(t, b.Update(l, 22))
  93. assert.True(t, b.Update(l, 23))
  94. assert.True(t, b.Update(l, 24))
  95. assert.True(t, b.Update(l, 25))
  96. assert.True(t, b.Update(l, 26))
  97. assert.True(t, b.Update(l, 27))
  98. assert.True(t, b.Update(l, 28))
  99. assert.True(t, b.Update(l, 29))
  100. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  101. assert.False(t, b.Update(l, 0))
  102. assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
  103. //tODO: make sure lostcounter doesn't increase in orderly increment
  104. assert.Equal(t, int64(20), b.lostCounter.Count())
  105. assert.Equal(t, int64(0), b.dupeCounter.Count())
  106. assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
  107. }
  108. func TestBitsLostCounter(t *testing.T) {
  109. l := test.NewLogger()
  110. b := NewBits(10)
  111. b.lostCounter.Clear()
  112. b.dupeCounter.Clear()
  113. b.outOfWindowCounter.Clear()
  114. //assert.True(t, b.Update(0))
  115. assert.True(t, b.Update(l, 0))
  116. assert.True(t, b.Update(l, 20))
  117. assert.True(t, b.Update(l, 21))
  118. assert.True(t, b.Update(l, 22))
  119. assert.True(t, b.Update(l, 23))
  120. assert.True(t, b.Update(l, 24))
  121. assert.True(t, b.Update(l, 25))
  122. assert.True(t, b.Update(l, 26))
  123. assert.True(t, b.Update(l, 27))
  124. assert.True(t, b.Update(l, 28))
  125. assert.True(t, b.Update(l, 29))
  126. assert.Equal(t, int64(20), b.lostCounter.Count())
  127. assert.Equal(t, int64(0), b.dupeCounter.Count())
  128. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  129. b = NewBits(10)
  130. b.lostCounter.Clear()
  131. b.dupeCounter.Clear()
  132. b.outOfWindowCounter.Clear()
  133. assert.True(t, b.Update(l, 0))
  134. assert.Equal(t, int64(0), b.lostCounter.Count())
  135. assert.True(t, b.Update(l, 9))
  136. assert.Equal(t, int64(0), b.lostCounter.Count())
  137. // 10 will set 0 index, 0 was already set, no lost packets
  138. assert.True(t, b.Update(l, 10))
  139. assert.Equal(t, int64(0), b.lostCounter.Count())
  140. // 11 will set 1 index, 1 was missed, we should see 1 packet lost
  141. assert.True(t, b.Update(l, 11))
  142. assert.Equal(t, int64(1), b.lostCounter.Count())
  143. // Now let's fill in the window, should end up with 8 lost packets
  144. assert.True(t, b.Update(l, 12))
  145. assert.True(t, b.Update(l, 13))
  146. assert.True(t, b.Update(l, 14))
  147. assert.True(t, b.Update(l, 15))
  148. assert.True(t, b.Update(l, 16))
  149. assert.True(t, b.Update(l, 17))
  150. assert.True(t, b.Update(l, 18))
  151. assert.True(t, b.Update(l, 19))
  152. assert.Equal(t, int64(8), b.lostCounter.Count())
  153. // Jump ahead by a window size
  154. assert.True(t, b.Update(l, 29))
  155. assert.Equal(t, int64(8), b.lostCounter.Count())
  156. // Now lets walk ahead normally through the window, the missed packets should fill in
  157. assert.True(t, b.Update(l, 30))
  158. assert.True(t, b.Update(l, 31))
  159. assert.True(t, b.Update(l, 32))
  160. assert.True(t, b.Update(l, 33))
  161. assert.True(t, b.Update(l, 34))
  162. assert.True(t, b.Update(l, 35))
  163. assert.True(t, b.Update(l, 36))
  164. assert.True(t, b.Update(l, 37))
  165. assert.True(t, b.Update(l, 38))
  166. // 39 packets tracked, 22 seen, 17 lost
  167. assert.Equal(t, int64(17), b.lostCounter.Count())
  168. // Jump ahead by 2 windows, should have recording 1 full window missing
  169. assert.True(t, b.Update(l, 58))
  170. assert.Equal(t, int64(27), b.lostCounter.Count())
  171. // Now lets walk ahead normally through the window, the missed packets should fill in from this window
  172. assert.True(t, b.Update(l, 59))
  173. assert.True(t, b.Update(l, 60))
  174. assert.True(t, b.Update(l, 61))
  175. assert.True(t, b.Update(l, 62))
  176. assert.True(t, b.Update(l, 63))
  177. assert.True(t, b.Update(l, 64))
  178. assert.True(t, b.Update(l, 65))
  179. assert.True(t, b.Update(l, 66))
  180. assert.True(t, b.Update(l, 67))
  181. // 68 packets tracked, 32 seen, 36 missed
  182. assert.Equal(t, int64(36), b.lostCounter.Count())
  183. assert.Equal(t, int64(0), b.dupeCounter.Count())
  184. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  185. }
  186. func BenchmarkBits(b *testing.B) {
  187. z := NewBits(10)
  188. for n := 0; n < b.N; n++ {
  189. for i := range z.bits {
  190. z.bits[i] = true
  191. }
  192. for i := range z.bits {
  193. z.bits[i] = false
  194. }
  195. }
  196. }