Skip to content

Add LSP Client and long running tests in tools#511

Open
chrisqm-dev wants to merge 4 commits intomainfrom
long-running
Open

Add LSP Client and long running tests in tools#511
chrisqm-dev wants to merge 4 commits intomainfrom
long-running

Conversation

@chrisqm-dev
Copy link
Copy Markdown
Contributor

Description of changes:

  • Add lsp client methods to start up and interact with the cfn language server
  • Can be used for telemetry generator as well
  • Add long-running tests
    • This tests the standalone.js and ensures it is usable for extended periods of time
    • Tests the following:
      • Completion on document updates
      • Hover on document updates
      • Region switching, and therefore public schema retrieval
      • Ensures performance doesn't degrade over time

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@chrisqm-dev chrisqm-dev requested a review from a team as a code owner March 31, 2026 21:53
const output = data.toString().trim();

// Readiness detection
if (output.includes('cfn-lint version')) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the only way to determine if lint, guard, and the schemas are ready is through the logs. #507 Introduces a new LSP request which will return the guard, lint, and schema statuses. This addition will make testing more robust and speed up test time, but this PR is functional without this change

@satyakigh
Copy link
Copy Markdown
Collaborator

Our folder and file names are usually camelCased unless its a bin/cli command file

@@ -0,0 +1,3 @@
export { LspClient } from './LspClient';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use index.ts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed index.ts file

@@ -0,0 +1,49 @@
import { InitializeParams } from 'vscode-languageserver-protocol';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can all of this go in LspConnectionInterface? Should LspConnectionInterface be LspConnection ? our file names don't usually have interface naming

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed LspConnectionInterface and file to LspConnection. Moved types.ts content into LspConnection.ts.

@@ -0,0 +1,49 @@
import { InitializeParams } from 'vscode-languageserver-protocol';

export interface LspClientConfig {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think a lot of these should be required not optional

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made every property required except for:

  • env
  • storageDir
  • suppressLogLevels

Also, added clientInfo and extensionInfo properties

suppressLogLevels?: string[];
}

export interface ReadinessFlags {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't all the types from src be used?

Copy link
Copy Markdown
Contributor Author

@chrisqm-dev chrisqm-dev Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified to use all the src types

.gitignore Outdated
.DS_Store
tools/*
!tools/*.ts
!tools/lsp-client/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous line can be updated to !tools/**/*.ts instead

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modified to use the lines: !tools//
!tools/**/
.ts

!tools/*/ is necessary because without it the subdirectories will be ignored

export type StandaloneTestMetrics = {
operationsAttempted: number;
operationsFailed: number;
averageDuration: number | null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't these just be an array of numbers and the user decides what to do with them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this test could run for a very long time and there are thousands of operations per minute, the duration array could get very large. We should keep the min, max, and average attributes to avoid having to calculate from the array. Added the durations array in case there's any other operations we use in the future, such as median or p99.

}
}

export function generateFinalReport(testStartTime: number): void {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will this report be used for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prints out to the github actions logs upon completing successfully. I wanted to replicate a test coverage output report similar to what you see in vitest. We can't use vitest since it will not work with node 18

}
}

void main();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will swallow the exception and succeed the run

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added logic so that the exception is not swallowed in the event an exception (such as hover validation failure) occurs, and it fails fast. In the catch, we will explicitly throw the error


const cache = new Map<string, string>();

const loadTemplate = (name: string): string => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template utils from src can be used directly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to using Templates const from the tst/utils

console.log('Initialization complete');
}

private async waitForSystemReadiness(): Promise<void> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The system is "ready" but the orchestrator is "initializing/initialized"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified verbiage, not using "ready", only initializing/initialized

@satyakigh
Copy link
Copy Markdown
Collaborator

Lots of references to "long-running" the caller of the main file defines the duration

@chrisqm-dev
Copy link
Copy Markdown
Contributor Author

Our folder and file names are usually camelCased unless its a bin/cli command file

Fixed folder and file names so that folders are camelCased and files are PascalCased, which matches the styling in the rest of the package

@chrisqm-dev
Copy link
Copy Markdown
Contributor Author

Lots of references to "long-running" the caller of the main file defines the duration

Changed to "Stability" tests instead of calling it LongRunning

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants