]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
build-and-test-all: Fix code coverage generation from meson dist tarball
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 29 Sep 2025 13:04:39 +0000 (15:04 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 30 Sep 2025 10:22:38 +0000 (12:22 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
.github/scripts/normalize_paths_in_coverage.py
.github/workflows/build-and-test-all.yml
tasks.py

index 78475acc6e934ecbf256b4c40d54c3ab84a6609e..95092c1e0805039f3d45eb2be52b7be365069a7d 100755 (executable)
@@ -2,15 +2,68 @@
 
 import os
 import sys
+from pathlib import Path
 
-if __name__ == '__main__':
+DEBUG = False
+
+def debug_print(string):
+    if DEBUG:
+        print(string)
+
+def get_relative_to_product_source_dir(product, target):
+    if product == 'auth':
+        # authoritative or tool
+        return target
+    if product == 'recursor':
+        return os.path.join('pdns', 'recursordist', target)
+    if product == 'dnsdist':
+        return os.path.join('pdns', 'dnsdistdist', target)
+    return None
+
+def remove_meson_dist_path(product, target):
+    # target looks like this: /tmp/dnsdist-meson-dist-build/meson-dist/dnsdist-0.0.0-git1/xsk.hh
+    path = Path(target)
+    index = path.parts.index('meson-dist')
+    # skip up to meson-dist and the directory below that,
+    # so we now have: xsk.hh
+    relevant = str(path.relative_to(path.parents[len(path.parts) - (index + 3)]))
+    return get_relative_to_product_source_dir(product, relevant)
+
+
+def remove_dist_dir_path(repositoryRoot, version, target):
+    # get rid of the distdir path, to get file paths as they are in the repository
+    # if we are building from meson, it might look like this:
+    # /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-0.0.0-git1/config.h
+    if f'pdns-{version}' in target:
+        # authoritative or tool
+        authPath = os.path.join(repositoryRoot, f'pdns-{version}')
+        relativeToAuth = os.path.relpath(target, authPath)
+        target = get_relative_to_product_source_dir('auth', relativeToAuth)
+        return target
+    if f'pdns-recursor-{version}' in target:
+        recPath = os.path.join(repositoryRoot, 'pdns', 'recursordist', f'pdns-recursor-{version}')
+        relativeToRec = os.path.relpath(target, recPath)
+        return get_relative_to_product_source_dir('recursor', relativeToRec)
+    if f'dnsdist-{version}' in target:
+        distPath = os.path.join(repositoryRoot, 'pdns', 'dnsdistdist', f'dnsdist-{version}')
+        relativeToDist = os.path.relpath(target, distPath)
+        target = get_relative_to_product_source_dir('dnsdist', relativeToDist)
+        return target
+
+    # let's assume we already have a full path to the repository, like
+    # /__w/pdns/pdns/pdns/auth-catalogzone.hh
+    distPath = os.path.join(repositoryRoot)
+    relativeToDist = os.path.relpath(target, distPath)
+    return relativeToDist
+
+def process():
     repositoryRoot = os.path.realpath(sys.argv[1])
-    version = sys.argv[2]
-    inputFile = sys.argv[3]
-    outputFile = sys.argv[4]
-    fromDistDir = sys.argv[5]
-    with open(inputFile, mode='r') as inputFilePtr:
-        with open(outputFile, mode='w') as outputFilePtr:
+    product = sys.argv[2]
+    version = sys.argv[3]
+    inputFile = sys.argv[4]
+    outputFile = sys.argv[5]
+    with open(inputFile, mode='r', encoding='utf-8') as inputFilePtr:
+        with open(outputFile, mode='w', encoding='utf-8') as outputFilePtr:
             for line in inputFilePtr:
                 if not line.startswith('SF:'):
                     outputFilePtr.write(line)
@@ -24,31 +77,30 @@ if __name__ == '__main__':
                 source_file = parts[1].rstrip()
                 # get rid of symbolic links
                 target = os.path.realpath(source_file)
+                debug_print(f'- Got source_file={source_file}, target={target}')
+
+                if '/meson-dist/' in target:
+                    # this is a file that comes from a meson dist tarball
+                    target = remove_meson_dist_path(product, target)
+                    debug_print(f'meson-dist -> target={target}')
+                else:
+                    target = remove_dist_dir_path(repositoryRoot, version, target)
+                    debug_print(f'dist dir -> target={target}')
 
-                # get rid of the distdir path, to get file paths as they are in the repository
-                if f'pdns-{version}' in target:
-                    # authoritative or tool
-                    authPath = os.path.join(repositoryRoot, f'pdns-{version}')
-                    relativeToAuth = os.path.relpath(target, authPath)
-                    target = relativeToAuth
-                elif f'pdns-recursor-{version}' in target:
-                    recPath = os.path.join(repositoryRoot, 'pdns', 'recursordist', f'pdns-recursor-{version}')
-                    relativeToRec = os.path.relpath(target, recPath)
-                    target = os.path.join('pdns', 'recursordist', relativeToRec)
-                elif f'dnsdist-{version}' in target:
-                    distPath = os.path.join(repositoryRoot, 'pdns', 'dnsdistdist', f'dnsdist-{version}')
-                    relativeToDist = os.path.relpath(target, distPath)
-                    target = os.path.join('pdns', 'dnsdistdist', relativeToDist)
-                elif fromDistDir == '1':
-                    print(f'Ignoring {target} that we could not map to a distdir', file=sys.stderr)
+                if target is None:
                     continue
 
                 # we need to properly map symbolic links
                 fullPath = os.path.join(repositoryRoot, target)
+                debug_print(f'fullPath is {fullPath}')
                 if os.path.islink(fullPath):
                     # get the link target
                     realPath = os.path.realpath(fullPath)
                     # and make it relative again
                     target = os.path.relpath(realPath, repositoryRoot)
 
+                debug_print(f'=> final target is {target}')
                 outputFilePtr.write(f"SF:{target}\n")
+
+if __name__ == '__main__':
+    process()
index 4bf9604ee7fb35f012b27b5e11ac0df7eccb605d..aefdf8003612ef49ce19cea0689c389ef401c0d2 100644 (file)
@@ -111,7 +111,7 @@ jobs:
       - run: ${{ env.INV_CMD }} ci-auth-run-unit-tests ${{ matrix.builder == 'meson' && '--meson' || '' }}
         env:
           PDNS_BUILD_PATH: ../pdns-${{ env.BUILDER_VERSION }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info ./pdns-auth-testrunner $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info ./pdns-auth-testrunner 'auth' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.builder == 'meson' }}
       - name: Coveralls Parallel auth unit
         if: ${{ env.COVERAGE == 'yes' && matrix.builder == 'meson' }}
@@ -199,7 +199,7 @@ jobs:
         working-directory: ./pdns/recursordist/
       - run: ${{ env.INV_CMD }} ci-rec-build ${{ matrix.builder == 'meson' && '--meson' || '' }}
       - run: ${{ env.INV_CMD }} ci-rec-run-unit-tests ${{ matrix.builder == 'meson' && '--meson' || '' }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info ./testrunner $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info ./testrunner 'recursor' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' && matrix.builder == 'meson' }}
       - name: Coveralls Parallel rec unit
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' && matrix.builder == 'meson' }}
@@ -298,7 +298,7 @@ jobs:
         if: ${{ matrix.builder == 'autotools' }}
       - run: ${{ env.INV_CMD }} ci-dnsdist-make-bear ${{ matrix.builder }}
       - run: ${{ env.INV_CMD }} ci-dnsdist-run-unit-tests ${{ matrix.builder }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info ./testrunner $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info ./testrunner 'dnsdist' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' && matrix.builder == 'meson'}}
       - name: Coveralls Parallel dnsdist unit
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' && matrix.builder == 'meson' }}
@@ -384,7 +384,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-auth-test-deps -b ${{ matrix.backend }}
       - run: ${{ env.INV_CMD }} test-api auth -b ${{ matrix.backend }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/sbin/pdns-auth $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/sbin/pdns-auth 'auth' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' }}
       - name: Coveralls Parallel auth API ${{ matrix.backend }}
         if: ${{ env.COVERAGE == 'yes' }}
@@ -516,7 +516,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-auth-test-deps -b ${{ matrix.backend }}
       - run: ${{ env.INV_CMD }} test-auth-backend -b ${{ matrix.backend }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/sbin/pdns-auth $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/sbin/pdns-auth 'auth' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' }}
       - name: Coveralls Parallel auth backend ${{ matrix.backend }}
         if: ${{ env.COVERAGE == 'yes' }}
@@ -559,7 +559,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-auth-test-deps
       - run: ${{ env.INV_CMD }} test-ixfrdist
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/bin/ixfrdist $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-auth/bin/ixfrdist 'auth' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' }}
       - name: Coveralls Parallel ixfrdist
         if: ${{ env.COVERAGE == 'yes' }}
@@ -611,7 +611,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-rec-test-deps
       - run: ${{ env.INV_CMD }} test-api recursor
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor 'recursor' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
       - name: Coveralls Parallel recursor API
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
@@ -665,7 +665,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-rec-test-deps
       - run: ${{ env.INV_CMD }} test-regression-recursor
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor 'recursor' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
       - name: Coveralls Parallel recursor regression
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
@@ -718,7 +718,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-rec-bulk-deps
       - run: ${{ env.INV_CMD }} test-bulk-recursor 100 ${{ matrix.threads }} ${{ matrix.mthreads }} ${{ matrix.shards }} ${{ matrix.IPv6 }}
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor 'recursor' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
       - name: Coveralls Parallel recursor bulk
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
@@ -769,7 +769,7 @@ jobs:
           ASAN_OPTIONS: detect_leaks=0
           TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ github.workspace }}/pdns/recursordist/recursor-tsan.supp"
       #  Disabled, it gives us: "/bin/bash: line 1: llvm-profdata-13: command not found" due to mismatch between deb and ubuntu versions
-      #- run: . ${{ github.workspace }}/.venv/bin/activate && inv generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE
+      #- run: . ${{ github.workspace }}/.venv/bin/activate && inv generate-coverage-info 'recursor' /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE
       #  if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
       #- name: Coveralls Parallel recursor bulk
       #  if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
@@ -825,7 +825,7 @@ jobs:
       - run: ${{ env.INV_CMD }} install-clang-runtime
       - run: ${{ env.INV_CMD }} install-dnsdist-test-deps $([ "$(. /etc/os-release && echo $VERSION_CODENAME)" = "bullseye" ] && echo "--skipXDP=True")
       - run: ${{ env.INV_CMD }} test-dnsdist $([ "$(. /etc/os-release && echo $VERSION_CODENAME)" = "bullseye" ] && echo "--skipXDP=True")
-      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/dnsdist/bin/dnsdist $GITHUB_WORKSPACE
+      - run: ${{ env.INV_CMD }} generate-coverage-info /opt/dnsdist/bin/dnsdist 'dnsdist' $GITHUB_WORKSPACE
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
       - name: Coveralls Parallel dnsdist regression
         if: ${{ env.COVERAGE == 'yes' && matrix.sanitizers != 'tsan' }}
index 34df1980d2d7a3fe3353fcfde327b84d8628e777..719240f206db60b9d24aef88fb588fc4998b825a 100644 (file)
--- a/tasks.py
+++ b/tasks.py
@@ -232,12 +232,12 @@ def install_coverage_deps(c):
         c.sudo(f'apt-get install -y --no-install-recommends llvm-{clang_version}')
 
 @task
-def generate_coverage_info(c, binary, outputDir):
+def generate_coverage_info(c, binary, product, outputDir):
     if is_coverage_enabled():
         version = os.getenv('BUILDER_VERSION')
         c.run(f'llvm-profdata-{clang_version} merge -sparse -o {outputDir}/temp.profdata /tmp/code-*.profraw')
         c.run(f'llvm-cov-{clang_version} export --format=lcov --ignore-filename-regex=\'^/usr/\' -instr-profile={outputDir}/temp.profdata -object {binary} > {outputDir}/coverage.lcov')
-        c.run(f'{outputDir}/.github/scripts/normalize_paths_in_coverage.py {outputDir} {version} {outputDir}/coverage.lcov {outputDir}/normalized_coverage.lcov 0')
+        c.run(f'{outputDir}/.github/scripts/normalize_paths_in_coverage.py {outputDir} {product} {version} {outputDir}/coverage.lcov {outputDir}/normalized_coverage.lcov 0')
         c.run(f'mv {outputDir}/normalized_coverage.lcov {outputDir}/coverage.lcov')
 
 def setup_authbind(c):