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  }