Skip to content

Commit ae22d1c

Browse files
committed
Use fixture for MySQL MQ tests
Route the full MySQL message queue test file through the runtime-agnostic fixture test adapter and use fixture ignore options for database-gated cases. Clear the long-poll deadline timer so Deno fixture leak checks stay clean. #748 (comment) Assisted-by: Codex:gpt-5.5
1 parent 20b46d5 commit ae22d1c

1 file changed

Lines changed: 63 additions & 59 deletions

File tree

packages/mysql/src/mq.test.ts

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { test as fixtureTest } from "@fedify/fixture";
1+
import { test } from "@fedify/fixture";
22
import { MysqlMessageQueue } from "@fedify/mysql/mq";
33
import { getRandomKey, testMessageQueue, waitFor } from "@fedify/testing";
44
import * as temporal from "@js-temporal/polyfill";
55
import assert from "node:assert/strict";
66
import process from "node:process";
7-
import { test } from "node:test";
87
import mysql from "mysql2/promise";
98

109
const Temporal = globalThis.Temporal ?? temporal.Temporal;
@@ -75,8 +74,8 @@ test("MysqlMessageQueue uses default options when none are provided", () => {
7574
// Standard shared test suite
7675
// ---------------------------------------------------------------------------
7776

78-
test("MysqlMessageQueue", { skip: dbUrl == null }, () => {
79-
if (dbUrl == null) return; // Bun does not support skip option
77+
test("MysqlMessageQueue", { ignore: dbUrl == null }, () => {
78+
if (dbUrl == null) return;
8079
const tableName = randomTableName("mq");
8180
const pools: mysql.Pool[] = [];
8281

@@ -98,11 +97,11 @@ test("MysqlMessageQueue", { skip: dbUrl == null }, () => {
9897
);
9998
});
10099

101-
fixtureTest(
100+
test(
102101
"MysqlMessageQueue.getDepth()",
103102
{ ignore: dbUrl == null },
104103
async () => {
105-
if (dbUrl == null) return; // Bun does not support skip option
104+
if (dbUrl == null) return;
106105
const pool = mysql.createPool(dbUrl);
107106
const tableName = randomTableName("depth");
108107
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -132,8 +131,8 @@ fixtureTest(
132131
// initialize() and drop()
133132
// ---------------------------------------------------------------------------
134133

135-
test("MysqlMessageQueue.initialize()", { skip: dbUrl == null }, async () => {
136-
if (dbUrl == null) return; // Bun does not support skip option
134+
test("MysqlMessageQueue.initialize()", { ignore: dbUrl == null }, async () => {
135+
if (dbUrl == null) return;
137136
const pool = mysql.createPool(dbUrl!);
138137
const tableName = randomTableName("init");
139138
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -197,9 +196,9 @@ test("MysqlMessageQueue.initialize()", { skip: dbUrl == null }, async () => {
197196

198197
test(
199198
"MysqlMessageQueue.initialize() is idempotent",
200-
{ skip: dbUrl == null },
199+
{ ignore: dbUrl == null },
201200
async () => {
202-
if (dbUrl == null) return; // Bun does not support skip option
201+
if (dbUrl == null) return;
203202
const pool = mysql.createPool(dbUrl!);
204203
const tableName = randomTableName("idem");
205204
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -222,8 +221,8 @@ test(
222221
},
223222
);
224223

225-
test("MysqlMessageQueue.drop()", { skip: dbUrl == null }, async () => {
226-
if (dbUrl == null) return; // Bun does not support skip option
224+
test("MysqlMessageQueue.drop()", { ignore: dbUrl == null }, async () => {
225+
if (dbUrl == null) return;
227226
const pool = mysql.createPool(dbUrl!);
228227
const tableName = randomTableName("drop");
229228
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -245,9 +244,9 @@ test("MysqlMessageQueue.drop()", { skip: dbUrl == null }, async () => {
245244

246245
test(
247246
"MysqlMessageQueue.drop() resets initialized flag so re-initialize works",
248-
{ skip: dbUrl == null },
247+
{ ignore: dbUrl == null },
249248
async () => {
250-
if (dbUrl == null) return; // Bun does not support skip option
249+
if (dbUrl == null) return;
251250
const pool = mysql.createPool(dbUrl!);
252251
const tableName = randomTableName("reinit");
253252
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -273,9 +272,9 @@ test(
273272

274273
test(
275274
"MysqlMessageQueue.drop() waits for in-flight initialize() before dropping",
276-
{ skip: dbUrl == null },
275+
{ ignore: dbUrl == null },
277276
async () => {
278-
if (dbUrl == null) return; // Bun does not support skip option
277+
if (dbUrl == null) return;
279278
const pool = mysql.createPool(dbUrl!);
280279
const tableName = randomTableName("droprace");
281280
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -308,9 +307,9 @@ test(
308307

309308
test(
310309
"MysqlMessageQueue concurrent initialization does not throw",
311-
{ skip: dbUrl == null },
310+
{ ignore: dbUrl == null },
312311
async () => {
313-
if (dbUrl == null) return; // Bun does not support skip option
312+
if (dbUrl == null) return;
314313
const pools: mysql.Pool[] = [];
315314
const tableName = randomTableName("concinit");
316315
try {
@@ -334,9 +333,9 @@ test(
334333

335334
test(
336335
"MysqlMessageQueue enqueue() and listen() racing on initialize() is safe",
337-
{ skip: dbUrl == null },
336+
{ ignore: dbUrl == null },
338337
async () => {
339-
if (dbUrl == null) return; // Bun does not support skip option
338+
if (dbUrl == null) return;
340339
const pool = mysql.createPool(dbUrl!);
341340
const tableName = randomTableName("race");
342341
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -369,9 +368,9 @@ test(
369368

370369
test(
371370
"MysqlMessageQueue processes messages enqueued before listen() starts",
372-
{ skip: dbUrl == null },
371+
{ ignore: dbUrl == null },
373372
async () => {
374-
if (dbUrl == null) return; // Bun does not support skip option
373+
if (dbUrl == null) return;
375374
const pool = mysql.createPool(dbUrl!);
376375
const tableName = randomTableName("preq");
377376
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -410,9 +409,9 @@ test(
410409

411410
test(
412411
"MysqlMessageQueue delayed message is not delivered early",
413-
{ skip: dbUrl == null },
412+
{ ignore: dbUrl == null },
414413
async () => {
415-
if (dbUrl == null) return; // Bun does not support skip option
414+
if (dbUrl == null) return;
416415
const pool = mysql.createPool(dbUrl!);
417416
const tableName = randomTableName("delay");
418417
const mq = new MysqlMessageQueue(pool, {
@@ -467,9 +466,9 @@ test(
467466

468467
test(
469468
"MysqlMessageQueue handles 30 concurrent enqueue() calls",
470-
{ skip: dbUrl == null },
469+
{ ignore: dbUrl == null },
471470
async () => {
472-
if (dbUrl == null) return; // Bun does not support skip option
471+
if (dbUrl == null) return;
473472
const pool = mysql.createPool(dbUrl!);
474473
const tableName = randomTableName("stress");
475474
const mq = new MysqlMessageQueue(pool, {
@@ -511,9 +510,9 @@ test(
511510

512511
test(
513512
"MysqlMessageQueue.enqueueMany() with empty array is a no-op",
514-
{ skip: dbUrl == null },
513+
{ ignore: dbUrl == null },
515514
async () => {
516-
if (dbUrl == null) return; // Bun does not support skip option
515+
if (dbUrl == null) return;
517516
const pool = mysql.createPool(dbUrl!);
518517
const tableName = randomTableName("emptyb");
519518
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -540,9 +539,9 @@ test(
540539

541540
test(
542541
"MysqlMessageQueue.enqueueMany() inserts all messages atomically",
543-
{ skip: dbUrl == null },
542+
{ ignore: dbUrl == null },
544543
async () => {
545-
if (dbUrl == null) return; // Bun does not support skip option
544+
if (dbUrl == null) return;
546545
const pool = mysql.createPool(dbUrl!);
547546
const tableName = randomTableName("batcha");
548547
const mq = new MysqlMessageQueue(pool, { tableName });
@@ -563,9 +562,9 @@ test(
563562

564563
test(
565564
"MysqlMessageQueue.enqueueMany() delivers all 100 messages via single INSERT",
566-
{ skip: dbUrl == null },
565+
{ ignore: dbUrl == null },
567566
async () => {
568-
if (dbUrl == null) return; // Bun does not support skip option
567+
if (dbUrl == null) return;
569568
const pool = mysql.createPool(dbUrl!);
570569
const tableName = randomTableName("bulk");
571570
const mq = new MysqlMessageQueue(pool, {
@@ -602,9 +601,9 @@ test(
602601

603602
test(
604603
"MysqlMessageQueue.enqueueMany() preserves insertion order for same ordering key",
605-
{ skip: dbUrl == null },
604+
{ ignore: dbUrl == null },
606605
async () => {
607-
if (dbUrl == null) return; // Bun does not support skip option
606+
if (dbUrl == null) return;
608607
const pool = mysql.createPool(dbUrl!);
609608
const tableName = randomTableName("bord");
610609
const mq = new MysqlMessageQueue(pool, {
@@ -648,9 +647,9 @@ test(
648647

649648
test(
650649
"MysqlMessageQueue listener survives handler errors",
651-
{ skip: dbUrl == null },
650+
{ ignore: dbUrl == null },
652651
async () => {
653-
if (dbUrl == null) return; // Bun does not support skip option
652+
if (dbUrl == null) return;
654653
const pool = mysql.createPool(dbUrl!);
655654
const tableName = randomTableName("hderr");
656655
const mq = new MysqlMessageQueue(pool, {
@@ -692,9 +691,9 @@ test(
692691

693692
test(
694693
"MysqlMessageQueue handlerTimeout prevents hung handler from blocking queue",
695-
{ skip: dbUrl == null },
694+
{ ignore: dbUrl == null },
696695
async () => {
697-
if (dbUrl == null) return; // Bun does not support skip option
696+
if (dbUrl == null) return;
698697
const pool = mysql.createPool(dbUrl!);
699698
const tableName = randomTableName("hdto");
700699
const mq = new MysqlMessageQueue(pool, {
@@ -737,9 +736,9 @@ test(
737736

738737
test(
739738
"MysqlMessageQueue handlerTimeout with ordering key releases the lock",
740-
{ skip: dbUrl == null },
739+
{ ignore: dbUrl == null },
741740
async () => {
742-
if (dbUrl == null) return; // Bun does not support skip option
741+
if (dbUrl == null) return;
743742
const pool = mysql.createPool(dbUrl!);
744743
const tableName = randomTableName("hdtolk");
745744
const mq = new MysqlMessageQueue(pool, {
@@ -785,9 +784,9 @@ test(
785784

786785
test(
787786
"MysqlMessageQueue advisory lock is released after processing (regression for lock-leak)",
788-
{ skip: dbUrl == null },
787+
{ ignore: dbUrl == null },
789788
async () => {
790-
if (dbUrl == null) return; // Bun does not support skip option
789+
if (dbUrl == null) return;
791790
// Use a pool with a small max to make lock leaks visible
792791
const pool = mysql.createPool({ uri: dbUrl!, connectionLimit: 3 });
793792
const tableName = randomTableName("lockleak");
@@ -830,9 +829,9 @@ test(
830829

831830
test(
832831
"MysqlMessageQueue GET_LOCK succeeds with a very long ordering key",
833-
{ skip: dbUrl == null },
832+
{ ignore: dbUrl == null },
834833
async () => {
835-
if (dbUrl == null) return; // Bun does not support skip option
834+
if (dbUrl == null) return;
836835
// A 200-char ordering key combined with a 20-char table name produces a
837836
// raw lock name that is 221 chars — well over MySQL's 64-char limit.
838837
// The lock name hashing logic must shorten it before calling GET_LOCK,
@@ -874,9 +873,9 @@ test(
874873

875874
test(
876875
"MysqlMessageQueue delivers each message to exactly one worker",
877-
{ skip: dbUrl == null },
876+
{ ignore: dbUrl == null },
878877
async () => {
879-
if (dbUrl == null) return; // Bun does not support skip option
878+
if (dbUrl == null) return;
880879
const pool1 = mysql.createPool(dbUrl!);
881880
const pool2 = mysql.createPool(dbUrl!);
882881
const tableName = randomTableName("onceonly");
@@ -934,9 +933,9 @@ test(
934933

935934
test(
936935
"MysqlMessageQueue two workers preserve ordering-key order",
937-
{ skip: dbUrl == null },
936+
{ ignore: dbUrl == null },
938937
async () => {
939-
if (dbUrl == null) return; // Bun does not support skip option
938+
if (dbUrl == null) return;
940939
const pool1 = mysql.createPool(dbUrl!);
941940
const pool2 = mysql.createPool(dbUrl!);
942941
const tableName = randomTableName("twowork");
@@ -993,9 +992,9 @@ test(
993992

994993
test(
995994
"MysqlMessageQueue listen() resolves promptly when aborted during poll interval",
996-
{ skip: dbUrl == null },
995+
{ ignore: dbUrl == null },
997996
async () => {
998-
if (dbUrl == null) return; // Bun does not support skip option
997+
if (dbUrl == null) return;
999998
const pool = mysql.createPool(dbUrl!);
1000999
const tableName = randomTableName("clrtmo");
10011000
// Use a very long poll interval so the test would hang if clearTimeout
@@ -1014,13 +1013,18 @@ test(
10141013
controller.abort();
10151014

10161015
// listen() must resolve well within the 60-second poll interval.
1017-
const deadline = new Promise<never>((_, reject) =>
1018-
setTimeout(
1016+
let deadlineTimer: ReturnType<typeof setTimeout> | undefined;
1017+
const deadline = new Promise<never>((_, reject) => {
1018+
deadlineTimer = setTimeout(
10191019
() => reject(new Error("listen() did not resolve in time")),
10201020
3_000,
1021-
)
1022-
);
1023-
await Promise.race([listening, deadline]);
1021+
);
1022+
});
1023+
try {
1024+
await Promise.race([listening, deadline]);
1025+
} finally {
1026+
clearTimeout(deadlineTimer);
1027+
}
10241028
} finally {
10251029
await mq.drop();
10261030
await pool.end();
@@ -1034,9 +1038,9 @@ test(
10341038

10351039
test(
10361040
"MysqlMessageQueue works with getRandomKey() from @fedify/testing",
1037-
{ skip: dbUrl == null },
1041+
{ ignore: dbUrl == null },
10381042
async () => {
1039-
if (dbUrl == null) return; // Bun does not support skip option
1043+
if (dbUrl == null) return;
10401044
// getRandomKey returns names like "fedify_test_mq_<uuid>" which may contain
10411045
// hyphens — unsuitable for MySQL identifiers. Users must replace hyphens.
10421046
const rawKey = getRandomKey("mq");
@@ -1071,9 +1075,9 @@ test(
10711075

10721076
test(
10731077
"MysqlMessageQueue with initialized: true skips DDL on first use",
1074-
{ skip: dbUrl == null },
1078+
{ ignore: dbUrl == null },
10751079
async () => {
1076-
if (dbUrl == null) return; // Bun does not support skip option
1080+
if (dbUrl == null) return;
10771081
const pool = mysql.createPool(dbUrl!);
10781082
const tableName = randomTableName("preini");
10791083
// Create table manually first

0 commit comments

Comments
 (0)