Skip to content

Commit

Permalink
Merge branch 'master' into fix-coverage-brda
Browse files Browse the repository at this point in the history
  • Loading branch information
vogelsgesang authored Oct 16, 2024
2 parents 663d870 + c115a86 commit 14d576b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
16 changes: 8 additions & 8 deletions src/bazel/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,12 @@ async function onTaskProcessEnd(event: vscode.TaskProcessEndEvent) {
if (taskDefinition.command === "coverage" && rawExitCode === 0) {
// Find the coverage file and load it.
const workspaceInfo = await getWorkspaceInfoFromTask(task.scope);
const outputPath = await new BazelInfo(
const bazelInfo = new BazelInfo(
getDefaultBazelExecutablePath(),
workspaceInfo.bazelWorkspacePath,
).getOne("output_path");
);
const outputPath = await bazelInfo.getOne("output_path");
const executionRoot = await bazelInfo.getOne("execution_root");

// Build a description string which will be displayed as part of the test run.
const execution = task.execution as vscode.ShellExecution;
Expand All @@ -183,12 +185,10 @@ async function onTaskProcessEnd(event: vscode.TaskProcessEndEvent) {
"the instrumentation filters are set correctly.",
);
} else {
// Show the coverage date
await showLcovCoverage(
description,
workspaceInfo.bazelWorkspacePath,
covFileStr,
);
// The `bazel coverage` runs the build/test/coverage in sandboxes with
// the similar/same layout of execution root, thus using it as the base
// for mapping the source files.
await showLcovCoverage(description, executionRoot, covFileStr);
}
} catch (e: any) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Expand Down
4 changes: 4 additions & 0 deletions src/test-explorer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export function activateTesting(): vscode.Disposable[] {

/**
* Display coverage information from a `.lcov` file.
*
* @param description The heading message for test (coverage) run.
* @param baseFolder The source file entries are relative paths to baseFolder.
* @param lcov The lcov report data in string.
*/
export async function showLcovCoverage(
description: string,
Expand Down
32 changes: 31 additions & 1 deletion src/test-explorer/lcov_parser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as vscode from "vscode";
import * as fs from "fs/promises";
import * as path from "path";
import * as child_process from "child_process";
import * as which from "which";
Expand Down Expand Up @@ -128,6 +129,32 @@ async function demangleNameUsingFilter(
return unmangled;
}

async function resolveSourceFilePath(
baseFolder: string,
sfPath: string,
): Promise<string> {
// Ignore and keep the not existing paths for matching in later
// phases.
const resolvedSfPath = path.resolve(baseFolder, sfPath);
// Path could be in pattern `external/<local_repository name>/...`,
// Try resolve the symlink for <exec root>/external/<local_repository name>,
// so that the SF path could be patched into `<real>/<path>/<to>/<repo>/...`.
const externalRepoMatch = sfPath.match(/^external\/([^/]+)(\/.*)/);
if (externalRepoMatch) {
const repoName = externalRepoMatch[1];
const rest = externalRepoMatch[2];
try {
const repoPath = await fs.realpath(`${baseFolder}/external/${repoName}`);
const realSourcePath = `${repoPath}${rest}`;
await fs.stat(realSourcePath);
return realSourcePath;
} catch {
// Ignore invalid paths and fallback to original resolved one.
}
}
return resolvedSfPath;
}

/**
* Coverage data from a Bazel run.
*
Expand All @@ -154,6 +181,9 @@ export class BazelFileCoverage extends vscode.FileCoverage {

/**
* Parses the LCOV coverage info into VS Code's representation
*
* @param baseFolder The source file entries are relative paths to baseFolder.
* @param lcov The lcov report data in string.
*/
export async function parseLcov(
baseFolder: string,
Expand Down Expand Up @@ -203,7 +233,7 @@ export async function parseLcov(
if (info !== undefined) {
throw new Error(`Duplicated SF entry`);
}
const filename = path.resolve(baseFolder, value);
const filename = await resolveSourceFilePath(baseFolder, value);
if (!infosByFile.has(filename)) {
infosByFile.set(filename, new FileCoverageInfo());
}
Expand Down

0 comments on commit 14d576b

Please sign in to comment.