Skip to content
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

Fix test baselining for tsserver host timeouts #50748

Merged
merged 1 commit into from Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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