github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/client/multi_test.go (about) 1 package client 2 3 import ( 4 "net/url" 5 "reflect" 6 "testing" 7 "time" 8 9 "github.com/go-kit/log" 10 "github.com/grafana/dskit/backoff" 11 "github.com/grafana/dskit/flagext" 12 "github.com/prometheus/client_golang/prometheus" 13 "github.com/prometheus/common/model" 14 "github.com/stretchr/testify/require" 15 16 "github.com/grafana/loki/clients/pkg/promtail/api" 17 "github.com/grafana/loki/clients/pkg/promtail/client/fake" 18 19 "github.com/grafana/loki/pkg/logproto" 20 lokiflag "github.com/grafana/loki/pkg/util/flagext" 21 util_log "github.com/grafana/loki/pkg/util/log" 22 ) 23 24 var ( 25 nilMetrics = NewMetrics(nil, nil) 26 metrics = NewMetrics(prometheus.DefaultRegisterer, nil) 27 ) 28 29 func TestNewMulti(t *testing.T) { 30 _, err := NewMulti(nilMetrics, nil, util_log.Logger, []Config{}...) 31 if err == nil { 32 t.Fatal("expected err but got nil") 33 } 34 host1, _ := url.Parse("http://localhost:3100") 35 host2, _ := url.Parse("https://grafana.com") 36 cc1 := Config{ 37 BatchSize: 20, 38 BatchWait: 1 * time.Second, 39 URL: flagext.URLValue{URL: host1}, 40 ExternalLabels: lokiflag.LabelSet{LabelSet: model.LabelSet{"order": "yaml"}}, 41 } 42 cc2 := Config{ 43 BatchSize: 10, 44 BatchWait: 1 * time.Second, 45 URL: flagext.URLValue{URL: host2}, 46 ExternalLabels: lokiflag.LabelSet{LabelSet: model.LabelSet{"hi": "there"}}, 47 } 48 49 clients, err := NewMulti(metrics, nil, util_log.Logger, cc1, cc2) 50 if err != nil { 51 t.Fatalf("expected err: nil got:%v", err) 52 } 53 multi := clients.(*MultiClient) 54 if len(multi.clients) != 2 { 55 t.Fatalf("expected client: 2 got:%d", len(multi.clients)) 56 } 57 actualCfg1 := clients.(*MultiClient).clients[0].(*client).cfg 58 // Yaml should overridden the command line so 'order: yaml' should be expected 59 expectedCfg1 := Config{ 60 BatchSize: 20, 61 BatchWait: 1 * time.Second, 62 URL: flagext.URLValue{URL: host1}, 63 ExternalLabels: lokiflag.LabelSet{LabelSet: model.LabelSet{"order": "yaml"}}, 64 } 65 66 if !reflect.DeepEqual(actualCfg1, expectedCfg1) { 67 t.Fatalf("expected cfg: %v got:%v", expectedCfg1, actualCfg1) 68 } 69 } 70 71 func TestNewMulti_BlockDuplicates(t *testing.T) { 72 _, err := NewMulti(nilMetrics, nil, util_log.Logger, []Config{}...) 73 if err == nil { 74 t.Fatal("expected err but got nil") 75 } 76 host1, _ := url.Parse("http://localhost:3100") 77 cc1 := Config{ 78 BatchSize: 20, 79 BatchWait: 1 * time.Second, 80 URL: flagext.URLValue{URL: host1}, 81 ExternalLabels: lokiflag.LabelSet{LabelSet: model.LabelSet{"order": "yaml"}}, 82 } 83 cc1Copy := cc1 84 85 _, err = NewMulti(metrics, nil, util_log.Logger, cc1, cc1Copy) 86 require.Error(t, err, "expected NewMulti to reject duplicate client configs") 87 88 cc1Copy.Name = "copy" 89 clients, err := NewMulti(metrics, nil, util_log.Logger, cc1, cc1Copy) 90 require.NoError(t, err, "expected NewMulti to reject duplicate client configs") 91 92 multi := clients.(*MultiClient) 93 if len(multi.clients) != 2 { 94 t.Fatalf("expected client: 2 got:%d", len(multi.clients)) 95 } 96 actualCfg1 := clients.(*MultiClient).clients[0].(*client).cfg 97 // Yaml should overridden the command line so 'order: yaml' should be expected 98 expectedCfg1 := Config{ 99 BatchSize: 20, 100 BatchWait: 1 * time.Second, 101 URL: flagext.URLValue{URL: host1}, 102 ExternalLabels: lokiflag.LabelSet{LabelSet: model.LabelSet{"order": "yaml"}}, 103 } 104 105 if !reflect.DeepEqual(actualCfg1, expectedCfg1) { 106 t.Fatalf("expected cfg: %v got:%v", expectedCfg1, actualCfg1) 107 } 108 } 109 110 func TestMultiClient_Stop(t *testing.T) { 111 var stopped int 112 113 stopping := func() { 114 stopped++ 115 } 116 fc := fake.New(stopping) 117 clients := []Client{fc, fc, fc, fc} 118 m := &MultiClient{ 119 clients: clients, 120 entries: make(chan api.Entry), 121 } 122 m.start() 123 m.Stop() 124 125 if stopped != len(clients) { 126 t.Fatal("missing stop call") 127 } 128 } 129 130 func TestMultiClient_Handle(t *testing.T) { 131 f := fake.New(func() {}) 132 clients := []Client{f, f, f, f, f, f} 133 m := &MultiClient{ 134 clients: clients, 135 entries: make(chan api.Entry), 136 } 137 m.start() 138 139 m.Chan() <- api.Entry{Labels: model.LabelSet{"foo": "bar"}, Entry: logproto.Entry{Line: "foo"}} 140 141 m.Stop() 142 143 if len(f.Received()) != len(clients) { 144 t.Fatal("missing handle call") 145 } 146 } 147 148 func TestMultiClient_Handle_Race(t *testing.T) { 149 u := flagext.URLValue{} 150 require.NoError(t, u.Set("http://localhost")) 151 c1, err := New(nilMetrics, Config{URL: u, BackoffConfig: backoff.Config{MaxRetries: 1}, Timeout: time.Microsecond}, nil, log.NewNopLogger()) 152 require.NoError(t, err) 153 c2, err := New(nilMetrics, Config{URL: u, BackoffConfig: backoff.Config{MaxRetries: 1}, Timeout: time.Microsecond}, nil, log.NewNopLogger()) 154 require.NoError(t, err) 155 clients := []Client{c1, c2} 156 m := &MultiClient{ 157 clients: clients, 158 entries: make(chan api.Entry), 159 } 160 m.start() 161 162 m.Chan() <- api.Entry{Labels: model.LabelSet{"foo": "bar", ReservedLabelTenantID: "1"}, Entry: logproto.Entry{Line: "foo"}} 163 164 m.Stop() 165 }