Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cherrypick-2.0: ts: Fix nil pointer panic on invalid TS query #23799

Merged
merged 1 commit into from
Mar 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions pkg/ts/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,10 @@ func (db *DB) Query(
aggFn = aggregatingIterator.max
case tspb.TimeSeriesQueryAggregator_MIN:
aggFn = aggregatingIterator.min
default:
return nil, nil, fmt.Errorf(
"query specified unknown time series aggregator: %s", query.GetSourceAggregator().String(),
)
}

// Filter the result of the aggregation function through a leading edge
Expand Down Expand Up @@ -1124,7 +1128,6 @@ func makeDataSpans(
return sourceSpans, nil
}

// getExtractionFunction returns
func getExtractionFunction(agg tspb.TimeSeriesQueryAggregator) (extractFn, error) {
switch agg {
case tspb.TimeSeriesQueryAggregator_AVG:
Expand All @@ -1136,7 +1139,7 @@ func getExtractionFunction(agg tspb.TimeSeriesQueryAggregator) (extractFn, error
case tspb.TimeSeriesQueryAggregator_MIN:
return (roachpb.InternalTimeSeriesSample).Minimum, nil
}
return nil, errors.Errorf("query specified unknown time series aggregator %s", agg.String())
return nil, errors.Errorf("query specified unknown time series downsampler %s", agg.String())
}

func downsampleSum(points ...roachpb.InternalTimeSeriesSample) float64 {
Expand Down Expand Up @@ -1177,7 +1180,6 @@ func downsampleAvg(points ...roachpb.InternalTimeSeriesSample) float64 {
return total / float64(count)
}

// getDownsampleFunction returns
func getDownsampleFunction(agg tspb.TimeSeriesQueryAggregator) (downsampleFn, error) {
switch agg {
case tspb.TimeSeriesQueryAggregator_AVG:
Expand All @@ -1189,5 +1191,5 @@ func getDownsampleFunction(agg tspb.TimeSeriesQueryAggregator) (downsampleFn, er
case tspb.TimeSeriesQueryAggregator_MIN:
return downsampleMin, nil
}
return nil, errors.Errorf("query specified unknown time series aggregator %s", agg.String())
return nil, errors.Errorf("query specified unknown time series downsampler %s", agg.String())
}
57 changes: 57 additions & 0 deletions pkg/ts/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1494,3 +1494,60 @@ func TestQueryWorkerMemoryMonitor(t *testing.T) {
t.Logf("total allocations for query: %d\n", memStatsAfter.TotalAlloc-memStatsBefore.TotalAlloc)
t.Logf("maximum allocations for query monitor: %d\n", limitedMon.MaximumBytes())
}

// TestQueryBadRequests confirms that the query method returns gentle errors for
// obviously bad incoming data.
func TestQueryBadRequests(t *testing.T) {
defer leaktest.AfterTest(t)()
tm := newTestModel(t)
tm.Start()
defer tm.Stop()

account := tm.workerMemMonitor.MakeBoundAccount()
defer account.Close(context.TODO())

// Query with a downsampler that is invalid, expect error.
downsampler := (tspb.TimeSeriesQueryAggregator)(999)
_, _, err := tm.DB.Query(
context.TODO(), tspb.Query{
Name: "metric.test",
Downsampler: downsampler.Enum(),
}, resolution1ns, 10, 0, 10000, 0, &account, tm.workerMemMonitor,
)
errorStr := "unknown time series downsampler"
if !testutils.IsError(err, errorStr) {
if err == nil {
t.Fatalf("bad query got no error, wanted to match %q", errorStr)
} else {
t.Fatalf("bad query got error %q, wanted to match %q", err.Error(), errorStr)
}
}

// Query with a aggregator that is invalid, expect error.
aggregator := (tspb.TimeSeriesQueryAggregator)(999)
_, _, err = tm.DB.Query(
context.TODO(), tspb.Query{
Name: "metric.test",
SourceAggregator: aggregator.Enum(),
}, resolution1ns, 10, 0, 10000, 0, &account, tm.workerMemMonitor,
)
errorStr = "unknown time series aggregator"
if !testutils.IsError(err, errorStr) {
if err == nil {
t.Fatalf("bad query got no error, wanted to match %q", errorStr)
} else {
t.Fatalf("bad query got error %q, wanted to match %q", err.Error(), errorStr)
}
}

// Query with an interpolator that is invalid, expect no error (default behavior is none).
derivative := (tspb.TimeSeriesQueryDerivative)(999)
_, _, err = tm.DB.Query(
context.TODO(), tspb.Query{
Derivative: derivative.Enum(),
}, resolution1ns, 10, 0, 10000, 0, &account, tm.workerMemMonitor,
)
if !testutils.IsError(err, "") {
t.Fatalf("bad query got error %q, wanted no error", err.Error())
}
}