package api import ( "os" "reflect" "regexp" "sort" "strings" "testing" ) // R-262: hostRestoreTest is a deliberate SUBSET of the agent's hub.RestoreTest. This pins WHICH subset: the hub decodes // exactly `hubRestoreTestFields`, and the agent fields it leaves out are exactly `knownUnmodelled`. When the agent's // source is beside this repo (the workspace), its RestoreTest json tags must equal the union — so an agent field added // later fails here until someone decides to model it or to list it as unmodelled. RED-PROOF: drop a field from the // struct, or delete an entry from knownUnmodelled → this test fails. func TestR262_RestoreTestFieldsAreAKnownSubset(t *testing.T) { // skipped (agent v0.133.0, R-672): a skipped test arrives as Pass=false with Error "skipped: …", which the hub // reads as a failed test with that reason — the agent's own comment calls that the honest reading. knownUnmodelled := []string{"mount_inventory", "mount_parity", "skipped"} var got []string rt := reflect.TypeOf(hostRestoreTest{}) for i := 0; i < rt.NumField(); i++ { got = append(got, strings.Split(rt.Field(i).Tag.Get("json"), ",")[0]) } sort.Strings(got) want := []string{"duration_seconds", "error", "pass", "scratch_vmid", "source_archive", "source_tier", "tested_at", "verified", "warnings", "warnings_recognized"} if !reflect.DeepEqual(got, want) { t.Fatalf("hostRestoreTest json fields = %v, want %v", got, want) } for _, f := range knownUnmodelled { for _, g := range got { if g == f { t.Fatalf("%s is listed as unmodelled but hostRestoreTest decodes it — update knownUnmodelled", f) } } } src, err := os.ReadFile("../../../../felhom-agent/internal/hub/report.go") if err != nil { t.Logf("agent source not beside this repo (%v) — the cross-repo half is not checked here", err) return } body := regexp.MustCompile(`(?s)type RestoreTest struct \{(.*?)\n\}`).FindSubmatch(src) if body == nil { t.Fatal("type RestoreTest struct not found in felhom-agent/internal/hub/report.go") } var agent []string for _, m := range regexp.MustCompile("json:\"([a-z_]+)").FindAllSubmatch(body[1], -1) { agent = append(agent, string(m[1])) } sort.Strings(agent) union := append(append([]string{}, want...), knownUnmodelled...) sort.Strings(union) if !reflect.DeepEqual(agent, union) { t.Fatalf("agent RestoreTest fields %v != hub fields + knownUnmodelled %v — model the new field or list it", agent, union) } }