Skip to content

Commit 0947a35

Browse files
author
Dave Bartolomeo
committed
Implement cancellation of test run
1 parent 207743e commit 0947a35

File tree

4 files changed

+45
-15
lines changed

4 files changed

+45
-15
lines changed

common/config/rush/shrinkwrap.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ dependencies:
5656
style-loader: 0.23.1
5757
through2: 3.0.1
5858
tmp: 0.1.0
59+
tree-kill: 1.2.2
5960
ts-loader: 5.4.5
6061
ts-node: 8.3.0
6162
ts-protoc-gen: 0.9.0
@@ -5690,6 +5691,11 @@ packages:
56905691
dev: false
56915692
resolution:
56925693
integrity: sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
5694+
/tree-kill/1.2.2:
5695+
dev: false
5696+
hasBin: true
5697+
resolution:
5698+
integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
56935699
/true-case-path/2.2.1:
56945700
dev: false
56955701
resolution:
@@ -6566,6 +6572,7 @@ packages:
65666572
style-loader: 0.23.1
65676573
through2: 3.0.1
65686574
tmp: 0.1.0
6575+
tree-kill: 1.2.2
65696576
ts-loader: /ts-loader/5.4.5/typescript@3.7.2
65706577
ts-node: /ts-node/8.3.0/typescript@3.7.2
65716578
ts-protoc-gen: 0.9.0
@@ -6585,7 +6592,7 @@ packages:
65856592
dev: false
65866593
name: '@rush-temp/vscode-codeql'
65876594
resolution:
6588-
integrity: sha512-1zj1CO19sanU2olFV3Kwf9OrG+92KO25WR6K1vnVHmScMj8H7aegRrjwyNeHi/IzxXDCAp68CZK+d4vEWBEa+g==
6595+
integrity: sha512-pHdIjv8YEIRicmnIzv2OB5cqdCRoKcF2ZbylLcaR+VP28TzoyYZK5q2anIYayibWa3Ik4la4pVGnSa344IatvA==
65896596
tarball: 'file:projects/vscode-codeql.tgz'
65906597
version: 0.0.0
65916598
registry: 'https://registry.npmjs.org/'
@@ -6649,6 +6656,7 @@ specifiers:
66496656
style-loader: ~0.23.1
66506657
through2: ^3.0.1
66516658
tmp: ^0.1.0
6659+
tree-kill: ~1.2.2
66526660
ts-loader: ^5.4.5
66536661
ts-node: ^8.3.0
66546662
ts-protoc-gen: ^0.9.0

extensions/ql-vscode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@
371371
"semmle-io-node": "^0.0.1",
372372
"semmle-vscode-utils": "^0.0.1",
373373
"tmp": "^0.1.0",
374+
"tree-kill": "~1.2.2",
374375
"unzipper": "~0.10.5",
375376
"vscode-jsonrpc": "^4.0.0",
376377
"vscode-languageclient": "^5.2.1",

extensions/ql-vscode/src/cli.ts

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import * as cpp from 'child-process-promise';
33
import * as fs from 'fs-extra';
44
import * as path from 'path';
55
import * as sarif from 'sarif';
6+
import * as tk from 'tree-kill';
67
import * as util from 'util';
78
import { Logger, ProgressReporter } from './logging';
8-
import { Disposable } from 'vscode';
9+
import { Disposable, CancellationToken } from 'vscode';
910
import { DistributionProvider } from './distribution';
1011
import { SortDirection } from './interface-types';
1112
import { assertNever } from './helpers-pure';
@@ -86,6 +87,7 @@ export type ResolvedTests = string[];
8687
* Options for `codeql test run`.
8788
*/
8889
export interface TestRunOptions {
90+
cancellationToken?: CancellationToken;
8991
logger?: Logger;
9092
}
9193

@@ -286,12 +288,14 @@ export class CodeQLCliServer implements Disposable {
286288
*
287289
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
288290
* @param commandArgs The arguments to pass to the `codeql` command.
291+
* @param cancellationToken CancellationToken to terminate the test process.
289292
* @param logger Logger to write text output from the command.
290293
* @returns The sequence of async events produced by the command.
291294
*/
292295
private async* runAsyncCodeQlCliCommandInternal(
293296
command: string[],
294297
commandArgs: string[],
298+
cancellationToken?: CancellationToken,
295299
logger?: Logger
296300
): AsyncGenerator<string, void, unknown> {
297301
// Add format argument first, in case commandArgs contains positional parameters.
@@ -306,16 +310,29 @@ export class CodeQLCliServer implements Disposable {
306310
const childPromise = cpp.spawn(codeqlPath, args);
307311
const child = childPromise.childProcess;
308312

309-
if (logger !== undefined) {
310-
// The human-readable output goes to stderr.
311-
logStream(child.stderr!, logger);
312-
}
313+
let cancellationRegistration: Disposable | undefined = undefined;
314+
try {
315+
if (cancellationToken !== undefined) {
316+
cancellationRegistration = cancellationToken.onCancellationRequested(_e => {
317+
tk(child.pid);
318+
});
319+
}
320+
if (logger !== undefined) {
321+
// The human-readable output goes to stderr.
322+
logStream(child.stderr!, logger);
323+
}
313324

314-
for await (const event of await splitStreamAtSeparators(child.stdout!, ['\0'])) {
315-
yield event;
316-
}
325+
for await (const event of await splitStreamAtSeparators(child.stdout!, ['\0'])) {
326+
yield event;
327+
}
317328

318-
await childPromise;
329+
await childPromise;
330+
}
331+
finally {
332+
if (cancellationRegistration !== undefined) {
333+
cancellationRegistration.dispose();
334+
}
335+
}
319336
}
320337

321338
/**
@@ -325,16 +342,19 @@ export class CodeQLCliServer implements Disposable {
325342
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
326343
* @param commandArgs The arguments to pass to the `codeql` command.
327344
* @param description Description of the action being run, to be shown in log and error messages.
345+
* @param cancellationToken CancellationToken to terminate the test process.
328346
* @param logger Logger to write text output from the command.
329347
* @returns The sequence of async events produced by the command.
330348
*/
331349
public async* runAsyncCodeQlCliCommand<EventType>(
332350
command: string[],
333351
commandArgs: string[],
334352
description: string,
353+
cancellationToken?: CancellationToken,
335354
logger?: Logger
336355
): AsyncGenerator<EventType, void, unknown> {
337-
for await (const event of await this.runAsyncCodeQlCliCommandInternal(command, commandArgs, logger)) {
356+
for await (const event of await this.runAsyncCodeQlCliCommandInternal(command, commandArgs,
357+
cancellationToken, logger)) {
338358
try {
339359
yield JSON.parse(event) as EventType;
340360
} catch (err) {
@@ -451,7 +471,7 @@ export class CodeQLCliServer implements Disposable {
451471
];
452472

453473
for await (const event of await this.runAsyncCodeQlCliCommand<TestCompleted>(['test', 'run'],
454-
subcommandArgs, 'Run CodeQL Tests', options.logger)) {
474+
subcommandArgs, 'Run CodeQL Tests', options.cancellationToken, options.logger)) {
455475
yield event;
456476
}
457477
}

extensions/ql-vscode/src/test-adapter.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
} from 'vscode-test-adapter-api';
1515
import { TestAdapterRegistrar } from 'vscode-test-adapter-util';
1616
import { QLTestFile, QLTestNode, QLTestDirectory, QLTestDiscovery } from './qltest-discovery';
17-
import { Event, EventEmitter, CancellationTokenSource } from 'vscode';
17+
import { Event, EventEmitter, CancellationTokenSource, CancellationToken } from 'vscode';
1818
import { DisposableObject } from 'semmle-vscode-utils';
1919
import { QLPackDiscovery } from './qlpack-discovery';
2020
import { CodeQLCliServer } from './cli';
@@ -194,7 +194,7 @@ export class QLTestAdapter extends DisposableObject implements TestAdapter {
194194
const testAdapter = this;
195195

196196
try {
197-
await this.runTests(tests);
197+
await this.runTests(tests, this.runningTask.token);
198198
}
199199
catch (e) {
200200
}
@@ -218,9 +218,10 @@ export class QLTestAdapter extends DisposableObject implements TestAdapter {
218218
}
219219
}
220220

221-
private async runTests(tests: string[]): Promise<void> {
221+
private async runTests(tests: string[], cancellationToken: CancellationToken): Promise<void> {
222222
const workspacePaths = await getOnDiskWorkspaceFolders();
223223
for await (const event of await this.cliServer.runTests(tests, workspacePaths, {
224+
cancellationToken: cancellationToken,
224225
logger: testLogger
225226
})) {
226227
this._testStates.fire({

0 commit comments

Comments
 (0)