Skip to content

Commit b2e0508

Browse files
committed
Merge branch 'topic/gnattest-coverage' into 'master'
Support GNATcoverage reporting and test runs See merge request eng/ide/ada_language_server!1900
2 parents 9625791 + 0af45a8 commit b2e0508

File tree

16 files changed

+1253
-66
lines changed

16 files changed

+1253
-66
lines changed

.gitlab-ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ als-cov:linux:
100100
# save coverage results
101101
- cp -v $RESULTS_DIR/coverage-cobertura/cobertura.xml $CI_PROJECT_DIR/coverage
102102
- cp -r $RESULTS_DIR/coverage-dhtml $CI_PROJECT_DIR/coverage/dhtml
103+
- cp -r $RESULTS_DIR/coverage-xml $CI_PROJECT_DIR/coverage/xml
103104

104105
# display coverage stats for global reporting
105106
- echo_coverage_stats --coverage-file $RESULTS_DIR/coverage-xml/index.xml
@@ -124,8 +125,9 @@ als-cov:linux:
124125
path: coverage/cobertura.xml
125126
paths:
126127
- anod-logs/
127-
# Also archive the report file for debugging the CI integration
128+
# Also archive coverage reports as files for other use
128129
- coverage/cobertura.xml
130+
- coverage/xml/
129131

130132
vscode-extension:linux:
131133
after_script:

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ section below it for the last release. -->
1313
* Add tasks and a CodeLens to run a given main with GNATemulator on non-native projects
1414
* Diagnostics are now emitted for issues encountered when trying to load an Alire crate
1515
* Commands to create a new main units and packages have been added, both available under the `File->New File...` menu
16+
* Add VS Code command `ada: GNATcoverage - Load an existing XML coverage report` for importing coverage reports
17+
* Support running GNATtest tests in coverage mode
1618

1719
## 26.0.202412190
1820

README.md

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ extension at
5353
- [Tasks](#tasks)
5454
- [Task Customization](#task-customization)
5555
- [Tasks for Project Mains](#tasks-for-project-mains)
56-
- [GNATtest Support](#gnattest-support)
57-
- [ALIRE Support](#alire-support)
56+
- [Alire Support](#alire-support)
57+
- [GNATtest Support](#gnattest-support)
58+
- [GNATcoverage Support](#gnatcoverage-support)
5859
- [Commands and Shortcuts](#commands-and-shortcuts)
5960
- [Ada: Go to other file](#ada-go-to-other-file)
6061
- [Ada: Add subprogram box](#ada-add-subprogram-box)
@@ -254,7 +255,15 @@ For example, if the project defines a `main1.adb` and `main2.adb` located under
254255
* `ada: Run main - src/main2.adb`
255256
* `ada: Build and run main - src/main2.adb`
256257

257-
#### GNATtest Support
258+
### Alire Support
259+
260+
When the workspace is an Alire crate (i.e. it contains an `alire.toml` file), the extension uses Alire to determine the GPR project that should be loaded and to obtain an environment where the crate's dependencies have been provisioned.
261+
262+
Moreover when working with an Alire crate, VS Code tasks automatically use standard Alire commands. For example, the `ada: Build current project` task uses the command `alr build` and the `ada: Clean current project` task uses the command `alr clean`.
263+
264+
All other tasks use `alr exec -- ...` to execute the command in the environment provided by Alire.
265+
266+
### GNATtest Support
258267

259268
If you install GNATtest, the Ada & SPARK extension for VS Code will provide the following functionalities:
260269

@@ -264,15 +273,15 @@ If you install GNATtest, the Ada & SPARK extension for VS Code will provide the
264273

265274
* Tests created with GNATtest will be loaded in the VS Code **Testing** view as follows.
266275

267-
<img src="doc/gnattest-test-tree.png" width="650" alt="GNATtest Test Tree">
276+
<img src="doc/gnattest-test-tree.png" width="650" alt="GNATtest Test Tree"/>
268277

269278
* Tests can be executed individually or in batch through the available buttons in the interface, or through the `Test: Run All Tests` command or related commands.
270279

271280
* Test execution always starts by executing the `ada: Build GNATtest test harness project` task to make sure that test executables are up to date.
272281

273282
* Test execution results are reflected in the test tree.
274283

275-
<img src="doc/gnattest-results.png" width="500" alt="GNATtest Test Results">
284+
<img src="doc/gnattest-results.png" width="500" alt="GNATtest Test Results"/>
276285

277286
GNATtest support has the following known limitations:
278287

@@ -284,13 +293,34 @@ GNATtest support has the following known limitations:
284293
* Sections of test sources delimited by `begin read only` and `end read only` comments are not really protected from inadvertant edits.
285294
To ensure proper interactions with GNATtest, you must refrain from making edits in those sections.
286295

287-
#### ALIRE Support
296+
### GNATcoverage Support
297+
298+
GNATcoverage coverage reports can be imported in VS Code as follows:
299+
300+
1. Instruct GNATcoverage to produce an [XML report](https://docs.adacore.com/live/wave/gnatdas/html/gnatdas_ug/gnatcov/cov_source.html#xml-report-xml-xml)
301+
2. Invoke the VS Code command `ada: GNATcoverage - Load an existing XML coverage report`
302+
3. Browse to the location of the GNATcoverage XML report and select the `index.xml` file
303+
304+
<img src="doc/gnatcov-report.png" width="1000" alt="GNATcoverage report in VS Code" />
305+
306+
Note that importing coverage reports does not require GNATcoverage to be installed. In particular, this enables a workflow where the coverage report is produced in CI and downloaded and imported into VS Code for visualization and analysis.
307+
308+
The GNATtest integration in VS Code also supports running tests in coverage mode, if GNATcoverage is installed on the development machine.
288309

289-
When the workspace is an ALIRE project (i.e. it contains an `alire.toml` file), tasks automatically use standard ALIRE commands.
310+
1. Run the task `ada: GNATcoverage - Setup runtime library` once to set up the GNATcoverage runtime library
311+
2. If you don't already have a test harness project created, use the task `ada: Create or update GNATtest test framework` to create one
312+
3. Switch to the _Test Explorer_ view or use the `Testing: Focus on Test Explorer View` command to do that
313+
4. Run the tests in coverage mode using the command `Test: Run All Tests with Coverage`, or use the "play" icon next to a single test or group of tests with the label _Run Test with Coverage_.
314+
5. In one go, VS Code will:
315+
1. Invoke [GNATcoverage source instrumentation](https://docs.adacore.com/live/wave/gnatdas/html/gnatdas_ug/gnatcov/src_traces.html)
316+
1. Build the test harness project
317+
1. Run the tests
318+
1. Invoke [GNATcoverage source coverage analysis](https://docs.adacore.com/live/wave/gnatdas/html/gnatdas_ug/gnatcov/cov_source.html)
319+
1. Load the GNATcoverage report into VS Code
290320

291-
For example, the `ada: Build current project` task uses the command `alr build` and the `ada: Clean current project` task uses the command `alr clean`.
321+
<img src="doc/gnattest-gnatcov.png" width="1000" alt="GNATtest with GNATcoverage in VS Code" />
292322

293-
All other tasks use `alr exec -- ...` to execute the command in the environment provided by ALIRE.
323+
Integrating the steps of source instrumentation and test harness build into the test execution workflow allows for a quick feedback loop: run a test, observe results and coverage, edit the test or the tested code, repeat... In this context invoking the VS Code commands `Test: Rerun Last Run` and `Test: Rerun Last Run with Coverage` with their respective keyboard shortcuts can be valuable.
294324

295325
### Commands and Shortcuts
296326

@@ -349,13 +379,13 @@ The VS Code extension has a few limitations and some differences compared to [GN
349379
* **Indentation/formatting**: it does not support automatic indentation when adding a newline and range/document
350380
formatting might no succeed on incomplete/illegal code.
351381

352-
* **Tooling support**: we currently provide support for some *SPARK*, *GNATtest* and *GNAT SAS* [Tasks](#tasks), but there is no support for tools such as *GNATcheck* or *GNATcoverage* yet.
382+
* **Tooling support**: we currently provide support for some *SPARK*, *GNATtest*, *GNATcoverage* and *GNAT SAS* [Tasks](#tasks), but some workflows may not be supported yet.
353383

354384
* **Alire support**: if the root folder contains an `alire.toml` file and
355385
there is `alr` executable in the `PATH`, then the language server fetches
356386
the project's search path, environment variables and the project's file
357387
name from the crate description. [Tasks](#tasks) are also automatically
358-
invoked with ALIRE in this case.
388+
invoked with Alire in this case.
359389

360390
* **Project support**: there is no `Scenario` view: users should configure scenarios via the *ada.scenarioVariables* setting (see the settings list available [here](doc/settings.md)). Saving the settings file after changing the values will automatically reload the project and update the
361391
predefined tasks to take into account the new scenario values.

doc/gnatcov-report.png

656 KB
Loading

doc/gnattest-gnatcov.png

390 KB
Loading

integration/vscode/ada/package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration/vscode/ada/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"publisher": "AdaCore",
77
"license": "GPL-3.0",
88
"engines": {
9-
"vscode": "^1.83.1"
9+
"vscode": "^1.88.0"
1010
},
1111
"categories": [
1212
"Programming Languages",
@@ -850,6 +850,10 @@
850850
"command": "ada.spark.tasks.proveLine",
851851
"title": "spark: Prove line (task wrapper)",
852852
"when": "editorLangId == ada && editorTextFocus"
853+
},
854+
{
855+
"command": "ada.loadGnatCovXMLReport",
856+
"title": "ada: GNATcoverage - Load an existing XML coverage report"
853857
}
854858
],
855859
"keybindings": [
@@ -1080,7 +1084,7 @@
10801084
"@types/command-exists": "1.2.3",
10811085
"@types/mocha": "10.0.7",
10821086
"@types/node": "16.18.16",
1083-
"@types/vscode": "1.83.1",
1087+
"@types/vscode": "~1.88.0",
10841088
"@types/ws": "8.5.12",
10851089
"@typescript-eslint/eslint-plugin": "8.3.0",
10861090
"@typescript-eslint/parser": "8.3.0",

integration/vscode/ada/src/ExtensionState.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,15 @@ export class ExtensionState {
450450
public getSparkTaskProvider() {
451451
return this.sparkTaskProvider;
452452
}
453+
454+
/**
455+
*
456+
* @returns the Ada task provider which can be useful for resolving tasks
457+
* created on the fly, e.g. when running GNATtest tests in coverage mode.
458+
*/
459+
public getAdaTaskProvider() {
460+
return this.adaTaskProvider;
461+
}
453462
}
454463

455464
/**

integration/vscode/ada/src/commands.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
getBuildAndRunTaskName,
2626
} from './taskProviders';
2727
import { createHelloWorldProject, walkthroughStartDebugging } from './walkthrough';
28+
import { loadGnatCoverageReport } from './gnattest';
2829

2930
/**
3031
* Identifier for a hidden command used for building and running a project main.
@@ -171,6 +172,10 @@ export function registerCommands(context: vscode.ExtensionContext, clients: Exte
171172
vscode.commands.registerCommand(CMD_SPARK_PROVE_SUBP, sparkProveSubprogram),
172173
);
173174

175+
context.subscriptions.push(
176+
commands.registerCommand('ada.loadGnatCovXMLReport', loadGnatCovXMLReport),
177+
);
178+
174179
registerTaskWrappers(context);
175180
}
176181

@@ -936,3 +941,24 @@ async function sparkProveSubprogram(
936941
*/
937942
return await vscode.tasks.executeTask(resolvedTask);
938943
}
944+
async function loadGnatCovXMLReport() {
945+
const selection = await vscode.window.showOpenDialog({
946+
canSelectFiles: true,
947+
canSelectFolders: false,
948+
canSelectMany: false,
949+
filters: {
950+
'index.xml': ['xml'],
951+
},
952+
title: "Select a 'index.xml' GNATcoverage report to load",
953+
});
954+
955+
if (selection && selection.length > 0 && selection[0]) {
956+
const path = selection[0].fsPath;
957+
if (!path.endsWith('index.xml')) {
958+
throw Error(
959+
`The selected file must be 'index.xml'. Instead, the selected file was: ${path}`,
960+
);
961+
}
962+
await loadGnatCoverageReport(path);
963+
}
964+
}

integration/vscode/ada/src/gnatTaskProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ export const getDiagnosticArgs = (): string[] => {
333333
const p_gnatef = ["'-cargs:ada'", '-gnatef'];
334334
return p_gnatef;
335335
};
336-
export function getScenarioArgs() {
336+
export function getScenarioArgs(): string[] {
337337
const vars: string[][] = Object.entries(
338338
vscode.workspace.getConfiguration('ada').get('scenarioVariables') ?? [],
339339
);

0 commit comments

Comments
 (0)