403Webshell
Server IP : 188.151.22.197  /  Your IP : 216.73.217.74
Web Server : Apache/2.4.62 (Rocky Linux) OpenSSL/3.5.5
System : Linux wsten.se 5.14.0-687.30.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Jul 27 13:09:21 UTC 2026 x86_64
User : apache ( 48)
PHP Version : 8.1.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /opt/gitlab/embedded/service/gitlab-rails/scripts/frontend/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/gitlab/embedded/service/gitlab-rails/scripts/frontend/check_jest_vue3_quarantine.js
#!/usr/bin/env node

const { spawnSync } = require('node:child_process');
const { readFile, open, stat, mkdir } = require('node:fs/promises');
const { join, relative, dirname } = require('node:path');
const defaultChalk = require('chalk');
const { program } = require('commander');
const IS_EE = require('../../config/helpers/is_ee_env');
const { getLocalQuarantinedFiles } = require('./jest_vue3_quarantine_utils');

const ROOT = join(__dirname, '..', '..');
const IS_CI = Boolean(process.env.CI);
const FIXTURES_HELP_URL =
  // eslint-disable-next-line no-restricted-syntax
  'https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#download-fixtures';

const DIR = join(ROOT, 'tmp/tests/frontend');

const JEST_JSON_OUTPUT = join(DIR, 'jest_results.json');
const JEST_STDERR = join(DIR, 'jest_stderr');

// Force basic color output in CI
const chalk = new defaultChalk.constructor({ level: IS_CI ? 1 : undefined });

let quarantinedFiles;
let filesThatChanged;

function parseArguments() {
  program
    .description(
      `
Checks whether Jest specs quarantined under Vue 3 should be unquarantined.

Usage examples
--------------

In CI:

    # Check quarantined files which were affected by changes in the merge request.
    $ scripts/frontend/check_jest_vue3_quarantine.js

    # Check all quarantined files, still subject to sharding/fixture separation.
    # Useful for tier 3 pipelines, or when dependencies change.
    $ scripts/frontend/check_jest_vue3_quarantine.js --all

Locally:

    # Run all quarantined files, including those which need fixtures.
    # See ${FIXTURES_HELP_URL}
    $ scripts/frontend/check_jest_vue3_quarantine.js --all

    # Run a particular spec
    $ scripts/frontend/check_jest_vue3_quarantine.js spec/frontend/foo_spec.js

    # Run specs in this branch that were modified since master
    $ scripts/frontend/check_jest_vue3_quarantine.js $(git diff master... --name-only)

    # Write to stdio normally instead of to temporary files
    $ scripts/frontend/check_jest_vue3_quarantine.js --stdio spec/frontend/foo_spec.js
    `.trim(),
    )
    .option(
      '--all',
      'Run all quarantined specs. Good for local testing, or in CI when configuration files have changed.',
    )
    .option(
      '--stdio',
      `Let Jest write to stderr as normal. By default, it writes to ${JEST_STDERR}. Should not be used in CI, as it can exceed maximum job log size.`,
    )
    .argument('[spec...]', 'List of spec files to run (incompatible with --all)')
    .parse(process.argv);
  const options = program.opts();

  let invalidArgumentsMessage;

  if (!IS_CI) {
    if (!options.all && program.args.length === 0) {
      invalidArgumentsMessage =
        'No spec files to check!\n\nWhen run locally, either add the --all option, or a list of spec files to check.';
    }

    if (options.all && program.args.length > 0) {
      invalidArgumentsMessage = `Do not pass arguments in addition to the --all option.`;
    }
  }

  if (invalidArgumentsMessage) {
    console.warn(`${chalk.red(invalidArgumentsMessage)}\n`);
    program.help();
  }
}

async function parseResults() {
  let results;
  try {
    results = JSON.parse(await readFile(JEST_JSON_OUTPUT, 'UTF-8'));
  } catch (e) {
    console.warn(e);
    // No JUnit report exists, or there was a parsing error. Either way, we
    // should not block the MR.
    return [];
  }

  return results.testResults.reduce((acc, { name, status }) => {
    if (status === 'passed') {
      acc.push(relative(ROOT, name));
    }

    return acc;
  }, []);
}

function reportSpecsShouldBeUnquarantined(files) {
  const docsLink =
    // eslint-disable-next-line no-restricted-syntax
    'https://docs.gitlab.com/ee/development/testing_guide/testing_vue3.html#quarantine-list';
  console.warn(' ');
  console.warn(
    `The following ${files.length} spec files either now pass under Vue 3, or no longer exist, and so must be removed from quarantine:`,
  );
  console.warn(' ');
  console.warn(files.join('\n'));
  console.warn(' ');
  console.warn(
    chalk.red(
      `To fix this job, remove the files listed above from the file ${chalk.underline('scripts/frontend/quarantined_vue3_specs.txt')}.`,
    ),
  );
  console.warn(`For more information, please see ${docsLink}.`);
}

async function changedFiles() {
  if (!IS_CI) {
    // We're not in CI, so `detect-tests` artifacts won't be available.
    return [];
  }

  const { GLCI_PREDICTIVE_CHANGED_FILES_PATH, GLCI_PREDICTIVE_MATCHING_JS_FILES_PATH } =
    process.env;

  const files = await Promise.all(
    [GLCI_PREDICTIVE_CHANGED_FILES_PATH, GLCI_PREDICTIVE_MATCHING_JS_FILES_PATH].map((path) =>
      readFile(path, 'UTF-8').then((content) => content.split(/\s+/).filter(Boolean)),
    ),
  );

  return files.flat();
}

function filterSet(set, predicate) {
  const result = new Set();

  for (const element of set) {
    if (predicate(element)) result.add(element);
  }

  return result;
}

function intersection(a, b) {
  return filterSet(a, (element) => b.has(element));
}

async function getRemovedQuarantinedSpecs() {
  const removedQuarantinedSpecs = [];

  const filesToCheckIfTheyExist = IS_CI
    ? // In CI, only check quarantined files the author has touched.
      // If we're in a FOSS pipeline, ignore EE specs which do not exist.
      filterSet(intersection(filesThatChanged, quarantinedFiles), (path) => {
        if (IS_EE) return true;

        if (path.startsWith('ee/')) {
          console.warn(`Ignoring non-existent EE spec ${path} as we are in FOSS mode.`);
          return false;
        }

        return true;
      })
    : // Locally, check all quarantined files
      quarantinedFiles;

  for (const file of filesToCheckIfTheyExist) {
    try {
      // eslint-disable-next-line no-await-in-loop
      await stat(file);
    } catch (e) {
      if (e.code === 'ENOENT') removedQuarantinedSpecs.push(file);
    }
  }

  return removedQuarantinedSpecs;
}

function getTestArguments() {
  if (IS_CI) {
    const nodeIndex = process.env.CI_NODE_INDEX ?? '1';
    const nodeTotal = process.env.CI_NODE_TOTAL ?? '1';

    const ciArguments = (touchedFiles) => [
      '--findRelatedTests',
      ...touchedFiles,
      '--passWithNoTests',
      `--shard=${nodeIndex}/${nodeTotal}`,
      '--testSequencer',
      './scripts/frontend/check_jest_vue3_quarantine_sequencer.js',
    ];

    if (program.opts().all) {
      console.warn(
        'Running in CI with --all. Checking all quarantined specs, subject to FixtureCISequencer sharding behavior.',
      );

      return ciArguments(quarantinedFiles);
    }

    console.warn(
      'Running in CI. Only specs affected by changes in the merge request will be checked.',
    );
    return ciArguments(filesThatChanged);
  }

  if (program.opts().all) {
    console.warn('Running locally with --all. Checking all quarantined specs.');
    return ['--runTestsByPath', ...quarantinedFiles];
  }

  if (program.args.length > 0) {
    const specs = program.args.filter((spec) => {
      const isQuarantined = quarantinedFiles.has(relative(ROOT, spec));
      if (!isQuarantined) console.warn(`Omitting file as it is not in quarantine list: ${spec}`);
      return isQuarantined;
    });

    if (specs.length === 0) {
      console.warn(`No quarantined specs to run!`);
      process.exit(1);
    }

    console.warn('Running locally. Checking given specs.');
    return ['--runTestsByPath', ...specs];
  }

  // ESLint's consistent-return rule requires something like this.
  return ['--this-should-never-happen-and-jest-should-fail'];
}

async function getStdio() {
  if (program.opts().stdio) {
    return 'inherit';
  }

  await mkdir(dirname(JEST_STDERR), { recursive: true });
  const jestStderr = (await open(JEST_STDERR, 'w')).createWriteStream();

  return ['inherit', 'inherit', jestStderr];
}

async function main() {
  parseArguments();

  filesThatChanged = await changedFiles();
  quarantinedFiles = new Set(await getLocalQuarantinedFiles());

  // Note: we don't care what Jest's exit code is.
  //
  // If it's zero, then either:
  //   - all specs passed, or
  //   - no specs were run.
  //
  // Both situations are handled later.
  //
  // If it's non-zero, then either:
  //   - one or more specs failed (which is expected!), or
  //   - there was some unknown error. We shouldn't block MRs in this case.
  spawnSync(
    'node_modules/.bin/jest',
    [
      '--config',
      'jest.config.js',
      '--ci',
      '--logHeapUsage',
      '--json',
      `--outputFile=${JEST_JSON_OUTPUT}`,
      ...getTestArguments(),
    ],
    {
      stdio: await getStdio(),
      env: {
        ...process.env,
        VUE_VERSION: '3',
      },
    },
  );

  const passed = await parseResults();
  const removedQuarantinedSpecs = await getRemovedQuarantinedSpecs();
  const filesToReport = [...passed, ...removedQuarantinedSpecs];

  if (filesToReport.length === 0) {
    // No tests ran, or there was some unexpected error. Either way, exit
    // successfully.
    console.warn('No spec files need to be removed from quarantine.');
    return;
  }

  process.exitCode = 1;
  reportSpecsShouldBeUnquarantined(filesToReport);
}

main().catch((e) => {
  // Don't block on unexpected errors.
  console.warn(e);
});

Youez - 2016 - github.com/yon3zu
LinuXploit