FlushOwnedWindows forwards every buffered mock that can be attributed right now — session/connection mocks (reusable, never window-bound) and per-test mocks whose ReqTimestampMock falls inside an already-resolved window — leaving only not-yet-attributable per-test mocks in the buffer for a future wi
()
| 575 | // ctx is cancelled and the relay, consumer, and InsertMock all drop it. |
| 576 | // Order within the buffer is preserved for the mocks left behind. |
| 577 | func (m *SyncMockManager) FlushOwnedWindows() { |
| 578 | if m == nil { |
| 579 | return |
| 580 | } |
| 581 | |
| 582 | var mocksToSend []*models.Mock |
| 583 | var lateMappings map[string][]string |
| 584 | |
| 585 | m.mu.Lock() |
| 586 | outChanBound, _ := m.outChanStatus() |
| 587 | if !outChanBound { |
| 588 | m.mu.Unlock() |
| 589 | return |
| 590 | } |
| 591 | mappingChan := m.mappingChan |
| 592 | |
| 593 | ownerWindow := func(t time.Time) (resolvedWindow, bool) { |
| 594 | for _, w := range m.recentWindows { |
| 595 | if !t.Before(w.start) && !t.After(w.end) { |
| 596 | return w, true |
| 597 | } |
| 598 | } |
| 599 | return resolvedWindow{}, false |
| 600 | } |
| 601 | |
| 602 | keepIdx := 0 |
| 603 | for i := 0; i < len(m.buffer); i++ { |
| 604 | mock := m.buffer[i] |
| 605 | if mock == nil { |
| 606 | continue |
| 607 | } |
| 608 | if lt := mock.TestModeInfo.Lifetime; lt == models.LifetimeSession || lt == models.LifetimeConnection { |
| 609 | // Reusable across tests; flush verbatim (never renamed), |
| 610 | // matching ResolveRange's lifetime carve-out. |
| 611 | mocksToSend = append(mocksToSend, mock) |
| 612 | continue |
| 613 | } |
| 614 | if w, ok := ownerWindow(mock.Spec.ReqTimestampMock); ok { |
| 615 | mock.Name = "mock-" + generateRandomString(8) |
| 616 | if w.mapping { |
| 617 | if lateMappings == nil { |
| 618 | lateMappings = make(map[string][]string) |
| 619 | } |
| 620 | lateMappings[w.testName] = append(lateMappings[w.testName], mock.Name) |
| 621 | } |
| 622 | mocksToSend = append(mocksToSend, mock) |
| 623 | continue |
| 624 | } |
| 625 | // STARTUP RESCUE: a startup-window mock the ownerWindow check above |
| 626 | // didn't claim (boot traffic owns no window; an early-test mock whose |
| 627 | // window hasn't resolved yet on this ticker tick). Flush it to disk |
| 628 | // proactively rather than leaving it parked in the buffer where a dedup |
| 629 | // cleanup, stale-cutoff, or memory-pressure wipe could reap it before it |
| 630 | // is ever persisted. |
| 631 | if isStartupMock(mock) { |
| 632 | mock.Name = "mock-" + generateRandomString(8) |
| 633 | mocksToSend = append(mocksToSend, mock) |
| 634 | continue |