// E2E part 5: SDAM monitoring stability, official driver. // Every other e2e file issues its commands and exits, so all of them pass // against a server whose *monitoring* is broken. This one just sits on an // idle connection and watches the driver's heartbeats. // // The failure it guards against: advertising `topologyVersion` in the hello // reply makes the driver monitor with an exhaust hello and expect a stream of // moreToCome replies. A server that answers once and goes back to reading // fails the heartbeat ("Server ended moreToCome unexpectedly"), the driver // drops the connection and clears the pool, and the client — MongoDB Compass, // say — shows a connect/disconnect loop once per heartbeat. const { MongoClient } = require('mongodb'); const URL = 'mongodb://127.0.0.1:27020'; const results = []; function check(name, cond, detail = '') { results.push({ name, ok: !!cond, detail: String(detail) }); if (!cond) console.error(` ✗ ${name} ${detail}`); } const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); // 500ms is the driver's floor for heartbeatFrequencyMS; over WATCH_MS it gives // ~10 heartbeats, enough that a per-heartbeat failure cannot hide. const HEARTBEAT_MS = 500; const WATCH_MS = 5000; async function main() { const client = new MongoClient(URL, { heartbeatFrequencyMS: HEARTBEAT_MS, serverSelectionTimeoutMS: 5000, }); let succeeded = 0; const failures = []; client.on('serverHeartbeatSucceeded', () => succeeded++); client.on('serverHeartbeatFailed', (e) => failures.push(e.failure ? e.failure.message : 'unknown')); // The pool is cleared when SDAM decides the server went away; on a healthy // idle connection it should never happen. client.on('connectionPoolCleared', () => failures.push('connectionPoolCleared')); await client.connect(); await client.db('e2e5').command({ ping: 1 }); await sleep(WATCH_MS); check('heartbeats actually ran', succeeded >= 5, `${succeeded} succeeded`); check('no heartbeat failed', failures.length === 0, failures.join(', ')); // A reset pool still recovers, so liveness alone would not catch the loop — // check it anyway, since a dead connection here means something worse. let usable = true; try { await client.db('e2e5').command({ ping: 1 }); } catch (e) { usable = false; check('connection usable after idle period', false, e.message); } if (usable) check('connection usable after idle period', true); await client.close(); const failed = results.filter((r) => !r.ok); console.log(`\n${results.length - failed.length}/${results.length} checks passed`); if (failed.length) { console.log('FAILED:', failed.map((f) => f.name).join(', ')); process.exit(1); } console.log('E2E5_OK'); } main().catch((e) => { console.error('E2E5_FAIL', e); process.exit(1); });