github.com/prebid/prebid-server/v2@v2.18.0/analytics/pubstack/eventchannel/eventchannel_test.go (about) 1 package eventchannel 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "io" 7 "math" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/benbjohnson/clock" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 var largeBufferSize = int64(math.MaxInt64) 17 var largeEventCount = int64(math.MaxInt64) 18 var maxTime = 2 * time.Hour 19 20 func readGz(encoded []byte) string { 21 gr, _ := gzip.NewReader(bytes.NewReader(encoded)) 22 defer gr.Close() 23 24 decoded, _ := io.ReadAll(gr) 25 return string(decoded) 26 } 27 28 func newSender(dataSent chan []byte) Sender { 29 mux := &sync.Mutex{} 30 return func(payload []byte) error { 31 mux.Lock() 32 defer mux.Unlock() 33 dataSent <- payload 34 return nil 35 } 36 } 37 38 func readChanOrTimeout(t *testing.T, c <-chan []byte, msgAndArgs ...interface{}) ([]byte, bool) { 39 t.Helper() 40 select { 41 case actual := <-c: 42 return actual, false 43 case <-time.After(200 * time.Millisecond): 44 return nil, assert.Fail(t, "Should receive an event, but did NOT", msgAndArgs...) 45 } 46 } 47 48 func TestEventChannelIsBufferFull(t *testing.T) { 49 send := func([]byte) error { return nil } 50 clockMock := clock.NewMock() 51 52 maxBufferSize := int64(15) 53 maxEventCount := int64(3) 54 55 eventChannel := NewEventChannel(send, clockMock, maxBufferSize, maxEventCount, maxTime) 56 defer eventChannel.Close() 57 58 eventChannel.buffer([]byte("one")) 59 eventChannel.buffer([]byte("two")) 60 61 assert.False(t, eventChannel.isBufferFull()) // not yet full by either max buffer size or max event count 62 63 eventChannel.buffer([]byte("three")) 64 65 assert.True(t, eventChannel.isBufferFull()) // full by event count (3) 66 67 eventChannel.reset() 68 69 assert.False(t, eventChannel.isBufferFull()) // was just reset, should not be full 70 71 eventChannel.buffer([]byte("larger-than-15-characters")) 72 73 assert.True(t, eventChannel.isBufferFull()) // full by max buffer size 74 } 75 76 func TestEventChannelReset(t *testing.T) { 77 send := func([]byte) error { return nil } 78 clockMock := clock.NewMock() 79 80 eventChannel := NewEventChannel(send, clockMock, largeBufferSize, largeEventCount, maxTime) 81 defer eventChannel.Close() 82 83 assert.Zero(t, eventChannel.metrics.eventCount) 84 assert.Zero(t, eventChannel.metrics.bufferSize) 85 86 eventChannel.buffer([]byte("one")) 87 88 assert.NotZero(t, eventChannel.metrics.eventCount) 89 assert.NotZero(t, eventChannel.metrics.bufferSize) 90 91 eventChannel.reset() 92 93 assert.Zero(t, eventChannel.buff.Len()) 94 assert.Zero(t, eventChannel.metrics.eventCount) 95 assert.Zero(t, eventChannel.metrics.bufferSize) 96 } 97 98 func TestEventChannelFlush(t *testing.T) { 99 dataSent := make(chan []byte) 100 send := newSender(dataSent) 101 clockMock := clock.NewMock() 102 103 eventChannel := NewEventChannel(send, clockMock, largeBufferSize, largeEventCount, maxTime) 104 defer eventChannel.Close() 105 106 eventChannel.buffer([]byte("one")) 107 eventChannel.buffer([]byte("two")) 108 eventChannel.buffer([]byte("three")) 109 eventChannel.flush() 110 111 data, _ := readChanOrTimeout(t, dataSent) 112 assert.Equal(t, "onetwothree", readGz(data)) 113 } 114 115 func TestEventChannelClose(t *testing.T) { 116 dataSent := make(chan []byte) 117 send := newSender(dataSent) 118 clockMock := clock.NewMock() 119 120 eventChannel := NewEventChannel(send, clockMock, largeBufferSize, largeEventCount, maxTime) 121 122 eventChannel.buffer([]byte("one")) 123 eventChannel.buffer([]byte("two")) 124 eventChannel.buffer([]byte("three")) 125 eventChannel.Close() 126 127 data, _ := readChanOrTimeout(t, dataSent) 128 assert.Equal(t, "onetwothree", readGz(data)) 129 } 130 131 func TestEventChannelPush(t *testing.T) { 132 dataSent := make(chan []byte) 133 send := newSender(dataSent) 134 clockMock := clock.NewMock() 135 136 eventChannel := NewEventChannel(send, clockMock, largeBufferSize, largeEventCount, 1*time.Second) 137 defer eventChannel.Close() 138 139 eventChannel.Push([]byte("1")) 140 eventChannel.Push([]byte("2")) 141 eventChannel.Push([]byte("3")) 142 143 clockMock.Add(1 * time.Second) // trigger event timer 144 145 data, _ := readChanOrTimeout(t, dataSent) 146 assert.ElementsMatch(t, []byte{'1', '2', '3'}, []byte(readGz(data))) 147 }