Skip to content

Commit

Permalink
Fix test baselining for tsserver host timeouts (#50748)
Browse files Browse the repository at this point in the history
  • Loading branch information
sheetalkamat committed Sep 13, 2022
1 parent 6d38487 commit a88c366
Show file tree
Hide file tree
Showing 27 changed files with 467 additions and 222 deletions.
Expand Up @@ -146,7 +146,7 @@ namespace ts.projectSystem {
logCacheAndClear(projectService.logger);

host.writeFile(imported.path, imported.content);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();
logSemanticDiagnostics(projectService, project, root);
logCacheAndClear(projectService.logger);
baselineTsserverLogs("cachingFileSystemInformation", "loads missing files from disk", projectService);
Expand Down Expand Up @@ -280,7 +280,7 @@ namespace ts.projectSystem {

// Create file cookie.ts
host.writeFile(file3.path, file3.content);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();
logCacheAndClear(projectService.logger);

projectService.openClientFile(file3.path);
Expand Down Expand Up @@ -479,15 +479,15 @@ namespace ts.projectSystem {
if (npmInstallComplete || timeoutDuringPartialInstallation) {
if (timeoutQueueLengthWhenRunningTimeouts) {
// Expected project update
projectService.checkTimeoutQueueLengthAndRun(timeoutQueueLengthWhenRunningTimeouts + 1); // Scheduled invalidation of resolutions
projectService.runQueuedTimeoutCallbacks(); // Actual update
host.checkTimeoutQueueLengthAndRun(timeoutQueueLengthWhenRunningTimeouts + 1); // Scheduled invalidation of resolutions
host.runQueuedTimeoutCallbacks(); // Actual update
}
else {
projectService.checkTimeoutQueueLengthAndRun(timeoutQueueLengthWhenRunningTimeouts);
host.checkTimeoutQueueLengthAndRun(timeoutQueueLengthWhenRunningTimeouts);
}
}
else {
projectService.checkTimeoutQueueLength(3);
host.checkTimeoutQueueLength(3);
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/testRunner/unittests/tsserver/configFileSearch.ts
Expand Up @@ -43,7 +43,7 @@ namespace ts.projectSystem {

// Delete config file - should create inferred project and not configured project
host.deleteFile(configFile.path);
service.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();
checkNumberOfProjects(service, { inferredProjects: 1 });
baselineTsserverLogs("configFileSearch", "should use projectRootPath when searching for inferred project again", service);
});
Expand Down Expand Up @@ -73,7 +73,7 @@ namespace ts.projectSystem {

// Delete config file - should create inferred project with project root path set
host.deleteFile(configFile.path);
service.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();
baselineTsserverLogs("configFileSearch", "should use projectRootPath when searching for inferred project again 2", service);
});

Expand All @@ -98,10 +98,10 @@ namespace ts.projectSystem {
const { host, projectService } = openClientFile([file, libFile, tsconfig]);

host.deleteFile(tsconfig.path);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();

host.writeFile(tsconfig.path, tsconfig.content);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();

baselineTsserverLogs("configFileSearch", "tsconfig for the file exists", projectService);
});
Expand All @@ -110,10 +110,10 @@ namespace ts.projectSystem {
const { host, projectService } = openClientFile([file, libFile]);

host.writeFile(tsconfig.path, tsconfig.content);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();

host.deleteFile(tsconfig.path);
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();

baselineTsserverLogs("configFileSearch", "tsconfig for the file does not exist", projectService);
});
Expand Down
20 changes: 10 additions & 10 deletions src/testRunner/unittests/tsserver/configuredProjects.ts
Expand Up @@ -90,11 +90,11 @@ namespace ts.projectSystem {

// Add a tsconfig file
host.writeFile(configFile.path, configFile.content);
projectService.checkTimeoutQueueLengthAndRun(2); // load configured project from disk + ensureProjectsForOpenFiles
host.checkTimeoutQueueLengthAndRun(2); // load configured project from disk + ensureProjectsForOpenFiles

// remove the tsconfig file
host.deleteFile(configFile.path);
projectService.checkTimeoutQueueLengthAndRun(1); // Refresh inferred projects
host.checkTimeoutQueueLengthAndRun(1); // Refresh inferred projects

baselineTsserverLogs("configuredProjects", "add and then remove a config file in a folder with loose files", projectService);
});
Expand All @@ -110,7 +110,7 @@ namespace ts.projectSystem {

// add a new ts file
host.writeFile(commonFile2.path, commonFile2.content);
projectService.checkTimeoutQueueLengthAndRun(2);
host.checkTimeoutQueueLengthAndRun(2);
baselineTsserverLogs("configuredProjects", "add new files to a configured project without file list", projectService);
});

Expand Down Expand Up @@ -548,7 +548,7 @@ namespace ts.projectSystem {
assert.isTrue(configProject1.hasOpenRef()); // file1 and file3

host.writeFile(configFile.path, "{}");
projectService.runQueuedTimeoutCallbacks();
host.runQueuedTimeoutCallbacks();

assert.isTrue(configProject1.hasOpenRef()); // file1, file2, file3
assert.isTrue(projectService.inferredProjects[0].isOrphan());
Expand Down Expand Up @@ -1033,23 +1033,23 @@ foo();`
strict: true
}
}));
projectService.checkTimeoutQueueLengthAndRun(3);
host.checkTimeoutQueueLengthAndRun(3);

host.writeFile(bravoExtendedConfig.path, JSON.stringify({
extends: "./alpha.tsconfig.json",
compilerOptions: {
strict: false
}
}));
projectService.checkTimeoutQueueLengthAndRun(2);
host.checkTimeoutQueueLengthAndRun(2);

host.writeFile(bConfig.path, JSON.stringify({
extends: "../extended/alpha.tsconfig.json",
}));
projectService.checkTimeoutQueueLengthAndRun(2);
host.checkTimeoutQueueLengthAndRun(2);

host.writeFile(alphaExtendedConfig.path, "{}");
projectService.checkTimeoutQueueLengthAndRun(3);
host.checkTimeoutQueueLengthAndRun(3);
baselineTsserverLogs("configuredProjects", "should watch the extended configs of multiple projects", projectService);
});

Expand Down Expand Up @@ -1183,8 +1183,8 @@ foo();`
projectService.openClientFile(file1.path);

host.writeFile(file2.path, file2.content);
projectService.runQueuedTimeoutCallbacks(); // Scheduled invalidation of resolutions
projectService.runQueuedTimeoutCallbacks(); // Actual update
host.runQueuedTimeoutCallbacks(); // Scheduled invalidation of resolutions
host.runQueuedTimeoutCallbacks(); // Actual update

// On next file open the files file2a should be closed and not watched any more
projectService.openClientFile(file2.path);
Expand Down
Expand Up @@ -442,7 +442,7 @@ namespace ts.projectSystem {

file3.content += "export class d {}";
host.writeFile(file3.path, file3.content);
session.checkTimeoutQueueLengthAndRun(2);
host.checkTimeoutQueueLengthAndRun(2);

// Since this is first event
verifyProjectsUpdatedInBackgroundEventHandler([{
Expand All @@ -453,8 +453,8 @@ namespace ts.projectSystem {
}]);

host.writeFile(file2.path, file2.content);
session.runQueuedTimeoutCallbacks(); // For invalidation
session.runQueuedTimeoutCallbacks(); // For actual update
host.runQueuedTimeoutCallbacks(); // For invalidation
host.runQueuedTimeoutCallbacks(); // For actual update

verifyProjectsUpdatedInBackgroundEventHandler(useSlashRootAsSomeNotRootFolderInUserDirectory ? [{
eventName: server.ProjectsUpdatedInBackgroundEvent,
Expand Down
93 changes: 42 additions & 51 deletions src/testRunner/unittests/tsserver/helpers.ts
Expand Up @@ -342,6 +342,41 @@ namespace ts.projectSystem {
}
}

function patchHostTimeouts(host: TestFSWithWatch.TestServerHostTrackingWrittenFiles, session: TestSession | TestProjectService) {
const originalCheckTimeoutQueueLength = host.checkTimeoutQueueLength;
const originalRunQueuedTimeoutCallbacks = host.runQueuedTimeoutCallbacks;
const originalRunQueuedImmediateCallbacks = host.runQueuedImmediateCallbacks;

host.checkTimeoutQueueLengthAndRun = checkTimeoutQueueLengthAndRun;
host.checkTimeoutQueueLength = checkTimeoutQueueLength;
host.runQueuedTimeoutCallbacks = runQueuedTimeoutCallbacks;
host.runQueuedImmediateCallbacks = runQueuedImmediateCallbacks;

function checkTimeoutQueueLengthAndRun(expected: number) {
session.baselineHost(`Before checking timeout queue length (${expected}) and running`);
originalCheckTimeoutQueueLength.call(host, expected);
originalRunQueuedTimeoutCallbacks.call(host);
session.baselineHost(`After checking timeout queue length (${expected}) and running`);
}

function checkTimeoutQueueLength(expected: number) {
session.baselineHost(`Checking timeout queue length: ${expected}`);
originalCheckTimeoutQueueLength.call(host, expected);
}

function runQueuedTimeoutCallbacks(timeoutId?: number) {
session.baselineHost(`Before running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
originalRunQueuedTimeoutCallbacks.call(host, timeoutId);
session.baselineHost(`After running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
}

function runQueuedImmediateCallbacks(checkCount?: number) {
session.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
originalRunQueuedImmediateCallbacks.call(host, checkCount);
session.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
}
}

export interface TestSessionOptions extends server.SessionOptions {
logger: Logger;
}
Expand All @@ -357,6 +392,7 @@ namespace ts.projectSystem {
super(opts);
this.logger = opts.logger;
this.testhost = TestFSWithWatch.changeToHostTrackingWrittenFiles(this.host as TestServerHost);
patchHostTimeouts(this.testhost, this);
}

getProjectService() {
Expand Down Expand Up @@ -408,29 +444,6 @@ namespace ts.projectSystem {
this.hostDiff = this.testhost.snap();
this.testhost.writtenFiles.clear();
}

checkTimeoutQueueLengthAndRun(expected: number) {
this.baselineHost(`Before checking timeout queue length (${expected}) and running`);
this.testhost.checkTimeoutQueueLengthAndRun(expected);
this.baselineHost(`After checking timeout queue length (${expected}) and running`);
}

checkTimeoutQueueLength(expected: number) {
this.baselineHost(`Checking timeout queue length: ${expected}`);
this.testhost.checkTimeoutQueueLength(expected);
}

runQueuedTimeoutCallbacks(timeoutId?: number) {
this.baselineHost(`Before running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
this.testhost.runQueuedTimeoutCallbacks(timeoutId);
this.baselineHost(`After running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
}

runQueuedImmediateCallbacks(checkCount?: number) {
this.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
this.testhost.runQueuedImmediateCallbacks(checkCount);
this.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
}
}

export function createSession(host: server.ServerHost, opts: Partial<TestSessionOptions> = {}) {
Expand Down Expand Up @@ -513,6 +526,7 @@ namespace ts.projectSystem {
...opts
});
this.testhost = TestFSWithWatch.changeToHostTrackingWrittenFiles(this.host as TestServerHost);
patchHostTimeouts(this.testhost, this);
this.baselineHost("Creating project service");
}

Expand All @@ -528,29 +542,6 @@ namespace ts.projectSystem {
this.hostDiff = this.testhost.snap();
this.testhost.writtenFiles.clear();
}

checkTimeoutQueueLengthAndRun(expected: number) {
this.baselineHost(`Before checking timeout queue length (${expected}) and running`);
this.testhost.checkTimeoutQueueLengthAndRun(expected);
this.baselineHost(`After checking timeout queue length (${expected}) and running`);
}

checkTimeoutQueueLength(expected: number) {
this.baselineHost(`Checking timeout queue length: ${expected}`);
this.testhost.checkTimeoutQueueLength(expected);
}

runQueuedTimeoutCallbacks(timeoutId?: number) {
this.baselineHost(`Before running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
this.testhost.runQueuedTimeoutCallbacks(timeoutId);
this.baselineHost(`After running timeout callback${timeoutId === undefined ? "s" : timeoutId}`);
}

runQueuedImmediateCallbacks(checkCount?: number) {
this.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
this.testhost.runQueuedImmediateCallbacks(checkCount);
this.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`);
}
}

export function createProjectService(host: TestServerHost, options?: Partial<TestProjectServiceOptions>) {
Expand Down Expand Up @@ -854,14 +845,14 @@ namespace ts.projectSystem {
Debug.assert(session.logger.logs.length);
for (let i = 0; i < files.length; i++) {
if (existingTimeouts !== undefined) {
session.checkTimeoutQueueLength(existingTimeouts + 1);
session.runQueuedTimeoutCallbacks(host.getNextTimeoutId() - 1);
host.checkTimeoutQueueLength(existingTimeouts + 1);
host.runQueuedTimeoutCallbacks(host.getNextTimeoutId() - 1);
}
else {
session.checkTimeoutQueueLengthAndRun(1);
host.checkTimeoutQueueLengthAndRun(1);
}
if (!skip?.[i]?.semantic) session.runQueuedImmediateCallbacks(1);
if (!skip?.[i]?.suggestion) session.runQueuedImmediateCallbacks(1);
if (!skip?.[i]?.semantic) host.runQueuedImmediateCallbacks(1);
if (!skip?.[i]?.suggestion) host.runQueuedImmediateCallbacks(1);
}
}

Expand Down

0 comments on commit a88c366

Please sign in to comment.