Path: blob/main/component/loki/source/file/decompresser_test.go
4096 views
package file12// This code is copied from Promtail to test their decompressor implementation3// of the reader interface.45import (6"os"7"sync"8"testing"9"time"1011"github.com/grafana/agent/component/common/loki/client/fake"1213"github.com/go-kit/log"14"github.com/grafana/agent/component/common/loki"15"github.com/prometheus/client_golang/prometheus"16"github.com/stretchr/testify/require"17"go.uber.org/atomic"18)1920type noopClient struct {21noopChan chan loki.Entry22wg sync.WaitGroup23once sync.Once24}2526func (n *noopClient) Chan() chan<- loki.Entry {27return n.noopChan28}2930func (n *noopClient) Stop() {31n.once.Do(func() { close(n.noopChan) })32}3334func newNoopClient() *noopClient {35c := &noopClient{noopChan: make(chan loki.Entry)}36c.wg.Add(1)37go func() {38defer c.wg.Done()39for range c.noopChan {40// noop41}42}()43return c44}4546func BenchmarkReadlines(b *testing.B) {47entryHandler := newNoopClient()4849scenarios := []struct {50name string51file string52}{53{54name: "2000 lines of log .tar.gz compressed",55file: "testdata/short-access.tar.gz",56},57{58name: "100000 lines of log .gz compressed",59file: "testdata/long-access.gz",60},61}6263for _, tc := range scenarios {64b.Run(tc.name, func(b *testing.B) {65decBase := &decompressor{66logger: log.NewNopLogger(),67running: atomic.NewBool(false),68handler: entryHandler,69path: tc.file,70}7172for i := 0; i < b.N; i++ {73newDec := decBase74newDec.metrics = newMetrics(prometheus.NewRegistry())75newDec.done = make(chan struct{})76newDec.readLines()77<-newDec.done78}79})80}81}8283func TestGigantiqueGunzipFile(t *testing.T) {84file := "testdata/long-access.gz"85handler := fake.NewClient(func() {})86defer handler.Stop()8788d := &decompressor{89logger: log.NewNopLogger(),90running: atomic.NewBool(false),91handler: handler,92path: file,93done: make(chan struct{}),94metrics: newMetrics(prometheus.NewRegistry()),95}9697d.readLines()9899<-d.done100time.Sleep(time.Millisecond * 200)101102entries := handler.Received()103require.Equal(t, 100000, len(entries))104}105106// TestOnelineFiles test the supported formats for log lines that only contain 1 line.107//108// Based on our experience, this is the scenario with the most edge cases.109func TestOnelineFiles(t *testing.T) {110fileContent, err := os.ReadFile("testdata/onelinelog.log")111require.NoError(t, err)112t.Run("gunzip file", func(t *testing.T) {113file := "testdata/onelinelog.log.gz"114handler := fake.NewClient(func() {})115defer handler.Stop()116117d := &decompressor{118logger: log.NewNopLogger(),119running: atomic.NewBool(false),120handler: handler,121path: file,122done: make(chan struct{}),123metrics: newMetrics(prometheus.NewRegistry()),124}125126d.readLines()127128<-d.done129time.Sleep(time.Millisecond * 200)130131entries := handler.Received()132require.Equal(t, 1, len(entries))133require.Equal(t, string(fileContent), entries[0].Line)134})135136t.Run("bzip2 file", func(t *testing.T) {137file := "testdata/onelinelog.log.bz2"138handler := fake.NewClient(func() {})139defer handler.Stop()140141d := &decompressor{142logger: log.NewNopLogger(),143running: atomic.NewBool(false),144handler: handler,145path: file,146done: make(chan struct{}),147metrics: newMetrics(prometheus.NewRegistry()),148}149150d.readLines()151152<-d.done153time.Sleep(time.Millisecond * 200)154155entries := handler.Received()156require.Equal(t, 1, len(entries))157require.Equal(t, string(fileContent), entries[0].Line)158})159160t.Run("tar.gz file", func(t *testing.T) {161file := "testdata/onelinelog.tar.gz"162handler := fake.NewClient(func() {})163defer handler.Stop()164165d := &decompressor{166logger: log.NewNopLogger(),167running: atomic.NewBool(false),168handler: handler,169path: file,170done: make(chan struct{}),171metrics: newMetrics(prometheus.NewRegistry()),172}173174d.readLines()175176<-d.done177time.Sleep(time.Millisecond * 200)178179entries := handler.Received()180require.Equal(t, 1, len(entries))181firstEntry := entries[0]182require.Contains(t, firstEntry.Line, "onelinelog.log") // contains .tar.gz headers183require.Contains(t, firstEntry.Line, `5.202.214.160 - - [26/Jan/2019:19:45:25 +0330] "GET / HTTP/1.1" 200 30975 "https://www.zanbil.ir/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0" "-"`)184})185}186187188