1'use strict'; 2const common = require('../common'); 3const assert = require('assert'); 4const cp = require('child_process'); 5const fs = require('fs'); 6const path = require('path'); 7const util = require('util'); 8 9const tests = Object.create(null); 10 11let gid = 1; 12let uid = 1; 13 14if (!common.isWindows) { 15 gid = process.getgid(); 16 uid = process.getuid(); 17} 18 19function wrapper(func, args) { 20 return `(${func.toString()})(${JSON.stringify(args)})`; 21} 22 23function access() { 24 const fs = require('fs'); 25 fs.writeFileSync('fs0.txt', '123', 'utf8'); 26 fs.access('fs0.txt', () => { 27 fs.unlinkSync('fs0.txt'); 28 }); 29} 30 31function chmod() { 32 const fs = require('fs'); 33 fs.writeFileSync('fs1.txt', '123', 'utf8'); 34 fs.chmod('fs1.txt', 100, () => { 35 fs.unlinkSync('fs1.txt'); 36 }); 37} 38 39function chown({ uid, gid }) { 40 const fs = require('fs'); 41 fs.writeFileSync('fs2.txt', '123', 'utf8'); 42 fs.chown('fs2.txt', uid, gid, () => { 43 fs.unlinkSync('fs2.txt'); 44 }); 45} 46 47function close() { 48 const fs = require('fs'); 49 fs.writeFile('fs3.txt', '123', 'utf8', () => { 50 fs.unlinkSync('fs3.txt'); 51 }); 52} 53 54function copyfile() { 55 const fs = require('fs'); 56 fs.writeFileSync('fs4.txt', '123', 'utf8'); 57 fs.copyFile('fs4.txt', 'a.txt', () => { 58 fs.unlinkSync('fs4.txt'); 59 fs.unlinkSync('a.txt'); 60 }); 61} 62 63function fchmod() { 64 const fs = require('fs'); 65 fs.writeFileSync('fs5.txt', '123', 'utf8'); 66 const fd = fs.openSync('fs5.txt', 'r+'); 67 fs.fchmod(fd, 100, () => { 68 fs.unlinkSync('fs5.txt'); 69 }); 70} 71 72function fchown({ uid, gid }) { 73 const fs = require('fs'); 74 fs.writeFileSync('fs6.txt', '123', 'utf8'); 75 const fd = fs.openSync('fs6.txt', 'r+'); 76 fs.fchown(fd, uid, gid, () => { 77 fs.unlinkSync('fs6.txt'); 78 }); 79} 80 81function fdatasync() { 82 const fs = require('fs'); 83 fs.writeFileSync('fs7.txt', '123', 'utf8'); 84 const fd = fs.openSync('fs7.txt', 'r+'); 85 fs.fdatasync(fd, () => { 86 fs.unlinkSync('fs7.txt'); 87 }); 88} 89 90function fstat() { 91 const fs = require('fs'); 92 fs.writeFileSync('fs8.txt', '123', 'utf8'); 93 fs.readFile('fs8.txt', () => { 94 fs.unlinkSync('fs8.txt'); 95 }); 96} 97 98function fsync() { 99 const fs = require('fs'); 100 fs.writeFileSync('fs9.txt', '123', 'utf8'); 101 const fd = fs.openSync('fs9.txt', 'r+'); 102 fs.fsync(fd, () => { 103 fs.unlinkSync('fs9.txt'); 104 }); 105} 106 107function ftruncate() { 108 const fs = require('fs'); 109 fs.writeFileSync('fs10.txt', '123', 'utf8'); 110 const fd = fs.openSync('fs10.txt', 'r+'); 111 fs.ftruncate(fd, 1, () => { 112 fs.unlinkSync('fs10.txt'); 113 }); 114} 115 116function futime() { 117 const fs = require('fs'); 118 fs.writeFileSync('fs11.txt', '123', 'utf8'); 119 const fd = fs.openSync('fs11.txt', 'r+'); 120 fs.futimes(fd, 1, 1, () => { 121 fs.unlinkSync('fs11.txt'); 122 }); 123} 124 125function lutime() { 126 const fs = require('fs'); 127 fs.writeFileSync('fs111.txt', '123', 'utf8'); 128 fs.lutimes('fs111.txt', 1, 1, () => { 129 fs.unlinkSync('fs111.txt'); 130 }); 131} 132 133function lchown({ uid, gid }) { 134 const fs = require('fs'); 135 fs.writeFileSync('fs12.txt', '123', 'utf8'); 136 fs.lchown('fs12.txt', uid, gid, () => { 137 fs.unlinkSync('fs12.txt'); 138 }); 139} 140 141function link() { 142 const fs = require('fs'); 143 fs.writeFileSync('fs13.txt', '123', 'utf8'); 144 fs.link('fs13.txt', 'fs14.txt', () => { 145 fs.unlinkSync('fs13.txt'); 146 fs.unlinkSync('fs14.txt'); 147 }); 148} 149 150function lstat() { 151 const fs = require('fs'); 152 fs.writeFileSync('fs15.txt', '123', 'utf8'); 153 fs.lstat('fs15.txt', () => { 154 fs.unlinkSync('fs15.txt'); 155 }); 156} 157 158function mkdir() { 159 const fs = require('fs'); 160 fs.mkdir('fstemp0', () => { 161 fs.rmdir('fstemp0', () => {}); 162 }); 163} 164 165function mktmp() { 166 fs.mkdtemp('fstemp1', (err, fp) => { 167 fs.rmdir(fp, () => {}); 168 }); 169} 170 171function open() { 172 const fs = require('fs'); 173 fs.writeFile('fs16.txt', '123', 'utf8', () => { 174 fs.unlinkSync('fs16.txt'); 175 }); 176} 177 178function read() { 179 const fs = require('fs'); 180 fs.writeFileSync('fs17.txt', '123', 'utf8'); 181 fs.readFile('fs17.txt', () => { 182 fs.unlinkSync('fs17.txt'); 183 }); 184} 185 186function readdir() { 187 const fs = require('fs'); 188 fs.readdir('./', () => {}); 189} 190 191function opendir() { 192 const fs = require('fs'); 193 fs.opendir('./', () => {}); 194} 195 196function realpath() { 197 const fs = require('fs'); 198 fs.writeFileSync('fs18.txt', '123', 'utf8'); 199 fs.linkSync('fs18.txt', 'fs19.txt'); 200 fs.realpath.native('fs19.txt', () => { 201 fs.unlinkSync('fs18.txt'); 202 fs.unlinkSync('fs19.txt'); 203 }); 204} 205 206function rename() { 207 const fs = require('fs'); 208 fs.writeFileSync('fs20.txt', '123', 'utf8'); 209 fs.rename('fs20.txt', 'fs21.txt', () => { 210 fs.unlinkSync('fs21.txt'); 211 }); 212} 213 214function rmdir() { 215 const fs = require('fs'); 216 fs.mkdirSync('fstemp2'); 217 fs.rmdir('fstemp2', () => {}); 218} 219 220function stat() { 221 const fs = require('fs'); 222 fs.writeFileSync('fs22.txt', '123', 'utf8'); 223 fs.stat('fs22.txt', () => { 224 fs.unlinkSync('fs22.txt'); 225 }); 226} 227 228function unlink() { 229 const fs = require('fs'); 230 fs.writeFileSync('fs23.txt', '123', 'utf8'); 231 fs.linkSync('fs23.txt', 'fs24.txt'); 232 fs.unlink('fs23.txt', () => {}); 233 fs.unlink('fs24.txt', () => {}); 234} 235 236function utime() { 237 const fs = require('fs'); 238 fs.writeFileSync('fs25.txt', '123', 'utf8'); 239 fs.utimes('fs25.txt', 1, 1, () => { 240 fs.unlinkSync('fs25.txt'); 241 }); 242} 243 244function write() { 245 const fs = require('fs'); 246 fs.writeFile('fs26.txt', '123', 'utf8', () => { 247 fs.unlinkSync('fs26.txt'); 248 }); 249} 250 251function symlink() { 252 const fs = require('fs'); 253 fs.writeFileSync('fs27.txt', '123', 'utf8'); 254 fs.symlink('fs27.txt', 'fs28.txt', () => { 255 fs.unlinkSync('fs27.txt'); 256 fs.unlinkSync('fs28.txt'); 257 }); 258} 259 260function readlink() { 261 const fs = require('fs'); 262 fs.writeFileSync('fs29.txt', '123', 'utf8'); 263 fs.symlinkSync('fs29.txt', 'fs30.txt'); 264 fs.readlink('fs30.txt', () => { 265 fs.unlinkSync('fs29.txt'); 266 fs.unlinkSync('fs30.txt'); 267 }); 268} 269// The key defined in get_fs_name_by_type function in node_file.cc and node_dir.cc 270tests.access = wrapper(access); 271tests.chmod = wrapper(chmod); 272tests.chown = wrapper(chown, { uid, gid }); 273tests.close = wrapper(close); 274tests.copyfile = wrapper(copyfile); 275tests.fchmod = wrapper(fchmod); 276tests.fchown = wrapper(fchown, { uid, gid }); 277tests.fdatasync = wrapper(fdatasync); 278tests.fstat = wrapper(fstat); 279tests.fsync = wrapper(fsync); 280tests.ftruncate = wrapper(ftruncate); 281tests.futime = wrapper(futime); 282tests.lutime = wrapper(lutime); 283tests.lchown = wrapper(lchown, { uid, gid }); 284tests.link = wrapper(link); 285tests.lstat = wrapper(lstat); 286tests.mkdir = wrapper(mkdir); 287tests.mkdtemp = wrapper(mktmp); 288tests.open = wrapper(open); 289tests.read = wrapper(read); 290tests.scandir = wrapper(readdir); 291tests.opendir = wrapper(opendir); 292tests.realpath = wrapper(realpath); 293tests.rename = wrapper(rename); 294tests.rmdir = wrapper(rmdir); 295tests.stat = wrapper(stat); 296tests.unlink = wrapper(unlink); 297tests.utime = wrapper(utime); 298tests.write = wrapper(write); 299 300// On windows, we need permissions to test symlink and readlink. 301// We'll only try to run these tests if we have enough privileges. 302if (common.canCreateSymLink()) { 303 tests.symlink = wrapper(symlink); 304 tests.readlink = wrapper(readlink); 305} 306const tmpdir = require('../common/tmpdir'); 307tmpdir.refresh(); 308const traceFile = path.join(tmpdir.path, 'node_trace.1.log'); 309 310for (const tr in tests) { 311 const proc = cp.spawnSync(process.execPath, 312 [ '--trace-events-enabled', 313 '--trace-event-categories', 'node.fs_dir.async,node.fs.async', 314 '-e', tests[tr] ], 315 { cwd: tmpdir.path, encoding: 'utf8' }); 316 317 // Make sure the operation is successful. 318 // Don't use assert with a custom message here. Otherwise the 319 // inspection in the message is done eagerly and wastes a lot of CPU 320 // time. 321 if (proc.status !== 0) { 322 throw new Error(`${tr}:\n${util.inspect(proc)}`); 323 } 324 325 // Confirm that trace log file is created. 326 assert(fs.existsSync(traceFile)); 327 const data = fs.readFileSync(traceFile); 328 const { traceEvents } = JSON.parse(data.toString()); 329 // Confirm that the data we want is produced 330 const traces = traceEvents.filter((item) => { 331 return [ 332 'node,node.fs,node.fs.async', 333 'node,node.fs_dir,node.fs_dir.async', 334 ].includes(item.cat); 335 }); 336 // Confirm that the data we want is produced 337 assert(traces.length > 0); 338 assert(traces.some((trace) => { 339 return trace.name === tr; 340 })); 341} 342