mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-05-17 00:26:36 +03:00
183 lines
6.1 KiB
Go
183 lines
6.1 KiB
Go
package tests
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/apptest"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
|
|
)
|
|
|
|
func TestClusterMaxUniqueTimeseries(t *testing.T) {
|
|
fs.MustRemoveDir(t.Name())
|
|
|
|
cmpOpt := cmpopts.IgnoreFields(apptest.PrometheusAPIV1QueryResponse{}, "Status", "Data.ResultType")
|
|
|
|
tc := apptest.NewTestCase(t)
|
|
defer tc.Stop()
|
|
vmstorage := tc.MustStartVmstorage("vmstorage", []string{
|
|
"-storageDataPath=" + tc.Dir() + "/vmstorage",
|
|
"-retentionPeriod=100y",
|
|
"-search.maxUniqueTimeseries=2",
|
|
})
|
|
vminsert := tc.MustStartVminsert("vminsert", []string{
|
|
"-storageNode=" + vmstorage.VminsertAddr(),
|
|
})
|
|
vmselectNoLimit := tc.MustStartVmselect("vmselect1", []string{
|
|
"-storageNode=" + vmstorage.VmselectAddr(),
|
|
"-search.tenantCacheExpireDuration=0",
|
|
})
|
|
vmselectSmallLimit := tc.MustStartVmselect("vmselect2", []string{
|
|
"-storageNode=" + vmstorage.VmselectAddr(),
|
|
"-search.tenantCacheExpireDuration=0",
|
|
"-search.maxUniqueTimeseries=1",
|
|
})
|
|
vmselectBigLimit := tc.MustStartVmselect("vmselect3", []string{
|
|
"-storageNode=" + vmstorage.VmselectAddr(),
|
|
"-search.tenantCacheExpireDuration=0",
|
|
"-search.maxUniqueTimeseries=3",
|
|
})
|
|
|
|
var commonSamples = []string{
|
|
`foo_bar1{instance="a"} 1.00 1652169660000`,
|
|
|
|
`foo_bar2{instance="a"} 1.00 1652169660000`,
|
|
`foo_bar2{instance="b"} 2.00 1652169660000`,
|
|
|
|
`foo_bar3{instance="a"} 1.00 1652169660000`,
|
|
`foo_bar3{instance="b"} 2.00 1652169660000`,
|
|
`foo_bar3{instance="c"} 3.00 1652169660000`,
|
|
}
|
|
|
|
// write data to two tenants
|
|
tenantIDs := []string{"0:0", "1:15"}
|
|
for _, tenantID := range tenantIDs {
|
|
vminsert.PrometheusAPIV1ImportPrometheus(t, commonSamples, apptest.QueryOpts{Tenant: tenantID})
|
|
vmstorage.ForceFlush(t)
|
|
}
|
|
|
|
instantCT := "2022-05-10T08:05:00.000Z"
|
|
|
|
// success - `/api/v1/query`
|
|
want := apptest.NewPrometheusAPIV1QueryResponse(t,
|
|
`{"data":
|
|
{"result":[
|
|
{"metric":{"__name__":"foo_bar1","instance":"a"},"value":[1652169900,"1"]}
|
|
]
|
|
}
|
|
}`,
|
|
)
|
|
queryRes := vmselectSmallLimit.PrometheusAPIV1Query(t, "foo_bar1", apptest.QueryOpts{
|
|
Time: instantCT,
|
|
})
|
|
if diff := cmp.Diff(want, queryRes, cmpOpt); diff != "" {
|
|
t.Fatalf("unexpected response (-want, +got):\n%s", diff)
|
|
}
|
|
|
|
// success - multitenant `/api/v1/query`
|
|
// query is split into two queries for each tenant, so the final result can exceed the limit.
|
|
want = apptest.NewPrometheusAPIV1QueryResponse(t,
|
|
`{"data":
|
|
{"result":[
|
|
{"metric":{"__name__":"foo_bar1","instance":"a","vm_account_id":"0","vm_project_id":"0"},"value":[1652169900,"1"]},
|
|
{"metric":{"__name__":"foo_bar1","instance":"a","vm_account_id":"1","vm_project_id":"15"},"value":[1652169900,"1"]}
|
|
]
|
|
}
|
|
}`,
|
|
)
|
|
queryRes = vmselectSmallLimit.PrometheusAPIV1Query(t, "foo_bar1", apptest.QueryOpts{
|
|
Time: instantCT,
|
|
Tenant: "multitenant",
|
|
})
|
|
if diff := cmp.Diff(want, queryRes, cmpOpt); diff != "" {
|
|
t.Fatalf("unexpected response (-want, +got):\n%s", diff)
|
|
}
|
|
|
|
// fail - `/api/v1/query`, exceed vmselect `maxUniqueTimeseries`
|
|
queryRes = vmselectSmallLimit.PrometheusAPIV1Query(t, "foo_bar2", apptest.QueryOpts{
|
|
Time: instantCT,
|
|
})
|
|
if queryRes.ErrorType != "422" {
|
|
t.Fatalf("unexpected status code, got %s, want %d, error message is: %v", queryRes.ErrorType, 422, queryRes.Error)
|
|
}
|
|
|
|
// fail - `/api/v1/query`, exceed vmstorage `maxUniqueTimeseries`
|
|
queryRes = vmselectNoLimit.PrometheusAPIV1Query(t, "foo_bar3", apptest.QueryOpts{
|
|
Time: instantCT,
|
|
})
|
|
if queryRes.ErrorType != "422" {
|
|
t.Fatalf("unexpected status code, got %s, want %d, error message is: %v", queryRes.ErrorType, 422, queryRes.Error)
|
|
}
|
|
|
|
// fail - `/api/v1/query`, vmselect `maxUniqueTimeseries` cannot exceed vmstorage `maxUniqueTimeseries`
|
|
queryRes = vmselectBigLimit.PrometheusAPIV1Query(t, "foo_bar3", apptest.QueryOpts{
|
|
Time: instantCT,
|
|
})
|
|
if queryRes.ErrorType != "422" {
|
|
t.Fatalf("unexpected status code, got %s, want %d, error message is: %v", queryRes.ErrorType, 422, queryRes.Error)
|
|
}
|
|
}
|
|
|
|
func TestClusterMaxSeries(t *testing.T) {
|
|
fs.MustRemoveDir(t.Name())
|
|
|
|
cmpSROpt := cmpopts.IgnoreFields(apptest.PrometheusAPIV1SeriesResponse{}, "Status", "IsPartial")
|
|
|
|
tc := apptest.NewTestCase(t)
|
|
defer tc.Stop()
|
|
vmstorage := tc.MustStartVmstorage("vmstorage", []string{
|
|
"-storageDataPath=" + tc.Dir() + "/vmstorage",
|
|
"-retentionPeriod=100y",
|
|
"-search.maxUniqueTimeseries=2",
|
|
})
|
|
vminsert := tc.MustStartVminsert("vminsert", []string{
|
|
"-storageNode=" + vmstorage.VminsertAddr(),
|
|
})
|
|
vmselectBigLimit := tc.MustStartVmselect("vmselect2", []string{
|
|
"-storageNode=" + vmstorage.VmselectAddr(),
|
|
"-search.tenantCacheExpireDuration=0",
|
|
"-search.maxSeries=3",
|
|
})
|
|
vmselectSmallLimit := tc.MustStartVmselect("vmselect1", []string{
|
|
"-storageNode=" + vmstorage.VmselectAddr(),
|
|
"-search.tenantCacheExpireDuration=0",
|
|
"-search.maxSeries=1",
|
|
})
|
|
|
|
var commonSamples = []string{
|
|
`foo_bar3{instance="a"} 1.00 1652169660000`,
|
|
`foo_bar3{instance="b"} 2.00 1652169660000`,
|
|
`foo_bar3{instance="c"} 3.00 1652169660000`,
|
|
}
|
|
|
|
// write data
|
|
vminsert.PrometheusAPIV1ImportPrometheus(t, commonSamples, apptest.QueryOpts{})
|
|
vmstorage.ForceFlush(t)
|
|
|
|
// success - `/api/v1/series`, vmselect `maxLabelsAPISeries` can exceed vmstorage `maxLabelsAPISeries``
|
|
wantSR := apptest.NewPrometheusAPIV1SeriesResponse(t,
|
|
`{"data": [
|
|
{"__name__":"foo_bar3","instance":"a"},
|
|
{"__name__":"foo_bar3","instance":"b"},
|
|
{"__name__":"foo_bar3","instance":"c"}
|
|
]
|
|
}`)
|
|
seriesRes := vmselectBigLimit.PrometheusAPIV1Series(t, "foo_bar3", apptest.QueryOpts{
|
|
Start: "2022-05-10T08:03:00.000Z",
|
|
})
|
|
if diff := cmp.Diff(wantSR.Sort(), seriesRes.Sort(), cmpSROpt); diff != "" {
|
|
t.Fatalf("unexpected response (-want, +got):\n%s", diff)
|
|
}
|
|
|
|
// fail - `/api/v1/series`, exceed vmselect `maxSeries`
|
|
seriesRes1 := vmselectSmallLimit.PrometheusAPIV1Series(t, "foo_bar3", apptest.QueryOpts{
|
|
Start: "2022-05-10T08:03:00.000Z",
|
|
})
|
|
if seriesRes1.ErrorType != "422" {
|
|
t.Fatalf("unexpected status code, got %s, want %d, error message is: %v", seriesRes.ErrorType, 422, seriesRes1.Error)
|
|
}
|
|
|
|
}
|