blob: 835afa2ac7900b097f891997defa4b22f50bbe94 [file] [log] [blame]
/**
* @license
* Copyright 2019 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as assert from 'node:assert'
import * as fs from 'node:fs'
import { withFixtures } from 'inline-fixtures'
import * as path from 'node:path'
import * as util from 'node:util'
import { patcher } from '../../node-patches/src/fs.cjs'
// We don't want to bring jest into this repo so we just fake the describe and it functions here
async function describe(_, fn) {
await fn()
}
async function it(_, fn) {
await fn()
}
describe('testing readdir', async () => {
await it('can readdir dirent in root', async () => {
await withFixtures(
{
a: { apples: 'contents' },
b: { file: 'contents' },
},
async (fixturesDir) => {
fixturesDir = fs.realpathSync(fixturesDir)
// create symlink from a to b
fs.symlinkSync(
path.join(fixturesDir, 'b', 'file'),
path.join(fixturesDir, 'a', 'link')
)
const revertPatches = patcher([fixturesDir])
let dirents = fs.readdirSync(path.join(fixturesDir, 'a'), {
withFileTypes: true,
})
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
dirents = await util.promisify(fs.readdir)(
path.join(fixturesDir, 'a'),
{ withFileTypes: true }
)
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
dirents = await fs.promises.readdir(
path.join(fixturesDir, 'a'),
{ withFileTypes: true }
)
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
// Assert the same with URL file references
dirents = fs.readdirSync(
new URL(`file://${path.join(fixturesDir, 'a')}`),
{
withFileTypes: true,
}
)
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
revertPatches()
}
)
})
await it('can readdir link dirents as files out of root', async () => {
await withFixtures(
{
a: { apples: 'contents' },
b: { file: 'contents' },
},
async (fixturesDir) => {
fixturesDir = fs.realpathSync(fixturesDir)
// create symlink from a to b
fs.symlinkSync(
path.join(fixturesDir, 'b', 'file'),
path.join(fixturesDir, 'a', 'link')
)
const revertPatches = patcher([path.join(fixturesDir, 'a')])
console.error('FOO')
console.error(fs.readdirSync)
let dirents = fs.readdirSync(path.join(fixturesDir, 'a'), {
withFileTypes: true,
})
console.error('BAR')
console.log(dirents)
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(!dirents[1].isSymbolicLink())
assert.ok(dirents[1].isFile())
console.error('FOO')
dirents = await util.promisify(fs.readdir)(
path.join(fixturesDir, 'a'),
{ withFileTypes: true }
)
console.error('BAR')
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(!dirents[1].isSymbolicLink())
assert.ok(dirents[1].isFile())
dirents = await fs.promises.readdir(
path.join(fixturesDir, 'a'),
{ withFileTypes: true }
)
assert.deepStrictEqual(dirents[0].name, 'apples')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.ok(dirents[0].isFile())
assert.ok(!dirents[1].isSymbolicLink())
assert.ok(dirents[1].isFile())
revertPatches()
}
)
})
await it('can readdir dirent in a sandbox', async () => {
await withFixtures(
{
sandbox: {},
execroot: { file: 'contents' },
},
async (fixturesDir) => {
fixturesDir = fs.realpathSync(fixturesDir)
// create symlink from execroot/link2 to execroot/file
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'file'),
path.join(fixturesDir, 'execroot', 'link2')
)
// create symlink from execroot/link to execroot/link2
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'link2'),
path.join(fixturesDir, 'execroot', 'link')
)
// create sandbox; relative symlinks are maintained (assume Bazel 6 with allow unresolved symlinks)
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'file'),
path.join(fixturesDir, 'sandbox', 'file')
)
fs.symlinkSync(
path.join(fixturesDir, 'sandbox', 'file'),
path.join(fixturesDir, 'sandbox', 'link2')
)
fs.symlinkSync(
path.join(fixturesDir, 'sandbox', 'link2'),
path.join(fixturesDir, 'sandbox', 'link')
)
const revertPatches = patcher([
path.join(fixturesDir, 'sandbox'),
])
let dirents = fs.readdirSync(
path.join(fixturesDir, 'sandbox'),
{
withFileTypes: true,
}
)
assert.deepStrictEqual(dirents[0].name, 'file')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.deepStrictEqual(dirents[2].name, 'link2')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
assert.ok(dirents[2].isSymbolicLink())
dirents = await util.promisify(fs.readdir)(
path.join(fixturesDir, 'sandbox'),
{ withFileTypes: true }
)
assert.deepStrictEqual(dirents[0].name, 'file')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.deepStrictEqual(dirents[2].name, 'link2')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
assert.ok(dirents[2].isSymbolicLink())
dirents = await fs.promises.readdir(
path.join(fixturesDir, 'sandbox'),
{ withFileTypes: true }
)
assert.deepStrictEqual(dirents[0].name, 'file')
assert.deepStrictEqual(dirents[1].name, 'link')
assert.deepStrictEqual(dirents[2].name, 'link2')
assert.ok(dirents[0].isFile())
assert.ok(dirents[1].isSymbolicLink())
assert.ok(dirents[2].isSymbolicLink())
revertPatches()
}
)
})
await it('includes parent calls in stack traces', async function readdirStackTest1() {
let err
try {
fs.readdirSync('/foo/bar' + Date.now())
} catch (e) {
err = e
} finally {
if (!err) assert.fail('readdirSync should fail on invalid path')
if (!err.stack.includes('readdirStackTest1'))
assert.fail(
`readdirSync error stack should contain calling method: ${err.stack}`
)
}
})
})