Skip to content

Commit

Permalink
query: Added tests for compatiblity for old components without InfoAPI.
Browse files Browse the repository at this point in the history
Signed-off-by: Bartlomiej Plotka <[email protected]>
  • Loading branch information
bwplotka committed Sep 7, 2021
1 parent b60b15f commit d8b3865
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 158 deletions.
1 change: 0 additions & 1 deletion pkg/query/endpointset.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ func (es *grpcEndpointSpec) getMetadataUsingStoreAPI(ctx context.Context, client
}

func (es *grpcEndpointSpec) fillExpectedAPIs(componentType component.Component, mintime, maxTime int64) infopb.InfoResponse {

switch componentType {
case component.Sidecar:
return infopb.InfoResponse{
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/compact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ func testCompactWithStoreGateway(t *testing.T, penaltyDedup bool) {
testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total"))
testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified"))

q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "1", []string{str.GRPCNetworkEndpoint()}).Build()
q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "1", str.GRPCNetworkEndpoint()).Build()
testutil.Ok(t, err)
testutil.Ok(t, s.StartAndWaitReady(q))

Expand Down
27 changes: 19 additions & 8 deletions test/e2e/e2ethanos/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ func NewPrometheus(sharedDir, name, config, promImage string, enableFeatures ...
}

func NewPrometheusWithSidecar(sharedDir, netName, name, config, promImage string, enableFeatures ...string) (*e2e.HTTPService, *Service, error) {
return NewPrometheusWithSidecarCustomImage(sharedDir, netName, name, config, promImage, DefaultImage(), enableFeatures...)
}

func NewPrometheusWithSidecarCustomImage(sharedDir, netName, name, config, promImage string, sidecarImage string, enableFeatures ...string) (*e2e.HTTPService, *Service, error) {
prom, dataDir, err := NewPrometheus(sharedDir, name, config, promImage, enableFeatures...)
if err != nil {
return nil, nil, err
Expand All @@ -104,7 +108,7 @@ func NewPrometheusWithSidecar(sharedDir, netName, name, config, promImage string

sidecar := NewService(
fmt.Sprintf("sidecar-%s", name),
DefaultImage(),
sidecarImage,
e2e.NewCommand("sidecar", e2e.BuildArgs(map[string]string{
"--debug.name": fmt.Sprintf("sidecar-%v", name),
"--grpc-address": ":9091",
Expand All @@ -129,6 +133,7 @@ type QuerierBuilder struct {
name string
routePrefix string
externalPrefix string
image string

storeAddresses []string
fileSDStoreAddresses []string
Expand All @@ -140,35 +145,41 @@ type QuerierBuilder struct {
tracingConfig string
}

func NewQuerierBuilder(sharedDir, name string, storeAddresses []string) *QuerierBuilder {
func NewQuerierBuilder(sharedDir, name string, storeAddresses ...string) *QuerierBuilder {
return &QuerierBuilder{
sharedDir: sharedDir,
name: name,
storeAddresses: storeAddresses,
image: DefaultImage(),
}
}

func (q *QuerierBuilder) WithFileSDStoreAddresses(fileSDStoreAddresses []string) *QuerierBuilder {
func (q *QuerierBuilder) WithImage(image string) *QuerierBuilder {
q.image = image
return q
}

func (q *QuerierBuilder) WithFileSDStoreAddresses(fileSDStoreAddresses ...string) *QuerierBuilder {
q.fileSDStoreAddresses = fileSDStoreAddresses
return q
}

func (q *QuerierBuilder) WithRuleAddresses(ruleAddresses []string) *QuerierBuilder {
func (q *QuerierBuilder) WithRuleAddresses(ruleAddresses ...string) *QuerierBuilder {
q.ruleAddresses = ruleAddresses
return q
}

func (q *QuerierBuilder) WithTargetAddresses(targetAddresses []string) *QuerierBuilder {
func (q *QuerierBuilder) WithTargetAddresses(targetAddresses ...string) *QuerierBuilder {
q.targetAddresses = targetAddresses
return q
}

func (q *QuerierBuilder) WithExemplarAddresses(exemplarAddresses []string) *QuerierBuilder {
func (q *QuerierBuilder) WithExemplarAddresses(exemplarAddresses ...string) *QuerierBuilder {
q.exemplarAddresses = exemplarAddresses
return q
}

func (q *QuerierBuilder) WithMetadataAddresses(metadataAddresses []string) *QuerierBuilder {
func (q *QuerierBuilder) WithMetadataAddresses(metadataAddresses ...string) *QuerierBuilder {
q.metadataAddresses = metadataAddresses
return q
}
Expand Down Expand Up @@ -260,7 +271,7 @@ func (q *QuerierBuilder) Build() (*Service, error) {

querier := NewService(
fmt.Sprintf("querier-%v", q.name),
DefaultImage(),
q.image,
e2e.NewCommand("query", args...),
e2e.NewHTTPReadinessProbe(8080, "/-/ready", 200, 200),
8080,
Expand Down
154 changes: 53 additions & 101 deletions test/e2e/exemplars_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/cortexproject/cortex/integration/e2e"
"github.com/pkg/errors"
"github.com/prometheus/prometheus/pkg/timestamp"
"github.com/thanos-io/thanos/pkg/exemplars/exemplarspb"
"github.com/thanos-io/thanos/pkg/store/labelpb"
Expand All @@ -26,68 +27,42 @@ func TestExemplarsAPI_Fanout(t *testing.T) {

netName := "e2e_test_exemplars_fanout"

var (
prom1, prom2 *e2e.HTTPService
sidecar1, sidecar2 *e2ethanos.Service
err error
s *e2e.Scenario
)

s, err = e2e.NewScenario(netName)
s, err := e2e.NewScenario(netName)
testutil.Ok(t, err)
t.Cleanup(e2ethanos.CleanScenario(t, s))

// 2x Prometheus.
_, sidecar1, err = e2ethanos.NewPrometheusWithSidecar(
s.SharedDir(),
netName,
"prom1",
defaultPromConfig("ha", 0, "", ""),
e2ethanos.DefaultPrometheusImage(),
e2ethanos.FeatureExemplarStorage,
)
testutil.Ok(t, err)
_, sidecar2, err = e2ethanos.NewPrometheusWithSidecar(
s.SharedDir(),
netName,
"prom2",
defaultPromConfig("ha", 1, "", ""),
e2ethanos.DefaultPrometheusImage(),
e2ethanos.FeatureExemplarStorage,
)
testutil.Ok(t, err)

tracingCfg := fmt.Sprintf(`type: JAEGER
stores := []string{
e2e.NetworkContainerHostPort(netName, "sidecar-prom1", 9091), // TODO(bwplotka): Use newer e2e lib to handle this in type safe manner.
e2e.NetworkContainerHostPort(netName, "sidecar-prom2", 9091), // TODO(bwplotka): Use newer e2e lib to handle this in type safe manner.
}
q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "query", stores...).
WithExemplarAddresses(stores...).
WithTracingConfig(fmt.Sprintf(`type: JAEGER
config:
sampler_type: const
sampler_param: 1
service_name: %s`, s.NetworkName()+"-query")

stores := []string{sidecar1.NetworkEndpointFor(s.NetworkName(), 9091), sidecar2.NetworkEndpointFor(s.NetworkName(), 9091)}
q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "query", stores).
WithExemplarAddresses(stores).
WithTracingConfig(tracingCfg).
service_name: %s`, s.NetworkName()+"-query")).
Build()
testutil.Ok(t, err)
testutil.Ok(t, s.StartAndWaitReady(q))

// Recreate Prometheus and sidecar with Thanos query scrape target.
prom1, sidecar1, err = e2ethanos.NewPrometheusWithSidecar(
prom1, sidecar1, err := e2ethanos.NewPrometheusWithSidecar(
s.SharedDir(),
netName,
"prom1",
defaultPromConfig("ha", 0, "", "", "localhost:9090", q.NetworkHTTPEndpoint()),
e2ethanos.DefaultPrometheusImage(),
"exemplar-storage",
e2ethanos.FeatureExemplarStorage,
)
testutil.Ok(t, err)
prom2, sidecar2, err = e2ethanos.NewPrometheusWithSidecar(
prom2, sidecar2, err := e2ethanos.NewPrometheusWithSidecar(
s.SharedDir(),
netName,
"prom2",
defaultPromConfig("ha", 1, "", "", "localhost:9090", q.NetworkHTTPEndpoint()),
e2ethanos.DefaultPrometheusImage(),
"exemplar-storage",
e2ethanos.FeatureExemplarStorage,
)
testutil.Ok(t, err)
testutil.Ok(t, s.StartAndWaitReady(prom1, sidecar1, prom2, sidecar2))
Expand All @@ -103,88 +78,65 @@ config:
end := timestamp.FromTime(now.Add(time.Hour))

// Send HTTP requests to thanos query to trigger exemplars.
labelNames(t, ctx, q.HTTPEndpoint(), nil, start, end, func(res []string) bool {
return true
})
labelNames(t, ctx, q.HTTPEndpoint(), nil, start, end, func(res []string) bool { return true })

t.Run("Basic exemplars query", func(t *testing.T) {
requiredSeriesLabels := map[string]string{
queryExemplars(t, ctx, q.HTTPEndpoint(), `http_request_duration_seconds_bucket{handler="label_names"}`, start, end, exemplarsOnExpectedSeries(map[string]string{
"__name__": "http_request_duration_seconds_bucket",
"handler": "label_names",
"job": "myself",
"method": "get",
"prometheus": "ha",
}
queryExemplars(t, ctx, q.HTTPEndpoint(), `http_request_duration_seconds_bucket{handler="label_names"}`,
start, end, func(data []*exemplarspb.ExemplarData) bool {
if len(data) != 1 {
return false
}

// Compare series labels.
seriesLabels := labelpb.ZLabelSetsToPromLabelSets(data[0].SeriesLabels)
for _, lbls := range seriesLabels {
for k, v := range requiredSeriesLabels {
if lbls.Get(k) != v {
return false
}
}
}

// Make sure the exemplar contains the correct traceID label.
for _, exemplar := range data[0].Exemplars {
for _, lbls := range labelpb.ZLabelSetsToPromLabelSets(exemplar.Labels) {
if !lbls.Has(traceIDLabel) {
return false
}
}
}
return true
})
}))
})

t.Run("Exemplars query with matched external label", func(t *testing.T) {
requiredSeriesLabels := map[string]string{
// Here replica is an external label.
queryExemplars(t, ctx, q.HTTPEndpoint(), `http_request_duration_seconds_bucket{handler="label_names", replica="0"}`, start, end, exemplarsOnExpectedSeries(map[string]string{
"__name__": "http_request_duration_seconds_bucket",
"handler": "label_names",
"job": "myself",
"method": "get",
"prometheus": "ha",
}
// Here replica is an external label.
queryExemplars(t, ctx, q.HTTPEndpoint(), `http_request_duration_seconds_bucket{handler="label_names", replica="0"}`,
start, end, func(data []*exemplarspb.ExemplarData) bool {
if len(data) != 1 {
return false
}

// Compare series labels.
seriesLabels := labelpb.ZLabelSetsToPromLabelSets(data[0].SeriesLabels)
for _, lbls := range seriesLabels {
for k, v := range requiredSeriesLabels {
if lbls.Get(k) != v {
return false
}
}
}

// Make sure the exemplar contains the correct traceID label.
for _, exemplar := range data[0].Exemplars {
for _, lbls := range labelpb.ZLabelSetsToPromLabelSets(exemplar.Labels) {
if !lbls.Has(traceIDLabel) {
return false
}
}
}
return true
})
}))
})

t.Run("Exemplars query doesn't match external label", func(t *testing.T) {
// Here replica is an external label, but it doesn't match.
queryExemplars(t, ctx, q.HTTPEndpoint(), `http_request_duration_seconds_bucket{handler="label_names", replica="foo"}`,
start, end, func(data []*exemplarspb.ExemplarData) bool {
return len(data) == 0
start, end, func(data []*exemplarspb.ExemplarData) error {
if len(data) > 0 {
return errors.Errorf("expected no examplers, got %v", data)
}
return nil
})
})
}

func exemplarsOnExpectedSeries(requiredSeriesLabels map[string]string) func(data []*exemplarspb.ExemplarData) error {
return func(data []*exemplarspb.ExemplarData) error {
if len(data) != 1 {
return errors.Errorf("unexpected result size, expected 1, got: %v", len(data))
}

// Compare series labels.
seriesLabels := labelpb.ZLabelSetsToPromLabelSets(data[0].SeriesLabels)
for _, lbls := range seriesLabels {
for k, v := range requiredSeriesLabels {
if lbls.Get(k) != v {
return errors.Errorf("unexpected labels in result, expected %v, got: %v", requiredSeriesLabels, seriesLabels)
}
}
}

// Make sure the exemplar contains the correct traceID label.
for _, exemplar := range data[0].Exemplars {
for _, lbls := range labelpb.ZLabelSetsToPromLabelSets(exemplar.Labels) {
if !lbls.Has(traceIDLabel) {
return errors.Errorf("unexpected labels in exemplar, expected %v, got: %v", traceIDLabel, exemplar.Labels)
}
}
}
return nil
}
}
4 changes: 2 additions & 2 deletions test/e2e/metadata_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func TestMetadataAPI_Fanout(t *testing.T) {
testutil.Ok(t, s.StartAndWaitReady(prom1, sidecar1, prom2, sidecar2))

stores := []string{sidecar1.GRPCNetworkEndpoint(), sidecar2.GRPCNetworkEndpoint()}
q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "query", stores).
WithMetadataAddresses(stores).
q, err := e2ethanos.NewQuerierBuilder(s.SharedDir(), "query", stores...).
WithMetadataAddresses(stores...).
Build()
testutil.Ok(t, err)
testutil.Ok(t, s.StartAndWaitReady(q))
Expand Down
Loading

0 comments on commit d8b3865

Please sign in to comment.