github.com/thanos-io/thanos@v0.32.5/test/e2e/info_api_test.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package e2e_test
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"fmt"
    10  	"io"
    11  	"net/http"
    12  	"path"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/efficientgo/e2e"
    17  	"github.com/prometheus/prometheus/model/labels"
    18  
    19  	"github.com/thanos-io/objstore/client"
    20  
    21  	"github.com/efficientgo/core/testutil"
    22  	e2edb "github.com/efficientgo/e2e/db"
    23  	"github.com/thanos-io/thanos/pkg/query"
    24  	"github.com/thanos-io/thanos/pkg/runutil"
    25  	"github.com/thanos-io/thanos/test/e2e/e2ethanos"
    26  )
    27  
    28  func TestInfo(t *testing.T) {
    29  	t.Parallel()
    30  
    31  	e, err := e2e.NewDockerEnvironment("e2e-test-info")
    32  	testutil.Ok(t, err)
    33  	t.Cleanup(e2ethanos.CleanScenario(t, e))
    34  
    35  	prom1, sidecar1 := e2ethanos.NewPrometheusWithSidecar(e, "alone1", e2ethanos.DefaultPromConfig("prom-alone1", 0, "", "", e2ethanos.LocalPrometheusTarget), "", e2ethanos.DefaultPrometheusImage(), "")
    36  	prom2, sidecar2 := e2ethanos.NewPrometheusWithSidecar(e, "alone2", e2ethanos.DefaultPromConfig("prom-alone2", 0, "", "", e2ethanos.LocalPrometheusTarget), "", e2ethanos.DefaultPrometheusImage(), "")
    37  	prom3, sidecar3 := e2ethanos.NewPrometheusWithSidecar(e, "alone3", e2ethanos.DefaultPromConfig("prom-alone3", 0, "", "", e2ethanos.LocalPrometheusTarget), "", e2ethanos.DefaultPrometheusImage(), "")
    38  	testutil.Ok(t, e2e.StartAndWaitReady(prom1, sidecar1, prom2, sidecar2, prom3, sidecar3))
    39  
    40  	const bucket = "info-api-test"
    41  	m := e2edb.NewMinio(e, "thanos-minio", bucket, e2edb.WithMinioTLS())
    42  	testutil.Ok(t, e2e.StartAndWaitReady(m))
    43  	store := e2ethanos.NewStoreGW(
    44  		e,
    45  		"1",
    46  		client.BucketConfig{
    47  			Type:   client.S3,
    48  			Config: e2ethanos.NewS3Config(bucket, m.InternalEndpoint("http"), m.InternalDir()),
    49  		},
    50  		"",
    51  		"",
    52  		nil,
    53  	)
    54  	testutil.Ok(t, e2e.StartAndWaitReady(store))
    55  
    56  	// Register `sidecar1` in all flags (i.e. '--store', '--rule', '--target', '--metadata', '--exemplar', '--endpoint') to verify
    57  	// '--endpoint' flag works properly works together with other flags ('--target', '--metadata' etc.).
    58  	// Register 2 sidecars and 1 storeGW using '--endpoint'.
    59  	// Register `sidecar3` twice to verify it is deduplicated.
    60  	q := e2ethanos.NewQuerierBuilder(e, "1", sidecar1.InternalEndpoint("grpc")).
    61  		WithTargetAddresses(sidecar1.InternalEndpoint("grpc")).
    62  		WithMetadataAddresses(sidecar1.InternalEndpoint("grpc")).
    63  		WithExemplarAddresses(sidecar1.InternalEndpoint("grpc")).
    64  		WithRuleAddresses(sidecar1.InternalEndpoint("grpc")).
    65  		WithEndpoints(
    66  			sidecar1.InternalEndpoint("grpc"),
    67  			sidecar2.InternalEndpoint("grpc"),
    68  			sidecar3.InternalEndpoint("grpc"),
    69  			store.InternalEndpoint("grpc"),
    70  		).
    71  		Init()
    72  	testutil.Ok(t, e2e.StartAndWaitReady(q))
    73  
    74  	expected := map[string][]query.EndpointStatus{
    75  		"sidecar": {
    76  			{
    77  				Name: "e2e-test-info-sidecar-alone1:9091",
    78  				LabelSets: []labels.Labels{{
    79  					{
    80  						Name:  "prometheus",
    81  						Value: "prom-alone1",
    82  					},
    83  					{
    84  						Name:  "replica",
    85  						Value: "0",
    86  					},
    87  				}},
    88  			},
    89  			{
    90  				Name: "e2e-test-info-sidecar-alone2:9091",
    91  				LabelSets: []labels.Labels{{
    92  					{
    93  						Name:  "prometheus",
    94  						Value: "prom-alone2",
    95  					},
    96  					{
    97  						Name:  "replica",
    98  						Value: "0",
    99  					},
   100  				}},
   101  			},
   102  			{
   103  				Name: "e2e-test-info-sidecar-alone3:9091",
   104  				LabelSets: []labels.Labels{{
   105  					{
   106  						Name:  "prometheus",
   107  						Value: "prom-alone3",
   108  					},
   109  					{
   110  						Name:  "replica",
   111  						Value: "0",
   112  					},
   113  				}},
   114  			},
   115  		},
   116  		"store": {
   117  			{
   118  				Name:      "e2e-test-info-store-gw-1:9091",
   119  				LabelSets: []labels.Labels{},
   120  			},
   121  		},
   122  	}
   123  
   124  	url := "http://" + path.Join(q.Endpoint("http"), "/api/v1/stores")
   125  
   126  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
   127  	defer cancel()
   128  
   129  	err = runutil.Retry(time.Second, ctx.Done(), func() error {
   130  
   131  		req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
   132  		if err != nil {
   133  			return err
   134  		}
   135  
   136  		resp, err := http.DefaultClient.Do(req)
   137  		if err != nil {
   138  			return err
   139  		}
   140  
   141  		body, err := io.ReadAll(resp.Body)
   142  		defer runutil.CloseWithErrCapture(&err, resp.Body, "response body close")
   143  
   144  		var res struct {
   145  			Data map[string][]query.EndpointStatus `json:"data"`
   146  		}
   147  
   148  		err = json.Unmarshal(body, &res)
   149  		if err != nil {
   150  			return err
   151  		}
   152  
   153  		if err = assertStoreStatus(t, "sidecar", res.Data, expected); err != nil {
   154  			return err
   155  		}
   156  
   157  		if err = assertStoreStatus(t, "store", res.Data, expected); err != nil {
   158  			return err
   159  		}
   160  
   161  		return nil
   162  	})
   163  	testutil.Ok(t, err)
   164  }
   165  
   166  func assertStoreStatus(t *testing.T, component string, res map[string][]query.EndpointStatus, expected map[string][]query.EndpointStatus) error {
   167  	t.Helper()
   168  
   169  	if len(res[component]) != len(expected[component]) {
   170  		return fmt.Errorf("expected %d %s, got: %d", len(expected[component]), component, len(res[component]))
   171  	}
   172  
   173  	for i, v := range res[component] {
   174  		// Set value of the fields which keep changing in every test run to their default value.
   175  		v.MaxTime = 0
   176  		v.MinTime = 0
   177  		v.LastCheck = time.Time{}
   178  
   179  		testutil.Equals(t, expected[component][i], v)
   180  	}
   181  
   182  	return nil
   183  }