mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 12:09:31 +00:00
tools/run_tests: Add --cov option
The option will generate an lcov file in the standard name lcov.info and print a coverage report after running tests. The lcov.info file is understood by many IDE plugins, e.g. "Coverage Gutters" for vscode. BUG=b:239255082 TEST=./tools/run_tests --cov Change-Id: I475c62ada73f100a984ad863e511083c69807aff Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3840956 Commit-Queue: Dennis Kempin <denniskempin@google.com> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: Dennis Kempin <denniskempin@google.com>
This commit is contained in:
parent
3b60f0ca33
commit
1e16dc6a8f
1 changed files with 35 additions and 14 deletions
|
@ -5,7 +5,6 @@
|
||||||
import argparse
|
import argparse
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import functools
|
import functools
|
||||||
import itertools
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
@ -13,11 +12,12 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Iterable, List, NamedTuple, Optional
|
from typing import Dict, Iterable, List, NamedTuple
|
||||||
|
|
||||||
from . import test_target, testvm
|
from . import test_target, testvm
|
||||||
|
from .common import all_tracked_files
|
||||||
|
from .test_config import BUILD_FEATURES, CRATE_OPTIONS, TestOption
|
||||||
from .test_target import TestTarget, Triple
|
from .test_target import TestTarget, Triple
|
||||||
from .test_config import CRATE_OPTIONS, TestOption, BUILD_FEATURES
|
|
||||||
|
|
||||||
USAGE = """\
|
USAGE = """\
|
||||||
Runs tests for crosvm locally, in a vm or on a remote device.
|
Runs tests for crosvm locally, in a vm or on a remote device.
|
||||||
|
@ -420,25 +420,42 @@ def find_crosvm_binary(executables: List[Executable]):
|
||||||
raise Exception("Cannot find crosvm executable")
|
raise Exception("Cannot find crosvm executable")
|
||||||
|
|
||||||
|
|
||||||
def generate_lcov(results: List[ExecutableResults], lcov_file: str):
|
def generate_lcov(
|
||||||
|
results: List[ExecutableResults], crosvm_binary: Path, lcov_file: str, print_report: bool
|
||||||
|
):
|
||||||
print("Merging profiles")
|
print("Merging profiles")
|
||||||
merged_file = testvm.cargo_target_dir() / "merged.profraw"
|
merged_file = testvm.cargo_target_dir() / "merged.profraw"
|
||||||
profiles = [str(p) for r in results if r.profile_files for p in r.profile_files]
|
profiles = [str(p) for r in results if r.profile_files for p in r.profile_files]
|
||||||
subprocess.check_call(["rust-profdata", "merge", "-sparse", *profiles, "-o", str(merged_file)])
|
subprocess.check_call(["rust-profdata", "merge", "-sparse", *profiles, "-o", str(merged_file)])
|
||||||
|
|
||||||
print("Exporting report")
|
print("Generating lcov")
|
||||||
|
all_rust_src = [f for f in all_tracked_files() if f.suffix == ".rs"]
|
||||||
lcov_data = subprocess.check_output(
|
lcov_data = subprocess.check_output(
|
||||||
[
|
[
|
||||||
"rust-cov",
|
"rust-cov",
|
||||||
"export",
|
"export",
|
||||||
"--format=lcov",
|
"--format=lcov",
|
||||||
"--ignore-filename-regex='/registry/'",
|
|
||||||
f"--instr-profile={merged_file}",
|
f"--instr-profile={merged_file}",
|
||||||
*(f"--object={r.binary_file}" for r in results),
|
*(f"--object={r.binary_file}" for r in results),
|
||||||
|
str(crosvm_binary),
|
||||||
|
*all_rust_src,
|
||||||
],
|
],
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
open(lcov_file, "w").write(lcov_data)
|
open(lcov_file, "w").write(lcov_data)
|
||||||
|
if print_report:
|
||||||
|
subprocess.check_call(
|
||||||
|
[
|
||||||
|
"rust-cov",
|
||||||
|
"report",
|
||||||
|
"-show-region-summary=False",
|
||||||
|
"-show-branch-summary=False",
|
||||||
|
f"-instr-profile={merged_file}",
|
||||||
|
*(f"-object={r.binary_file}" for r in results),
|
||||||
|
str(crosvm_binary),
|
||||||
|
*all_rust_src,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -473,6 +490,11 @@ def main():
|
||||||
"--build-only",
|
"--build-only",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--cov",
|
||||||
|
action="store_true",
|
||||||
|
help="Generates lcov.info and prints coverage report.",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--generate-lcov",
|
"--generate-lcov",
|
||||||
help="Generate an lcov code coverage profile",
|
help="Generate an lcov code coverage profile",
|
||||||
|
@ -518,7 +540,9 @@ def main():
|
||||||
print()
|
print()
|
||||||
build_target = Triple.from_shorthand(args.arch)
|
build_target = Triple.from_shorthand(args.arch)
|
||||||
|
|
||||||
collect_coverage = args.generate_lcov
|
if args.cov:
|
||||||
|
args.generate_lcov = "lcov.info"
|
||||||
|
collect_coverage = bool(args.generate_lcov)
|
||||||
emulator_cmd = args.emulator.split(" ") if args.emulator else None
|
emulator_cmd = args.emulator.split(" ") if args.emulator else None
|
||||||
build_target = Triple.from_shorthand(args.build_target) if args.build_target else None
|
build_target = Triple.from_shorthand(args.build_target) if args.build_target else None
|
||||||
target = test_target.TestTarget(args.target, build_target, emulator_cmd)
|
target = test_target.TestTarget(args.target, build_target, emulator_cmd)
|
||||||
|
@ -537,11 +561,8 @@ def main():
|
||||||
|
|
||||||
# Upload dependencies plus the main crosvm binary for integration tests if the
|
# Upload dependencies plus the main crosvm binary for integration tests if the
|
||||||
# crosvm binary is not excluded from testing.
|
# crosvm binary is not excluded from testing.
|
||||||
extra_files = (
|
crosvm_binary = find_crosvm_binary(executables).binary_path
|
||||||
[find_crosvm_binary(executables).binary_path]
|
extra_files = [crosvm_binary] if not exclude_crosvm(target.build_triple) else []
|
||||||
if not exclude_crosvm(target.build_triple)
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
|
|
||||||
test_target.prepare_target(target, extra_files=extra_files)
|
test_target.prepare_target(target, extra_files=extra_files)
|
||||||
|
|
||||||
|
@ -556,8 +577,8 @@ def main():
|
||||||
print()
|
print()
|
||||||
print(f"Round {i+1}/{args.repeat}:")
|
print(f"Round {i+1}/{args.repeat}:")
|
||||||
results = [*execute_all(test_executables, target, args.retry + 1, collect_coverage)]
|
results = [*execute_all(test_executables, target, args.retry + 1, collect_coverage)]
|
||||||
if args.generate_lcov:
|
if args.generate_lcov and i == args.repeat - 1:
|
||||||
generate_lcov(results, args.generate_lcov)
|
generate_lcov(results, crosvm_binary, args.generate_lcov, args.cov)
|
||||||
all_results.extend(results)
|
all_results.extend(results)
|
||||||
random.shuffle(test_executables)
|
random.shuffle(test_executables)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue