From de6cbac3c4e44de797bc2a4755fb765cf5a49f55 Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Tue, 11 May 2021 09:56:48 -0600 Subject: tests: improve code coverage support Fix the exclusion path for lcov; it should exclude the directory with source code, not object files. Use the COV environment variable to * control whether we build for coverage or not * select the output directory Add a separate target for generating the report, so we can get a report for all of the tests together or just a single test. Add documentation. Signed-off-by: Paul Fagerburg Change-Id: I2bd2bfdedfab291aabeaa968c10b17e9b61c9c0a Reviewed-on: https://review.coreboot.org/c/coreboot/+/54072 Tested-by: build bot (Jenkins) Reviewed-by: Jakub Czapiga --- tests/Makefile.inc | 56 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/Makefile.inc b/tests/Makefile.inc index cd25e0f80998..6cf92fa999c8 100644 --- a/tests/Makefile.inc +++ b/tests/Makefile.inc @@ -1,9 +1,18 @@ # SPDX-License-Identifier: GPL-2.0-only testsrc = $(top)/tests + +# Place the build output in one of two places depending on COV, so that code +# built with code coverage never mixes with code built without code coverage. +ifeq ($(COV),1) +testobj = $(obj)/coverage +else testobj = $(obj)/tests +endif + cmockasrc = 3rdparty/cmocka cmockaobj = $(objutil)/cmocka +coverage_dir = coverage_reports CMOCKA_LIB := $(cmockaobj)/src/libcmocka.so @@ -51,6 +60,12 @@ TEST_LDFLAGS += -Wl,--gc-sections TEST_CFLAGS += -fno-pie -fno-pic TEST_LDFLAGS += -no-pie +# Enable code coverage if COV=1 +ifeq ($(COV),1) +TEST_CFLAGS += --coverage +TEST_LDFLAGS += --coverage +endif + # Extra attributes for unit tests, declared per test attributes:= srcs cflags config mocks stage @@ -99,7 +114,7 @@ $$($(1)-config-file): $(TEST_KCONFIG_AUTOHEADER) $($(1)-objs): TEST_CFLAGS += -I$$(dir $$($(1)-config-file)) \ -D__$$(shell echo $$($(1)-stage) | tr '[:lower:]' '[:upper:]')__ -$($(1)-objs): $(obj)/$(1)/%.o: $$$$*.c $$($(1)-config-file) +$($(1)-objs): $(testobj)/$(1)/%.o: $$$$*.c $$($(1)-config-file) mkdir -p $$(dir $$@) $(HOSTCC) $(HOSTCFLAGS) $$(TEST_CFLAGS) $($(1)-cflags) -MMD \ -MT $$@ -c $$< -o $$@ @@ -111,10 +126,10 @@ $($(1)-bin): $($(1)-objs) $(CMOCKA_LIB) endef $(foreach test, $(alltests), \ - $(eval $(test)-objs:=$(addprefix $(obj)/$(test)/, \ + $(eval $(test)-objs:=$(addprefix $(testobj)/$(test)/, \ $(patsubst %.c,%.o,$($(test)-srcs))))) $(foreach test, $(alltests), \ - $(eval $(test)-bin:=$(obj)/$(test)/run)) + $(eval $(test)-bin:=$(testobj)/$(test)/run)) $(foreach test, $(alltests), \ $(eval $(call TEST_CC_template,$(test)))) @@ -168,15 +183,31 @@ $(alltests): $$($$(@)-bin) rm -f $(testobj)/junit-$(subst /,_,$^).xml $(testobj)/$(subst /,_,$^).failed -./$^ || echo failed > $(testobj)/$(subst /,_,$^).failed -.PHONY: coverage-unit-tests +# Build a code coverage report by collecting all the gcov files into a single +# report. If COV is not set, this might be a user error, and they're trying +# to generate a coverage report without first having built and run the code +# with code coverage. So instead of silently correcting it by adding COV=1, +# let's flag it to the user so they can be sure they're doing the thing they +# want to do. -coverage-unit-tests: TEST_CFLAGS += --coverage -coverage-unit-tests: TEST_LDFLAGS += --coverage -coverage-unit-tests: clean-unit-tests unit-tests - lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '*/$(testobj)/*' - genhtml -q -o build/tests/coverage_rpt -t "coreboot unit tests" \ +.PHONY: coverage-report clean-coverage-report + +ifeq ($(COV),1) +coverage-report: + lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' + genhtml -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" \ -s $(testobj)/tests.info +clean-coverage-report: + rm -Rf $(testobj)/$(coverage_dir) +else +coverage-report: + COV=1 V=$(V) $(MAKE) coverage-report + +clean-coverage-report: + COV=1 V=$(V) $(MAKE) clean-coverage-report +endif + unit-tests: build-unit-tests run-unit-tests build-unit-tests: $(test-bins) @@ -195,7 +226,7 @@ run-unit-tests: $(alltests) fi $(addprefix clean-,$(alltests)): clean-%: - rm -rf $(obj)/$* + rm -rf $(testobj)/$* clean-unit-tests: rm -rf $(testobj) @@ -208,11 +239,12 @@ list-unit-tests: help-unit-tests help:: @echo '*** coreboot unit-tests targets ***' + @echo ' Use "COV=1 make [target]" to enable code coverage for unit tests' @echo ' unit-tests - Run all unit-tests from tests/' @echo ' clean-unit-tests - Remove unit-tests build artifacts' @echo ' list-unit-tests - List all unit-tests' @echo ' - Build and run single unit-test' @echo ' clean- - Remove single unit-test build artifacts' - @echo ' coverage-unit-tests - Build unit tests for code coverage and' - @echo ' generate a code coverage report' + @echo ' coverage-report - Generate a code coverage report' + @echo ' clean-coverage-report - Remove the code coverage report' @echo -- cgit v1.2.3