Ctrl K
ComunidadGuías…

pkg/prom/types_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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)
	}
}