emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests - #935

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake
Aug 22, 2026
Merged

emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests#935
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/fix-gui-conn-test-flake

Conversation

@pm25coder

Copy link
Copy Markdown
Collaborator

Summary

Fixes an intermittent GUI test failure (P2 onRecoveredcancelledByParent) in emrg/gui/test/conn-manager.test.js.

Root cause

conn-manager.test.js creates ConnManager instances inline and never tears them down. Several tests schedule single-connection backoff retries via _scheduleSingleRetry (an unref'dsetTimeout). When a test finishes with a retry timer still pending, the timer fires during a later test, spawning stray mock connections (ensureDaemon / open → new MockWs). The stray connections steal the shared currentMockWs slot, so the running test's mock driver answers the wrong connection, recoverAll never completes, and the test hangs → cancelledByParent with "Promise resolution is still pending but the event loop has already resolved".

Reproduction: failed 3/3 full-file runs (incl. standalone full-suite), while the onRecovered test passes 1/1 in isolation (--test-name-pattern=onRecovered) — confirming cross-test interference.

Fix

  • conn-manager.js: add destroy() (clears pending backoff timers, disconnect records, closes all connections, clears hooks) + static instance registry with destroyAll() for unified teardown.
  • conn-manager.test.js: call ConnManager.destroyAll() in afterEach; add a regression test verifying destroy() clears a pending backoff timer and no stray connection is created afterwards.

Verification

  • GUI suite (cd emrg/gui && npm test) — 3 consecutive full runs, all clean: 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skipped (before: 249 pass + 1 cancelled).
  • Backend: uv run pytest tests/ -q938 passed / 65 skipped.
  • Doc-count guard: tests/test_doc_counts.py 4/4 passed (Agent.md GUI breakdown synced 258 → 259).
  • from emrg.client.app import run_client + emrg --help OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Needs fix — the fix itself is good, but the diff is polluted with a full-file line-ending conversion.

The good part ✅: ConnManager.destroy() / ConnManager.destroyAll() + afterEach(() => ConnManager.destroyAll()) correctly addresses the onRecovered flake (leaked unref'd backoff timers/connections crossing test boundaries), and the new destroy test is well-designed. CI green (test + test-windows).

The blocking issue ❌: the PR rewrites all 3 files (Agent.md, conn-manager.js, conn-manager.test.js) from LF to CRLF — 970 additions / 929 deletions for ~20 semantic lines (git diff -w confirms only the intended changes). Master uses LF for .js/.md (per .gitattributes, only .cmd/.bat/.ps1 are CRLF). This pollutes git blame, breaks the repo's line-ending convention, and will cause merge conflicts with any parallel change to these files.

Request: re-submit with only the semantic changes, keeping LF line endings. E.g.:

git config core.autocrlf false # or add to .gitattributes
# renormalize: git add --renormalize the 3 files, or recreate the branch

Happy to re-review as soon as the diff is clean.

@pm25coder
pm25coderforce-pushed the feature/fix-gui-conn-test-flake branch from a430f80 to 61f14f1CompareAugust 22, 2026 06:19
@pm25coder

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for the detailed review — you're right about the line endings. Root cause and fix below.

Root cause: The original branch commit was created via the GitHub Git Data API (git-over-https push to github.com:443 is blocked from this environment, so a script assembled the commit programmatically). That script read the files from the working tree, where core.autocrlf=true (Windows default) had converted every line to CRLF — so the uploaded blobs carried CRLF line endings, producing the whole-file LF→CRLF rewrite you saw (970 additions / 929 deletions).

Fix: I recreated the branch head as a single clean commit from current master (2066da4, which now includes the merged #934) with the three files stored as LF blobs (verified CRLF=0 at the blob level):

  • 61f14f1emrg: fix GUI conn-manager test flake — teardown leaked managers/timers between tests
  • PR diff is now exactly the semantic changes: Agent.md +2/−2 (test-count doc update), conn-manager.js +24, conn-manager.test.js +17 (43 insertions / 2 deletions total)
  • Local blobs were byte-checked: git cat-file confirms LF-only, matching the repo's .gitattributes convention

CI has re-triggered on the new head (run 32556680129, test + test-windows). I'll confirm when it's green. The semantic content is identical to what I verified locally (GUI suite 259 tests / 251 pass / 0 fail / 0 cancelled / 8 skip, 3 consecutive clean runs).

Apologies for the extra review round — the Git Data API fallback for push-blocked networks needs to preserve LF normalization; noted for future PRs from this environment. Happy to adjust further if anything still looks off.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — Root cause correctly fixed: the CI flake was caused by the Git Data API returning CRLF line endings (creating a noisy diff), and the author fixed it by normalizing line endings on the client side. Diff is clean (Agent.md +2/-2, conn-manager.js +24, conn-manager.test.js +17), no line-ending pollution, CI run 32556680129 fully green (test + test-windows). Previous ❌ review was against the old polluted head and is superseded.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified head 61f14f1: diff is exactly the semantic changes (Agent.md +2/−2, conn-manager.js +24, conn-manager.test.js +17; no line-ending pollution), CI run 32556680129 green (test + test-windows), mergeable CLEAN. Teardown via ConnManager.destroyAll() + afterEach correctly closes the leaked-timers flake; destroy test is well-designed.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Independent fresh-eyes review of head 61f14f1:

  • Root cause correctly addressed: unref'd per-connection backoff timers leaked across tests, firing during later tests and creating stray connections/recovery (the onRecovered cancelledByParent flake).
  • static _instances registry + destroy() (clears _singleRetries, _disconnects, closes all conns, clears hooks, unregisters) + destroyAll() in test afterEach is a complete teardown net; [..._instances] copy-iteration is correct since destroy() mutates the set during iteration.
  • New P6 test directly proves: backoff timer cleared, all() empty after destroy, and no stray connection 250ms later.
  • Agent.md counts stay balanced (19→20 conn-manager, 130→129 renderer smoke, total 259).
  • CI: test + test-windows both pass (run 32556680129); mergeStateStatus CLEAN.

@argszero
argszero merged commit d56cc2d into argszero:masterAug 22, 2026
2 checks passed
argszero pushed a commit that referenced this pull request Aug 22, 2026
…doc-count conflict: pytest 1008 + GUI 20/129 from #935)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@pm25coder@argszero