11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci'use strict';
231cb0ef41Sopenharmony_ciconst common = require('../common');
241cb0ef41Sopenharmony_ciconst assert = require('assert');
251cb0ef41Sopenharmony_ciconst path = require('path');
261cb0ef41Sopenharmony_ciconst fs = require('fs');
271cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir');
281cb0ef41Sopenharmony_ciconst tmp = tmpdir.path;
291cb0ef41Sopenharmony_ciconst filename = path.resolve(tmp, 'truncate-file.txt');
301cb0ef41Sopenharmony_ciconst data = Buffer.alloc(1024 * 16, 'x');
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_citmpdir.refresh();
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cilet stat;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ciconst msg = 'Using fs.truncate with a file descriptor is deprecated.' +
371cb0ef41Sopenharmony_ci            ' Please use fs.ftruncate with a file descriptor instead.';
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci// Check truncateSync
401cb0ef41Sopenharmony_cifs.writeFileSync(filename, data);
411cb0ef41Sopenharmony_cistat = fs.statSync(filename);
421cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 1024 * 16);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_cifs.truncateSync(filename, 1024);
451cb0ef41Sopenharmony_cistat = fs.statSync(filename);
461cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 1024);
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cifs.truncateSync(filename);
491cb0ef41Sopenharmony_cistat = fs.statSync(filename);
501cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 0);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci// Check ftruncateSync
531cb0ef41Sopenharmony_cifs.writeFileSync(filename, data);
541cb0ef41Sopenharmony_ciconst fd = fs.openSync(filename, 'r+');
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_cistat = fs.statSync(filename);
571cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 1024 * 16);
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cifs.ftruncateSync(fd, 1024);
601cb0ef41Sopenharmony_cistat = fs.statSync(filename);
611cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 1024);
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_cifs.ftruncateSync(fd);
641cb0ef41Sopenharmony_cistat = fs.statSync(filename);
651cb0ef41Sopenharmony_ciassert.strictEqual(stat.size, 0);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// truncateSync
681cb0ef41Sopenharmony_cicommon.expectWarning('DeprecationWarning', msg, 'DEP0081');
691cb0ef41Sopenharmony_cifs.truncateSync(fd);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cifs.closeSync(fd);
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci// Async tests
741cb0ef41Sopenharmony_citestTruncate(common.mustSucceed(() => {
751cb0ef41Sopenharmony_ci  testFtruncate(common.mustSucceed());
761cb0ef41Sopenharmony_ci}));
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_cifunction testTruncate(cb) {
791cb0ef41Sopenharmony_ci  fs.writeFile(filename, data, function(er) {
801cb0ef41Sopenharmony_ci    if (er) return cb(er);
811cb0ef41Sopenharmony_ci    fs.stat(filename, function(er, stat) {
821cb0ef41Sopenharmony_ci      if (er) return cb(er);
831cb0ef41Sopenharmony_ci      assert.strictEqual(stat.size, 1024 * 16);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci      fs.truncate(filename, 1024, function(er) {
861cb0ef41Sopenharmony_ci        if (er) return cb(er);
871cb0ef41Sopenharmony_ci        fs.stat(filename, function(er, stat) {
881cb0ef41Sopenharmony_ci          if (er) return cb(er);
891cb0ef41Sopenharmony_ci          assert.strictEqual(stat.size, 1024);
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci          fs.truncate(filename, function(er) {
921cb0ef41Sopenharmony_ci            if (er) return cb(er);
931cb0ef41Sopenharmony_ci            fs.stat(filename, function(er, stat) {
941cb0ef41Sopenharmony_ci              if (er) return cb(er);
951cb0ef41Sopenharmony_ci              assert.strictEqual(stat.size, 0);
961cb0ef41Sopenharmony_ci              cb();
971cb0ef41Sopenharmony_ci            });
981cb0ef41Sopenharmony_ci          });
991cb0ef41Sopenharmony_ci        });
1001cb0ef41Sopenharmony_ci      });
1011cb0ef41Sopenharmony_ci    });
1021cb0ef41Sopenharmony_ci  });
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_cifunction testFtruncate(cb) {
1061cb0ef41Sopenharmony_ci  fs.writeFile(filename, data, function(er) {
1071cb0ef41Sopenharmony_ci    if (er) return cb(er);
1081cb0ef41Sopenharmony_ci    fs.stat(filename, function(er, stat) {
1091cb0ef41Sopenharmony_ci      if (er) return cb(er);
1101cb0ef41Sopenharmony_ci      assert.strictEqual(stat.size, 1024 * 16);
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci      fs.open(filename, 'w', function(er, fd) {
1131cb0ef41Sopenharmony_ci        if (er) return cb(er);
1141cb0ef41Sopenharmony_ci        fs.ftruncate(fd, 1024, function(er) {
1151cb0ef41Sopenharmony_ci          if (er) return cb(er);
1161cb0ef41Sopenharmony_ci          fs.stat(filename, function(er, stat) {
1171cb0ef41Sopenharmony_ci            if (er) return cb(er);
1181cb0ef41Sopenharmony_ci            assert.strictEqual(stat.size, 1024);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci            fs.ftruncate(fd, function(er) {
1211cb0ef41Sopenharmony_ci              if (er) return cb(er);
1221cb0ef41Sopenharmony_ci              fs.stat(filename, function(er, stat) {
1231cb0ef41Sopenharmony_ci                if (er) return cb(er);
1241cb0ef41Sopenharmony_ci                assert.strictEqual(stat.size, 0);
1251cb0ef41Sopenharmony_ci                fs.close(fd, cb);
1261cb0ef41Sopenharmony_ci              });
1271cb0ef41Sopenharmony_ci            });
1281cb0ef41Sopenharmony_ci          });
1291cb0ef41Sopenharmony_ci        });
1301cb0ef41Sopenharmony_ci      });
1311cb0ef41Sopenharmony_ci    });
1321cb0ef41Sopenharmony_ci  });
1331cb0ef41Sopenharmony_ci}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci// Make sure if the size of the file is smaller than the length then it is
1361cb0ef41Sopenharmony_ci// filled with zeroes.
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci{
1391cb0ef41Sopenharmony_ci  const file1 = path.resolve(tmp, 'truncate-file-1.txt');
1401cb0ef41Sopenharmony_ci  fs.writeFileSync(file1, 'Hi');
1411cb0ef41Sopenharmony_ci  fs.truncateSync(file1, 4);
1421cb0ef41Sopenharmony_ci  assert(fs.readFileSync(file1).equals(Buffer.from('Hi\u0000\u0000')));
1431cb0ef41Sopenharmony_ci}
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci{
1461cb0ef41Sopenharmony_ci  const file2 = path.resolve(tmp, 'truncate-file-2.txt');
1471cb0ef41Sopenharmony_ci  fs.writeFileSync(file2, 'Hi');
1481cb0ef41Sopenharmony_ci  const fd = fs.openSync(file2, 'r+');
1491cb0ef41Sopenharmony_ci  process.on('beforeExit', () => fs.closeSync(fd));
1501cb0ef41Sopenharmony_ci  fs.ftruncateSync(fd, 4);
1511cb0ef41Sopenharmony_ci  assert(fs.readFileSync(file2).equals(Buffer.from('Hi\u0000\u0000')));
1521cb0ef41Sopenharmony_ci}
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci{
1551cb0ef41Sopenharmony_ci  const file3 = path.resolve(tmp, 'truncate-file-3.txt');
1561cb0ef41Sopenharmony_ci  fs.writeFileSync(file3, 'Hi');
1571cb0ef41Sopenharmony_ci  fs.truncate(file3, 4, common.mustSucceed(() => {
1581cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file3).equals(Buffer.from('Hi\u0000\u0000')));
1591cb0ef41Sopenharmony_ci  }));
1601cb0ef41Sopenharmony_ci}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci{
1631cb0ef41Sopenharmony_ci  const file4 = path.resolve(tmp, 'truncate-file-4.txt');
1641cb0ef41Sopenharmony_ci  fs.writeFileSync(file4, 'Hi');
1651cb0ef41Sopenharmony_ci  const fd = fs.openSync(file4, 'r+');
1661cb0ef41Sopenharmony_ci  process.on('beforeExit', () => fs.closeSync(fd));
1671cb0ef41Sopenharmony_ci  fs.ftruncate(fd, 4, common.mustSucceed(() => {
1681cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file4).equals(Buffer.from('Hi\u0000\u0000')));
1691cb0ef41Sopenharmony_ci  }));
1701cb0ef41Sopenharmony_ci}
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci{
1731cb0ef41Sopenharmony_ci  const file5 = path.resolve(tmp, 'truncate-file-5.txt');
1741cb0ef41Sopenharmony_ci  fs.writeFileSync(file5, 'Hi');
1751cb0ef41Sopenharmony_ci  const fd = fs.openSync(file5, 'r+');
1761cb0ef41Sopenharmony_ci  process.on('beforeExit', () => fs.closeSync(fd));
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci  ['', false, null, {}, []].forEach((input) => {
1791cb0ef41Sopenharmony_ci    const received = common.invalidArgTypeHelper(input);
1801cb0ef41Sopenharmony_ci    assert.throws(
1811cb0ef41Sopenharmony_ci      () => fs.truncate(file5, input, common.mustNotCall()),
1821cb0ef41Sopenharmony_ci      {
1831cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
1841cb0ef41Sopenharmony_ci        name: 'TypeError',
1851cb0ef41Sopenharmony_ci        message: `The "len" argument must be of type number.${received}`
1861cb0ef41Sopenharmony_ci      }
1871cb0ef41Sopenharmony_ci    );
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci    assert.throws(
1901cb0ef41Sopenharmony_ci      () => fs.ftruncate(fd, input),
1911cb0ef41Sopenharmony_ci      {
1921cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
1931cb0ef41Sopenharmony_ci        name: 'TypeError',
1941cb0ef41Sopenharmony_ci        message: `The "len" argument must be of type number.${received}`
1951cb0ef41Sopenharmony_ci      }
1961cb0ef41Sopenharmony_ci    );
1971cb0ef41Sopenharmony_ci  });
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  [-1.5, 1.5].forEach((input) => {
2001cb0ef41Sopenharmony_ci    assert.throws(
2011cb0ef41Sopenharmony_ci      () => fs.truncate(file5, input),
2021cb0ef41Sopenharmony_ci      {
2031cb0ef41Sopenharmony_ci        code: 'ERR_OUT_OF_RANGE',
2041cb0ef41Sopenharmony_ci        name: 'RangeError',
2051cb0ef41Sopenharmony_ci        message: 'The value of "len" is out of range. It must be ' +
2061cb0ef41Sopenharmony_ci                  `an integer. Received ${input}`
2071cb0ef41Sopenharmony_ci      }
2081cb0ef41Sopenharmony_ci    );
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci    assert.throws(
2111cb0ef41Sopenharmony_ci      () => fs.ftruncate(fd, input),
2121cb0ef41Sopenharmony_ci      {
2131cb0ef41Sopenharmony_ci        code: 'ERR_OUT_OF_RANGE',
2141cb0ef41Sopenharmony_ci        name: 'RangeError',
2151cb0ef41Sopenharmony_ci        message: 'The value of "len" is out of range. It must be ' +
2161cb0ef41Sopenharmony_ci                  `an integer. Received ${input}`
2171cb0ef41Sopenharmony_ci      }
2181cb0ef41Sopenharmony_ci    );
2191cb0ef41Sopenharmony_ci  });
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci  fs.ftruncate(fd, undefined, common.mustSucceed(() => {
2221cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file5).equals(Buffer.from('')));
2231cb0ef41Sopenharmony_ci  }));
2241cb0ef41Sopenharmony_ci}
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci{
2271cb0ef41Sopenharmony_ci  const file6 = path.resolve(tmp, 'truncate-file-6.txt');
2281cb0ef41Sopenharmony_ci  fs.writeFileSync(file6, 'Hi');
2291cb0ef41Sopenharmony_ci  const fd = fs.openSync(file6, 'r+');
2301cb0ef41Sopenharmony_ci  process.on('beforeExit', () => fs.closeSync(fd));
2311cb0ef41Sopenharmony_ci  fs.ftruncate(fd, -1, common.mustSucceed(() => {
2321cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file6).equals(Buffer.from('')));
2331cb0ef41Sopenharmony_ci  }));
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci{
2371cb0ef41Sopenharmony_ci  const file7 = path.resolve(tmp, 'truncate-file-7.txt');
2381cb0ef41Sopenharmony_ci  fs.writeFileSync(file7, 'Hi');
2391cb0ef41Sopenharmony_ci  fs.truncate(file7, undefined, common.mustSucceed(() => {
2401cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file7).equals(Buffer.from('')));
2411cb0ef41Sopenharmony_ci  }));
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci{
2451cb0ef41Sopenharmony_ci  const file8 = path.resolve(tmp, 'non-existent-truncate-file.txt');
2461cb0ef41Sopenharmony_ci  const validateError = (err) => {
2471cb0ef41Sopenharmony_ci    assert.strictEqual(file8, err.path);
2481cb0ef41Sopenharmony_ci    assert.strictEqual(
2491cb0ef41Sopenharmony_ci      err.message,
2501cb0ef41Sopenharmony_ci      `ENOENT: no such file or directory, open '${file8}'`);
2511cb0ef41Sopenharmony_ci    assert.strictEqual(err.code, 'ENOENT');
2521cb0ef41Sopenharmony_ci    assert.strictEqual(err.syscall, 'open');
2531cb0ef41Sopenharmony_ci    return true;
2541cb0ef41Sopenharmony_ci  };
2551cb0ef41Sopenharmony_ci  fs.truncate(file8, 0, common.mustCall(validateError));
2561cb0ef41Sopenharmony_ci}
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci['', false, null, {}, []].forEach((input) => {
2591cb0ef41Sopenharmony_ci  assert.throws(
2601cb0ef41Sopenharmony_ci    () => fs.truncate('/foo/bar', input),
2611cb0ef41Sopenharmony_ci    {
2621cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
2631cb0ef41Sopenharmony_ci      name: 'TypeError',
2641cb0ef41Sopenharmony_ci      message: 'The "len" argument must be of type number.' +
2651cb0ef41Sopenharmony_ci               common.invalidArgTypeHelper(input)
2661cb0ef41Sopenharmony_ci    }
2671cb0ef41Sopenharmony_ci  );
2681cb0ef41Sopenharmony_ci});
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci['', false, null, undefined, {}, []].forEach((input) => {
2711cb0ef41Sopenharmony_ci  ['ftruncate', 'ftruncateSync'].forEach((fnName) => {
2721cb0ef41Sopenharmony_ci    assert.throws(
2731cb0ef41Sopenharmony_ci      () => fs[fnName](input),
2741cb0ef41Sopenharmony_ci      {
2751cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
2761cb0ef41Sopenharmony_ci        name: 'TypeError',
2771cb0ef41Sopenharmony_ci        message: 'The "fd" argument must be of type number.' +
2781cb0ef41Sopenharmony_ci                 common.invalidArgTypeHelper(input)
2791cb0ef41Sopenharmony_ci      }
2801cb0ef41Sopenharmony_ci    );
2811cb0ef41Sopenharmony_ci  });
2821cb0ef41Sopenharmony_ci});
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci{
2851cb0ef41Sopenharmony_ci  const file1 = path.resolve(tmp, 'truncate-file-1.txt');
2861cb0ef41Sopenharmony_ci  fs.writeFileSync(file1, 'Hi');
2871cb0ef41Sopenharmony_ci  fs.truncateSync(file1, -1);  // Negative coerced to 0, No error.
2881cb0ef41Sopenharmony_ci  assert(fs.readFileSync(file1).equals(Buffer.alloc(0)));
2891cb0ef41Sopenharmony_ci}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci{
2921cb0ef41Sopenharmony_ci  const file1 = path.resolve(tmp, 'truncate-file-2.txt');
2931cb0ef41Sopenharmony_ci  fs.writeFileSync(file1, 'Hi');
2941cb0ef41Sopenharmony_ci  // Negative coerced to 0, No error.
2951cb0ef41Sopenharmony_ci  fs.truncate(file1, -1, common.mustSucceed(() => {
2961cb0ef41Sopenharmony_ci    assert(fs.readFileSync(file1).equals(Buffer.alloc(0)));
2971cb0ef41Sopenharmony_ci  }));
2981cb0ef41Sopenharmony_ci}
299