From c77acd95224604da2eda8bcf192e2633b742f55b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 21 Sep 2026 11:40:52 +0000 Subject: [PATCH 1/3] test: stop connection-pool fake timers from leaking Install and restore Jest fake timers per test so later suites that need real clocks, such as labelLoader watch, are not poisoned. Co-authored-by: Doug Rathbone --- tests/cgateConnectionPool.test.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/cgateConnectionPool.test.js b/tests/cgateConnectionPool.test.js index 1184c96..9bcb864 100644 --- a/tests/cgateConnectionPool.test.js +++ b/tests/cgateConnectionPool.test.js @@ -12,9 +12,6 @@ jest.mock('net', () => ({ createConnection: jest.fn() })); -// Mock timers -jest.useFakeTimers(); - /** * Creates a mock CgateConnection that emits 'connect' asynchronously. * Pass { failConnect: true } to emit 'error' instead. @@ -51,6 +48,9 @@ describe('CgateConnectionPool', () => { let randomSpy; beforeEach(() => { + // Per-test timers, not module-scope: a leftover useFakeTimers() here + // used to leak into later files that need real clocks (labelLoader watch). + jest.useFakeTimers(); jest.clearAllMocks(); jest.clearAllTimers(); randomSpy = jest.spyOn(Math, 'random').mockReturnValue(0.5); @@ -82,6 +82,7 @@ describe('CgateConnectionPool', () => { if (pool.isStarted) { await pool.stop(); } + jest.useRealTimers(); }); describe('Constructor', () => { From 0012d34bc21df4b54e77bb9554a5cb6e9b3e9da0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 21 Sep 2026 11:40:56 +0000 Subject: [PATCH 2/3] test: restore require graph after standalone config load The standalone settings test replaced require.resolve and require.cache without putting them back, which can fail later tests in the same worker. Co-authored-by: Doug Rathbone --- tests/config/configLoader.test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/config/configLoader.test.js b/tests/config/configLoader.test.js index 6683eac..6fbc623 100644 --- a/tests/config/configLoader.test.js +++ b/tests/config/configLoader.test.js @@ -601,7 +601,12 @@ describe('ConfigLoader', () => { ha_discovery_enabled: false }; + let originalResolve; + let originalCache; + beforeEach(() => { + originalResolve = require.resolve; + originalCache = require.cache; mockEnvironmentDetector.detect.mockReturnValue({ type: 'standalone', isAddon: false, @@ -611,6 +616,11 @@ describe('ConfigLoader', () => { }); }); + afterEach(() => { + require.resolve = originalResolve; + require.cache = originalCache; + }); + test('should load standalone configuration from settings.js', () => { fs.existsSync.mockReturnValue(true); From 669720f677f1f39f004f51ae01930b2816914e5c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 21 Sep 2026 11:40:56 +0000 Subject: [PATCH 3/3] fix: default command queue cap from schema ThrottledQueue used a hardcoded 1000 when maxSize was omitted, even though the rest of the bridge reads maxQueueSize from schema. Co-authored-by: Doug Rathbone --- src/throttledQueue.js | 4 ++-- tests/throttledQueue.test.js | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/throttledQueue.js b/src/throttledQueue.js index 6022aef..243eb52 100644 --- a/src/throttledQueue.js +++ b/src/throttledQueue.js @@ -9,7 +9,7 @@ class ThrottledQueue { * @param {number} intervalMs - Minimum interval between processing items * @param {string} name - Queue name for logging * @param {Object} [options] - Additional options - * @param {number} [options.maxSize=1000] - Maximum queue size (0 = unlimited) + * @param {number} [options.maxSize] - Maximum queue size (0 = unlimited; default: schema maxQueueSize) * @param {Function} [options.getIntervalMs] - Dynamic interval override; returns the delay before processing the next item * @param {Function} [options.canProcessFn] - Gate checked before each item; processing retries when it returns false * @param {number} [options.retryWhenBlockedMs] - Delay before retrying when canProcessFn blocks processing @@ -47,7 +47,7 @@ class ThrottledQueue { this._active = false; this._length = 0; this._name = name; - this._maxSize = options.maxSize !== undefined ? options.maxSize : 1000; + this._maxSize = options.maxSize !== undefined ? options.maxSize : resolveSetting({}, 'maxQueueSize'); this._getIntervalMs = typeof options.getIntervalMs === 'function' ? options.getIntervalMs : null; this._canProcessFn = typeof options.canProcessFn === 'function' ? options.canProcessFn : null; const retryMinMs = options.retryWhenBlockedMinMs !== undefined diff --git a/tests/throttledQueue.test.js b/tests/throttledQueue.test.js index e6ed7e6..4b6318e 100644 --- a/tests/throttledQueue.test.js +++ b/tests/throttledQueue.test.js @@ -241,9 +241,10 @@ describe('ThrottledQueue', () => { }); describe('Queue size limits', () => { - it('should default to maxSize of 1000', () => { + it('should default to the schema maxQueueSize', () => { + const { resolveSetting } = require('../src/config/schema'); const queue = new ThrottledQueue(jest.fn(), 100); - expect(queue.maxSize).toBe(1000); + expect(queue.maxSize).toBe(resolveSetting({}, 'maxQueueSize')); }); it('should accept custom maxSize', () => {