pkg/prom/types_test.go
Rama main · réplica de lectura del repositorio original.
package prom
import (
"encoding/json"
"math"
"strings"
"testing"
)
func TestDataPoint_MarshalJSON_SpecialFloats(t *testing.T) {
cases := []struct {
name string
dp DataPoint
want string
}{
{"finite", DataPoint{Timestamp: 1700000000, Value: 0.5}, `{"timestamp":1700000000,"value":0.5}`},
{"integer-valued", DataPoint{Timestamp: 1, Value: 42}, `{"timestamp":1,"value":42}`},
{"negative", DataPoint{Timestamp: 2, Value: -3.5}, `{"timestamp":2,"value":-3.5}`},
{"NaN", DataPoint{Timestamp: 3, Value: math.NaN()}, `{"timestamp":3,"value":null}`},
{"+Inf", DataPoint{Timestamp: 4, Value: math.Inf(1)}, `{"timestamp":4,"value":null}`},
{"-Inf", DataPoint{Timestamp: 5, Value: math.Inf(-1)}, `{"timestamp":5,"value":null}`},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
b, err := json.Marshal(tc.dp)
if err != nil {
t.Fatalf("marshal: %v", err)
}
if string(b) != tc.want {
t.Errorf("got %s, want %s", b, tc.want)
}
})
}
}
// A single NaN/Inf value must not fail json.Marshal of the whole series
// ("json: unsupported value: NaN") — that would break the entire query response
// for both REST and MCP. The series must marshal cleanly, with null gaps.
func TestSeries_MarshalJSON_WithNaNDoesNotFail(t *testing.T) {
s := Series{
Labels: map[string]string{"pod": "web-1"},
DataPoints: []DataPoint{
{Timestamp: 1, Value: 0.5},
{Timestamp: 2, Value: math.NaN()},
{Timestamp: 3, Value: math.Inf(1)},
},
}
b, err := json.Marshal([]Series{s})
if err != nil {
t.Fatalf("marshalling a series containing NaN/Inf must not fail: %v", err)
}
got := string(b)
if strings.Count(got, "null") != 2 {
t.Errorf("expected 2 null gaps, got %s", got)
}
if !strings.Contains(got, `"value":0.5`) {
t.Errorf("finite value should be preserved, got %s", got)
}
}
// A whole series serializes with non-finite points as explicit null gaps, so
// the payload stays valid JSON, the point shape stays uniform, and clients read
// null (never a fabricated 0).
func TestSeries_MarshalJSON_NullForNonFiniteValues(t *testing.T) {
s := Series{
Labels: map[string]string{"pod": "a"},
DataPoints: []DataPoint{
{Timestamp: 1, Value: 1.5},
{Timestamp: 2, Value: math.NaN()},
},
}
b, err := json.Marshal(s)
if err != nil {
t.Fatalf("marshal series: %v", err)
}
got := string(b)
if !strings.Contains(got, `{"timestamp":2,"value":null}`) {
t.Errorf("NaN point should serialize as value:null, got %s", got)
}
if strings.Contains(got, `"value":0`) {
t.Errorf("must not fabricate a 0 for the gap, got %s", got)
}
}