11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst fs = require('fs');
41cb0ef41Sopenharmony_ciconst path = require('path');
51cb0ef41Sopenharmony_ciconst { pathToFileURL } = require('url');
61cb0ef41Sopenharmony_ciconst { isMainThread } = require('worker_threads');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_cifunction rmSync(pathname) {
91cb0ef41Sopenharmony_ci  fs.rmSync(pathname, { maxRetries: 3, recursive: true, force: true });
101cb0ef41Sopenharmony_ci}
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst testRoot = process.env.NODE_TEST_DIR ?
131cb0ef41Sopenharmony_ci  fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Using a `.` prefixed name, which is the convention for "hidden" on POSIX,
161cb0ef41Sopenharmony_ci// gets tools to ignore it by default or by simple rules, especially eslint.
171cb0ef41Sopenharmony_ciconst tmpdirName = '.tmp.' +
181cb0ef41Sopenharmony_ci  (process.env.TEST_SERIAL_ID || process.env.TEST_THREAD_ID || '0');
191cb0ef41Sopenharmony_ciconst tmpPath = path.join(testRoot, tmpdirName);
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cilet firstRefresh = true;
221cb0ef41Sopenharmony_cifunction refresh() {
231cb0ef41Sopenharmony_ci  rmSync(tmpPath);
241cb0ef41Sopenharmony_ci  fs.mkdirSync(tmpPath);
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  if (firstRefresh) {
271cb0ef41Sopenharmony_ci    firstRefresh = false;
281cb0ef41Sopenharmony_ci    // Clean only when a test uses refresh. This allows for child processes to
291cb0ef41Sopenharmony_ci    // use the tmpdir and only the parent will clean on exit.
301cb0ef41Sopenharmony_ci    process.on('exit', onexit);
311cb0ef41Sopenharmony_ci  }
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cifunction onexit() {
351cb0ef41Sopenharmony_ci  // Change directory to avoid possible EBUSY
361cb0ef41Sopenharmony_ci  if (isMainThread)
371cb0ef41Sopenharmony_ci    process.chdir(testRoot);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  try {
401cb0ef41Sopenharmony_ci    rmSync(tmpPath);
411cb0ef41Sopenharmony_ci  } catch (e) {
421cb0ef41Sopenharmony_ci    console.error('Can\'t clean tmpdir:', tmpPath);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci    const files = fs.readdirSync(tmpPath);
451cb0ef41Sopenharmony_ci    console.error('Files blocking:', files);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci    if (files.some((f) => f.startsWith('.nfs'))) {
481cb0ef41Sopenharmony_ci      // Warn about NFS "silly rename"
491cb0ef41Sopenharmony_ci      console.error('Note: ".nfs*" might be files that were open and ' +
501cb0ef41Sopenharmony_ci                    'unlinked but not closed.');
511cb0ef41Sopenharmony_ci      console.error('See http://nfs.sourceforge.net/#faq_d2 for details.');
521cb0ef41Sopenharmony_ci    }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    console.error();
551cb0ef41Sopenharmony_ci    throw e;
561cb0ef41Sopenharmony_ci  }
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cifunction resolve(...paths) {
601cb0ef41Sopenharmony_ci  return path.resolve(tmpPath, ...paths);
611cb0ef41Sopenharmony_ci}
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_cifunction hasEnoughSpace(size) {
641cb0ef41Sopenharmony_ci  const { bavail, bsize } = fs.statfsSync(tmpPath);
651cb0ef41Sopenharmony_ci  return bavail >= Math.ceil(size / bsize);
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_cifunction fileURL(...paths) {
691cb0ef41Sopenharmony_ci  // When called without arguments, add explicit trailing slash
701cb0ef41Sopenharmony_ci  const fullPath = path.resolve(tmpPath + path.sep, ...paths);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  return pathToFileURL(fullPath);
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_cimodule.exports = {
761cb0ef41Sopenharmony_ci  fileURL,
771cb0ef41Sopenharmony_ci  hasEnoughSpace,
781cb0ef41Sopenharmony_ci  path: tmpPath,
791cb0ef41Sopenharmony_ci  refresh,
801cb0ef41Sopenharmony_ci  resolve,
811cb0ef41Sopenharmony_ci};
82