Skip to content

Run rustdoc-gui tests in parallel #86692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 15, 2021
126 changes: 113 additions & 13 deletions src/tools/rustdoc-gui/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// ```
const fs = require("fs");
const path = require("path");
const os = require('os');
const {Options, runTest} = require('browser-ui-test');

function showHelp() {
Expand Down Expand Up @@ -70,12 +71,49 @@ function parseOptions(args) {
return null;
}

/// Print single char status information without \n
function char_printer(n_tests) {
const max_per_line = 10;
let current = 0;
return {
successful: function() {
current += 1;
if (current % max_per_line === 0) {
process.stdout.write(`. (${current}/${n_tests})${os.EOL}`);
} else {
process.stdout.write(".");
}
},
erroneous: function() {
current += 1;
if (current % max_per_line === 0) {
process.stderr.write(`F (${current}/${n_tests})${os.EOL}`);
} else {
process.stderr.write("F");
}
},
finish: function() {
const spaces = " ".repeat(max_per_line - (current % max_per_line));
process.stdout.write(`${spaces} (${current}/${n_tests})${os.EOL}${os.EOL}`);
},
};
}

/// Sort array by .file_name property
function by_filename(a, b) {
return a.file_name - b.file_name;
}

async function main(argv) {
let opts = parseOptions(argv.slice(2));
if (opts === null) {
process.exit(1);
}

// Print successful tests too
let debug = false;
// Run tests in sequentially
let no_headless = false;
const options = new Options();
try {
// This is more convenient that setting fields one by one.
Expand All @@ -84,13 +122,15 @@ async function main(argv) {
"--variable", "DOC_PATH", opts["doc_folder"],
];
if (opts["debug"]) {
debug = true;
args.push("--debug");
}
if (opts["show_text"]) {
args.push("--show-text");
}
if (opts["no_headless"]) {
args.push("--no-headless");
no_headless = true;
}
options.parseArguments(args);
} catch (error) {
Expand All @@ -101,25 +141,85 @@ async function main(argv) {
let failed = false;
let files;
if (opts["files"].length === 0) {
files = fs.readdirSync(opts["tests_folder"]).filter(file => path.extname(file) == ".goml");
files = fs.readdirSync(opts["tests_folder"]);
} else {
files = opts["files"].filter(file => path.extname(file) == ".goml");
files = opts["files"];
}
files = files.filter(file => path.extname(file) == ".goml");
if (files.length === 0) {
console.error("rustdoc-gui: No test selected");
process.exit(2);
}

files.sort();
for (var i = 0; i < files.length; ++i) {
const testPath = path.join(opts["tests_folder"], files[i]);
await runTest(testPath, options).then(out => {
const [output, nb_failures] = out;
console.log(output);
if (nb_failures > 0) {

console.log(`Running ${files.length} rustdoc-gui tests...`);
process.setMaxListeners(files.length + 1);
let tests = [];
let results = {
successful: [],
failed: [],
errored: [],
};
const status_bar = char_printer(files.length);
for (let i = 0; i < files.length; ++i) {
const file_name = files[i];
const testPath = path.join(opts["tests_folder"], file_name);
tests.push(
runTest(testPath, options)
.then(out => {
const [output, nb_failures] = out;
results[nb_failures === 0 ? "successful" : "failed"].push({
file_name: file_name,
output: output,
});
if (nb_failures > 0) {
status_bar.erroneous()
failed = true;
} else {
status_bar.successful()
}
})
.catch(err => {
results.errored.push({
file_name: file_name,
output: err,
});
status_bar.erroneous();
failed = true;
}
}).catch(err => {
console.error(err);
failed = true;
})
);
if (no_headless) {
await tests[i];
}
}
if (!no_headless) {
await Promise.all(tests);
}
status_bar.finish();

if (debug) {
results.successful.sort(by_filename);
results.successful.forEach(r => {
console.log(r.output);
});
}

if (results.failed.length > 0) {
console.log("");
results.failed.sort(by_filename);
results.failed.forEach(r => {
console.log(r.output);
});
}
if (results.errored.length > 0) {
console.log(os.EOL);
// print run errors on the bottom so developers see them better
results.errored.sort(by_filename);
results.errored.forEach(r => {
console.error(r.output);
});
}

if (failed) {
process.exit(1);
}
Expand Down