[rocprofiler-compute] added ctest coverage and cdash submission (#366)
* added cdash automatic CI upload * added cdash automatic CI upload * tweaked wording * changed nightly to continuous * removed unnecessary dry-run arg * updated README.md * edited workflow description * update coverage * formatted cmakelists.txt * ruff formatting and update coverage
このコミットが含まれているのは:
@@ -0,0 +1,89 @@
|
||||
name: rocprofiler-compute CDash Coverage Upload
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- 'projects/rocprofiler-compute/coverage/coverage-latest.xml'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
coverage_file:
|
||||
description: 'Path to coverage XML file'
|
||||
required: false
|
||||
default: 'projects/rocprofiler-compute/coverage/coverage-latest.xml'
|
||||
|
||||
concurrency:
|
||||
group: rocprofiler-compute-cdash-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
upload-coverage:
|
||||
runs-on: ubuntu-latest
|
||||
name: Upload Coverage to CDash
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: projects/rocprofiler-compute
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: Check Coverage File Exists
|
||||
working-directory: projects/rocprofiler-compute
|
||||
run: |
|
||||
COVERAGE_FILE="${{ github.event.inputs.coverage_file || 'coverage/coverage-latest.xml' }}"
|
||||
if [[ "$COVERAGE_FILE" == projects/rocprofiler-compute/* ]]; then
|
||||
COVERAGE_FILE="${COVERAGE_FILE#projects/rocprofiler-compute/}"
|
||||
fi
|
||||
|
||||
if [ ! -f "$COVERAGE_FILE" ]; then
|
||||
echo "ERROR: Coverage file not found at $COVERAGE_FILE!"
|
||||
echo "Please run manual coverage generation"
|
||||
echo "Use: cd projects/rocprofiler-compute && ./utils/update_coverage.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COVERAGE_INFO=$(python3 -c "
|
||||
import xml.etree.ElementTree as ET
|
||||
try:
|
||||
tree = ET.parse('$COVERAGE_FILE')
|
||||
root = tree.getroot()
|
||||
line_rate = float(root.get('line-rate', 0)) * 100
|
||||
print(f'{line_rate:.1f}%')
|
||||
except Exception as e:
|
||||
print(f'Error parsing coverage: {e}')
|
||||
exit(1)
|
||||
")
|
||||
|
||||
echo "Line Coverage: $COVERAGE_INFO"
|
||||
echo "COVERAGE_INFO=$COVERAGE_INFO" >> $GITHUB_ENV
|
||||
echo "COVERAGE_FILE=$COVERAGE_FILE" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload to CDash
|
||||
working-directory: projects/rocprofiler-compute
|
||||
run: |
|
||||
GIT_SHA_SHORT=$(git rev-parse --short HEAD)
|
||||
BRANCH_NAME=${GITHUB_REF#refs/heads/}
|
||||
|
||||
python3 utils/run-ci.py \
|
||||
--coverage-file "${{ env.COVERAGE_FILE }}" \
|
||||
--build-name "${BRANCH_NAME}-${GIT_SHA_SHORT}-$(date +%Y%m%d)" \
|
||||
--mode "Continuous" \
|
||||
--site "Monorepo-Upload" \
|
||||
--project-name "rocprofiler-compute" \
|
||||
--source-dir "." \
|
||||
--binary-dir "build"
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
echo "## CDash Upload Complete!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Line Coverage**: ${{ env.COVERAGE_INFO }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Commit**: $(git rev-parse --short HEAD)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **CDash Project**: rocprofiler-compute" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Coverage File**: ${{ env.COVERAGE_FILE }}" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -170,13 +170,17 @@ endif()
|
||||
message(STATUS "Enable tests compilation: ${ENABLE_TESTS}")
|
||||
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
|
||||
option(ENABLE_COVERAGE "Enable code coverage" OFF)
|
||||
set(COV_OPTION "")
|
||||
if(${ENABLE_COVERAGE})
|
||||
set(COV_OPTION "--cov=src" "--cov-append" "--cov-report=term-missing"
|
||||
"--cov-report=lcov:tests/coverage.info")
|
||||
# "--cov-report=term-missing" "--cov-report=xml:tests/coverage.xml")
|
||||
|
||||
set(CTEST_COVERAGE_COMMAND "python3")
|
||||
set(CTEST_COVERAGE_EXTRA_FLAGS "-m" "coverage" "xml" "-o"
|
||||
"${CMAKE_BINARY_DIR}/coverage.xml")
|
||||
endif()
|
||||
message(STATUS "Code coverage: ${ENABLE_COVERAGE}")
|
||||
|
||||
@@ -351,6 +355,42 @@ add_test(
|
||||
${COV_OPTION} ${PROJECT_SOURCE_DIR}/tests/test_autogen_config.py
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
# -----------------------------------
|
||||
# Generate coverage tests
|
||||
# -----------------------------------
|
||||
|
||||
if(${ENABLE_COVERAGE})
|
||||
set(ALL_TEST_NAMES
|
||||
test_profile_kernel_execution
|
||||
test_profile_dispatch
|
||||
test_profile_mem
|
||||
test_profile_join
|
||||
test_profile_sort
|
||||
test_profile_misc
|
||||
test_profile_section
|
||||
test_profile_sets_func
|
||||
test_analyze_commands
|
||||
test_analyze_workloads
|
||||
test_L1_cache_counters
|
||||
test_num_xcds_spec_class
|
||||
test_num_xcds_cli_output
|
||||
test_db_connector
|
||||
test_utils
|
||||
test_autogen_config)
|
||||
|
||||
string(REPLACE ";" ";" ALL_TESTS_STRING "${ALL_TEST_NAMES}")
|
||||
|
||||
add_test(
|
||||
NAME generate_coverage_report
|
||||
COMMAND ${Python3_EXECUTABLE} -m coverage xml -o ${CMAKE_BINARY_DIR}/coverage.xml
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
generate_coverage_report
|
||||
PROPERTIES DEPENDS "${ALL_TESTS_STRING}" LABELS "coverage" ENVIRONMENT
|
||||
"COVERAGE_FILE=${PROJECT_SOURCE_DIR}/.coverage")
|
||||
endif()
|
||||
|
||||
# ---------
|
||||
# Install
|
||||
# ---------
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Coverage Workflow for rocprofiler-compute in Monorepo
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the coverage generation and CDash upload workflow for `rocprofiler-compute` within the super-repo structure.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
monorepo/
|
||||
├── projects/
|
||||
│ └── rocprofiler-compute/
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── coverage/
|
||||
│ │ └── coverage-latest.xml # committed coverage file
|
||||
│ ├── utils/
|
||||
│ │ ├── update_coverage.sh # coverage generation/update script
|
||||
│ │ └── run-ci.py # CDash upload script
|
||||
│ └── ...
|
||||
└── .github/
|
||||
└── workflows/
|
||||
└── rocprofiler-compute-cdash.yml # gitHub Action for auto-upload
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### 1. Manual Coverage Generation (Periodic Update)
|
||||
|
||||
Run this periodically to update the coverage baseline:
|
||||
|
||||
```bash
|
||||
# From monorepo root
|
||||
cd projects/rocprofiler-compute
|
||||
./utils/update_coverage.sh
|
||||
|
||||
# This will:
|
||||
# - Build with coverage enabled
|
||||
# - Run all tests
|
||||
# - Generate coverage.xml
|
||||
# - Copy/overwrite to coverage/coverage-latest.xml
|
||||
# - Show instructions for committing
|
||||
```
|
||||
|
||||
### 2. Commit Coverage to Repository
|
||||
|
||||
```bash
|
||||
# From monorepo root
|
||||
git add projects/rocprofiler-compute/coverage/coverage-latest.xml
|
||||
git commit -m "rocprofiler-compute: Update coverage to XX.X% line coverage"
|
||||
git push origin develop
|
||||
```
|
||||
|
||||
### 3. Automatic CDash Upload
|
||||
|
||||
When `coverage/coverage-latest.xml` is pushed to `develop` branch:
|
||||
- GitHub Action triggers automatically
|
||||
- Uploads coverage to CDash
|
||||
- Posts summary to GitHub Actions
|
||||
|
||||
## CDash Project
|
||||
|
||||
View results at: https://my.cdash.org/index.php?project=rocprofiler-compute
|
||||
|
||||
## Maintenance
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Coverage Generation Fails
|
||||
|
||||
```bash
|
||||
#check Python dependencies
|
||||
pip install coverage pytest pytest-cov
|
||||
|
||||
#verify tests can run
|
||||
cd projects/rocprofiler-compute/build
|
||||
ctest --verbose
|
||||
```
|
||||
ファイル差分が大きすぎるため省略します
差分を読み込み
+257
@@ -0,0 +1,257 @@
|
||||
#!/usr/bin/env python3
|
||||
##############################################################################
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
CI script to upload coverage XML files to CDash
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def detect_repo_structure():
|
||||
"""Detect if in monorepo or standalone structure"""
|
||||
cwd = Path.cwd()
|
||||
|
||||
if "projects/rocprofiler-compute" in str(cwd):
|
||||
parts = cwd.parts
|
||||
idx = parts.index("rocprofiler-compute")
|
||||
if idx > 0 and parts[idx - 1] == "projects":
|
||||
monorepo_root = Path(*parts[: idx - 1])
|
||||
project_root = monorepo_root / "projects" / "rocprofiler-compute"
|
||||
return True, monorepo_root, project_root
|
||||
|
||||
if (cwd / "CMakeLists.txt").exists():
|
||||
with open(cwd / "CMakeLists.txt", "r") as f:
|
||||
content = f.read()
|
||||
if (
|
||||
"project(rocprofiler-compute" in content
|
||||
or "project(\n rocprofiler-compute" in content
|
||||
):
|
||||
return False, None, cwd
|
||||
|
||||
return False, None, cwd
|
||||
|
||||
|
||||
def create_ctest_script(args):
|
||||
"""Generate a CTest script for uploading coverage data"""
|
||||
|
||||
script_content = f"""
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
set(CTEST_PROJECT_NAME "{args.project_name}")
|
||||
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.14)
|
||||
set(CTEST_SUBMIT_URL "{args.submit_url}")
|
||||
else()
|
||||
set(CTEST_DROP_METHOD "https")
|
||||
set(CTEST_DROP_SITE "{args.cdash_host}")
|
||||
set(CTEST_DROP_LOCATION "{args.submit_path}")
|
||||
endif()
|
||||
|
||||
set(CTEST_SITE "{args.site}")
|
||||
set(CTEST_BUILD_NAME "{args.build_name}")
|
||||
set(CTEST_SOURCE_DIRECTORY "{args.source_dir}")
|
||||
set(CTEST_BINARY_DIRECTORY "{args.binary_dir}")
|
||||
|
||||
ctest_start({args.mode})
|
||||
|
||||
set(CTEST_COVERAGE_COMMAND "python3")
|
||||
set(CTEST_COVERAGE_EXTRA_FLAGS "-m" "coverage" "xml")
|
||||
|
||||
file(COPY "{args.coverage_file}" DESTINATION "${{CTEST_BINARY_DIRECTORY}}")
|
||||
ctest_coverage()
|
||||
ctest_submit(PARTS Coverage RETRY_COUNT 3 RETRY_DELAY 5)
|
||||
"""
|
||||
return script_content
|
||||
|
||||
|
||||
def main():
|
||||
if not os.getenv("CI"):
|
||||
print("WARNING: CDash upload should normally only be done from CI/CD")
|
||||
response = input("Continue anyway? (y/N): ")
|
||||
if response.lower() != "y":
|
||||
print("Aborted.")
|
||||
return 1
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Upload coverage XML to CDash for rocprofiler-compute"
|
||||
)
|
||||
|
||||
# required
|
||||
parser.add_argument(
|
||||
"--coverage-file", required=True, help="Path to coverage XML file"
|
||||
)
|
||||
parser.add_argument("--build-name", required=True, help="Build name for CDash")
|
||||
|
||||
# optional
|
||||
parser.add_argument(
|
||||
"--project-name", default="rocprofiler-compute", help="CDash project name"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--submit-url",
|
||||
default="https://my.cdash.org/submit.php?project=rocprofiler-compute",
|
||||
help="CDash submission URL",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cdash-host", default="my.cdash.org", help="CDash host (for older CMake)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--submit-path",
|
||||
default="/submit.php?project=rocprofiler-compute",
|
||||
help="CDash submission path (for older CMake)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--site",
|
||||
default=None,
|
||||
help="Site name for CDash (auto-detected if not provided)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source-dir",
|
||||
default=None,
|
||||
help="Source directory path (auto-detected if not provided)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--binary-dir",
|
||||
default=None,
|
||||
help="Binary directory path (defaults to source-dir/build)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mode",
|
||||
default="Experimental",
|
||||
choices=["Experimental", "Nightly", "Continuous"],
|
||||
help="CTest dashboard mode",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
is_monorepo, monorepo_root, project_root = detect_repo_structure()
|
||||
|
||||
if not args.source_dir:
|
||||
args.source_dir = str(project_root)
|
||||
|
||||
if not args.binary_dir:
|
||||
args.binary_dir = os.path.join(args.source_dir, "build")
|
||||
|
||||
if not args.site:
|
||||
if is_monorepo:
|
||||
args.site = f"Monorepo-{os.uname().nodename}"
|
||||
else:
|
||||
args.site = os.uname().nodename
|
||||
|
||||
coverage_path = Path(args.coverage_file)
|
||||
if not coverage_path.is_absolute():
|
||||
if not coverage_path.exists():
|
||||
coverage_path = project_root / args.coverage_file
|
||||
|
||||
if not coverage_path.exists():
|
||||
print(f"ERROR: Coverage file not found: {coverage_path}", file=sys.stderr)
|
||||
print(f" Searched in: {Path(args.coverage_file).absolute()}")
|
||||
print(f" And in: {project_root / args.coverage_file}")
|
||||
return 1
|
||||
|
||||
args.coverage_file = str(coverage_path.absolute())
|
||||
args.source_dir = str(Path(args.source_dir).absolute())
|
||||
args.binary_dir = str(Path(args.binary_dir).absolute())
|
||||
|
||||
print(f"Repository type: {'Monorepo' if is_monorepo else 'Standalone'}")
|
||||
print(f"Project root: {project_root}")
|
||||
print(f"Uploading coverage file: {args.coverage_file}")
|
||||
print(f"Build name: {args.build_name}")
|
||||
print(f"Project: {args.project_name}")
|
||||
print(f"Site: {args.site}")
|
||||
print(f"Submit URL: {args.submit_url}")
|
||||
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
tree = ET.parse(args.coverage_file)
|
||||
root = tree.getroot()
|
||||
line_rate = float(root.get("line-rate", 0)) * 100
|
||||
print(f"Line Coverage: {line_rate:.1f}%")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not parse coverage percentage: {e}")
|
||||
|
||||
script_content = create_ctest_script(args)
|
||||
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".cmake", delete=False) as f:
|
||||
f.write(script_content)
|
||||
script_path = f.name
|
||||
|
||||
print(f"\nScript written to: {script_path}")
|
||||
|
||||
original_dir = os.getcwd()
|
||||
os.chdir(args.source_dir)
|
||||
|
||||
cmd = ["ctest", "-S", script_path, "-V"]
|
||||
print(f"Executing: {' '.join(cmd)}")
|
||||
print(f"Working directory: {os.getcwd()}")
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if result.stdout:
|
||||
print("\nSTDOUT:")
|
||||
print(result.stdout)
|
||||
|
||||
if result.stderr:
|
||||
print("\nSTDERR:")
|
||||
print(result.stderr)
|
||||
|
||||
os.chdir(original_dir)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"\nCTest failed with return code: {result.returncode}")
|
||||
return result.returncode
|
||||
|
||||
print("\n✅ Coverage successfully uploaded to CDash!")
|
||||
print(
|
||||
f"View results at: {
|
||||
args.submit_url.replace('/submit.php?project=', '/index.php?project=')
|
||||
}"
|
||||
)
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error executing CTest script: {e}", file=sys.stderr)
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
finally:
|
||||
if "script_path" in locals():
|
||||
try:
|
||||
os.unlink(script_path)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
##############################################################################
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
##############################################################################
|
||||
|
||||
# generate coverage for develop branch - stores file in repo
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [[ "$SCRIPT_DIR" == */projects/rocprofiler-compute/* ]]; then
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
MONOREPO_ROOT="$(cd "$PROJECT_ROOT/../.." && pwd)"
|
||||
IS_MONOREPO=true
|
||||
else
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
MONOREPO_ROOT=""
|
||||
IS_MONOREPO=false
|
||||
fi
|
||||
|
||||
BUILD_DIR="$PROJECT_ROOT/build"
|
||||
COVERAGE_FILE="$PROJECT_ROOT/coverage/coverage-latest.xml"
|
||||
|
||||
echo "=== Generating Coverage for rocprofiler-compute ==="
|
||||
echo "Project root: $PROJECT_ROOT"
|
||||
if [ "$IS_MONOREPO" = true ]; then
|
||||
echo "Monorepo root: $MONOREPO_ROOT"
|
||||
fi
|
||||
|
||||
echo "Setting up clean build..."
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
echo "Configuring with coverage enabled..."
|
||||
cmake -DENABLE_COVERAGE=ON -DENABLE_TESTS=ON -DPYTEST_NUMPROCS=8 ..
|
||||
|
||||
echo "Building..."
|
||||
make -j$(nproc)
|
||||
|
||||
echo "Running ALL tests to generate coverage (this may take a while)..."
|
||||
ctest --verbose --output-on-failure --parallel 1 || {
|
||||
echo "WARNING: Some tests failed, but continuing with coverage generation"
|
||||
}
|
||||
|
||||
echo "Generating coverage report..."
|
||||
if ctest -R generate_coverage_report --output-on-failure --parallel 2; then
|
||||
echo "Coverage report generated via ctest"
|
||||
else
|
||||
echo "Trying alternative coverage generation..."
|
||||
cd "$PROJECT_ROOT"
|
||||
python3 -m coverage combine || true
|
||||
python3 -m coverage xml -o "$BUILD_DIR/coverage.xml"
|
||||
cd "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
if [ ! -f "coverage.xml" ]; then
|
||||
echo "ERROR: coverage.xml not generated"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COVERAGE_INFO=$(python3 -c "
|
||||
import xml.etree.ElementTree as ET
|
||||
tree = ET.parse('coverage.xml')
|
||||
root = tree.getroot()
|
||||
line_rate = float(root.get('line-rate', 0)) * 100
|
||||
print(f'{line_rate:.1f}%')
|
||||
")
|
||||
|
||||
mkdir -p "$PROJECT_ROOT/coverage"
|
||||
cp coverage.xml "$COVERAGE_FILE"
|
||||
|
||||
echo ""
|
||||
echo "=== Coverage Generated Successfully ==="
|
||||
echo "Line Coverage: $COVERAGE_INFO"
|
||||
echo "File: $COVERAGE_FILE"
|
||||
echo ""
|
||||
|
||||
echo "Coverage file generated: coverage/coverage-latest.xml"
|
||||
echo "To update official coverage:"
|
||||
echo " 1. Commit this file to develop branch"
|
||||
echo " 2. GitHub Actions will automatically upload to CDash"
|
||||
新しいイシューから参照
ユーザーをブロックする