Split rwc input files (#18772)

* Handle translation between new and old log format styles

* Iteration

* Strip all backcompat

* Remove new parenthesis

* Handle directories in the test perf heuristic measurement

* Optional catch bindings!
This commit is contained in:
Wesley Wigham 2017-09-26 15:55:21 -07:00 committed by GitHub
parent ecef2dc970
commit 6ffee104ca
6 changed files with 105 additions and 18 deletions

View File

@ -978,8 +978,9 @@ gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
.pipe(gulp.dest(builtLocalDirectory));
});
gulp.task("tsc-instrumented", "Builds an instrumented tsc.js", ["local", loggedIOJsPath, instrumenterJsPath, servicesFile], (done) => {
exec(host, [instrumenterJsPath, "record", "iocapture", builtLocalCompiler], done, done);
gulp.task("tsc-instrumented", "Builds an instrumented tsc.js - run with --test=[testname]", ["local", loggedIOJsPath, instrumenterJsPath, servicesFile], (done) => {
const test = cmdLineOptions["tests"] || "iocapture";
exec(host, [instrumenterJsPath, "record", test, builtLocalCompiler], done, done);
});
gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", serverFile], () => {

View File

@ -1104,9 +1104,10 @@ var instrumenterPath = harnessDirectory + 'instrumenter.ts';
var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js';
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true, { lib: "es6", types: ["node"], noOutFile: true, outDir: builtLocalDirectory });
desc("Builds an instrumented tsc.js");
desc("Builds an instrumented tsc.js - run with test=[testname]");
task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function () {
var cmd = host + ' ' + instrumenterJsPath + ' record iocapture ' + builtLocalDirectory + compilerFilename;
var test = process.env.test || process.env.tests || process.env.t || "iocapture";
var cmd = host + ' ' + instrumenterJsPath + " record " + test + " " + builtLocalDirectory + compilerFilename;
console.log(cmd);
var ex = jake.createExec([cmd]);
ex.addListener("cmdEnd", function () {

View File

@ -1717,8 +1717,12 @@ namespace Harness {
return resultName;
}
function sanitizeTestFilePath(name: string) {
return ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", Utils.canonicalizeForHarness);
export function sanitizeTestFilePath(name: string) {
const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", Utils.canonicalizeForHarness);
if (ts.startsWith(path, "/")) {
return path.substring(1);
}
return path;
}
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
@ -2068,7 +2072,7 @@ namespace Harness {
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
const [name, content, count] = value as [string, string, number | undefined];
if (count === 0) continue; // Allow error reporter to skip writing files without errors
const relativeFileName = relativeFileBase + (ts.startsWith(name, "/") ? "" : "/") + name + extension;
const relativeFileName = relativeFileBase + "/" + name + extension;
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
const comparison = compareToBaseline(content, relativeFileName, opts);
try {

View File

@ -5,8 +5,10 @@
/// <reference path="..\..\src\harness\typeWriter.ts" />
interface FileInformation {
contents: string;
contents?: string;
contentsPath?: string;
codepage: number;
bom?: string;
}
interface FindFileResult {
@ -27,13 +29,15 @@ interface IOLog {
filesRead: IOLogFile[];
filesWritten: {
path: string;
contents: string;
contents?: string;
contentsPath?: string;
bom: boolean;
}[];
filesDeleted: string[];
filesAppended: {
path: string;
contents: string;
contents?: string;
contentsPath?: string;
}[];
fileExists: {
path: string;
@ -129,6 +133,72 @@ namespace Playback {
};
}
export function newStyleLogIntoOldStyleLog(log: IOLog, host: ts.System | Harness.IO, baseName: string) {
for (const file of log.filesAppended) {
if (file.contentsPath) {
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
delete file.contentsPath;
}
}
for (const file of log.filesWritten) {
if (file.contentsPath) {
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
delete file.contentsPath;
}
}
for (const file of log.filesRead) {
if (file.result.contentsPath) {
// `readFile` strips away a BOM (and actually reinerprets the file contents according to the correct encoding)
// - but this has the unfortunate sideeffect of removing the BOM from any outputs based on the file, so we readd it here.
file.result.contents = (file.result.bom || "") + host.readFile(ts.combinePaths(baseName, file.result.contentsPath));
delete file.result.contentsPath;
}
}
return log;
}
export function oldStyleLogIntoNewStyleLog(log: IOLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
if (log.filesAppended) {
for (const file of log.filesAppended) {
if (file.contents !== undefined) {
file.contentsPath = ts.combinePaths("appended", Harness.Compiler.sanitizeTestFilePath(file.path));
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
delete file.contents;
}
}
}
if (log.filesWritten) {
for (const file of log.filesWritten) {
if (file.contents !== undefined) {
file.contentsPath = ts.combinePaths("written", Harness.Compiler.sanitizeTestFilePath(file.path));
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
delete file.contents;
}
}
}
if (log.filesRead) {
for (const file of log.filesRead) {
const { contents } = file.result;
if (contents !== undefined) {
file.result.contentsPath = ts.combinePaths("read", Harness.Compiler.sanitizeTestFilePath(file.path));
writeFile(ts.combinePaths(baseTestName, file.result.contentsPath), contents);
const len = contents.length;
if (len >= 2 && contents.charCodeAt(0) === 0xfeff) {
file.result.bom = "\ufeff";
}
if (len >= 2 && contents.charCodeAt(0) === 0xfffe) {
file.result.bom = "\ufffe";
}
if (len >= 3 && contents.charCodeAt(0) === 0xefbb && contents.charCodeAt(1) === 0xbf) {
file.result.bom = "\uefbb\xbf";
}
delete file.result.contents;
}
}
}
return log;
}
function initWrapper(wrapper: PlaybackSystem, underlying: ts.System): void;
function initWrapper(wrapper: PlaybackIO, underlying: Harness.IO): void;
function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.IO): void {
@ -164,9 +234,9 @@ namespace Playback {
wrapper.endRecord = () => {
if (recordLog !== undefined) {
let i = 0;
const fn = () => recordLogFileNameBase + i + ".json";
while (underlying.fileExists(fn())) i++;
underlying.writeFile(fn(), JSON.stringify(recordLog));
const fn = () => recordLogFileNameBase + i;
while (underlying.fileExists(fn() + ".json")) i++;
underlying.writeFile(ts.combinePaths(fn(), "test.json"), JSON.stringify(oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(ts.combinePaths(fn(), path), string), fn()), null, 4)); // tslint:disable-line:no-null-keyword
recordLog = undefined;
}
};

View File

@ -57,8 +57,19 @@ namespace Harness.Parallel.Host {
for (const file of files) {
let size: number;
if (!perfData) {
size = statSync(file).size;
try {
size = statSync(file).size;
}
catch {
// May be a directory
try {
size = Harness.IO.listFiles(file, /.*/g, { recursive: true }).reduce((acc, elem) => acc + statSync(elem).size, 0);
}
catch {
// Unknown test kind, just return 0 and let the historical analysis take over after one run
size = 0;
}
}
}
else {
const hashedName = hashName(runner.kind(), file);

View File

@ -36,7 +36,7 @@ namespace RWC {
Subfolder: "rwc",
Baselinefolder: "internal/baselines"
};
const baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
const baseName = ts.getBaseFileName(jsonPath);
let currentDirectory: string;
let useCustomLibraryFile: boolean;
let skipTypeAndSymbolbaselines = false;
@ -61,7 +61,7 @@ namespace RWC {
this.timeout(800000); // Allow long timeouts for RWC compilations
let opts: ts.ParsedCommandLine;
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
const ioLog: IOLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
currentDirectory = ioLog.currentDirectory;
useCustomLibraryFile = ioLog.useCustomLibraryFile;
skipTypeAndSymbolbaselines = ioLog.filesRead.reduce((acc, elem) => (elem && elem.result && elem.result.contents) ? acc + elem.result.contents.length : acc, 0) > typeAndSymbolSizeLimit;
@ -253,7 +253,7 @@ namespace RWC {
class RWCRunner extends RunnerBase {
public enumerateTestFiles() {
return Harness.IO.listFiles("internal/cases/rwc/", /.+\.json$/);
return Harness.IO.getDirectories("internal/cases/rwc/");
}
public kind(): TestRunnerKind {