返回 DeepSeek-Reasonix
metrics_mirror_test.go
根目录 / cmd / e2ebench / metrics_mirror_test.go
1 package main
2
3 import (
4 "reflect"
5 "strings"
6 "testing"
7
8 "reasonix/internal/cli"
9 )
10
11 // jsonTags collects a struct's JSON field names, descending into embedded and
12 // nested structs the way encoding/json itself does.
13 func jsonTags(t reflect.Type, into map[string]bool) {
14 for i := range t.NumField() {
15 f := t.Field(i)
16 tag, _, _ := strings.Cut(f.Tag.Get("json"), ",")
17 if tag == "-" {
18 continue
19 }
20 if tag != "" {
21 into[tag] = true
22 }
23 ft := f.Type
24 for ft.Kind() == reflect.Pointer {
25 ft = ft.Elem()
26 }
27 if ft.Kind() == reflect.Struct && ft.PkgPath() != "time" {
28 jsonTags(ft, into)
29 }
30 }
31 }
32
33 // The bench reads a metrics file the agent writes, and the two structs are
34 // hand-mirrored. A tag the bench reads that nobody emits does not fail: the
35 // field silently stays zero and every report built on it quietly reads as
36 // "this never happened". Renaming one side must break the build, not the data.
37 func TestBenchMetricsOnlyReadTagsTheAgentEmits(t *testing.T) {
38 emitted := map[string]bool{}
39 jsonTags(reflect.TypeFor[cli.RunMetrics](), emitted)
40
41 read := map[string]bool{}
42 jsonTags(reflect.TypeFor[runMetrics](), read)
43
44 var orphaned []string
45 for tag := range read {
46 if !emitted[tag] {
47 orphaned = append(orphaned, tag)
48 }
49 }
50 if len(orphaned) > 0 {
51 t.Fatalf("e2ebench reads metrics tags no agent writes: %v\n"+
52 "either internal/cli.RunMetrics lost them in a rename, or the bench "+
53 "invented them; both leave the field zero in every report", orphaned)
54 }
55 }
56
56 lines GO