github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/unmarshal/unmarshal_test.go (about) 1 package unmarshal 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/grafana/loki/pkg/loghttp" 13 legacy_loghttp "github.com/grafana/loki/pkg/loghttp/legacy" 14 "github.com/grafana/loki/pkg/logproto" 15 "github.com/grafana/loki/pkg/util/marshal" 16 ) 17 18 // covers requests to /loki/api/v1/push 19 var pushTests = []struct { 20 expected []logproto.Stream 21 actual string 22 }{ 23 { 24 []logproto.Stream{ 25 { 26 Entries: []logproto.Entry{ 27 { 28 Timestamp: time.Unix(0, 123456789012345), 29 Line: "super line", 30 }, 31 }, 32 Labels: `{test="test"}`, 33 }, 34 }, 35 `{ 36 "streams": [ 37 { 38 "stream": { 39 "test": "test" 40 }, 41 "values":[ 42 [ "123456789012345", "super line" ] 43 ] 44 } 45 ] 46 }`, 47 }, 48 } 49 50 func Test_DecodePushRequest(t *testing.T) { 51 for i, pushTest := range pushTests { 52 var actual logproto.PushRequest 53 closer := ioutil.NopCloser(strings.NewReader(pushTest.actual)) 54 55 err := DecodePushRequest(closer, &actual) 56 require.NoError(t, err) 57 58 require.Equalf(t, pushTest.expected, actual.Streams, "Push Test %d failed", i) 59 } 60 } 61 62 func Benchmark_DecodePushRequest(b *testing.B) { 63 requestFmt := `{ 64 "streams": [ 65 { 66 "stream": { 67 "test": "test", 68 "foo" : "bar" 69 }, 70 "values":[ 71 %s 72 ] 73 } 74 ] 75 }` 76 var entries strings.Builder 77 for i := 0; i < 10000; i++ { 78 entries.WriteString(`[ "123456789012345", "WARN [CompactionExecutor:61771] 2021-01-12 09:40:23,192 TimeWindowCompactionController.java:41 - You are running with sstables overlapping checks disabled, it can result in loss of data" ],`) 79 } 80 requestString := fmt.Sprintf(requestFmt, entries.String()[:len(entries.String())-1]) 81 r := strings.NewReader("") 82 83 b.ResetTimer() 84 b.ReportAllocs() 85 86 for n := 0; n < b.N; n++ { 87 var actual logproto.PushRequest 88 r.Reset(requestString) 89 err := DecodePushRequest(r, &actual) 90 require.NoError(b, err) 91 require.Equal(b, 10000, len(actual.Streams[0].Entries)) 92 } 93 } 94 95 type websocket struct { 96 buf []byte 97 } 98 99 func (ws *websocket) WriteMessage(t int, data []byte) error { 100 ws.buf = append(ws.buf, data...) 101 return nil 102 } 103 104 func (ws *websocket) ReadMessage() (int, []byte, error) { 105 return 0, ws.buf, nil 106 } 107 108 func Test_ReadTailResponse(t *testing.T) { 109 ws := &websocket{} 110 require.NoError(t, marshal.WriteTailResponseJSON(legacy_loghttp.TailResponse{ 111 Streams: []logproto.Stream{ 112 {Labels: `{app="bar"}`, Entries: []logproto.Entry{{Timestamp: time.Unix(0, 2), Line: "2"}}}, 113 }, 114 DroppedEntries: []legacy_loghttp.DroppedEntry{ 115 {Timestamp: time.Unix(0, 1), Labels: `{app="foo"}`}, 116 }, 117 }, ws)) 118 res := &loghttp.TailResponse{} 119 require.NoError(t, ReadTailResponseJSON(res, ws)) 120 121 require.Equal(t, &loghttp.TailResponse{ 122 Streams: []loghttp.Stream{ 123 { 124 Labels: loghttp.LabelSet{"app": "bar"}, 125 Entries: []loghttp.Entry{{Timestamp: time.Unix(0, 2), Line: "2"}}, 126 }, 127 }, 128 DroppedStreams: []loghttp.DroppedStream{ 129 {Timestamp: time.Unix(0, 1), Labels: loghttp.LabelSet{"app": "foo"}}, 130 }, 131 }, res) 132 // Do it twice to verify we reset correctly slices. 133 require.NoError(t, ReadTailResponseJSON(res, ws)) 134 135 require.Equal(t, &loghttp.TailResponse{ 136 Streams: []loghttp.Stream{ 137 { 138 Labels: loghttp.LabelSet{"app": "bar"}, 139 Entries: []loghttp.Entry{{Timestamp: time.Unix(0, 2), Line: "2"}}, 140 }, 141 }, 142 DroppedStreams: []loghttp.DroppedStream{ 143 {Timestamp: time.Unix(0, 1), Labels: loghttp.LabelSet{"app": "foo"}}, 144 }, 145 }, res) 146 }