github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/client/batch_test.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/prometheus/common/model" 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 12 "github.com/grafana/loki/clients/pkg/promtail/api" 13 14 "github.com/grafana/loki/pkg/logproto" 15 ) 16 17 func TestBatch_add(t *testing.T) { 18 t.Parallel() 19 20 tests := map[string]struct { 21 inputEntries []api.Entry 22 expectedSizeBytes int 23 }{ 24 "empty batch": { 25 inputEntries: []api.Entry{}, 26 expectedSizeBytes: 0, 27 }, 28 "single stream with single log entry": { 29 inputEntries: []api.Entry{ 30 {Labels: model.LabelSet{}, Entry: logEntries[0].Entry}, 31 }, 32 expectedSizeBytes: len(logEntries[0].Entry.Line), 33 }, 34 "single stream with multiple log entries": { 35 inputEntries: []api.Entry{ 36 {Labels: model.LabelSet{}, Entry: logEntries[0].Entry}, 37 {Labels: model.LabelSet{}, Entry: logEntries[1].Entry}, 38 }, 39 expectedSizeBytes: len(logEntries[0].Entry.Line) + len(logEntries[1].Entry.Line), 40 }, 41 "multiple streams with multiple log entries": { 42 inputEntries: []api.Entry{ 43 {Labels: model.LabelSet{"type": "a"}, Entry: logEntries[0].Entry}, 44 {Labels: model.LabelSet{"type": "a"}, Entry: logEntries[1].Entry}, 45 {Labels: model.LabelSet{"type": "b"}, Entry: logEntries[2].Entry}, 46 }, 47 expectedSizeBytes: len(logEntries[0].Entry.Line) + len(logEntries[1].Entry.Line) + len(logEntries[2].Entry.Line), 48 }, 49 } 50 51 for testName, testData := range tests { 52 testData := testData 53 54 t.Run(testName, func(t *testing.T) { 55 b := newBatch() 56 57 for _, entry := range testData.inputEntries { 58 b.add(entry) 59 } 60 61 assert.Equal(t, testData.expectedSizeBytes, b.sizeBytes()) 62 }) 63 } 64 } 65 66 func TestBatch_encode(t *testing.T) { 67 t.Parallel() 68 69 tests := map[string]struct { 70 inputBatch *batch 71 expectedEntriesCount int 72 }{ 73 "empty batch": { 74 inputBatch: newBatch(), 75 expectedEntriesCount: 0, 76 }, 77 "single stream with single log entry": { 78 inputBatch: newBatch( 79 api.Entry{Labels: model.LabelSet{}, Entry: logEntries[0].Entry}, 80 ), 81 expectedEntriesCount: 1, 82 }, 83 "single stream with multiple log entries": { 84 inputBatch: newBatch( 85 api.Entry{Labels: model.LabelSet{}, Entry: logEntries[0].Entry}, 86 api.Entry{Labels: model.LabelSet{}, Entry: logEntries[1].Entry}, 87 ), 88 expectedEntriesCount: 2, 89 }, 90 "multiple streams with multiple log entries": { 91 inputBatch: newBatch( 92 api.Entry{Labels: model.LabelSet{"type": "a"}, Entry: logEntries[0].Entry}, 93 api.Entry{Labels: model.LabelSet{"type": "a"}, Entry: logEntries[1].Entry}, 94 api.Entry{Labels: model.LabelSet{"type": "b"}, Entry: logEntries[2].Entry}, 95 ), 96 expectedEntriesCount: 3, 97 }, 98 } 99 100 for testName, testData := range tests { 101 testData := testData 102 103 t.Run(testName, func(t *testing.T) { 104 t.Parallel() 105 106 _, entriesCount, err := testData.inputBatch.encode() 107 require.NoError(t, err) 108 assert.Equal(t, testData.expectedEntriesCount, entriesCount) 109 }) 110 } 111 } 112 113 func TestHashCollisions(t *testing.T) { 114 b := newBatch() 115 116 ls1 := model.LabelSet{"app": "l", "uniq0": "0", "uniq1": "1"} 117 ls2 := model.LabelSet{"app": "m", "uniq0": "1", "uniq1": "1"} 118 119 require.False(t, ls1.Equal(ls2)) 120 require.Equal(t, ls1.FastFingerprint(), ls2.FastFingerprint()) 121 122 const entriesPerLabel = 10 123 124 for i := 0; i < entriesPerLabel; i++ { 125 b.add(api.Entry{Labels: ls1, Entry: logproto.Entry{Timestamp: time.Now(), Line: fmt.Sprintf("line %d", i)}}) 126 b.add(api.Entry{Labels: ls2, Entry: logproto.Entry{Timestamp: time.Now(), Line: fmt.Sprintf("line %d", i)}}) 127 } 128 129 // make sure that colliding labels are stored properly as independent streams 130 req, entries := b.createPushRequest() 131 assert.Len(t, req.Streams, 2) 132 assert.Equal(t, 2*entriesPerLabel, entries) 133 134 if req.Streams[0].Labels == ls1.String() { 135 assert.Equal(t, ls1.String(), req.Streams[0].Labels) 136 assert.Equal(t, ls2.String(), req.Streams[1].Labels) 137 } else { 138 assert.Equal(t, ls2.String(), req.Streams[0].Labels) 139 assert.Equal(t, ls1.String(), req.Streams[1].Labels) 140 } 141 }