From 624f169363b97cd392d54df696e4452f7d0bf9f6 Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Sat, 8 Aug 2026 08:35:48 -0600 Subject: [PATCH 1/2] test(meshcore): make setup-abort reconnect contract resilient to cleanup The `attemptMeshcoreReconnect treats setup AbortError as superseded reconnect` source contract sliced a fixed 900-char window after the `isMeshcoreSetupAbortError(err)` marker. The PR-review fix that adds `lateTransport.cleanup(openedDriverIdentityId)` (plus its comment) before `return 'defer'` pushed the defer past that window, failing renderer-ui CI. Delimit the abort branch at the non-abort `return 'retry'` path instead of a char count, and additionally assert the branch performs the late-transport cleanup, so the contract tracks intent without being length-brittle. --- .../runtime/useMeshcoreRuntime.reconnect.test.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts b/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts index 037c85e20..f32d84841 100644 --- a/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts +++ b/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts @@ -521,9 +521,16 @@ describe('useMeshcoreRuntime manual disconnect must not auto-reconnect', () => { // and left status=reconnecting with no further attempts (n7eal / #792 MeshCore TCP). const abortIdx = reconnectBody.indexOf('isMeshcoreSetupAbortError(err)'); expect(abortIdx).toBeGreaterThan(-1); - const abortBlock = reconnectBody.slice(abortIdx, abortIdx + 900); + // Delimit the abort branch at the non-abort retry path rather than a fixed + // char window, so adding late-transport cleanup before the defer cannot push + // `return 'defer'` out of range. + const retryIdx = reconnectBody.indexOf("return 'retry'", abortIdx); + expect(retryIdx).toBeGreaterThan(abortIdx); + const abortBlock = reconnectBody.slice(abortIdx, retryIdx); expect(abortBlock).toContain('meshcoreDeferredReconnectRef.current = true'); expect(abortBlock).toContain("return 'defer'"); + // Setup abort must clean up any transport this doomed attempt opened before deferring. + expect(abortBlock).toContain('lateTransport.cleanup(openedDriverIdentityId)'); expect(abortBlock).not.toMatch(/meshcoreIsReconnectingRef\.current = false/); }); From 4424a06b2169a59bff5d9e34cb6351d134116b63 Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Sat, 8 Aug 2026 09:19:14 -0600 Subject: [PATCH 2/2] test(meshcore): assert setup-abort cleans up transport before deferring Strengthen the setup-abort reconnect source contract to check ordering, not just presence: compare the indices of lateTransport.cleanup(openedDriverIdentityId) and return 'defer' and assert cleanup runs first, so a future edit cannot move the defer ahead of the late-transport cleanup. --- .../runtime/useMeshcoreRuntime.reconnect.test.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts b/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts index f32d84841..ced2262b2 100644 --- a/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts +++ b/src/renderer/runtime/useMeshcoreRuntime.reconnect.test.ts @@ -528,9 +528,13 @@ describe('useMeshcoreRuntime manual disconnect must not auto-reconnect', () => { expect(retryIdx).toBeGreaterThan(abortIdx); const abortBlock = reconnectBody.slice(abortIdx, retryIdx); expect(abortBlock).toContain('meshcoreDeferredReconnectRef.current = true'); - expect(abortBlock).toContain("return 'defer'"); - // Setup abort must clean up any transport this doomed attempt opened before deferring. - expect(abortBlock).toContain('lateTransport.cleanup(openedDriverIdentityId)'); + // Setup abort must clean up any transport this doomed attempt opened *before* deferring, + // otherwise a late-opened driver leaks while the deferred restart brings up a fresh one. + const cleanupIdx = abortBlock.indexOf('lateTransport.cleanup(openedDriverIdentityId)'); + const deferIdx = abortBlock.indexOf("return 'defer'"); + expect(cleanupIdx).toBeGreaterThan(-1); + expect(deferIdx).toBeGreaterThan(-1); + expect(cleanupIdx).toBeLessThan(deferIdx); expect(abortBlock).not.toMatch(/meshcoreIsReconnectingRef\.current = false/); });