11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir');
61cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
71cb0ef41Sopenharmony_ciconst path = require('path');
81cb0ef41Sopenharmony_ciconst fs = require('fs');
91cb0ef41Sopenharmony_ciconst fsPromises = fs.promises;
101cb0ef41Sopenharmony_ciconst {
111cb0ef41Sopenharmony_ci  access,
121cb0ef41Sopenharmony_ci  chmod,
131cb0ef41Sopenharmony_ci  chown,
141cb0ef41Sopenharmony_ci  copyFile,
151cb0ef41Sopenharmony_ci  lchown,
161cb0ef41Sopenharmony_ci  link,
171cb0ef41Sopenharmony_ci  lchmod,
181cb0ef41Sopenharmony_ci  lstat,
191cb0ef41Sopenharmony_ci  lutimes,
201cb0ef41Sopenharmony_ci  mkdir,
211cb0ef41Sopenharmony_ci  mkdtemp,
221cb0ef41Sopenharmony_ci  open,
231cb0ef41Sopenharmony_ci  readFile,
241cb0ef41Sopenharmony_ci  readdir,
251cb0ef41Sopenharmony_ci  readlink,
261cb0ef41Sopenharmony_ci  realpath,
271cb0ef41Sopenharmony_ci  rename,
281cb0ef41Sopenharmony_ci  rmdir,
291cb0ef41Sopenharmony_ci  stat,
301cb0ef41Sopenharmony_ci  statfs,
311cb0ef41Sopenharmony_ci  symlink,
321cb0ef41Sopenharmony_ci  truncate,
331cb0ef41Sopenharmony_ci  unlink,
341cb0ef41Sopenharmony_ci  utimes,
351cb0ef41Sopenharmony_ci  writeFile
361cb0ef41Sopenharmony_ci} = fsPromises;
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciconst tmpDir = tmpdir.path;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cilet dirc = 0;
411cb0ef41Sopenharmony_cifunction nextdir() {
421cb0ef41Sopenharmony_ci  return `test${++dirc}`;
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci// fs.promises should be enumerable.
461cb0ef41Sopenharmony_ciassert.strictEqual(
471cb0ef41Sopenharmony_ci  Object.prototype.propertyIsEnumerable.call(fs, 'promises'),
481cb0ef41Sopenharmony_ci  true
491cb0ef41Sopenharmony_ci);
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci{
521cb0ef41Sopenharmony_ci  access(__filename, 0)
531cb0ef41Sopenharmony_ci    .then(common.mustCall());
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  assert.rejects(
561cb0ef41Sopenharmony_ci    access('this file does not exist', 0),
571cb0ef41Sopenharmony_ci    {
581cb0ef41Sopenharmony_ci      code: 'ENOENT',
591cb0ef41Sopenharmony_ci      name: 'Error',
601cb0ef41Sopenharmony_ci      message: /^ENOENT: no such file or directory, access/
611cb0ef41Sopenharmony_ci    }
621cb0ef41Sopenharmony_ci  );
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  assert.rejects(
651cb0ef41Sopenharmony_ci    access(__filename, 8),
661cb0ef41Sopenharmony_ci    {
671cb0ef41Sopenharmony_ci      code: 'ERR_OUT_OF_RANGE',
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci  );
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  assert.rejects(
721cb0ef41Sopenharmony_ci    access(__filename, { [Symbol.toPrimitive]() { return 5; } }),
731cb0ef41Sopenharmony_ci    {
741cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
751cb0ef41Sopenharmony_ci    }
761cb0ef41Sopenharmony_ci  );
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cifunction verifyStatObject(stat) {
801cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat, 'object');
811cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.dev, 'number');
821cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.mode, 'number');
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_cifunction verifyStatFsObject(stat, isBigint = false) {
861cb0ef41Sopenharmony_ci  const valueType = isBigint ? 'bigint' : 'number';
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat, 'object');
891cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.type, valueType);
901cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.bsize, valueType);
911cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.blocks, valueType);
921cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.bfree, valueType);
931cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.bavail, valueType);
941cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.files, valueType);
951cb0ef41Sopenharmony_ci  assert.strictEqual(typeof stat.ffree, valueType);
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciasync function getHandle(dest) {
991cb0ef41Sopenharmony_ci  await copyFile(fixtures.path('baz.js'), dest);
1001cb0ef41Sopenharmony_ci  await access(dest);
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  return open(dest, 'r+');
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ciasync function executeOnHandle(dest, func) {
1061cb0ef41Sopenharmony_ci  let handle;
1071cb0ef41Sopenharmony_ci  try {
1081cb0ef41Sopenharmony_ci    handle = await getHandle(dest);
1091cb0ef41Sopenharmony_ci    await func(handle);
1101cb0ef41Sopenharmony_ci  } finally {
1111cb0ef41Sopenharmony_ci    if (handle) {
1121cb0ef41Sopenharmony_ci      await handle.close();
1131cb0ef41Sopenharmony_ci    }
1141cb0ef41Sopenharmony_ci  }
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci{
1181cb0ef41Sopenharmony_ci  async function doTest() {
1191cb0ef41Sopenharmony_ci    tmpdir.refresh();
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci    const dest = path.resolve(tmpDir, 'baz.js');
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci    // handle is object
1241cb0ef41Sopenharmony_ci    {
1251cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
1261cb0ef41Sopenharmony_ci        assert.strictEqual(typeof handle, 'object');
1271cb0ef41Sopenharmony_ci      });
1281cb0ef41Sopenharmony_ci    }
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci    // file stats
1311cb0ef41Sopenharmony_ci    {
1321cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
1331cb0ef41Sopenharmony_ci        let stats = await handle.stat();
1341cb0ef41Sopenharmony_ci        verifyStatObject(stats);
1351cb0ef41Sopenharmony_ci        assert.strictEqual(stats.size, 35);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci        await handle.truncate(1);
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci        stats = await handle.stat();
1401cb0ef41Sopenharmony_ci        verifyStatObject(stats);
1411cb0ef41Sopenharmony_ci        assert.strictEqual(stats.size, 1);
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci        stats = await stat(dest);
1441cb0ef41Sopenharmony_ci        verifyStatObject(stats);
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci        stats = await handle.stat();
1471cb0ef41Sopenharmony_ci        verifyStatObject(stats);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci        await handle.datasync();
1501cb0ef41Sopenharmony_ci        await handle.sync();
1511cb0ef41Sopenharmony_ci      });
1521cb0ef41Sopenharmony_ci    }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci    // File system stats
1551cb0ef41Sopenharmony_ci    {
1561cb0ef41Sopenharmony_ci      const statFs = await statfs(dest);
1571cb0ef41Sopenharmony_ci      verifyStatFsObject(statFs);
1581cb0ef41Sopenharmony_ci    }
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci    // File system stats bigint
1611cb0ef41Sopenharmony_ci    {
1621cb0ef41Sopenharmony_ci      const statFs = await statfs(dest, { bigint: true });
1631cb0ef41Sopenharmony_ci      verifyStatFsObject(statFs, true);
1641cb0ef41Sopenharmony_ci    }
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci    // Test fs.read promises when length to read is zero bytes
1671cb0ef41Sopenharmony_ci    {
1681cb0ef41Sopenharmony_ci      const dest = path.resolve(tmpDir, 'test1.js');
1691cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
1701cb0ef41Sopenharmony_ci        const buf = Buffer.from('DAWGS WIN');
1711cb0ef41Sopenharmony_ci        const bufLen = buf.length;
1721cb0ef41Sopenharmony_ci        await handle.write(buf);
1731cb0ef41Sopenharmony_ci        const ret = await handle.read(Buffer.alloc(bufLen), 0, 0, 0);
1741cb0ef41Sopenharmony_ci        assert.strictEqual(ret.bytesRead, 0);
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci        await unlink(dest);
1771cb0ef41Sopenharmony_ci      });
1781cb0ef41Sopenharmony_ci    }
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci    // Use fallback buffer allocation when input not buffer
1811cb0ef41Sopenharmony_ci    {
1821cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
1831cb0ef41Sopenharmony_ci        const ret = await handle.read(0, 0, 0, 0);
1841cb0ef41Sopenharmony_ci        assert.strictEqual(ret.buffer.length, 16384);
1851cb0ef41Sopenharmony_ci      });
1861cb0ef41Sopenharmony_ci    }
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci    // Bytes written to file match buffer
1891cb0ef41Sopenharmony_ci    {
1901cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
1911cb0ef41Sopenharmony_ci        const buf = Buffer.from('hello fsPromises');
1921cb0ef41Sopenharmony_ci        const bufLen = buf.length;
1931cb0ef41Sopenharmony_ci        await handle.write(buf);
1941cb0ef41Sopenharmony_ci        const ret = await handle.read(Buffer.alloc(bufLen), 0, bufLen, 0);
1951cb0ef41Sopenharmony_ci        assert.strictEqual(ret.bytesRead, bufLen);
1961cb0ef41Sopenharmony_ci        assert.deepStrictEqual(ret.buffer, buf);
1971cb0ef41Sopenharmony_ci      });
1981cb0ef41Sopenharmony_ci    }
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci    // Truncate file to specified length
2011cb0ef41Sopenharmony_ci    {
2021cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
2031cb0ef41Sopenharmony_ci        const buf = Buffer.from('hello FileHandle');
2041cb0ef41Sopenharmony_ci        const bufLen = buf.length;
2051cb0ef41Sopenharmony_ci        await handle.write(buf, 0, bufLen, 0);
2061cb0ef41Sopenharmony_ci        const ret = await handle.read(Buffer.alloc(bufLen), 0, bufLen, 0);
2071cb0ef41Sopenharmony_ci        assert.strictEqual(ret.bytesRead, bufLen);
2081cb0ef41Sopenharmony_ci        assert.deepStrictEqual(ret.buffer, buf);
2091cb0ef41Sopenharmony_ci        await truncate(dest, 5);
2101cb0ef41Sopenharmony_ci        assert.strictEqual((await readFile(dest)).toString(), 'hello');
2111cb0ef41Sopenharmony_ci      });
2121cb0ef41Sopenharmony_ci    }
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci    // Invalid change of ownership
2151cb0ef41Sopenharmony_ci    {
2161cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
2171cb0ef41Sopenharmony_ci        await chmod(dest, 0o666);
2181cb0ef41Sopenharmony_ci        await handle.chmod(0o666);
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci        await chmod(dest, (0o10777));
2211cb0ef41Sopenharmony_ci        await handle.chmod(0o10777);
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci        if (!common.isWindows) {
2241cb0ef41Sopenharmony_ci          await chown(dest, process.getuid(), process.getgid());
2251cb0ef41Sopenharmony_ci          await handle.chown(process.getuid(), process.getgid());
2261cb0ef41Sopenharmony_ci        }
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci        await assert.rejects(
2291cb0ef41Sopenharmony_ci          async () => {
2301cb0ef41Sopenharmony_ci            await chown(dest, 1, -2);
2311cb0ef41Sopenharmony_ci          },
2321cb0ef41Sopenharmony_ci          {
2331cb0ef41Sopenharmony_ci            code: 'ERR_OUT_OF_RANGE',
2341cb0ef41Sopenharmony_ci            name: 'RangeError',
2351cb0ef41Sopenharmony_ci            message: 'The value of "gid" is out of range. ' +
2361cb0ef41Sopenharmony_ci                     'It must be >= -1 && <= 4294967295. Received -2'
2371cb0ef41Sopenharmony_ci          });
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci        await assert.rejects(
2401cb0ef41Sopenharmony_ci          async () => {
2411cb0ef41Sopenharmony_ci            await handle.chown(1, -2);
2421cb0ef41Sopenharmony_ci          },
2431cb0ef41Sopenharmony_ci          {
2441cb0ef41Sopenharmony_ci            code: 'ERR_OUT_OF_RANGE',
2451cb0ef41Sopenharmony_ci            name: 'RangeError',
2461cb0ef41Sopenharmony_ci            message: 'The value of "gid" is out of range. ' +
2471cb0ef41Sopenharmony_ci                      'It must be >= -1 && <= 4294967295. Received -2'
2481cb0ef41Sopenharmony_ci          });
2491cb0ef41Sopenharmony_ci      });
2501cb0ef41Sopenharmony_ci    }
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci    // Set modification times
2531cb0ef41Sopenharmony_ci    {
2541cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci        await utimes(dest, new Date(), new Date());
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci        try {
2591cb0ef41Sopenharmony_ci          await handle.utimes(new Date(), new Date());
2601cb0ef41Sopenharmony_ci        } catch (err) {
2611cb0ef41Sopenharmony_ci          // Some systems do not have futimes. If there is an error,
2621cb0ef41Sopenharmony_ci          // expect it to be ENOSYS
2631cb0ef41Sopenharmony_ci          common.expectsError({
2641cb0ef41Sopenharmony_ci            code: 'ENOSYS',
2651cb0ef41Sopenharmony_ci            name: 'Error'
2661cb0ef41Sopenharmony_ci          })(err);
2671cb0ef41Sopenharmony_ci        }
2681cb0ef41Sopenharmony_ci      });
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci    // Set modification times with lutimes
2721cb0ef41Sopenharmony_ci    {
2731cb0ef41Sopenharmony_ci      const a_time = new Date();
2741cb0ef41Sopenharmony_ci      a_time.setMinutes(a_time.getMinutes() - 1);
2751cb0ef41Sopenharmony_ci      const m_time = new Date();
2761cb0ef41Sopenharmony_ci      m_time.setHours(m_time.getHours() - 1);
2771cb0ef41Sopenharmony_ci      await lutimes(dest, a_time, m_time);
2781cb0ef41Sopenharmony_ci      const stats = await stat(dest);
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ci      assert.strictEqual(a_time.toString(), stats.atime.toString());
2811cb0ef41Sopenharmony_ci      assert.strictEqual(m_time.toString(), stats.mtime.toString());
2821cb0ef41Sopenharmony_ci    }
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci    // create symlink
2851cb0ef41Sopenharmony_ci    {
2861cb0ef41Sopenharmony_ci      const newPath = path.resolve(tmpDir, 'baz2.js');
2871cb0ef41Sopenharmony_ci      await rename(dest, newPath);
2881cb0ef41Sopenharmony_ci      let stats = await stat(newPath);
2891cb0ef41Sopenharmony_ci      verifyStatObject(stats);
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci      if (common.canCreateSymLink()) {
2921cb0ef41Sopenharmony_ci        const newLink = path.resolve(tmpDir, 'baz3.js');
2931cb0ef41Sopenharmony_ci        await symlink(newPath, newLink);
2941cb0ef41Sopenharmony_ci        if (!common.isWindows) {
2951cb0ef41Sopenharmony_ci          await lchown(newLink, process.getuid(), process.getgid());
2961cb0ef41Sopenharmony_ci        }
2971cb0ef41Sopenharmony_ci        stats = await lstat(newLink);
2981cb0ef41Sopenharmony_ci        verifyStatObject(stats);
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci        assert.strictEqual(newPath.toLowerCase(),
3011cb0ef41Sopenharmony_ci                           (await realpath(newLink)).toLowerCase());
3021cb0ef41Sopenharmony_ci        assert.strictEqual(newPath.toLowerCase(),
3031cb0ef41Sopenharmony_ci                           (await readlink(newLink)).toLowerCase());
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci        const newMode = 0o666;
3061cb0ef41Sopenharmony_ci        if (common.isOSX) {
3071cb0ef41Sopenharmony_ci          // `lchmod` is only available on macOS.
3081cb0ef41Sopenharmony_ci          await lchmod(newLink, newMode);
3091cb0ef41Sopenharmony_ci          stats = await lstat(newLink);
3101cb0ef41Sopenharmony_ci          assert.strictEqual(stats.mode & 0o777, newMode);
3111cb0ef41Sopenharmony_ci        } else {
3121cb0ef41Sopenharmony_ci          await Promise.all([
3131cb0ef41Sopenharmony_ci            assert.rejects(
3141cb0ef41Sopenharmony_ci              lchmod(newLink, newMode),
3151cb0ef41Sopenharmony_ci              common.expectsError({
3161cb0ef41Sopenharmony_ci                code: 'ERR_METHOD_NOT_IMPLEMENTED',
3171cb0ef41Sopenharmony_ci                name: 'Error',
3181cb0ef41Sopenharmony_ci                message: 'The lchmod() method is not implemented'
3191cb0ef41Sopenharmony_ci              })
3201cb0ef41Sopenharmony_ci            ),
3211cb0ef41Sopenharmony_ci          ]);
3221cb0ef41Sopenharmony_ci        }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci        await unlink(newLink);
3251cb0ef41Sopenharmony_ci      }
3261cb0ef41Sopenharmony_ci    }
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci    // specify symlink type
3291cb0ef41Sopenharmony_ci    {
3301cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir());
3311cb0ef41Sopenharmony_ci      await symlink(tmpDir, dir, 'dir');
3321cb0ef41Sopenharmony_ci      const stats = await lstat(dir);
3331cb0ef41Sopenharmony_ci      assert.strictEqual(stats.isSymbolicLink(), true);
3341cb0ef41Sopenharmony_ci      await unlink(dir);
3351cb0ef41Sopenharmony_ci    }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci    // create hard link
3381cb0ef41Sopenharmony_ci    {
3391cb0ef41Sopenharmony_ci      const newPath = path.resolve(tmpDir, 'baz2.js');
3401cb0ef41Sopenharmony_ci      const newLink = path.resolve(tmpDir, 'baz4.js');
3411cb0ef41Sopenharmony_ci      await link(newPath, newLink);
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci      await unlink(newLink);
3441cb0ef41Sopenharmony_ci    }
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ci    // Testing readdir lists both files and directories
3471cb0ef41Sopenharmony_ci    {
3481cb0ef41Sopenharmony_ci      const newDir = path.resolve(tmpDir, 'dir');
3491cb0ef41Sopenharmony_ci      const newFile = path.resolve(tmpDir, 'foo.js');
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci      await mkdir(newDir);
3521cb0ef41Sopenharmony_ci      await writeFile(newFile, 'DAWGS WIN!', 'utf8');
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci      const stats = await stat(newDir);
3551cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
3561cb0ef41Sopenharmony_ci      const list = await readdir(tmpDir);
3571cb0ef41Sopenharmony_ci      assert.notStrictEqual(list.indexOf('dir'), -1);
3581cb0ef41Sopenharmony_ci      assert.notStrictEqual(list.indexOf('foo.js'), -1);
3591cb0ef41Sopenharmony_ci      await rmdir(newDir);
3601cb0ef41Sopenharmony_ci      await unlink(newFile);
3611cb0ef41Sopenharmony_ci    }
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci    // Use fallback encoding when input is null
3641cb0ef41Sopenharmony_ci    {
3651cb0ef41Sopenharmony_ci      const newFile = path.resolve(tmpDir, 'dogs_running.js');
3661cb0ef41Sopenharmony_ci      await writeFile(newFile, 'dogs running', { encoding: null });
3671cb0ef41Sopenharmony_ci      const fileExists = fs.existsSync(newFile);
3681cb0ef41Sopenharmony_ci      assert.strictEqual(fileExists, true);
3691cb0ef41Sopenharmony_ci    }
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci    // `mkdir` when options is number.
3721cb0ef41Sopenharmony_ci    {
3731cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir());
3741cb0ef41Sopenharmony_ci      await mkdir(dir, 777);
3751cb0ef41Sopenharmony_ci      const stats = await stat(dir);
3761cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
3771cb0ef41Sopenharmony_ci    }
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci    // `mkdir` when options is string.
3801cb0ef41Sopenharmony_ci    {
3811cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir());
3821cb0ef41Sopenharmony_ci      await mkdir(dir, '777');
3831cb0ef41Sopenharmony_ci      const stats = await stat(dir);
3841cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
3851cb0ef41Sopenharmony_ci    }
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci    // `mkdirp` when folder does not yet exist.
3881cb0ef41Sopenharmony_ci    {
3891cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir(), nextdir());
3901cb0ef41Sopenharmony_ci      await mkdir(dir, { recursive: true });
3911cb0ef41Sopenharmony_ci      const stats = await stat(dir);
3921cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
3931cb0ef41Sopenharmony_ci    }
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci    // `mkdirp` when path is a file.
3961cb0ef41Sopenharmony_ci    {
3971cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir(), nextdir());
3981cb0ef41Sopenharmony_ci      await mkdir(path.dirname(dir));
3991cb0ef41Sopenharmony_ci      await writeFile(dir, '');
4001cb0ef41Sopenharmony_ci      assert.rejects(
4011cb0ef41Sopenharmony_ci        mkdir(dir, { recursive: true }),
4021cb0ef41Sopenharmony_ci        {
4031cb0ef41Sopenharmony_ci          code: 'EEXIST',
4041cb0ef41Sopenharmony_ci          message: /EEXIST: .*mkdir/,
4051cb0ef41Sopenharmony_ci          name: 'Error',
4061cb0ef41Sopenharmony_ci          syscall: 'mkdir',
4071cb0ef41Sopenharmony_ci        }
4081cb0ef41Sopenharmony_ci      );
4091cb0ef41Sopenharmony_ci    }
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci    // `mkdirp` when part of the path is a file.
4121cb0ef41Sopenharmony_ci    {
4131cb0ef41Sopenharmony_ci      const file = path.join(tmpDir, nextdir(), nextdir());
4141cb0ef41Sopenharmony_ci      const dir = path.join(file, nextdir(), nextdir());
4151cb0ef41Sopenharmony_ci      await mkdir(path.dirname(file));
4161cb0ef41Sopenharmony_ci      await writeFile(file, '');
4171cb0ef41Sopenharmony_ci      assert.rejects(
4181cb0ef41Sopenharmony_ci        mkdir(dir, { recursive: true }),
4191cb0ef41Sopenharmony_ci        {
4201cb0ef41Sopenharmony_ci          code: 'ENOTDIR',
4211cb0ef41Sopenharmony_ci          message: /ENOTDIR: .*mkdir/,
4221cb0ef41Sopenharmony_ci          name: 'Error',
4231cb0ef41Sopenharmony_ci          syscall: 'mkdir',
4241cb0ef41Sopenharmony_ci        }
4251cb0ef41Sopenharmony_ci      );
4261cb0ef41Sopenharmony_ci    }
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci    // mkdirp ./
4291cb0ef41Sopenharmony_ci    {
4301cb0ef41Sopenharmony_ci      const dir = path.resolve(tmpDir, `${nextdir()}/./${nextdir()}`);
4311cb0ef41Sopenharmony_ci      await mkdir(dir, { recursive: true });
4321cb0ef41Sopenharmony_ci      const stats = await stat(dir);
4331cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
4341cb0ef41Sopenharmony_ci    }
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci    // mkdirp ../
4371cb0ef41Sopenharmony_ci    {
4381cb0ef41Sopenharmony_ci      const dir = path.resolve(tmpDir, `${nextdir()}/../${nextdir()}`);
4391cb0ef41Sopenharmony_ci      await mkdir(dir, { recursive: true });
4401cb0ef41Sopenharmony_ci      const stats = await stat(dir);
4411cb0ef41Sopenharmony_ci      assert(stats.isDirectory());
4421cb0ef41Sopenharmony_ci    }
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci    // fs.mkdirp requires the recursive option to be of type boolean.
4451cb0ef41Sopenharmony_ci    // Everything else generates an error.
4461cb0ef41Sopenharmony_ci    {
4471cb0ef41Sopenharmony_ci      const dir = path.join(tmpDir, nextdir(), nextdir());
4481cb0ef41Sopenharmony_ci      ['', 1, {}, [], null, Symbol('test'), () => {}].forEach((recursive) => {
4491cb0ef41Sopenharmony_ci        assert.rejects(
4501cb0ef41Sopenharmony_ci          // mkdir() expects to get a boolean value for options.recursive.
4511cb0ef41Sopenharmony_ci          async () => mkdir(dir, { recursive }),
4521cb0ef41Sopenharmony_ci          {
4531cb0ef41Sopenharmony_ci            code: 'ERR_INVALID_ARG_TYPE',
4541cb0ef41Sopenharmony_ci            name: 'TypeError'
4551cb0ef41Sopenharmony_ci          }
4561cb0ef41Sopenharmony_ci        );
4571cb0ef41Sopenharmony_ci      });
4581cb0ef41Sopenharmony_ci    }
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ci    // `mkdtemp` with invalid numeric prefix
4611cb0ef41Sopenharmony_ci    {
4621cb0ef41Sopenharmony_ci      await mkdtemp(path.resolve(tmpDir, 'FOO'));
4631cb0ef41Sopenharmony_ci      assert.rejects(
4641cb0ef41Sopenharmony_ci        // mkdtemp() expects to get a string prefix.
4651cb0ef41Sopenharmony_ci        async () => mkdtemp(1),
4661cb0ef41Sopenharmony_ci        {
4671cb0ef41Sopenharmony_ci          code: 'ERR_INVALID_ARG_TYPE',
4681cb0ef41Sopenharmony_ci          name: 'TypeError'
4691cb0ef41Sopenharmony_ci        }
4701cb0ef41Sopenharmony_ci      );
4711cb0ef41Sopenharmony_ci    }
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci    // Regression test for https://github.com/nodejs/node/issues/38168
4741cb0ef41Sopenharmony_ci    {
4751cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
4761cb0ef41Sopenharmony_ci        await assert.rejects(
4771cb0ef41Sopenharmony_ci          async () => handle.write('abc', 0, 'hex'),
4781cb0ef41Sopenharmony_ci          {
4791cb0ef41Sopenharmony_ci            code: 'ERR_INVALID_ARG_VALUE',
4801cb0ef41Sopenharmony_ci            message: /'encoding' is invalid for data of length 3/
4811cb0ef41Sopenharmony_ci          }
4821cb0ef41Sopenharmony_ci        );
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci        const ret = await handle.write('abcd', 0, 'hex');
4851cb0ef41Sopenharmony_ci        assert.strictEqual(ret.bytesWritten, 2);
4861cb0ef41Sopenharmony_ci      });
4871cb0ef41Sopenharmony_ci    }
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci    // Test prototype methods calling with contexts other than FileHandle
4901cb0ef41Sopenharmony_ci    {
4911cb0ef41Sopenharmony_ci      await executeOnHandle(dest, async (handle) => {
4921cb0ef41Sopenharmony_ci        await assert.rejects(() => handle.stat.call({}), {
4931cb0ef41Sopenharmony_ci          code: 'ERR_INTERNAL_ASSERTION',
4941cb0ef41Sopenharmony_ci          message: /handle must be an instance of FileHandle/
4951cb0ef41Sopenharmony_ci        });
4961cb0ef41Sopenharmony_ci      });
4971cb0ef41Sopenharmony_ci    }
4981cb0ef41Sopenharmony_ci  }
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  doTest().then(common.mustCall());
5011cb0ef41Sopenharmony_ci}
502