|
1 | | -import { mkdtemp, writeFile } from 'node:fs/promises'; |
| 1 | +import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'; |
2 | 2 | import { tmpdir } from 'node:os'; |
3 | 3 | import { join } from 'node:path'; |
4 | 4 | import { DatabaseSync } from 'node:sqlite'; |
@@ -145,6 +145,31 @@ describe('sqlite driver storage behavior', () => { |
145 | 145 | await expect(first.read()).rejects.toMatchObject({ code: 'store-closed' }); |
146 | 146 | })); |
147 | 147 |
|
| 148 | + it('refuses to open a fresh root store beside one under the pre-#201 file name', () => |
| 149 | + withRoot(async (root) => { |
| 150 | + const definition = counterDefinition(); |
| 151 | + const pre201Name = `state-sqlite-test-counter-${Buffer.from(definition.id, 'utf8').toString('hex').slice(0, 12)}.sqlite`; |
| 152 | + const pre201File = join(root, pre201Name); |
| 153 | + await writeFile(pre201File, 'pre-#201 store'); |
| 154 | + |
| 155 | + const refusal = createSqliteStateDriver({ root }).open(definition); |
| 156 | + await expect(refusal).rejects.toMatchObject({ code: 'corrupt', name: 'AgentStateError' }); |
| 157 | + await expect(refusal).rejects.toThrow(`found a store at '${pre201File}' under the pre-#201 file name`); |
| 158 | + await expect(refusal).rejects.toThrow('Move that file and its -wal/-shm sidecars out of the state root'); |
| 159 | + expect(await readdir(root)).toEqual([pre201Name]); |
| 160 | + expect(await readFile(pre201File, 'utf8')).toBe('pre-#201 store'); |
| 161 | + |
| 162 | + await rm(pre201File); |
| 163 | + const store = await createSqliteStateDriver({ root }).open(definition); |
| 164 | + await store.dispatch('bumped', { by: 1 }, { idempotencyKey: 'k1' }); |
| 165 | + await store.close(); |
| 166 | + // Once the current store exists it is authoritative; a pre-#201 file beside it is not consulted. |
| 167 | + await writeFile(pre201File, 'pre-#201 store'); |
| 168 | + const reopened = await createSqliteStateDriver({ root }).open(definition); |
| 169 | + await expect(reopened.read()).resolves.toEqual({ revision: 1, state: { count: 1 } }); |
| 170 | + await reopened.close(); |
| 171 | + })); |
| 172 | + |
148 | 173 | it('keeps the original commit input while migrating each committed result', () => |
149 | 174 | withRoot(async (root) => { |
150 | 175 | const file = join(root, 'migrating-reset.sqlite'); |
|
0 commit comments