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  }