Skip to content

Commit 0e23fdb

Browse files
committed
fixup! fixup! fixup! fixup! fix: fallback to gauge for protofmt-based negotiations
1 parent 67f184c commit 0e23fdb

File tree

1 file changed

+110
-13
lines changed

1 file changed

+110
-13
lines changed

pkg/metrics_store/metrics_writer_test.go

Lines changed: 110 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package metricsstore_test
17+
package metricsstore
1818

1919
import (
2020
"fmt"
21+
"github.com/google/go-cmp/cmp"
22+
"github.com/prometheus/common/expfmt"
23+
"reflect"
2124
"strings"
2225
"testing"
2326

24-
"github.com/prometheus/common/expfmt"
25-
2627
v1 "k8s.io/api/core/v1"
2728
"k8s.io/apimachinery/pkg/api/meta"
2829
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930

3031
"k8s.io/kube-state-metrics/v2/pkg/metric"
31-
metricsstore "k8s.io/kube-state-metrics/v2/pkg/metrics_store"
3232
)
3333

3434
func TestWriteAllWithSingleStore(t *testing.T) {
@@ -62,7 +62,7 @@ func TestWriteAllWithSingleStore(t *testing.T) {
6262

6363
return []metric.FamilyInterface{&mf1, &mf2}
6464
}
65-
store := metricsstore.NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
65+
store := NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
6666
svcs := []v1.Service{
6767
{
6868
ObjectMeta: metav1.ObjectMeta{
@@ -86,7 +86,7 @@ func TestWriteAllWithSingleStore(t *testing.T) {
8686
}
8787
}
8888

89-
multiNsWriter := metricsstore.NewMetricsWriter(store)
89+
multiNsWriter := NewMetricsWriter(store)
9090
w := strings.Builder{}
9191
err := multiNsWriter.WriteAll(&w)
9292
if err != nil {
@@ -150,7 +150,7 @@ func TestWriteAllWithMultipleStores(t *testing.T) {
150150

151151
return []metric.FamilyInterface{&mf1, &mf2}
152152
}
153-
s1 := metricsstore.NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
153+
s1 := NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
154154
svcs1 := []v1.Service{
155155
{
156156
ObjectMeta: metav1.ObjectMeta{
@@ -190,15 +190,15 @@ func TestWriteAllWithMultipleStores(t *testing.T) {
190190
},
191191
},
192192
}
193-
s2 := metricsstore.NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
193+
s2 := NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
194194
for _, s := range svcs2 {
195195
svc := s
196196
if err := s2.Add(&svc); err != nil {
197197
t.Fatal(err)
198198
}
199199
}
200200

201-
multiNsWriter := metricsstore.NewMetricsWriter(s1, s2)
201+
multiNsWriter := NewMetricsWriter(s1, s2)
202202
w := strings.Builder{}
203203
err := multiNsWriter.WriteAll(&w)
204204
if err != nil {
@@ -250,9 +250,9 @@ func TestWriteAllWithEmptyStores(t *testing.T) {
250250

251251
return []metric.FamilyInterface{&mf1, &mf2}
252252
}
253-
store := metricsstore.NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
253+
store := NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc)
254254

255-
multiNsWriter := metricsstore.NewMetricsWriter(store)
255+
multiNsWriter := NewMetricsWriter(store)
256256
w := strings.Builder{}
257257
err := multiNsWriter.WriteAll(&w)
258258
if err != nil {
@@ -266,6 +266,103 @@ func TestWriteAllWithEmptyStores(t *testing.T) {
266266
}
267267
}
268268

269+
// TODO: AFAIR empty headers are ignored by Prometheus? If not, we should remove them.
270+
func TestSanitizeHeaders(t *testing.T) {
271+
boilerplateHeaders := []string{
272+
"",
273+
"",
274+
"# HELP foo foo_help\n# TYPE foo gauge",
275+
"# HELP foo foo_help\n# TYPE foo info",
276+
"# HELP foo foo_help\n# TYPE foo stateset",
277+
"# HELP foo foo_help\n# TYPE foo counter",
278+
}
279+
duplicatedBoilerplateHeaders := []string{
280+
"",
281+
"",
282+
"# HELP foo foo_help\n# TYPE foo gauge",
283+
"# HELP foo foo_help\n# TYPE foo gauge",
284+
"# HELP foo foo_help\n# TYPE foo info",
285+
"# HELP foo foo_help\n# TYPE foo info",
286+
"# HELP foo foo_help\n# TYPE foo stateset",
287+
"# HELP foo foo_help\n# TYPE foo stateset",
288+
"# HELP foo foo_help\n# TYPE foo counter",
289+
"# HELP foo foo_help\n# TYPE foo counter",
290+
}
291+
dedepedBoilerplateHeaders := []string{
292+
"",
293+
"",
294+
"# HELP foo foo_help\n# TYPE foo gauge",
295+
"",
296+
"# HELP foo foo_help\n# TYPE foo info",
297+
"",
298+
"# HELP foo foo_help\n# TYPE foo stateset",
299+
"",
300+
"# HELP foo foo_help\n# TYPE foo counter",
301+
"",
302+
}
303+
protoIngestibleHeaders := []string{
304+
"",
305+
"",
306+
"# HELP foo foo_help\n# TYPE foo gauge",
307+
"# HELP foo foo_help\n# TYPE foo gauge",
308+
"# HELP foo foo_help\n# TYPE foo gauge",
309+
"# HELP foo foo_help\n# TYPE foo counter",
310+
}
311+
dedepedProtoIngestibleHeaders := []string{
312+
"",
313+
"",
314+
"# HELP foo foo_help\n# TYPE foo gauge",
315+
"",
316+
"# HELP foo foo_help\n# TYPE foo gauge",
317+
"",
318+
"# HELP foo foo_help\n# TYPE foo gauge",
319+
"",
320+
"# HELP foo foo_help\n# TYPE foo counter",
321+
"",
322+
}
323+
testcases := []struct {
324+
name string
325+
contentType expfmt.Format
326+
headers []string
327+
expectedHeaders []string
328+
}{
329+
{
330+
name: "text-format unique headers",
331+
contentType: expfmt.FmtText,
332+
headers: boilerplateHeaders,
333+
expectedHeaders: boilerplateHeaders,
334+
},
335+
{
336+
name: "text-format consecutive duplicate headers",
337+
contentType: expfmt.FmtText,
338+
headers: duplicatedBoilerplateHeaders,
339+
expectedHeaders: dedepedBoilerplateHeaders,
340+
},
341+
{
342+
name: "proto-format unique headers",
343+
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
344+
headers: boilerplateHeaders,
345+
expectedHeaders: protoIngestibleHeaders,
346+
},
347+
{
348+
name: "proto-format consecutive duplicate headers",
349+
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
350+
headers: duplicatedBoilerplateHeaders,
351+
expectedHeaders: dedepedProtoIngestibleHeaders,
352+
},
353+
}
354+
355+
for _, testcase := range testcases {
356+
writer := NewMetricsWriter(NewMetricsStore(testcase.headers, nil))
357+
t.Run(testcase.name, func(t *testing.T) {
358+
SanitizeHeaders(string(testcase.contentType), MetricsWriterList{writer})
359+
if !reflect.DeepEqual(testcase.expectedHeaders, writer.stores[0].headers) {
360+
t.Fatalf("(-want, +got):\n%s", cmp.Diff(testcase.expectedHeaders, writer.stores[0].headers))
361+
}
362+
})
363+
}
364+
}
365+
269366
func BenchmarkSanitizeHeaders(b *testing.B) {
270367
benchmarks := []struct {
271368
name string
@@ -303,10 +400,10 @@ func BenchmarkSanitizeHeaders(b *testing.B) {
303400
headers = append(headers, fmt.Sprintf("# HELP foo_%d foo_help\n# TYPE foo_%d info", j, j))
304401
}
305402
}
306-
writer := metricsstore.NewMetricsWriter(metricsstore.NewMetricsStore(headers, nil))
403+
writer := NewMetricsWriter(NewMetricsStore(headers, nil))
307404
b.Run(benchmark.name, func(b *testing.B) {
308405
for i := 0; i < b.N; i++ {
309-
metricsstore.SanitizeHeaders(string(benchmark.contentType), metricsstore.MetricsWriterList{writer})
406+
SanitizeHeaders(string(benchmark.contentType), MetricsWriterList{writer})
310407
}
311408
})
312409
}

0 commit comments

Comments
 (0)