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