mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
test(file-reference-local): pin the unreadable-subtree test to POSIX non-root
chmod 0 can only deny directory reads on POSIX to a non-root owner: Windows exposes no directory permission bits for readdir, and root bypasses them. Where the fixture stays readable the sealed candidate is indexed, so the unreadable-branch behavior is pinned on POSIX non-root. An injected readdir failure keeps that branch covered on every platform.
This commit is contained in:
@@ -9,6 +9,24 @@ import {
|
||||
WorkspaceFileSearch,
|
||||
} from '../src/search.ts'
|
||||
|
||||
const fsControl = vi.hoisted(() => ({
|
||||
/** Absolute path whose `readdir` rejects; the injectable stand-in for chmod 0. */
|
||||
denyReaddir: undefined as string | undefined,
|
||||
}))
|
||||
|
||||
vi.mock('node:fs/promises', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('node:fs/promises')>()
|
||||
return {
|
||||
...actual,
|
||||
readdir: (async (path: unknown, ...rest: never[]) => {
|
||||
if (fsControl.denyReaddir !== undefined && String(path) === fsControl.denyReaddir) {
|
||||
throw Object.assign(new Error('EACCES: injected unreadable directory'), { code: 'EACCES' })
|
||||
}
|
||||
return (actual.readdir as (path: unknown, ...args: never[]) => Promise<unknown>)(path, ...rest)
|
||||
}) as typeof actual.readdir,
|
||||
}
|
||||
})
|
||||
|
||||
const searches: WorkspaceFileSearch[] = []
|
||||
const roots: string[] = []
|
||||
/** Permission-stripped directories; restored before cleanup can remove them. */
|
||||
@@ -199,7 +217,13 @@ describe('WorkspaceFileSearch', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('lets an unreadable subtree cost only its own candidates', async () => {
|
||||
// chmod 0 can only deny directory reads on POSIX to a non-root owner:
|
||||
// Windows exposes no directory permission bits for readdir, and root
|
||||
// bypasses them. Where the fixture stays readable the sealed candidate is
|
||||
// indexed, so the unreadable-branch behavior is pinned on POSIX non-root.
|
||||
it.runIf(
|
||||
process.getuid !== undefined && process.getuid() !== 0,
|
||||
)('lets an unreadable subtree cost only its own candidates', async () => {
|
||||
const root = await workspace()
|
||||
const locked = join(root, 'locked')
|
||||
await mkdir(locked, { recursive: true })
|
||||
@@ -216,6 +240,29 @@ describe('WorkspaceFileSearch', () => {
|
||||
expect(await files.list('locked', signal)).toEqual([{ path: 'locked', kind: 'directory' }])
|
||||
})
|
||||
|
||||
// The chmod-0 fixture above cannot be built on Windows (no directory
|
||||
// permission bits) or as root (bits are bypassed). An injected readdir
|
||||
// failure keeps the unreadable-branch behavior covered on every platform.
|
||||
it('lets an injected readdir failure cost only its own candidates', async () => {
|
||||
const root = await workspace()
|
||||
const locked = join(root, 'locked')
|
||||
await mkdir(locked, { recursive: true })
|
||||
await writeFile(join(locked, 'sealed.ts'), 'sealed')
|
||||
fsControl.denyReaddir = locked
|
||||
try {
|
||||
const files = search(root)
|
||||
const signal = new AbortController().signal
|
||||
|
||||
// The branch itself yields nothing, and the rest of the tree still does.
|
||||
expect(await files.list('sealed', signal)).toEqual([])
|
||||
expect(await files.list('README', signal)).toEqual([{ path: 'README.md', kind: 'file' }])
|
||||
// The directory is still offered: only reading through it fails.
|
||||
expect(await files.list('locked', signal)).toEqual([{ path: 'locked', kind: 'directory' }])
|
||||
} finally {
|
||||
fsControl.denyReaddir = undefined
|
||||
}
|
||||
})
|
||||
|
||||
it('enforces the entry cap', async () => {
|
||||
const root = await workspace()
|
||||
const capped = search(root, { maxEntries: 2 })
|
||||
|
||||
Reference in New Issue
Block a user