Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 84 additions & 28 deletions virttest/env_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from avocado.core import exceptions
from avocado.utils import archive
from avocado.utils import cpu as cpu_utils
from avocado.utils import crypto
from avocado.utils import crypto, path
from avocado.utils import process as a_process
from six.moves import xrange

Expand All @@ -43,7 +43,11 @@
from virttest._wrappers import lazy_import
from virttest.test_setup.aexpect import KillTailThreads
from virttest.test_setup.core import SetupManager
from virttest.test_setup.gcov import ResetQemuGCov
from virttest.test_setup.gcov import (
ResetGCov,
collect_gcovr_coverage,
collect_lcov_coverage,
)
from virttest.test_setup.kernel import KSMSetup, ReloadKVMModules
from virttest.test_setup.libvirt_setup import LibvirtdDebugLogConfig
from virttest.test_setup.memory import HugePagesSetup, TransparentHugePagesSetup
Expand Down Expand Up @@ -1000,7 +1004,7 @@ def preprocess(test, params, env):
# and last running during pre/postprocess. That way vms will be actually
# off to ensure data is written to disk.
_setup_manager.register(ProcessVMOff)
_setup_manager.register(ResetQemuGCov)
_setup_manager.register(ResetGCov)
_setup_manager.register(VerifyHostDMesg)
_setup_manager.register(SwitchSMTOff)
_setup_manager.register(CheckRunningAsRoot)
Expand Down Expand Up @@ -1319,32 +1323,84 @@ def postprocess(test, params, env):

# Collect code coverage report for qemu if enabled
if params.get("gcov_qemu", "no") == "yes":
qemu_builddir = os.path.join(test.bindir, "build", "qemu")
if os.path.isdir(qemu_builddir) and utils_package.package_install("gcovr"):
gcov_qemu_dir = utils_misc.get_path(test.debugdir, "gcov_qemu")
os.makedirs(gcov_qemu_dir)
os.chdir(qemu_builddir)
collect_cmd_opts = params.get("gcov_qemu_collect_cmd_opts", "--html")
online_count = (
cpu_utils.online_count()
if hasattr(cpu_utils, "online_count")
else cpu_utils.online_cpus_count()
)
collect_cmd = "gcovr -j %s -o %s -s %s ." % (
online_count,
os.path.join(gcov_qemu_dir, "gcov.html"),
collect_cmd_opts,
)
a_process.system(collect_cmd, shell=True)
if params.get("gcov_qemu_compress", "no") == "yes":
os.chdir(test.debugdir)
archive.compress("gcov_qemu.tar.gz", gcov_qemu_dir)
shutil.rmtree(gcov_qemu_dir, ignore_errors=True)
qemu_builddir = params.get(
"gcov_qemu_builddir", os.path.join(test.bindir, "build", "qemu")
)
gcov_format = params.get("gcov_qemu_format", "html")
test_name = params.get("shortname", getattr(test, "name", "unknown_test"))
if hasattr(test_name, "uid"):
test_name = str(test_name.uid)

if gcov_format == "lcov":
try:
path.find_command("lcov")
except path.CmdNotFoundError:
LOG.warning("lcov package not installed, cannot collect QEMU coverage")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For lcov , we needs to use https://github.com/LuyaoHuang/lcov --rhel version since it fix the issue that test case can not contain special letters. So here we needs to consider this point

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's right. I think it's better to put lcov installation part in ci, similar place with libvirt/qemu coverage package installation, so I just checked lcov command here.

else:
gcov_qemu_dir = utils_misc.get_path(test.debugdir, "gcov_qemu")
collect_lcov_coverage(qemu_builddir, gcov_qemu_dir, test_name, "qemu")

if params.get("gcov_qemu_compress", "no") == "yes":
os.chdir(test.debugdir)
archive.compress("gcov_qemu.tar.gz", gcov_qemu_dir)
shutil.rmtree(gcov_qemu_dir, ignore_errors=True)
else:
LOG.warning(
"Check either qemu build directory availablilty"
" or install gcovr package for qemu coverage report"
)
if utils_package.package_install("gcovr"):
gcov_qemu_dir = utils_misc.get_path(test.debugdir, "gcov_qemu")
collect_cmd_opts = params.get("gcov_qemu_collect_cmd_opts", "--html")
collect_gcovr_coverage(
qemu_builddir, gcov_qemu_dir, "qemu", collect_cmd_opts
)

if params.get("gcov_qemu_compress", "no") == "yes":
os.chdir(test.debugdir)
archive.compress("gcov_qemu.tar.gz", gcov_qemu_dir)
shutil.rmtree(gcov_qemu_dir, ignore_errors=True)
else:
LOG.warning("gcovr package not installed, cannot collect QEMU coverage")
Comment thread
YongxueHong marked this conversation as resolved.

# Collect code coverage report for libvirt if enabled
if params.get("gcov_libvirt", "no") == "yes":
libvirt_builddir = params.get("gcov_libvirt_builddir", "/var/tmp/libvirt")
gcov_format = params.get("gcov_libvirt_format", "html")
test_name = params.get("shortname", getattr(test, "name", "unknown_test"))
if hasattr(test_name, "uid"):
test_name = str(test_name.uid)

if gcov_format == "lcov":
try:
path.find_command("lcov")
except path.CmdNotFoundError:
LOG.warning(
"lcov package not installed, cannot collect libvirt coverage"
)
else:
gcov_libvirt_dir = utils_misc.get_path(test.debugdir, "gcov_libvirt")
collect_lcov_coverage(
libvirt_builddir, gcov_libvirt_dir, test_name, "libvirt"
)

if params.get("gcov_libvirt_compress", "no") == "yes":
os.chdir(test.debugdir)
archive.compress("gcov_libvirt.tar.gz", gcov_libvirt_dir)
shutil.rmtree(gcov_libvirt_dir, ignore_errors=True)
else:
if utils_package.package_install("gcovr"):
gcov_libvirt_dir = utils_misc.get_path(test.debugdir, "gcov_libvirt")
collect_cmd_opts = params.get("gcov_libvirt_collect_cmd_opts", "--html")
collect_gcovr_coverage(
libvirt_builddir, gcov_libvirt_dir, "libvirt", collect_cmd_opts
)

if params.get("gcov_libvirt_compress", "no") == "yes":
os.chdir(test.debugdir)
archive.compress("gcov_libvirt.tar.gz", gcov_libvirt_dir)
shutil.rmtree(gcov_libvirt_dir, ignore_errors=True)
else:
LOG.warning(
"gcovr package not installed, cannot collect libvirt coverage"
)

# Postprocess all VMs and images
try:
process(
Expand Down
31 changes: 31 additions & 0 deletions virttest/shared/cfg/base.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -904,13 +904,18 @@ sysprep_options = "--operations machine-id"

# Enable Code Coverage report
# prerequisite: qemu build test is run with --enable-gcov
# or libvirt is built with --enable-coverage
# configure option and preserve_srcdir = yes
# and qemu build dir is available
# Enable/disable gcov for qemu, default: disable
gcov_qemu = no
# Enable/disable to reset the code coverage report
# generated/collected by previous test
gcov_qemu_reset = yes
# Coverage output format: lcov (generates .info tracefiles) or html (generates HTML reports)
# For per-test lcov tracefiles with --test-name, use "lcov"
# For aggregated HTML reports with gcovr, use "html"
gcov_qemu_format = html
# Additional command options for gcovr
# E:g:- "--html-details --html --exclude-directories=capstone"
# above options will be required to collect detailed html
Expand All @@ -920,6 +925,32 @@ gcov_qemu_reset = yes
gcov_qemu_collect_cmd_opts = "--html"
# Enable/disable to compress code coverage report
gcov_qemu_compress = no
# Qemu build directory where .gcda files are generated
gcov_qemu_builddir = /var/tmp/qemu
# Fail test if coverage reset fails
gcov_qemu_reset_strict = yes

# Libvirt code coverage configuration
# Enable/disable gcov for libvirt, default: disable
gcov_libvirt = no
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether collect libvirt or qemu code coverage depends on parameters dynamically passed in by Kar, therefore needs to confirm with Kar members whether this parameter value can be override by parameters passed in by Kar

Copy link
Copy Markdown
Contributor Author

@Yingshun Yingshun Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kar and avocado can set different variants values in command line. Please check the test results in description.

# Enable/disable to reset the libvirt coverage report
# generated/collected by previous test
gcov_libvirt_reset = yes
# Coverage output format: lcov or html
gcov_libvirt_format = lcov
# Libvirt build directory where .gcda files are generated
gcov_libvirt_builddir = /var/tmp/libvirt
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we use libvirt virtcov packages, the value for this needs to be /builddir/build/BUILD

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need to get the proper path after the package installation, so I just put a fake dir here. Users need to specify the correct one during their testings.

# Additional command options for gcovr when format is html
# E.g.: "--html-details --html --exclude-unreachable-branches"
gcov_libvirt_collect_cmd_opts = "--html"
# Enable/disable to compress libvirt code coverage report
gcov_libvirt_compress = no
# Libvirt daemon to restart after coverage reset (if needed)
gcov_libvirt_daemon = libvirtd
# Enable/disable restarting libvirt daemon after coverage reset
gcov_libvirt_restart_daemon = no
# Fail test if coverage reset fails
gcov_libvirt_reset_strict = yes

Linux:
# param for installing stress tool from repo
Expand Down
Loading
Loading