(t *testing.T)
| 687 | } |
| 688 | |
| 689 | func TestExecutionFrameChildSharesAsyncContext(t *testing.T) { |
| 690 | ctx, cancel := context.WithCancel(context.Background()) |
| 691 | defer cancel() |
| 692 | frame, closeFrame := newTestFrame(t, ctx) |
| 693 | defer closeFrame() |
| 694 | |
| 695 | completions := make(chan int64, 1) |
| 696 | if err := frame.SetCompletions(completions); err != nil { |
| 697 | t.Fatalf("SetCompletions() failed: %v", err) |
| 698 | } |
| 699 | |
| 700 | // Counts are taken relative to a baseline, since ExecutionFrame draws its tracker from a |
| 701 | // process-global pool whose starting pending count is not guaranteed to be zero. |
| 702 | base := frame.ActiveAsyncCalls() |
| 703 | |
| 704 | child := frame.Push(EmptyActivation()) |
| 705 | if got := child.ActiveAsyncCalls(); got != base { |
| 706 | t.Errorf("child ActiveAsyncCalls() = %d, wanted %d (shared parent ctx)", got, base) |
| 707 | } |
| 708 | |
| 709 | // A call launched from the child frame must be visible through the shared parent tracker. |
| 710 | resChild := child.ComputeResult(1, "fn", "fn_int", asyncReturning(types.Int(5), nil), []ref.Val{types.Int(1)}) |
| 711 | if unk, ok := resChild.(*types.Unknown); ok { |
| 712 | child.DispatchPendingAsyncCalls(unk.IDs()) |
| 713 | } |
| 714 | if got := child.ActiveAsyncCalls(); got != base+1 { |
| 715 | t.Errorf("child ActiveAsyncCalls() after launch = %d, wanted %d", got, base+1) |
| 716 | } |
| 717 | |
| 718 | parent := child.Pop() |
| 719 | if parent != frame { |
| 720 | t.Fatalf("Pop() did not return the parent frame") |
| 721 | } |
| 722 | if got := frame.ActiveAsyncCalls(); got != base+1 { |
| 723 | t.Errorf("parent ActiveAsyncCalls() after Pop = %d, wanted %d", got, base+1) |
| 724 | } |
| 725 | // The launched call is retrievable via the parent frame's AsyncCall accessor. |
| 726 | select { |
| 727 | case callID := <-completions: |
| 728 | if call := frame.AsyncCall(callID); call == nil { |
| 729 | t.Errorf("AsyncCall(%d) = nil, wanted a call record from the shared tracker", callID) |
| 730 | } |
| 731 | case <-time.After(2 * time.Second): |
| 732 | t.Fatal("timed out waiting for child call completion") |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | type recordingObserver struct { |
| 737 | started atomic.Int32 |
nothing calls this directly
no test coverage detected