Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 36a4e0d

Browse files
authored
Merge pull request #1518 from grafana/fix-removeabovebelowpercentile-panic
Fix removeabovebelowpercentile panic
2 parents ccaecc2 + 9be2275 commit 36a4e0d

3 files changed

+69
-0
lines changed

expr/data_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ var d = []schema.Point{
6161
{Val: 250, Ts: 60},
6262
}
6363

64+
var allNulls = []schema.Point{
65+
{Val: math.NaN(), Ts: 10},
66+
{Val: math.NaN(), Ts: 20},
67+
{Val: math.NaN(), Ts: 30},
68+
{Val: math.NaN(), Ts: 40},
69+
{Val: math.NaN(), Ts: 50},
70+
{Val: math.NaN(), Ts: 60},
71+
}
72+
6473
var sumab = []schema.Point{
6574
{Val: 0, Ts: 10},
6675
{Val: math.MaxFloat64, Ts: 20},

expr/func_removeabovebelowpercentile.go

+7
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func (s *FuncRemoveAboveBelowPercentile) Exec(cache map[Req][]models.Series) ([]
5858
serie.Tags = serie.CopyTagsWith("nPercentile", fmt.Sprintf("%g", s.n))
5959

6060
percentile := getPercentileValue(serie.Datapoints, s.n, sortedDatapointVals)
61+
if math.IsNaN(percentile) {
62+
continue
63+
}
6164

6265
out := pointSlicePool.Get().([]schema.Point)
6366
for _, p := range serie.Datapoints {
@@ -91,6 +94,10 @@ func getPercentileValue(datapoints []schema.Point, n float64, sortedDatapointVal
9194
}
9295
}
9396

97+
if len(sortedDatapointVals) == 0 {
98+
return math.NaN()
99+
}
100+
94101
sort.Float64s(sortedDatapointVals)
95102

96103
index := math.Min(math.Ceil(n/100.0*float64(len(sortedDatapointVals)+1)), float64(len(sortedDatapointVals))) - 1

expr/func_removeabovebelowpercentile_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,59 @@ func TestRemoveBelowPercentileSingleAllNonNull(t *testing.T) {
181181
)
182182
}
183183

184+
// TestRemoveBelowPercentileWithNulls verifies that, just like Graphite, series with all nulls, are removed from the output
185+
func TestRemoveBelowPercentileWithNulls(t *testing.T) {
186+
testRemoveAboveBelowPercentile(
187+
"removeBelowPercentile",
188+
false,
189+
50,
190+
[]models.Series{
191+
{
192+
Interval: 10,
193+
QueryPatt: "abcd",
194+
Target: "a",
195+
Datapoints: getCopy(a),
196+
},
197+
{
198+
Interval: 10,
199+
QueryPatt: "abcd",
200+
Target: "b",
201+
Datapoints: getCopy(allNulls),
202+
},
203+
},
204+
[]models.Series{
205+
{
206+
Interval: 10,
207+
QueryPatt: "removeBelowPercentile(a, 50)",
208+
Datapoints: []schema.Point{
209+
{Val: math.NaN(), Ts: 10},
210+
{Val: math.NaN(), Ts: 20},
211+
{Val: 5.5, Ts: 30},
212+
{Val: math.NaN(), Ts: 40},
213+
{Val: math.NaN(), Ts: 50},
214+
{Val: 1234567890, Ts: 60},
215+
},
216+
},
217+
},
218+
t,
219+
)
220+
testRemoveAboveBelowPercentile(
221+
"removeBelowPercentile",
222+
false,
223+
50,
224+
[]models.Series{
225+
{
226+
Interval: 10,
227+
QueryPatt: "abcd",
228+
Target: "b",
229+
Datapoints: getCopy(allNulls),
230+
},
231+
},
232+
[]models.Series{},
233+
t,
234+
)
235+
}
236+
184237
func testRemoveAboveBelowPercentile(name string, above bool, n float64, in []models.Series, out []models.Series, t *testing.T) {
185238
f := NewRemoveAboveBelowPercentileConstructor(above)()
186239
f.(*FuncRemoveAboveBelowPercentile).in = NewMock(in)

0 commit comments

Comments
 (0)