From 39e30e53acb6d70a23643e2af39a14ba597e2498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Mon, 10 Feb 2025 08:31:25 +0100 Subject: [PATCH] experimental: query: sort keys in json-marshal (#1220) --- experimental/apis/data/v0alpha1/query.go | 8 +++++- experimental/apis/data/v0alpha1/query_test.go | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/experimental/apis/data/v0alpha1/query.go b/experimental/apis/data/v0alpha1/query.go index 6e9af4af6..a50315753 100644 --- a/experimental/apis/data/v0alpha1/query.go +++ b/experimental/apis/data/v0alpha1/query.go @@ -3,6 +3,8 @@ package v0alpha1 import ( "encoding/json" "fmt" + "maps" + "slices" "strconv" "unsafe" @@ -309,7 +311,11 @@ func writeQuery(g *DataQuery, stream *j.Stream) { // The additional properties if g.additional != nil { - for k, v := range g.additional { + // we must sort the map-keys to always produce the same JSON + keys := slices.Sorted(maps.Keys(g.additional)) + + for _, k := range keys { + v := g.additional[k] stream.WriteMore() stream.WriteObjectField(k) stream.WriteVal(v) diff --git a/experimental/apis/data/v0alpha1/query_test.go b/experimental/apis/data/v0alpha1/query_test.go index 0677651b9..aa112ad53 100644 --- a/experimental/apis/data/v0alpha1/query_test.go +++ b/experimental/apis/data/v0alpha1/query_test.go @@ -7,6 +7,31 @@ import ( "github.com/stretchr/testify/require" ) +func TestSerializeAdditionalQueryFieldsOrdered(t *testing.T) { + q := DataQuery{ + CommonQueryProperties: CommonQueryProperties{ + RefID: "A", + MaxDataPoints: 10, + IntervalMS: 500, + }, + additional: map[string]any{ + "utcOffsetSec": 3600, + "exemplar": false, + "instant": false, + "range": true, + "editorMode": "code", + "legendFormat": "__auto", + }, + } + jsonBytes, err := json.Marshal(q) + require.NoError(t, err) + // NOTE: we cannot use require.JSONEq() here, + // because we want to make sure the object-keys + // are ordered + expectedBytes := []byte(`{"refId":"A","maxDataPoints":10,"intervalMs":500,"editorMode":"code","exemplar":false,"instant":false,"legendFormat":"__auto","range":true,"utcOffsetSec":3600}`) + require.Equal(t, expectedBytes, jsonBytes) +} + func TestParseQueriesIntoQueryDataRequest(t *testing.T) { request := []byte(`{ "queries": [