status merges per-org stats across CPs: active_sessions summed, orgs unioned.
(t *testing.T)
| 265 | t.Fatalf("sqlstate filter = %+v, want just org b", got.Errors) |
| 266 | } |
| 267 | |
| 268 | // scope=local: local only, no fan-out. |
| 269 | fetcher.calls = 0 |
| 270 | rec = httptest.NewRecorder() |
| 271 | r.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/api/v1/errors?scope=local", nil)) |
| 272 | _ = json.Unmarshal(rec.Body.Bytes(), &got) |
| 273 | if len(got.Errors) != 1 || got.Errors[0].Org != "a" { |
| 274 | t.Fatalf("scope=local errors = %+v, want 1 (local only)", got.Errors) |
| 275 | } |
| 276 | if atomic.LoadInt32(&fetcher.calls) != 0 { |
| 277 | t.Fatalf("scope=local must NOT fan out, fetcher ran %d times", fetcher.calls) |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | // /status merges per-org stats across CPs: active_sessions summed, orgs unioned. |
| 282 | func TestStatusAggregateAcrossCPs(t *testing.T) { |
| 283 | gin.SetMode(gin.TestMode) |
| 284 | local := &fakeLiveInfo{orgStats: []OrgStatus{{Name: "a", ActiveSessions: 1, MaxWorkers: 5}}} |
| 285 | peerBody, _ := json.Marshal(ClusterStatus{Orgs: []OrgStatus{ |
| 286 | {Name: "a", ActiveSessions: 1, MaxWorkers: 5}, |
| 287 | {Name: "b", ActiveSessions: 2, MaxWorkers: 0}, |
| 288 | }}) |
| 289 | fetcher := &fakePeerFetcher{byPath: map[string][][]byte{"/api/v1/status": {peerBody}}} |
| 290 | |
| 291 | r := gin.New() |
| 292 | registerAPIWithStore(r.Group("/api/v1"), nil, local, fetcher) |
| 293 | rec := httptest.NewRecorder() |
| 294 | r.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/api/v1/status", nil)) |
| 295 | |
| 296 | var cs ClusterStatus |
| 297 | if err := json.Unmarshal(rec.Body.Bytes(), &cs); err != nil { |
| 298 | t.Fatalf("unmarshal: %v", err) |
| 299 | } |
| 300 | if cs.TotalSessions != 4 { // a:1+1, b:2 |
| 301 | t.Fatalf("total_sessions = %d, want 4", cs.TotalSessions) |
| 302 | } |
| 303 | if cs.TotalOrgs != 2 { |
nothing calls this directly
no test coverage detected