2
0

bits_test.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. assert.True(t, b.Update(l, 1))
  15. assert.EqualValues(t, 1, b.current)
  16. g := []bool{true, true, false, false, false, false, false, false, false, false}
  17. assert.Equal(t, g, b.bits)
  18. // Receive two
  19. assert.True(t, b.Check(l, 2))
  20. assert.True(t, b.Update(l, 2))
  21. assert.EqualValues(t, 2, b.current)
  22. g = []bool{true, true, true, false, false, false, false, false, false, false}
  23. assert.Equal(t, g, b.bits)
  24. // Receive two again - it will fail
  25. assert.False(t, b.Check(l, 2))
  26. assert.False(t, b.Update(l, 2))
  27. assert.EqualValues(t, 2, b.current)
  28. // Jump ahead to 15, which should clear everything and set the 6th element
  29. assert.True(t, b.Check(l, 15))
  30. assert.True(t, b.Update(l, 15))
  31. assert.EqualValues(t, 15, b.current)
  32. g = []bool{false, false, false, false, false, true, false, false, false, false}
  33. assert.Equal(t, g, b.bits)
  34. // Mark 14, which is allowed because it is in the window
  35. assert.True(t, b.Check(l, 14))
  36. assert.True(t, b.Update(l, 14))
  37. assert.EqualValues(t, 15, b.current)
  38. g = []bool{false, false, false, false, true, true, false, false, false, false}
  39. assert.Equal(t, g, b.bits)
  40. // Mark 5, which is not allowed because it is not in the window
  41. assert.False(t, b.Check(l, 5))
  42. assert.False(t, b.Update(l, 5))
  43. assert.EqualValues(t, 15, b.current)
  44. g = []bool{false, false, false, false, true, true, false, false, false, false}
  45. assert.Equal(t, g, b.bits)
  46. // make sure we handle wrapping around once to the current position
  47. b = NewBits(10)
  48. assert.True(t, b.Update(l, 1))
  49. assert.True(t, b.Update(l, 11))
  50. assert.Equal(t, []bool{false, true, false, false, false, false, false, false, false, false}, b.bits)
  51. // Walk through a few windows in order
  52. b = NewBits(10)
  53. for i := uint64(1); i <= 100; i++ {
  54. assert.True(t, b.Check(l, i), "Error while checking %v", i)
  55. assert.True(t, b.Update(l, i), "Error while updating %v", i)
  56. }
  57. assert.False(t, b.Check(l, 1), "Out of window check")
  58. }
  59. func TestBitsLargeJumps(t *testing.T) {
  60. l := test.NewLogger()
  61. b := NewBits(10)
  62. b.lostCounter.Clear()
  63. b = NewBits(10)
  64. b.lostCounter.Clear()
  65. assert.True(t, b.Update(l, 55)) // We saw packet 55 and can still track 45,46,47,48,49,50,51,52,53,54
  66. assert.Equal(t, int64(45), b.lostCounter.Count())
  67. assert.True(t, b.Update(l, 100)) // We saw packet 55 and 100 and can still track 90,91,92,93,94,95,96,97,98,99
  68. assert.Equal(t, int64(89), b.lostCounter.Count())
  69. assert.True(t, b.Update(l, 200)) // We saw packet 55, 100, and 200 and can still track 190,191,192,193,194,195,196,197,198,199
  70. assert.Equal(t, int64(188), b.lostCounter.Count())
  71. }
  72. func TestBitsDupeCounter(t *testing.T) {
  73. l := test.NewLogger()
  74. b := NewBits(10)
  75. b.lostCounter.Clear()
  76. b.dupeCounter.Clear()
  77. b.outOfWindowCounter.Clear()
  78. assert.True(t, b.Update(l, 1))
  79. assert.Equal(t, int64(0), b.dupeCounter.Count())
  80. assert.False(t, b.Update(l, 1))
  81. assert.Equal(t, int64(1), b.dupeCounter.Count())
  82. assert.True(t, b.Update(l, 2))
  83. assert.Equal(t, int64(1), b.dupeCounter.Count())
  84. assert.True(t, b.Update(l, 3))
  85. assert.Equal(t, int64(1), b.dupeCounter.Count())
  86. assert.False(t, b.Update(l, 1))
  87. assert.Equal(t, int64(0), b.lostCounter.Count())
  88. assert.Equal(t, int64(2), b.dupeCounter.Count())
  89. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  90. }
  91. func TestBitsOutOfWindowCounter(t *testing.T) {
  92. l := test.NewLogger()
  93. b := NewBits(10)
  94. b.lostCounter.Clear()
  95. b.dupeCounter.Clear()
  96. b.outOfWindowCounter.Clear()
  97. assert.True(t, b.Update(l, 20))
  98. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  99. assert.True(t, b.Update(l, 21))
  100. assert.True(t, b.Update(l, 22))
  101. assert.True(t, b.Update(l, 23))
  102. assert.True(t, b.Update(l, 24))
  103. assert.True(t, b.Update(l, 25))
  104. assert.True(t, b.Update(l, 26))
  105. assert.True(t, b.Update(l, 27))
  106. assert.True(t, b.Update(l, 28))
  107. assert.True(t, b.Update(l, 29))
  108. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  109. assert.False(t, b.Update(l, 0))
  110. assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
  111. assert.Equal(t, int64(19), b.lostCounter.Count()) // packet 0 wasn't lost
  112. assert.Equal(t, int64(0), b.dupeCounter.Count())
  113. assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
  114. }
  115. func TestBitsLostCounter(t *testing.T) {
  116. l := test.NewLogger()
  117. b := NewBits(10)
  118. b.lostCounter.Clear()
  119. b.dupeCounter.Clear()
  120. b.outOfWindowCounter.Clear()
  121. assert.True(t, b.Update(l, 20))
  122. assert.True(t, b.Update(l, 21))
  123. assert.True(t, b.Update(l, 22))
  124. assert.True(t, b.Update(l, 23))
  125. assert.True(t, b.Update(l, 24))
  126. assert.True(t, b.Update(l, 25))
  127. assert.True(t, b.Update(l, 26))
  128. assert.True(t, b.Update(l, 27))
  129. assert.True(t, b.Update(l, 28))
  130. assert.True(t, b.Update(l, 29))
  131. assert.Equal(t, int64(19), b.lostCounter.Count()) // packet 0 wasn't lost
  132. assert.Equal(t, int64(0), b.dupeCounter.Count())
  133. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  134. b = NewBits(10)
  135. b.lostCounter.Clear()
  136. b.dupeCounter.Clear()
  137. b.outOfWindowCounter.Clear()
  138. assert.True(t, b.Update(l, 9))
  139. assert.Equal(t, int64(0), b.lostCounter.Count())
  140. // 10 will set 0 index, 0 was already set, no lost packets
  141. assert.True(t, b.Update(l, 10))
  142. assert.Equal(t, int64(0), b.lostCounter.Count())
  143. // 11 will set 1 index, 1 was missed, we should see 1 packet lost
  144. assert.True(t, b.Update(l, 11))
  145. assert.Equal(t, int64(1), b.lostCounter.Count())
  146. // Now let's fill in the window, should end up with 8 lost packets
  147. assert.True(t, b.Update(l, 12))
  148. assert.True(t, b.Update(l, 13))
  149. assert.True(t, b.Update(l, 14))
  150. assert.True(t, b.Update(l, 15))
  151. assert.True(t, b.Update(l, 16))
  152. assert.True(t, b.Update(l, 17))
  153. assert.True(t, b.Update(l, 18))
  154. assert.True(t, b.Update(l, 19))
  155. assert.Equal(t, int64(8), b.lostCounter.Count())
  156. // Jump ahead by a window size
  157. assert.True(t, b.Update(l, 29))
  158. assert.Equal(t, int64(8), b.lostCounter.Count())
  159. // Now lets walk ahead normally through the window, the missed packets should fill in
  160. assert.True(t, b.Update(l, 30))
  161. assert.True(t, b.Update(l, 31))
  162. assert.True(t, b.Update(l, 32))
  163. assert.True(t, b.Update(l, 33))
  164. assert.True(t, b.Update(l, 34))
  165. assert.True(t, b.Update(l, 35))
  166. assert.True(t, b.Update(l, 36))
  167. assert.True(t, b.Update(l, 37))
  168. assert.True(t, b.Update(l, 38))
  169. // 39 packets tracked, 22 seen, 17 lost
  170. assert.Equal(t, int64(17), b.lostCounter.Count())
  171. // Jump ahead by 2 windows, should have recording 1 full window missing
  172. assert.True(t, b.Update(l, 58))
  173. assert.Equal(t, int64(27), b.lostCounter.Count())
  174. // Now lets walk ahead normally through the window, the missed packets should fill in from this window
  175. assert.True(t, b.Update(l, 59))
  176. assert.True(t, b.Update(l, 60))
  177. assert.True(t, b.Update(l, 61))
  178. assert.True(t, b.Update(l, 62))
  179. assert.True(t, b.Update(l, 63))
  180. assert.True(t, b.Update(l, 64))
  181. assert.True(t, b.Update(l, 65))
  182. assert.True(t, b.Update(l, 66))
  183. assert.True(t, b.Update(l, 67))
  184. // 68 packets tracked, 32 seen, 36 missed
  185. assert.Equal(t, int64(36), b.lostCounter.Count())
  186. assert.Equal(t, int64(0), b.dupeCounter.Count())
  187. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  188. }
  189. func TestBitsLostCounterIssue1(t *testing.T) {
  190. l := test.NewLogger()
  191. b := NewBits(10)
  192. b.lostCounter.Clear()
  193. b.dupeCounter.Clear()
  194. b.outOfWindowCounter.Clear()
  195. assert.True(t, b.Update(l, 4))
  196. assert.Equal(t, int64(0), b.lostCounter.Count())
  197. assert.True(t, b.Update(l, 1))
  198. assert.Equal(t, int64(0), b.lostCounter.Count())
  199. assert.True(t, b.Update(l, 9))
  200. assert.Equal(t, int64(0), b.lostCounter.Count())
  201. assert.True(t, b.Update(l, 2))
  202. assert.Equal(t, int64(0), b.lostCounter.Count())
  203. assert.True(t, b.Update(l, 3))
  204. assert.Equal(t, int64(0), b.lostCounter.Count())
  205. assert.True(t, b.Update(l, 5))
  206. assert.Equal(t, int64(0), b.lostCounter.Count())
  207. assert.True(t, b.Update(l, 6))
  208. assert.Equal(t, int64(0), b.lostCounter.Count())
  209. assert.True(t, b.Update(l, 7))
  210. assert.Equal(t, int64(0), b.lostCounter.Count())
  211. // assert.True(t, b.Update(l, 8))
  212. assert.True(t, b.Update(l, 10))
  213. assert.Equal(t, int64(0), b.lostCounter.Count())
  214. assert.True(t, b.Update(l, 11))
  215. assert.Equal(t, int64(0), b.lostCounter.Count())
  216. assert.True(t, b.Update(l, 14))
  217. assert.Equal(t, int64(0), b.lostCounter.Count())
  218. // Issue seems to be here, we reset missing packet 8 to false here and don't increment the lost counter
  219. assert.True(t, b.Update(l, 19))
  220. assert.Equal(t, int64(1), b.lostCounter.Count())
  221. assert.True(t, b.Update(l, 12))
  222. assert.Equal(t, int64(1), b.lostCounter.Count())
  223. assert.True(t, b.Update(l, 13))
  224. assert.Equal(t, int64(1), b.lostCounter.Count())
  225. assert.True(t, b.Update(l, 15))
  226. assert.Equal(t, int64(1), b.lostCounter.Count())
  227. assert.True(t, b.Update(l, 16))
  228. assert.Equal(t, int64(1), b.lostCounter.Count())
  229. assert.True(t, b.Update(l, 17))
  230. assert.Equal(t, int64(1), b.lostCounter.Count())
  231. assert.True(t, b.Update(l, 18))
  232. assert.Equal(t, int64(1), b.lostCounter.Count())
  233. assert.True(t, b.Update(l, 20))
  234. assert.Equal(t, int64(1), b.lostCounter.Count())
  235. assert.True(t, b.Update(l, 21))
  236. // We missed packet 8 above
  237. assert.Equal(t, int64(1), b.lostCounter.Count())
  238. assert.Equal(t, int64(0), b.dupeCounter.Count())
  239. assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
  240. }
  241. func BenchmarkBits(b *testing.B) {
  242. z := NewBits(10)
  243. for n := 0; n < b.N; n++ {
  244. for i := range z.bits {
  245. z.bits[i] = true
  246. }
  247. for i := range z.bits {
  248. z.bits[i] = false
  249. }
  250. }
  251. }