mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 18:18:21 +00:00
fix(mcp): retry Claude user config locks
This commit is contained in:
1 parent
f59536a81f
commit
cf90f48240
6 files changed
+313
-176
No files matched your search
@@ -194,26 +194,54 @@ describe('ensureImageAnalysisMcp', () => {
|
||||
expect(lockSpy.mock.calls[0]?.[0]).toBe(path.join(tempHome as string, '.claude.json.ccs-lock'));
|
||||
});
|
||||
|
||||
it('returns false instead of throwing when ~/.claude.json is already locked', () => {
|
||||
it('retries ~/.claude.json lock acquisition before provisioning', () => {
|
||||
setupTempHome();
|
||||
writeEnabledConfig();
|
||||
const claudeUserConfigPath = path.join(tempHome as string, '.claude.json');
|
||||
fs.writeFileSync(claudeUserConfigPath, '{}\n', 'utf8');
|
||||
|
||||
let calls = 0;
|
||||
spyOn(lockfile, 'lockSync').mockImplementation(() => {
|
||||
calls++;
|
||||
if (calls === 1) {
|
||||
const error = new Error('Lock file is already being held') as NodeJS.ErrnoException;
|
||||
error.code = 'ELOCKED';
|
||||
throw error;
|
||||
}
|
||||
return (() => undefined) as ReturnType<typeof lockfile.lockSync>;
|
||||
});
|
||||
|
||||
expect(ensureImageAnalysisMcp()).toBe(true);
|
||||
expect(calls).toBe(2);
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(claudeUserConfigPath, 'utf8')) as {
|
||||
mcpServers: Record<string, unknown>;
|
||||
};
|
||||
expect(config.mcpServers[getImageAnalysisMcpServerName()]).toEqual(getManagedConfig());
|
||||
});
|
||||
|
||||
it('returns false instead of throwing when ~/.claude.json stays locked', () => {
|
||||
setupTempHome();
|
||||
writeEnabledConfig();
|
||||
|
||||
const claudeUserConfigPath = path.join(tempHome as string, '.claude.json');
|
||||
fs.writeFileSync(claudeUserConfigPath, '{}\n', 'utf8');
|
||||
fs.writeFileSync(path.join(tempHome as string, '.claude.json.ccs-lock'), '', 'utf8');
|
||||
|
||||
const release = lockfile.lockSync(path.join(tempHome as string, '.claude.json.ccs-lock'), {
|
||||
stale: 10000,
|
||||
}) as () => void;
|
||||
let now = 0;
|
||||
spyOn(Date, 'now').mockImplementation(() => {
|
||||
now += 10001;
|
||||
return now;
|
||||
});
|
||||
spyOn(lockfile, 'lockSync').mockImplementation(() => {
|
||||
const error = new Error('Lock file is already being held') as NodeJS.ErrnoException;
|
||||
error.code = 'ELOCKED';
|
||||
throw error;
|
||||
});
|
||||
|
||||
try {
|
||||
let result: boolean | undefined;
|
||||
expect(() => {
|
||||
result = ensureImageAnalysisMcp();
|
||||
}).not.toThrow();
|
||||
expect(result).toBe(false);
|
||||
} finally {
|
||||
release();
|
||||
}
|
||||
let result: boolean | undefined;
|
||||
expect(() => {
|
||||
result = ensureImageAnalysisMcp();
|
||||
}).not.toThrow();
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user