|
9 | 9 | */ |
10 | 10 |
|
11 | 11 | "use strict"; |
| 12 | +// Flags: --expose-gc |
| 13 | + |
12 | 14 | const assert = require("assert"); |
13 | 15 | const { DatabaseSync } = require("@photostructure/sqlite"); |
14 | 16 | const { test, beforeEach } = require("node:test"); |
@@ -193,3 +195,39 @@ test("sql error messages are descriptive", () => { |
193 | 195 | }, |
194 | 196 | ); |
195 | 197 | }); |
| 198 | + |
| 199 | +test.skip("a tag store keeps the database alive by itself" /* Requires --expose-gc flag */, () => { |
| 200 | + const sql = new DatabaseSync(":memory:").createTagStore(); |
| 201 | + |
| 202 | + sql.db.exec("CREATE TABLE test (data INTEGER)"); |
| 203 | + |
| 204 | + global.gc(); |
| 205 | + |
| 206 | + // eslint-disable-next-line no-unused-expressions |
| 207 | + sql.run`INSERT INTO test (data) VALUES (1)`; |
| 208 | +}); |
| 209 | + |
| 210 | +test.skip("tag store prevents circular reference leaks" /* Requires --expose-gc flag and Node.js internal GC test utilities */, async () => { |
| 211 | + const { gcUntil } = require("../common/gc"); |
| 212 | + |
| 213 | + const before = process.memoryUsage().heapUsed; |
| 214 | + |
| 215 | + // Create many SQLTagStore + DatabaseSync pairs with circular references |
| 216 | + for (let i = 0; i < 1000; i++) { |
| 217 | + const sql = new DatabaseSync(":memory:").createTagStore(); |
| 218 | + sql.db.exec("CREATE TABLE test (data INTEGER)"); |
| 219 | + // eslint-disable-next-line no-void |
| 220 | + sql.db.setAuthorizer(() => void sql.db); |
| 221 | + } |
| 222 | + |
| 223 | + // GC until memory stabilizes or give up after 20 attempts |
| 224 | + await gcUntil( |
| 225 | + "tag store leak check", |
| 226 | + () => { |
| 227 | + const after = process.memoryUsage().heapUsed; |
| 228 | + // Memory should not grow significantly (allow 50% margin for noise) |
| 229 | + return after < before * 1.5; |
| 230 | + }, |
| 231 | + 20, |
| 232 | + ); |
| 233 | +}); |
0 commit comments