From ee2ee398cefdea6f44518a2645ab402b24957340 Mon Sep 17 00:00:00 2001 From: _Kerman Date: Tue, 25 Aug 2026 14:13:06 +0800 Subject: [PATCH] test(credentials-local): seed fixtures atomically to close a boot-read race The concurrent-migrator test wrote the winner document with a plain writeFile, whose truncate-then-write window lets the boot's unlocked initial read observe an empty file and boot an empty store under load. Seed fixtures through writeFileAtomic instead, matching how the provider itself persists, so a reader sees either the old or the new complete document. --- .../credentials/credentials-local/tests/migration.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/credentials/credentials-local/tests/migration.spec.ts b/packages/credentials/credentials-local/tests/migration.spec.ts index 30fec951e3..85babed89e 100644 --- a/packages/credentials/credentials-local/tests/migration.spec.ts +++ b/packages/credentials/credentials-local/tests/migration.spec.ts @@ -4,16 +4,16 @@ // keeps the loud rejection local.spec exercises. import { afterEach, describe, expect, it } from 'vitest' import { Context } from '@deepseek-ai/cordis' -import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' +import { mkdtemp, readFile, rm, stat } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { credentialRef } from '@deepseek-ai/dsh-credentials' -import { withFileLock } from '@deepseek-ai/dsh-atomic-write' +import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write' import { LocalCredentialProvider, renderFlatLayoutMigration } from '../src/index.ts' /** Credential documents are seeded owner-only, exactly as the provider creates them. */ function writeCredentials(file: string, text: string): Promise { - return writeFile(file, text, { mode: 0o600 }) + return writeFileAtomic(file, text, { mode: 0o600, dirMode: 0o700 }) } const cleanups: Array<() => Promise> = []