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  }