package confmgr import ( "errors" "testing" ) func TestSnapshotCapturesAndCoerces(t *testing.T) { set := ConfigSet{ ID: "set1", Name: "s", Parameters: []Parameter{ {Key: "v", DS: "epics", Signal: "PSU:V", Type: TypeFloat}, {Key: "n", DS: "epics", Signal: "PSU:N", Type: TypeInt}, {Key: "en", DS: "epics", Signal: "PSU:EN", Type: TypeBool}, {Key: "mode", DS: "epics", Signal: "PSU:MODE", Type: TypeEnum, EnumValues: []string{"off", "low", "high"}}, {Key: "wf", DS: "epics", Signal: "PSU:WF", Type: TypeFloatArray}, {Key: "lbl", DS: "epics", Signal: "PSU:LBL", Type: TypeString}, }, } live := map[string]any{ "PSU:V": 24.5, "PSU:N": 3.0, // float reading → coerced to int64 "PSU:EN": int64(1), // numeric → bool true "PSU:MODE": int64(2), // enum index → "high" "PSU:WF": []float64{1, 2, 3}, "PSU:LBL": "ready", } res := Snapshot(set, func(_, signal string) (any, error) { v, ok := live[signal] if !ok { return nil, errors.New("not read") } return v, nil }) if res.Captured != 6 || res.Failed != 0 { t.Fatalf("summary: captured=%d failed=%d", res.Captured, res.Failed) } if res.Values["v"] != 24.5 { t.Errorf("v = %v, want 24.5", res.Values["v"]) } if res.Values["n"] != int64(3) { t.Errorf("n = %v (%T), want int64(3)", res.Values["n"], res.Values["n"]) } if res.Values["en"] != true { t.Errorf("en = %v, want true", res.Values["en"]) } if res.Values["mode"] != "high" { t.Errorf("mode = %v, want high", res.Values["mode"]) } if res.Values["lbl"] != "ready" { t.Errorf("lbl = %v, want ready", res.Values["lbl"]) } // The captured values must validate against the set. inst := ConfigInstance{SetID: set.ID, Values: res.Values} if err := inst.ValidateAgainst(set); err != nil { t.Errorf("snapshot values fail validation: %v", err) } } func TestSnapshotReadFailureRecorded(t *testing.T) { set := ConfigSet{ ID: "set1", Name: "s", Parameters: []Parameter{ {Key: "a", DS: "epics", Signal: "A", Type: TypeFloat}, {Key: "b", DS: "epics", Signal: "B", Type: TypeFloat}, }, } res := Snapshot(set, func(_, signal string) (any, error) { if signal == "B" { return nil, errors.New("offline") } return 1.0, nil }) if res.Captured != 1 || res.Failed != 1 { t.Fatalf("summary: captured=%d failed=%d", res.Captured, res.Failed) } if _, ok := res.Values["b"]; ok { t.Errorf("failed parameter must not appear in values") } }