blob: b64746c39d139f8d8e25c6a7f850a14fdb5ccde1 [file]
/**
* @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.
*/
const assert = require('assert')
const fs = require('fs')
const withFixtures = require('inline-fixtures').withFixtures
const path = require('path')
const util = require('util')
const patcher = require('../../node-patches/src/fs').patcher
// 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 opendir', async () => {
await it('can opendir 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 patchedFs = Object.assign({}, fs)
patchedFs.promises = Object.assign({}, fs.promises)
patcher(patchedFs, [fixturesDir])
let dir
dir = await util.promisify(patchedFs.opendir)(
path.join(fixturesDir, 'a')
)
const entry1 = await dir.read()
const entry2 = await util.promisify(dir.read.bind(dir))()
const empty = await dir.read()
let names = [entry1.name, entry2.name]
names.sort()
assert.deepStrictEqual(names, ['apples', 'link'])
let maybeLink = entry1.name === 'link' ? entry1 : entry2
assert.ok(maybeLink.isSymbolicLink())
assert.ok(!empty, 'last read should be falsey')
}
)
})
await it('can opendir dirent link 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 patchedFs = Object.assign({}, fs)
patchedFs.promises = Object.assign({}, fs.promises)
patcher(patchedFs, [path.join(fixturesDir, 'a')])
let dir
dir = await util.promisify(patchedFs.opendir)(
path.join(fixturesDir, 'a')
)
const entry1 = await dir.read()
const entry2 = await util.promisify(dir.read.bind(dir))()
const empty = await dir.read()
let names = [entry1.name, entry2.name]
names.sort()
assert.ok(!empty)
assert.deepStrictEqual(names, ['apples', 'link'])
let maybeLink = entry1.name === 'link' ? entry1 : entry2
console.error(entry1, entry2)
assert.ok(!maybeLink.isSymbolicLink())
}
)
})
await it('can async iterate opendir', 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 patchedFs = Object.assign({}, fs)
patchedFs.promises = Object.assign({}, fs.promises)
patcher(patchedFs, [path.join(fixturesDir)])
const dir = await util.promisify(patchedFs.opendir)(
path.join(fixturesDir, 'a')
)
const names = []
for await (const entry of dir) {
names.push(entry.name)
if (entry.name === 'link') {
assert.ok(entry.isSymbolicLink())
} else if (entry.name === 'apples') {
assert.ok(entry.isFile())
}
}
names.sort()
assert.deepStrictEqual(names, ['apples', 'link'])
}
)
})
await it('can async iterate opendir link 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 patchedFs = Object.assign({}, fs)
patchedFs.promises = Object.assign({}, fs.promises)
patcher(patchedFs, [path.join(fixturesDir, 'a')])
const dir = await util.promisify(patchedFs.opendir)(
path.join(fixturesDir, 'a')
)
const names = []
for await (const entry of dir) {
names.push(entry.name)
if (entry.name === 'link') {
assert.ok(!entry.isSymbolicLink())
assert.ok(entry.isFile())
} else if (entry.name === 'apples') {
assert.ok(entry.isFile())
}
}
names.sort()
assert.deepStrictEqual(names, ['apples', 'link'])
}
)
})
await it('can opendir 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
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'file'),
path.join(fixturesDir, 'sandbox', 'file')
)
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'link'),
path.join(fixturesDir, 'sandbox', 'link')
)
fs.symlinkSync(
path.join(fixturesDir, 'execroot', 'link2'),
path.join(fixturesDir, 'sandbox', 'link2')
)
const patchedFs = Object.assign({}, fs)
patchedFs.promises = Object.assign({}, fs.promises)
patcher(patchedFs, [path.join(fixturesDir, 'sandbox')])
let dir
dir = await util.promisify(patchedFs.opendir)(
path.join(fixturesDir, 'sandbox')
)
const entry1 = await dir.read()
const entry2 = await util.promisify(dir.read.bind(dir))()
const entry3 = await util.promisify(dir.read.bind(dir))()
const empty = await dir.read()
let names = [entry1.name, entry2.name, entry3.name]
names.sort()
assert.deepStrictEqual(names, ['file', 'link', 'link2'])
assert.ok(
entry1.name === 'file'
? !entry1.isSymbolicLink()
: entry1.isSymbolicLink()
)
assert.ok(
entry2.name === 'file'
? !entry2.isSymbolicLink()
: entry2.isSymbolicLink()
)
assert.ok(
entry3.name === 'file'
? !entry3.isSymbolicLink()
: entry3.isSymbolicLink()
)
assert.ok(!empty, 'last read should be falsey')
}
)
})
})