diff --git a/test/e2e/receive_test.go b/test/e2e/receive_test.go index c938a4f040..9e715bc3a8 100644 --- a/test/e2e/receive_test.go +++ b/test/e2e/receive_test.go @@ -1215,3 +1215,74 @@ func TestReceiveCpnp(t *testing.T) { }, v) } + +func TestNewTenant(t *testing.T) { + e, err := e2e.NewDockerEnvironment("new-tenant") + testutil.Ok(t, err) + t.Cleanup(e2ethanos.CleanScenario(t, e)) + + // Setup 3 ingestors. + i1 := e2ethanos.NewReceiveBuilder(e, "i1").WithIngestionEnabled().Init() + i2 := e2ethanos.NewReceiveBuilder(e, "i2").WithIngestionEnabled().Init() + i3 := e2ethanos.NewReceiveBuilder(e, "i3").WithIngestionEnabled().Init() + + h := receive.HashringConfig{ + Endpoints: []receive.Endpoint{ + {Address: i1.InternalEndpoint("grpc")}, + {Address: i2.InternalEndpoint("grpc")}, + {Address: i3.InternalEndpoint("grpc")}, + }, + } + + // Setup 1 distributor with double replication + r1 := e2ethanos.NewReceiveBuilder(e, "r1").WithRouting(2, h).Init() + testutil.Ok(t, e2e.StartAndWaitReady(i1, i2, i3, r1)) + + q := e2ethanos.NewQuerierBuilder(e, "1", i1.InternalEndpoint("grpc"), i2.InternalEndpoint("grpc"), i3.InternalEndpoint("grpc")).Init() + testutil.Ok(t, e2e.StartAndWaitReady(q)) + testutil.Ok(t, q.WaitSumMetricsWithOptions(e2emon.Equals(3), []string{"thanos_store_nodes_grpc_connections"}, e2emon.WaitMissingMetrics())) + + rp1 := e2ethanos.NewReverseProxy(e, "1", "tenant-1", "http://"+r1.InternalEndpoint("remote-write")) + prom1 := e2ethanos.NewPrometheus(e, "1", e2ethanos.DefaultPromConfig("prom1", 0, "http://"+rp1.InternalEndpoint("http")+"/api/v1/receive", "", e2ethanos.LocalPrometheusTarget), "", e2ethanos.DefaultPrometheusImage()) + testutil.Ok(t, e2e.StartAndWaitReady(rp1, prom1)) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + t.Cleanup(cancel) + + expectedReplicationFactor := 2.0 + + queryAndAssert(t, ctx, q.Endpoint("http"), func() string { return "count(up) by (prometheus, tenant_id)" }, time.Now, promclient.QueryOptions{ + Deduplicate: false, + }, model.Vector{ + &model.Sample{ + Metric: model.Metric{ + "prometheus": "prom1", + "tenant_id": "tenant-1", + }, + Value: model.SampleValue(expectedReplicationFactor), + }, + }) + + rp2 := e2ethanos.NewReverseProxy(e, "2", "tenant-2", "http://"+r1.InternalEndpoint("remote-write")) + prom2 := e2ethanos.NewPrometheus(e, "2", e2ethanos.DefaultPromConfig("prom2", 0, "http://"+rp2.InternalEndpoint("http")+"/api/v1/receive", "", e2ethanos.LocalPrometheusTarget), "", e2ethanos.DefaultPrometheusImage()) + testutil.Ok(t, e2e.StartAndWaitReady(rp2, prom2)) + + queryAndAssert(t, ctx, q.Endpoint("http"), func() string { return "count(up) by (prometheus, tenant_id)" }, time.Now, promclient.QueryOptions{ + Deduplicate: false, + }, model.Vector{ + &model.Sample{ + Metric: model.Metric{ + "prometheus": "prom1", + "tenant_id": "tenant-1", + }, + Value: model.SampleValue(expectedReplicationFactor), + }, + &model.Sample{ + Metric: model.Metric{ + "prometheus": "prom2", + "tenant_id": "tenant-2", + }, + Value: model.SampleValue(expectedReplicationFactor), + }, + }) +}