]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
build: scope gcov report to rsync's own source; add coverage-all
authorAndrew Tridgell <andrew@tridgell.net>
Sun, 24 May 2026 02:39:19 +0000 (12:39 +1000)
committerAndrew Tridgell <andrew@tridgell.net>
Sun, 24 May 2026 21:44:12 +0000 (07:44 +1000)
The coverage report counted bundled third-party code (zlib/, popt/, and the
PostgreSQL/ISC lib/ imports getaddrinfo/getpass/inet_ntop/inet_pton) that rsync
ships but does not own, muddying the percentages. Add a COVERAGE_EXCLUDE gcovr
filter (shared by all coverage targets) so the report reflects rsync's own code:
on the same data, lines 63.9%->65.5%, functions 81.4%->85.0%, branches
55.0%->56.5% (rsync's own md5/mdfour/wildmatch/etc. stay in the report).

Add 'make coverage-all': run the suite under pipe + --protocol=30 + --protocol=29
+ --use-tcp, accumulating into the shared .gcda (not cleared between runs), then
one merged scoped report -- covers the daemon/TCP and protocol-compat paths a
single pipe run misses (lines 67.6%, functions 87.6%, branches 58.6%). Also add
'make coverage-fallback' for a separate --disable-openat2 build (different .gcno,
so it can't merge with the openat2 report). CI is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Makefile.in

index 9e9b9a82e6e51908bf4927135185cffd48013057..bde2c5897127ae55547255d21e982bc594292705 100644 (file)
@@ -281,7 +281,7 @@ clean: cleantests
                git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
                *.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
        rm -f *.gcno *.gcda lib/*.gcno lib/*.gcda zlib/*.gcno zlib/*.gcda popt/*.gcno popt/*.gcda
-       rm -rf coverage coverage-tcp
+       rm -rf coverage coverage-tcp coverage-all coverage-fallback
 
 .PHONY: cleantests
 cleantests:
@@ -342,6 +342,15 @@ COVERAGE_J = $(CHECK_J)
 COVERAGE_DIR = coverage
 COVERAGE_RUNFLAGS =
 
+# Bundled third-party code that rsync ships but does not own; excluded from the
+# coverage report so the percentages reflect rsync's own source. zlib/ and popt/
+# are wholly vendored; the named lib/ files are PostgreSQL (getaddrinfo) and ISC
+# (inet_ntop/inet_pton) / standalone (getpass) imports. The other lib/*.c
+# (md5, mdfour, wildmatch, permstring, pool_alloc, snprintf, sysacls, sysxattrs,
+# compat) are rsync's own and stay in the report.
+COVERAGE_EXCLUDE = -e '(^|/)zlib/' -e '(^|/)popt/' \
+       -e '(^|/)lib/(getaddrinfo|getpass|inet_ntop|inet_pton)\.'
+
 .PHONY: check
 check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
        $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J)
@@ -369,7 +378,7 @@ coverage: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
        find . -name '*.gcda' -delete
        @rc=0; $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(COVERAGE_J) $(COVERAGE_RUNFLAGS) || rc=$$?; \
          rm -rf $(COVERAGE_DIR) && mkdir -p $(COVERAGE_DIR); \
-         gcovr --root $(srcdir) --decisions --print-summary \
+         gcovr --root $(srcdir) $(COVERAGE_EXCLUDE) --decisions --print-summary \
              --html-details -o $(COVERAGE_DIR)/index.html . || exit $$?; \
          echo "Coverage report written to $(COVERAGE_DIR)/index.html"; \
          if test $$rc != 0; then \
@@ -383,6 +392,40 @@ coverage: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
 coverage-tcp:
        $(MAKE) coverage COVERAGE_RUNFLAGS=--use-tcp COVERAGE_DIR=coverage-tcp
 
+# Comprehensive single report: run the suite under several configurations,
+# accumulating into the shared .gcda counters (NOT cleared between runs), then
+# emit one merged, rsync-scoped report. Covers the default (pipe) transport, the
+# protocol-29/30 compat branches, and the real-TCP daemon path (which also runs
+# the require_tcp-only tests). Run under sudo to additionally cover root-only
+# paths (devices, chown, use-chroot, protected-regular). Local target -- CI uses
+# the plain `coverage`/`coverage-tcp` targets.
+.PHONY: coverage-all
+coverage-all: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
+       @case '$(CFLAGS)' in *--coverage*) ;; \
+         *) echo "*** not a coverage build; reconfigure with --enable-coverage"; exit 1 ;; esac
+       @command -v gcovr >/dev/null 2>&1 || { echo "*** gcovr not found (pip install gcovr)"; exit 1; }
+       find . -name '*.gcda' -delete
+       @rc=0; \
+         for cfg in '' '--protocol=30' '--protocol=29' '--use-tcp'; do \
+           echo "===== coverage-all: runtests.py $$cfg ====="; \
+           $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(COVERAGE_J) $$cfg || rc=$$?; \
+         done; \
+         rm -rf coverage-all && mkdir -p coverage-all; \
+         gcovr --root $(srcdir) $(COVERAGE_EXCLUDE) --decisions --print-summary \
+             --html-details -o coverage-all/index.html . || exit $$?; \
+         echo "Merged coverage report written to coverage-all/index.html"; \
+         if test $$rc != 0; then \
+           echo "*** some suite runs FAILED (status $$rc) -- report still written above"; \
+         fi; \
+         exit $$rc
+
+# Coverage for the portable (non-openat2) resolver tier. Requires a SEPARATE
+# build configured with --enable-coverage --disable-openat2: its .gcno differ
+# from the openat2 build, so this report cannot be merged with the others.
+.PHONY: coverage-fallback
+coverage-fallback:
+       $(MAKE) coverage COVERAGE_DIR=coverage-fallback
+
 wildtest.o: wildtest.c t_stub.o lib/wildmatch.c rsync.h config.h
 wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)