github.com/thanos-io/thanos@v0.32.5/pkg/promclient/promclient_e2e_test.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package promclient
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"net/url"
    10  	"os"
    11  	"path"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/oklog/ulid"
    16  	"github.com/prometheus/common/model"
    17  	"github.com/prometheus/prometheus/config"
    18  	"github.com/prometheus/prometheus/model/labels"
    19  	"github.com/prometheus/prometheus/model/timestamp"
    20  	"gopkg.in/yaml.v3"
    21  
    22  	"github.com/efficientgo/core/testutil"
    23  	"github.com/thanos-io/thanos/pkg/block/metadata"
    24  	"github.com/thanos-io/thanos/pkg/runutil"
    25  	"github.com/thanos-io/thanos/pkg/testutil/e2eutil"
    26  )
    27  
    28  func TestIsWALFileAccessible_e2e(t *testing.T) {
    29  	e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) {
    30  		testutil.Ok(t, p.Start())
    31  
    32  		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
    33  		defer cancel()
    34  		testutil.Ok(t, runutil.Retry(time.Second, ctx.Done(), func() error { return IsWALDirAccessible(p.Dir()) }))
    35  
    36  		testutil.NotOk(t, IsWALDirAccessible(path.Join(p.Dir(), "/non-existing")))
    37  		testutil.NotOk(t, IsWALDirAccessible(path.Join(p.Dir(), "/../")))
    38  	})
    39  }
    40  
    41  func TestExternalLabels_e2e(t *testing.T) {
    42  	e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) {
    43  		// Keep consistent with the config processing in function (*Client).ExternalLabels.
    44  		cfg := config.Config{GlobalConfig: config.GlobalConfig{ExternalLabels: []labels.Label{
    45  			{Name: "region", Value: "eu-west"},
    46  			{Name: "az", Value: "1"},
    47  		}}}
    48  		cfgData, err := yaml.Marshal(cfg)
    49  		testutil.Ok(t, err)
    50  		p.SetConfig(string(cfgData))
    51  
    52  		testutil.Ok(t, p.Start())
    53  
    54  		u, err := url.Parse(fmt.Sprintf("http://%s", p.Addr()))
    55  		testutil.Ok(t, err)
    56  
    57  		ext, err := NewDefaultClient().ExternalLabels(context.Background(), u)
    58  		testutil.Ok(t, err)
    59  
    60  		testutil.Equals(t, 2, len(ext))
    61  		testutil.Equals(t, "eu-west", ext.Get("region"))
    62  		testutil.Equals(t, "1", ext.Get("az"))
    63  	})
    64  }
    65  
    66  func TestConfiguredFlags_e2e(t *testing.T) {
    67  	e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) {
    68  		testutil.Ok(t, p.Start())
    69  
    70  		u, err := url.Parse(fmt.Sprintf("http://%s", p.Addr()))
    71  		testutil.Ok(t, err)
    72  
    73  		flags, err := NewDefaultClient().ConfiguredFlags(context.Background(), u)
    74  		testutil.Ok(t, err)
    75  
    76  		testutil.Assert(t, flags.WebEnableAdminAPI, "")
    77  		testutil.Assert(t, !flags.WebEnableLifecycle, "")
    78  		testutil.Equals(t, p.Dir(), flags.TSDBPath)
    79  		testutil.Equals(t, int64(2*time.Hour), int64(flags.TSDBMinTime))
    80  		testutil.Equals(t, int64(4.8*float64(time.Hour)), int64(flags.TSDBMaxTime))
    81  		testutil.Equals(t, int64(2*24*time.Hour), int64(flags.TSDBRetention))
    82  	})
    83  }
    84  
    85  func TestSnapshot_e2e(t *testing.T) {
    86  	e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) {
    87  		now := time.Now()
    88  
    89  		ctx := context.Background()
    90  		// Create artificial block.
    91  		id, err := e2eutil.CreateBlockWithTombstone(
    92  			ctx,
    93  			p.Dir(),
    94  			[]labels.Labels{labels.FromStrings("a", "b")},
    95  			10,
    96  			timestamp.FromTime(now.Add(-6*time.Hour)),
    97  			timestamp.FromTime(now.Add(-4*time.Hour)),
    98  			nil,
    99  			0,
   100  			metadata.NoneFunc,
   101  		)
   102  		testutil.Ok(t, err)
   103  
   104  		testutil.Ok(t, p.Start())
   105  
   106  		u, err := url.Parse(fmt.Sprintf("http://%s", p.Addr()))
   107  		testutil.Ok(t, err)
   108  
   109  		// Prometheus since 2.7.0 don't write empty blocks even if it's head block. So it's no matter passing skip_head true or false here
   110  		// Pass skipHead = true to support all prometheus versions and assert that snapshot creates only one file
   111  		// https://github.com/prometheus/tsdb/pull/374.
   112  		dir, err := NewDefaultClient().Snapshot(ctx, u, true)
   113  		testutil.Ok(t, err)
   114  
   115  		_, err = os.Stat(path.Join(p.Dir(), dir, id.String()))
   116  		testutil.Ok(t, err)
   117  
   118  		files, err := os.ReadDir(path.Join(p.Dir(), dir))
   119  		testutil.Ok(t, err)
   120  
   121  		for _, f := range files {
   122  			_, err := ulid.Parse(f.Name())
   123  			testutil.Ok(t, err)
   124  		}
   125  
   126  		testutil.Equals(t, 1, len(files))
   127  	})
   128  }
   129  
   130  func TestRule_UnmarshalScalarResponse(t *testing.T) {
   131  	var (
   132  		scalarJSONResult              = []byte(`[1541196373.677,"1"]`)
   133  		invalidLengthScalarJSONResult = []byte(`[1541196373.677,"1", "nonsense"]`)
   134  		invalidDataScalarJSONResult   = []byte(`["foo","bar"]`)
   135  
   136  		vectorResult   model.Vector
   137  		expectedVector = model.Vector{&model.Sample{
   138  			Metric:    model.Metric{},
   139  			Value:     1,
   140  			Timestamp: model.Time(1541196373677)}}
   141  	)
   142  	// Test valid input.
   143  	vectorResult, err := convertScalarJSONToVector(scalarJSONResult)
   144  	testutil.Ok(t, err)
   145  	testutil.Equals(t, vectorResult.String(), expectedVector.String())
   146  
   147  	// Test invalid length of scalar data structure.
   148  	_, err = convertScalarJSONToVector(invalidLengthScalarJSONResult)
   149  	testutil.NotOk(t, err)
   150  
   151  	// Test invalid format of scalar data.
   152  	_, err = convertScalarJSONToVector(invalidDataScalarJSONResult)
   153  	testutil.NotOk(t, err)
   154  }
   155  
   156  func TestQueryRange_e2e(t *testing.T) {
   157  	e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) {
   158  		now := time.Now()
   159  
   160  		ctx := context.Background()
   161  		// Create artificial block.
   162  		_, err := e2eutil.CreateBlock(
   163  			ctx,
   164  			p.Dir(),
   165  			[]labels.Labels{labels.FromStrings("a", "b")},
   166  			10,
   167  			timestamp.FromTime(now.Add(-2*time.Hour)),
   168  			timestamp.FromTime(now),
   169  			nil,
   170  			0,
   171  			metadata.NoneFunc,
   172  		)
   173  		testutil.Ok(t, err)
   174  
   175  		testutil.Ok(t, p.Start())
   176  
   177  		u, err := url.Parse(fmt.Sprintf("http://%s", p.Addr()))
   178  		testutil.Ok(t, err)
   179  
   180  		res, _, _, err := NewDefaultClient().QueryRange(
   181  			ctx,
   182  			u,
   183  			`{a="b"}`,
   184  			timestamp.FromTime(now.Add(-2*time.Hour)),
   185  			timestamp.FromTime(now),
   186  			14,
   187  			QueryOptions{},
   188  		)
   189  		testutil.Ok(t, err)
   190  
   191  		testutil.Equals(t, len(res) > 0, true)
   192  	})
   193  }