Add LSP Client and long running tests in tools#511
Conversation
| const output = data.toString().trim(); | ||
|
|
||
| // Readiness detection | ||
| if (output.includes('cfn-lint version')) { |
There was a problem hiding this comment.
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
|
Our folder and file names are usually camelCased unless its a bin/cli command file |
| export type StandaloneTestMetrics = { | ||
| operationsAttempted: number; | ||
| operationsFailed: number; | ||
| averageDuration: number | null; |
There was a problem hiding this comment.
Can't these just be an array of numbers and the user decides what to do with them
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
What will this report be used for?
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
This will swallow the exception and succeed the run
There was a problem hiding this comment.
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
|
Lots of references to "long-running" the caller of the main file defines the duration |
Fixed folder and file names so that folders are camelCased and files are PascalCased, which matches the styling in the rest of the package |
Changed to "Stability" tests instead of calling it LongRunning |
eed185f to
2ddb466
Compare
562aac8 to
30b5b8e
Compare
bdd25b8 to
9375221
Compare
| async testAllScenarios(uri: string): Promise<void> { | ||
| // Test 1: Top-level completion using full document update | ||
| const basicTemplate = `AWSTemplateFormatVersion: '2010-09-09' | ||
| `; |
There was a problem hiding this comment.
nit: remove extra line
There was a problem hiding this comment.
the '`' is placed on a new line so that the completion provider returns all the top level resources, since the completion provider will only return these values on a new line
| *.node | ||
| .DS_Store | ||
| tools/* | ||
| !tools/*.ts |
There was a problem hiding this comment.
Just need !tools/**/*.ts
There was a problem hiding this comment.
Removed !tools/**/*.ts
| const output = data.toString().trim(); | ||
|
|
||
| // Log filtering - keep for debugging | ||
| const suppressLevels = this.config.suppressLogLevels ?? ['INFO', 'DEBUG']; |
There was a problem hiding this comment.
This line can be moved out of the function, this only needs to execute once
There was a problem hiding this comment.
Moved suppressLevels outside of the function
| protected isShutdown = false; | ||
| protected workspaceConfig: Record<string, unknown>[] = [{}]; | ||
|
|
||
| constructor(protected config: LspClientConfig) { |
There was a problem hiding this comment.
Changed config to private
| path: string; | ||
| } | ||
|
|
||
| function parseSimpleArgs(): Partial<Config> { |
There was a problem hiding this comment.
Use yargs similar to the other tools
There was a problem hiding this comment.
yargs cannot be used in node 18:
Error: yargs parser supports a minimum Node.js version of 20. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions
| @@ -0,0 +1,72 @@ | |||
| export interface Config { | |||
There was a problem hiding this comment.
This file should just return a Config object, instead of exporting the parsers
There was a problem hiding this comment.
Fixed so that Config.ts exports a config object instead of parseConfig()
| content: string; | ||
| } | ||
|
|
||
| export const TEMPLATE_CONFIGS: TemplateConfig[] = [ |
There was a problem hiding this comment.
Templates? Test Templates?
There is no config here
There was a problem hiding this comment.
Renamed const to TEST_TEMPLATES
| }, | ||
| }; | ||
|
|
||
| export function getTesterConfig(operationType: OperationType): TesterConfig { |
There was a problem hiding this comment.
If getTesterConfig is required, we don't need to export TESTER_CONFIG, but easier would just be to export TESTER_CONFIG and use it directly TESTER_CONFIG[operationType]
calling getTesterConfig or TESTER_CONFIG[operationType] once is trivial
There was a problem hiding this comment.
Removed getter function to instead use the const directly
| @@ -0,0 +1,27 @@ | |||
| import { recordOperation } from '../Monitoring'; | |||
There was a problem hiding this comment.
Renamed file to "TesterUtils.ts"
| run: node cfn-lsp-server-standalone.js --version | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci |
There was a problem hiding this comment.
This probably won't work for node 18
There was a problem hiding this comment.
Confirmed this works for node 18 by running npm ci locally with node 18
| contents: read | ||
|
|
||
| jobs: | ||
| check-beta-release: |
There was a problem hiding this comment.
this handles the main branch as well? Alpha?
There was a problem hiding this comment.
Added a workflow for alpha to work. We need a release for this test to work as it requires a pre-built standalone file, which is not created on every push to main.
3b40c92 to
f3210fd
Compare
kddejong
left a comment
There was a problem hiding this comment.
A few comments below, requesting changes for the report timing bug.
| try { | ||
| await orchestrator.initialize(); | ||
| await orchestrator.runTests(); | ||
| generateFinalReport(Date.now()); |
There was a problem hiding this comment.
generateFinalReport(Date.now()) is called after the tests finish, so the reported runtime will always be ~0 minutes. Capture the start time before runTests() and pass that in. (Or just use the startTime that initializeMonitoring() already tracks internally.)
There was a problem hiding this comment.
Fixed to use startTime value appropriately
| export interface LspConnection { | ||
| initialize(): Promise<void>; | ||
| sendRequest(method: string, params: any): Promise<any>; | ||
| sendNotification(method: string, params: any): Promise<void>; |
There was a problem hiding this comment.
There's a lot of any throughout the client and testers — is there a reason we're not using the types from vscode-languageserver-protocol? Things like Hover, CompletionList, CompletionParams, etc. would give you compile-time safety on the validators for free.
There was a problem hiding this comment.
Added typing for the specific lsp requests.
For sendRequest, sendNotification, and onRequest,any will still be necessary since it can be used for any request object.
| metric.averageDuration === null | ||
| ? duration | ||
| : (metric.averageDuration * (metric.operations - 1) + duration) / metric.operations; | ||
| metric.minDuration = metric.minDuration === null ? duration : Math.min(metric.minDuration, duration); |
There was a problem hiding this comment.
durations is pushed to on every operation but never read anywhere. What's it for?
There was a problem hiding this comment.
This was originally going to be used to generate metrics other than average (for example, median duration which requires the durations list). Those metrics were not implemented since average was sufficient. Removed the durations list, we can add it back if we later determine more metrics are needed
|
|
||
| await this.client.updateDocument(uri, 2, s3Template); | ||
|
|
||
| await retryOperationWithPerformance( |
There was a problem hiding this comment.
Nit: the document versions (2, 3, 4, 5, 6) are hardcoded across the testers and orchestrator. Works fine now but could get fragile if more testers are added. A shared counter would help down the road.
There was a problem hiding this comment.
Added nextDocumentVersion() and resetDocumentVersion() helpers
Description of changes:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.