|
|
|
|
@ -29,6 +29,8 @@ import ( |
|
|
|
|
"github.com/prometheus/common/route" |
|
|
|
|
"golang.org/x/net/context" |
|
|
|
|
|
|
|
|
|
"github.com/prometheus/prometheus/pkg/labels" |
|
|
|
|
"github.com/prometheus/prometheus/pkg/timestamp" |
|
|
|
|
"github.com/prometheus/prometheus/promql" |
|
|
|
|
"github.com/prometheus/prometheus/retrieval" |
|
|
|
|
) |
|
|
|
|
@ -55,17 +57,17 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
now := model.Now() |
|
|
|
|
now := time.Now() |
|
|
|
|
|
|
|
|
|
tr := targetRetrieverFunc(func() []retrieval.Target { |
|
|
|
|
return []retrieval.Target{ |
|
|
|
|
*retrieval.NewTarget( |
|
|
|
|
model.LabelSet{ |
|
|
|
|
labels.FromMap(map[string]string{ |
|
|
|
|
model.SchemeLabel: "http", |
|
|
|
|
model.AddressLabel: "example.com:8080", |
|
|
|
|
model.MetricsPathLabel: "/metrics", |
|
|
|
|
}, |
|
|
|
|
model.LabelSet{}, |
|
|
|
|
}), |
|
|
|
|
nil, |
|
|
|
|
url.Values{}, |
|
|
|
|
), |
|
|
|
|
} |
|
|
|
|
@ -75,10 +77,11 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
Storage: suite.Storage(), |
|
|
|
|
QueryEngine: suite.QueryEngine(), |
|
|
|
|
targetRetriever: tr, |
|
|
|
|
now: func() model.Time { return now }, |
|
|
|
|
now: func() time.Time { return now }, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
start := model.Time(0) |
|
|
|
|
start := time.Unix(0, 0) |
|
|
|
|
|
|
|
|
|
var tests = []struct { |
|
|
|
|
endpoint apiFunc |
|
|
|
|
params map[string]string |
|
|
|
|
@ -90,13 +93,13 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
endpoint: api.query, |
|
|
|
|
query: url.Values{ |
|
|
|
|
"query": []string{"2"}, |
|
|
|
|
"time": []string{"123.3"}, |
|
|
|
|
"time": []string{"123.4"}, |
|
|
|
|
}, |
|
|
|
|
response: &queryData{ |
|
|
|
|
ResultType: model.ValScalar, |
|
|
|
|
Result: &model.Scalar{ |
|
|
|
|
Value: 2, |
|
|
|
|
Timestamp: start.Add(123*time.Second + 300*time.Millisecond), |
|
|
|
|
ResultType: promql.ValueTypeScalar, |
|
|
|
|
Result: promql.Scalar{ |
|
|
|
|
V: 2, |
|
|
|
|
T: timestamp.FromTime(start.Add(123*time.Second + 400*time.Millisecond)), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
@ -107,10 +110,10 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"time": []string{"1970-01-01T00:02:03Z"}, |
|
|
|
|
}, |
|
|
|
|
response: &queryData{ |
|
|
|
|
ResultType: model.ValScalar, |
|
|
|
|
Result: &model.Scalar{ |
|
|
|
|
Value: 0.333, |
|
|
|
|
Timestamp: start.Add(123 * time.Second), |
|
|
|
|
ResultType: promql.ValueTypeScalar, |
|
|
|
|
Result: promql.Scalar{ |
|
|
|
|
V: 0.333, |
|
|
|
|
T: timestamp.FromTime(start.Add(123 * time.Second)), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
@ -121,10 +124,10 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"time": []string{"1970-01-01T01:02:03+01:00"}, |
|
|
|
|
}, |
|
|
|
|
response: &queryData{ |
|
|
|
|
ResultType: model.ValScalar, |
|
|
|
|
Result: &model.Scalar{ |
|
|
|
|
Value: 0.333, |
|
|
|
|
Timestamp: start.Add(123 * time.Second), |
|
|
|
|
ResultType: promql.ValueTypeScalar, |
|
|
|
|
Result: promql.Scalar{ |
|
|
|
|
V: 0.333, |
|
|
|
|
T: timestamp.FromTime(start.Add(123 * time.Second)), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
@ -134,10 +137,10 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"query": []string{"0.333"}, |
|
|
|
|
}, |
|
|
|
|
response: &queryData{ |
|
|
|
|
ResultType: model.ValScalar, |
|
|
|
|
Result: &model.Scalar{ |
|
|
|
|
Value: 0.333, |
|
|
|
|
Timestamp: now, |
|
|
|
|
ResultType: promql.ValueTypeScalar, |
|
|
|
|
Result: promql.Scalar{ |
|
|
|
|
V: 0.333, |
|
|
|
|
T: timestamp.FromTime(now), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
@ -150,15 +153,15 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"step": []string{"1"}, |
|
|
|
|
}, |
|
|
|
|
response: &queryData{ |
|
|
|
|
ResultType: model.ValMatrix, |
|
|
|
|
Result: model.Matrix{ |
|
|
|
|
&model.SampleStream{ |
|
|
|
|
Values: []model.SamplePair{ |
|
|
|
|
{Value: 0, Timestamp: start}, |
|
|
|
|
{Value: 1, Timestamp: start.Add(1 * time.Second)}, |
|
|
|
|
{Value: 2, Timestamp: start.Add(2 * time.Second)}, |
|
|
|
|
ResultType: promql.ValueTypeMatrix, |
|
|
|
|
Result: promql.Matrix{ |
|
|
|
|
promql.Series{ |
|
|
|
|
Points: []promql.Point{ |
|
|
|
|
{V: 0, T: timestamp.FromTime(start)}, |
|
|
|
|
{V: 1, T: timestamp.FromTime(start.Add(1 * time.Second))}, |
|
|
|
|
{V: 2, T: timestamp.FromTime(start.Add(2 * time.Second))}, |
|
|
|
|
}, |
|
|
|
|
Metric: model.Metric{}, |
|
|
|
|
Metric: nil, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
@ -237,7 +240,7 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
params: map[string]string{ |
|
|
|
|
"name": "__name__", |
|
|
|
|
}, |
|
|
|
|
response: model.LabelValues{ |
|
|
|
|
response: []string{ |
|
|
|
|
"test_metric1", |
|
|
|
|
"test_metric2", |
|
|
|
|
}, |
|
|
|
|
@ -247,7 +250,7 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
params: map[string]string{ |
|
|
|
|
"name": "foo", |
|
|
|
|
}, |
|
|
|
|
response: model.LabelValues{ |
|
|
|
|
response: []string{ |
|
|
|
|
"bar", |
|
|
|
|
"boo", |
|
|
|
|
}, |
|
|
|
|
@ -265,11 +268,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric2`}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric2", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric2", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
@ -277,23 +277,18 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric1{foo=~".+o"}`}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric1", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric1", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
endpoint: api.series, |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric1{foo=~"o$"}`, `test_metric1{foo=~".+o"}`}, |
|
|
|
|
"match[]": []string{`test_metric1{foo=~".+o$"}`, `test_metric1{foo=~".+o"}`}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric1", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric1", "foo", "boo"), |
|
|
|
|
labels.FromStrings("__name__", "test_metric1", "foo", "boo"), // TODO(fabxc): see comment in implementation.
|
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
@ -301,11 +296,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric1{foo=~".+o"}`, `none`}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric1", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric1", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// Start and end before series starts.
|
|
|
|
|
@ -316,7 +308,7 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"-2"}, |
|
|
|
|
"end": []string{"-1"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{}, |
|
|
|
|
response: []labels.Labels{}, |
|
|
|
|
}, |
|
|
|
|
// Start and end after series ends.
|
|
|
|
|
{ |
|
|
|
|
@ -326,7 +318,7 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"100000"}, |
|
|
|
|
"end": []string{"100001"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{}, |
|
|
|
|
response: []labels.Labels{}, |
|
|
|
|
}, |
|
|
|
|
// Start before series starts, end after series ends.
|
|
|
|
|
{ |
|
|
|
|
@ -336,11 +328,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"-1"}, |
|
|
|
|
"end": []string{"100000"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric2", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric2", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// Start and end within series.
|
|
|
|
|
@ -351,11 +340,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"1"}, |
|
|
|
|
"end": []string{"100"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric2", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric2", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// Start within series, end after.
|
|
|
|
|
@ -366,11 +352,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"1"}, |
|
|
|
|
"end": []string{"100000"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric2", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric2", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// Start before series, end within series.
|
|
|
|
|
@ -381,11 +364,8 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
"start": []string{"-1"}, |
|
|
|
|
"end": []string{"1"}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric2", |
|
|
|
|
"foo": "boo", |
|
|
|
|
}, |
|
|
|
|
response: []labels.Labels{ |
|
|
|
|
labels.FromStrings("__name__", "test_metric2", "foo", "boo"), |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// Missing match[] query params in series requests.
|
|
|
|
|
@ -399,45 +379,45 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
}, |
|
|
|
|
// The following tests delete time series from the test storage. They
|
|
|
|
|
// must remain at the end and are fixed in their order.
|
|
|
|
|
{ |
|
|
|
|
endpoint: api.dropSeries, |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric1{foo=~".+o"}`}, |
|
|
|
|
}, |
|
|
|
|
response: struct { |
|
|
|
|
NumDeleted int `json:"numDeleted"` |
|
|
|
|
}{1}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
endpoint: api.series, |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`test_metric1`}, |
|
|
|
|
}, |
|
|
|
|
response: []model.Metric{ |
|
|
|
|
{ |
|
|
|
|
"__name__": "test_metric1", |
|
|
|
|
"foo": "bar", |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, { |
|
|
|
|
endpoint: api.dropSeries, |
|
|
|
|
query: url.Values{ |
|
|
|
|
"match[]": []string{`{__name__=~".+"}`}, |
|
|
|
|
}, |
|
|
|
|
response: struct { |
|
|
|
|
NumDeleted int `json:"numDeleted"` |
|
|
|
|
}{2}, |
|
|
|
|
}, { |
|
|
|
|
endpoint: api.targets, |
|
|
|
|
response: []*Target{ |
|
|
|
|
&Target{ |
|
|
|
|
DiscoveredLabels: model.LabelSet{}, |
|
|
|
|
Labels: model.LabelSet{}, |
|
|
|
|
ScrapeUrl: "http://example.com:8080/metrics", |
|
|
|
|
Health: "unknown", |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
// {
|
|
|
|
|
// endpoint: api.dropSeries,
|
|
|
|
|
// query: url.Values{
|
|
|
|
|
// "match[]": []string{`test_metric1{foo=~".+o"}`},
|
|
|
|
|
// },
|
|
|
|
|
// response: struct {
|
|
|
|
|
// NumDeleted int `json:"numDeleted"`
|
|
|
|
|
// }{1},
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// endpoint: api.series,
|
|
|
|
|
// query: url.Values{
|
|
|
|
|
// "match[]": []string{`test_metric1`},
|
|
|
|
|
// },
|
|
|
|
|
// response: []model.Metric{
|
|
|
|
|
// {
|
|
|
|
|
// "__name__": "test_metric1",
|
|
|
|
|
// "foo": "bar",
|
|
|
|
|
// },
|
|
|
|
|
// },
|
|
|
|
|
// }, {
|
|
|
|
|
// endpoint: api.dropSeries,
|
|
|
|
|
// query: url.Values{
|
|
|
|
|
// "match[]": []string{`{__name__=~".+"}`},
|
|
|
|
|
// },
|
|
|
|
|
// response: struct {
|
|
|
|
|
// NumDeleted int `json:"numDeleted"`
|
|
|
|
|
// }{2},
|
|
|
|
|
// }, {
|
|
|
|
|
// endpoint: api.targets,
|
|
|
|
|
// response: []*Target{
|
|
|
|
|
// &Target{
|
|
|
|
|
// DiscoveredLabels: nil,
|
|
|
|
|
// Labels: nil,
|
|
|
|
|
// ScrapeUrl: "http://example.com:8080/metrics",
|
|
|
|
|
// Health: "unknown",
|
|
|
|
|
// },
|
|
|
|
|
// },
|
|
|
|
|
// },
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, test := range tests { |
|
|
|
|
@ -470,8 +450,6 @@ func TestEndpoints(t *testing.T) { |
|
|
|
|
if !reflect.DeepEqual(resp, test.response) { |
|
|
|
|
t.Fatalf("Response does not match, expected:\n%+v\ngot:\n%+v", test.response, resp) |
|
|
|
|
} |
|
|
|
|
// Ensure that removed metrics are unindexed before the next request.
|
|
|
|
|
suite.Storage().WaitForIndexing() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -599,9 +577,8 @@ func TestParseTime(t *testing.T) { |
|
|
|
|
t.Errorf("Expected error for %q but got none", test.input) |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
res := model.TimeFromUnixNano(test.result.UnixNano()) |
|
|
|
|
if !test.fail && ts != res { |
|
|
|
|
t.Errorf("Expected time %v for input %q but got %v", res, test.input, ts) |
|
|
|
|
if !test.fail && !ts.Equal(test.result) { |
|
|
|
|
t.Errorf("Expected time %v for input %q but got %v", test.result, test.input, ts) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|