11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciif (!process.features.inspector) return;
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst fs = require('fs');
81cb0ef41Sopenharmony_ciconst path = require('path');
91cb0ef41Sopenharmony_ciconst { spawnSync } = require('child_process');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir');
121cb0ef41Sopenharmony_citmpdir.refresh();
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cilet dirc = 0;
151cb0ef41Sopenharmony_cifunction nextdir() {
161cb0ef41Sopenharmony_ci  return `cov_${++dirc}`;
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci// Outputs coverage when event loop is drained, with no async logic.
201cb0ef41Sopenharmony_ci{
211cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
221cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
231cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/basic'),
241cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
251cb0ef41Sopenharmony_ci  if (output.status !== 0) {
261cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
291cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
301cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('basic.js', coverageDirectory);
311cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
321cb0ef41Sopenharmony_ci  // First branch executed.
331cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
341cb0ef41Sopenharmony_ci  // Second branch did not execute.
351cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0);
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// Outputs coverage when error is thrown in first tick.
391cb0ef41Sopenharmony_ci{
401cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
411cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
421cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/throw'),
431cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
441cb0ef41Sopenharmony_ci  if (output.status !== 1) {
451cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 1);
481cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('throw.js', coverageDirectory);
491cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage, 'coverage not found for file');
501cb0ef41Sopenharmony_ci  // First branch executed.
511cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
521cb0ef41Sopenharmony_ci  // Second branch did not execute.
531cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0);
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci// Outputs coverage when process.exit(1) exits process.
571cb0ef41Sopenharmony_ci{
581cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
591cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
601cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/exit-1'),
611cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
621cb0ef41Sopenharmony_ci  if (output.status !== 1) {
631cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 1);
661cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
671cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('exit-1.js', coverageDirectory);
681cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage, 'coverage not found for file');
691cb0ef41Sopenharmony_ci  // First branch executed.
701cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
711cb0ef41Sopenharmony_ci  // Second branch did not execute.
721cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0);
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci// Outputs coverage when process.kill(process.pid, "SIGINT"); exits process.
761cb0ef41Sopenharmony_ci{
771cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
781cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
791cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/sigint'),
801cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
811cb0ef41Sopenharmony_ci  if (!common.isWindows) {
821cb0ef41Sopenharmony_ci    if (output.signal !== 'SIGINT') {
831cb0ef41Sopenharmony_ci      console.log(output.stderr.toString());
841cb0ef41Sopenharmony_ci    }
851cb0ef41Sopenharmony_ci    assert.strictEqual(output.signal, 'SIGINT');
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
881cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('sigint.js', coverageDirectory);
891cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
901cb0ef41Sopenharmony_ci  // First branch executed.
911cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
921cb0ef41Sopenharmony_ci  // Second branch did not execute.
931cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0);
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci// Outputs coverage from subprocess.
971cb0ef41Sopenharmony_ci{
981cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
991cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
1001cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/spawn-subprocess'),
1011cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
1021cb0ef41Sopenharmony_ci  if (output.status !== 0) {
1031cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
1061cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
1071cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('subprocess.js',
1081cb0ef41Sopenharmony_ci                                             coverageDirectory);
1091cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
1101cb0ef41Sopenharmony_ci  // First branch executed.
1111cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[1].ranges[0].count, 1);
1121cb0ef41Sopenharmony_ci  // Second branch did not execute.
1131cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[1].ranges[1].count, 0);
1141cb0ef41Sopenharmony_ci}
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci// Outputs coverage from worker.
1171cb0ef41Sopenharmony_ci{
1181cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
1191cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
1201cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/worker'),
1211cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
1221cb0ef41Sopenharmony_ci  if (output.status !== 0) {
1231cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
1241cb0ef41Sopenharmony_ci  }
1251cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
1261cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
1271cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('subprocess.js',
1281cb0ef41Sopenharmony_ci                                             coverageDirectory);
1291cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
1301cb0ef41Sopenharmony_ci  // First branch executed.
1311cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[1].ranges[0].count, 1);
1321cb0ef41Sopenharmony_ci  // Second branch did not execute.
1331cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[1].ranges[1].count, 0);
1341cb0ef41Sopenharmony_ci}
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci// Does not output coverage if NODE_V8_COVERAGE is empty.
1371cb0ef41Sopenharmony_ci{
1381cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
1391cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
1401cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/spawn-subprocess-no-cov'),
1411cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
1421cb0ef41Sopenharmony_ci  if (output.status !== 0) {
1431cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
1461cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
1471cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('subprocess.js',
1481cb0ef41Sopenharmony_ci                                             coverageDirectory);
1491cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage, undefined);
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci// Disables async hooks before writing coverage.
1531cb0ef41Sopenharmony_ci{
1541cb0ef41Sopenharmony_ci  const coverageDirectory = path.join(tmpdir.path, nextdir());
1551cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
1561cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/async-hooks'),
1571cb0ef41Sopenharmony_ci  ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } });
1581cb0ef41Sopenharmony_ci  if (output.status !== 0) {
1591cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
1621cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
1631cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('async-hooks.js',
1641cb0ef41Sopenharmony_ci                                             coverageDirectory);
1651cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
1661cb0ef41Sopenharmony_ci  // First branch executed.
1671cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci// Outputs coverage when the coverage directory is not absolute.
1711cb0ef41Sopenharmony_ci{
1721cb0ef41Sopenharmony_ci  const coverageDirectory = nextdir();
1731cb0ef41Sopenharmony_ci  const absoluteCoverageDirectory = path.join(tmpdir.path, coverageDirectory);
1741cb0ef41Sopenharmony_ci  const output = spawnSync(process.execPath, [
1751cb0ef41Sopenharmony_ci    require.resolve('../fixtures/v8-coverage/basic'),
1761cb0ef41Sopenharmony_ci  ], {
1771cb0ef41Sopenharmony_ci    cwd: tmpdir.path,
1781cb0ef41Sopenharmony_ci    env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory }
1791cb0ef41Sopenharmony_ci  });
1801cb0ef41Sopenharmony_ci  if (output.status !== 0) {
1811cb0ef41Sopenharmony_ci    console.log(output.stderr.toString());
1821cb0ef41Sopenharmony_ci  }
1831cb0ef41Sopenharmony_ci  assert.strictEqual(output.status, 0);
1841cb0ef41Sopenharmony_ci  assert.strictEqual(output.stderr.toString(), '');
1851cb0ef41Sopenharmony_ci  const fixtureCoverage = getFixtureCoverage('basic.js',
1861cb0ef41Sopenharmony_ci                                             absoluteCoverageDirectory);
1871cb0ef41Sopenharmony_ci  assert.ok(fixtureCoverage);
1881cb0ef41Sopenharmony_ci  // First branch executed.
1891cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1);
1901cb0ef41Sopenharmony_ci  // Second branch did not execute.
1911cb0ef41Sopenharmony_ci  assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0);
1921cb0ef41Sopenharmony_ci}
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci// Extracts the coverage object for a given fixture name.
1951cb0ef41Sopenharmony_cifunction getFixtureCoverage(fixtureFile, coverageDirectory) {
1961cb0ef41Sopenharmony_ci  const coverageFiles = fs.readdirSync(coverageDirectory);
1971cb0ef41Sopenharmony_ci  for (const coverageFile of coverageFiles) {
1981cb0ef41Sopenharmony_ci    const coverage = require(path.join(coverageDirectory, coverageFile));
1991cb0ef41Sopenharmony_ci    for (const fixtureCoverage of coverage.result) {
2001cb0ef41Sopenharmony_ci      if (fixtureCoverage.url.indexOf(`/${fixtureFile}`) !== -1) {
2011cb0ef41Sopenharmony_ci        return fixtureCoverage;
2021cb0ef41Sopenharmony_ci      }
2031cb0ef41Sopenharmony_ci    }
2041cb0ef41Sopenharmony_ci  }
2051cb0ef41Sopenharmony_ci}
206