Skip to content

Commit

Permalink
replace run_tests_in_ci.js
Browse files Browse the repository at this point in the history
  • Loading branch information
dconeybe committed Aug 12, 2023
1 parent c2b7d7f commit 70a9e99
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 207 deletions.
2 changes: 1 addition & 1 deletion packages/firestore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"test:lite:browser:nameddb": "karma start --single-run --lite --databaseId=test-db",
"test:lite:browser:debug": "karma start --browsers=Chrome --lite --auto-watch",
"test": "run-s lint test:all",
"test:ci": "node ../../scripts/run_tests_in_ci2.js -s test:all:ci",
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all:ci",
"test:all:ci": "run-s test:browser test:travis test:lite:browser test:browser:prod:nameddb test:lite:browser:nameddb",
"test:all": "run-p test:browser test:lite:browser test:travis test:minified test:browser:prod:nameddb test:lite:browser:nameddb",
"test:browser": "karma start --single-run",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ apiDescribe('Count queries', persistence => {

it("count query doesn't use converter", () => {
const testDocs = {
a: { author: 'authorA', title: 'titleA' },
a: { author: 'authorA', title: 'titleX' },
b: { author: 'authorB', title: 'titleB' }
};
const throwingConverter = {
Expand Down
175 changes: 112 additions & 63 deletions scripts/run_tests_in_ci.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @license
* Copyright 2020 Google LLC
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,77 +17,126 @@

const yargs = require('yargs');
const path = require('path');
const { spawn } = require('child-process-promise');
const { writeFileSync } = require('fs');
const child_process = require('node:child_process');
const fs = require('node:fs');

const LOGDIR = process.env.CI ? process.env.HOME : '/tmp';
// Maps the packages where we should not run `test:all` and instead isolate the cross-browser tests.
// TODO(dwyfrequency): Update object with `storage` and `firestore` packages.
const crossBrowserPackages = {
'packages/auth': 'test:browser:unit',
'packages/auth-compat': 'test:browser:unit',
'packages/firestore': 'test:browser:unit',
'packages/firestore-compat': 'test:browser'
};

function writeLogs(status, name, logText) {
const safeName = name.replace(/@/g, 'at_').replace(/\//g, '_');
writeFileSync(path.join(LOGDIR, `${safeName}-ci-log.txt`), logText, {
encoding: 'utf8'
});
writeFileSync(
path.join(LOGDIR, `${safeName}-ci-summary.txt`),
`${status}: ${name}`,
{ encoding: 'utf8' }

async function main() {
const { scriptName, workingDir } = parseArgs();
const { name } = require(`${workingDir}/package.json`);
logPrefix = name;

const logFilePath = path.join(LOGDIR, `${makeSafePath(name)}-ci-log.txt`);
const testProcessExitCode = await runTestProcess(
workingDir,
scriptName,
logFilePath
);

const summaryFilePath = path.join(
LOGDIR,
`${makeSafePath(name)}-ci-summary.txt`
);
writeSummaryFile(summaryFilePath, name, testProcessExitCode === 0);

await printFile(logFilePath);

process.exit(testProcessExitCode);
}

const argv = yargs.options({
d: {
type: 'string',
desc: 'current working directory',
default: '.'
},
s: {
type: 'string',
desc: 'the npm script to run',
default: 'test'
async function runTestProcess(workingDir, scriptName, logFilePath) {
log(`Saving test process output to file: ${logFilePath}`);
const logFileHandle = fs.openSync(logFilePath, 'w');
try {
const args = ['yarn', '--cwd', workingDir, scriptName];
log(`Starting test process: ${args.join(' ')}`);
const proc = child_process.spawn(args[0], args.splice(1), {
stdio: ['inherit', logFileHandle, logFileHandle]
});
proc.once('spawn', () => log(`Started test process with PID: ${proc.pid}`));
const exitCode = await new Promise((resolve, reject) => {
proc.once('close', resolve);
proc.once('error', reject);
});
log(`Test process completed with exit code: ${exitCode}`);
return exitCode === 0 ? true : false;
} finally {
fs.close(logFileHandle);
}
}).argv;
}

(async () => {
const myPath = argv.d;
let scriptName = argv.s;
const dir = path.resolve(myPath);
const { name } = require(`${dir}/package.json`);
function writeSummaryFile(summaryFilePath, name, testProcessSuccessful) {
const statusString = testProcessSuccessful ? 'Success' : 'Failure';
const line = `${statusString}: ${name}`;
log(`Writing summary to file ${summaryFilePath}: ${line}`);
fs.writeFileSync(summaryFilePath, line, { encoding: 'utf8' });
}

let stdout = '';
let stderr = '';
try {
if (process.env?.BROWSERS) {
for (const package in crossBrowserPackages) {
if (dir.endsWith(package)) {
scriptName = crossBrowserPackages[package];
}
}
async function printFile(path) {
log('========================================================');
log(`==== BEGIN ${path}`);
log('========================================================');
const readStream = fs.createReadStream(path);
readStream.pipe(process.stdout);
await new Promise((resolve, reject) => {
readStream.once('end', resolve);
readStream.once('error', reject);
});
log('========================================================');
log(`==== END ${path}`);
log('========================================================');
}

let logPrefix = '';

function log() {
console.log('run_tests_in_ci.js', logPrefix, ...arguments);
}

function makeSafePath(s) {
return s.replace(/@/g, 'at_').replace(/\//g, '_');
}

function parseArgs() {
const argv = yargs.options({
d: {
type: 'string',
desc: 'current working directory',
default: '.'
},
s: {
type: 'string',
desc: 'the npm script to run',
default: 'test'
}
const testProcess = spawn('yarn', ['--cwd', dir, scriptName]);
}).argv;

testProcess.childProcess.stdout.on('data', data => {
stdout += data.toString();
});
testProcess.childProcess.stderr.on('data', data => {
stderr += data.toString();
});
return {
scriptName: resolveScriptNameArg(argv.s),
workingDir: path.resolve(argv.d)
};
}

function resolveScriptNameArg(scriptName) {
// Maps the packages where we should not run `test:all` and instead isolate the cross-browser tests.
// TODO(dwyfrequency): Update object with `storage` and `firestore` packages.
const crossBrowserPackages = {
'packages/auth': 'test:browser:unit',
'packages/auth-compat': 'test:browser:unit',
'packages/firestore': 'test:browser:unit',
'packages/firestore-compat': 'test:browser'
};

await testProcess;
console.log('Success: ' + name);
writeLogs('Success', name, stdout + '\n' + stderr);
} catch (e) {
console.error('Failure: ' + name);
console.log(stdout);
console.error(stderr);
writeLogs('Failure', name, stdout + '\n' + stderr);
process.exit(1);
if (process.env?.BROWSERS) {
for (const package in crossBrowserPackages) {
if (dir.endsWith(package)) {
scriptName = crossBrowserPackages[package];
}
}
}
})();

return scriptName;
}

main();
142 changes: 0 additions & 142 deletions scripts/run_tests_in_ci2.js

This file was deleted.

0 comments on commit 70a9e99

Please sign in to comment.