(t *testing.T)
| 283 | } |
| 284 | |
| 285 | func TestTrackerComprehensionReuse(t *testing.T) { |
| 286 | // Regression: a single AST node id evaluated repeatedly with distinct argument values (as |
| 287 | // happens for an async call inside a comprehension) must register one call per distinct |
| 288 | // argument set, and re-lookups must return the existing state rather than relaunching. A |
| 289 | // node-id-keyed map collapses these into a single slot, causing every re-evaluation pass to |
| 290 | // relaunch every iteration and never converge. |
| 291 | tracker := newAsyncCallStateTracker() |
| 292 | completions := make(chan int64, 8) |
| 293 | gate := newAsyncGate(0, completions) |
| 294 | impl := asyncReturning(types.Int(0), nil) |
| 295 | const id = int64(1) |
| 296 | |
| 297 | args := [][]ref.Val{ |
| 298 | {types.Int(1)}, |
| 299 | {types.Int(2)}, |
| 300 | {types.Int(3)}, |
| 301 | } |
| 302 | states := make([]*asyncCallState, len(args)) |
| 303 | for i, a := range args { |
| 304 | states[i] = tracker.getOrCreate(id, "fn", "fn_int", a, impl, gate) |
| 305 | } |
| 306 | |
| 307 | // Each distinct argument set is a distinct, uniquely-identified call. |
| 308 | seen := map[int64]bool{} |
| 309 | for _, s := range states { |
| 310 | if seen[s.CallID()] { |
| 311 | t.Errorf("duplicate callID %d across distinct args", s.CallID()) |
| 312 | } |
| 313 | seen[s.CallID()] = true |
| 314 | } |
| 315 | |
| 316 | // Re-evaluation: every prior (id, args) tuple must resolve to its existing state and must |
| 317 | // not register a new call. |
| 318 | for i, a := range args { |
| 319 | if got := tracker.getOrCreate(id, "fn", "fn_int", a, impl, gate); got != states[i] { |
| 320 | t.Errorf("re-lookup of args %v returned a new state, wanted the existing one", a) |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | // Identical string arguments at the same node dedup to a single call. |
| 325 | s1 := tracker.getOrCreate(2, "fn", "fn_str", []ref.Val{types.String("k")}, impl, gate) |
| 326 | s2 := tracker.getOrCreate(2, "fn", "fn_str", []ref.Val{types.String("k")}, impl, gate) |
| 327 | if s1 != s2 { |
| 328 | t.Error("identical string args did not dedup to a single call") |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | func TestTrackerRegistrationLookup(t *testing.T) { |
| 333 | tracker := newAsyncCallStateTracker() |
nothing calls this directly
no test coverage detected