From 7127435a4ddff4c96c28c25cfe3f4873279e17a5 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:00:34 +0200 Subject: [PATCH 1/5] Update run_tests.sh --- run_tests.sh | 231 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 143 insertions(+), 88 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 3319805..36843f9 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -2,149 +2,204 @@ set -e +# Find all directories (under start_dir) that contain a CMakeLists.txt find_cmake_subdirs() { local start_dir="$1" - local cmakedirs=$(find "$start_dir" -type d -exec test -e '{}/CMakeLists.txt' \; -print -prune) - for cmakedir in $cmakedirs; do - echo "$cmakedir" - done + local cmakedirs + cmakedirs=$(find "$start_dir" -type f -name 'CMakeLists.txt' -printf '%h\n' | sort -u) + echo "$cmakedirs" } -test_cpp_projects() { -local subdirs=$(find_cmake_subdirs .) -local current_dir=$(pwd) - -local cpp_test_log="$current_dir/cpp_test.log" -: > "$cpp_test_log" # truncate the log file - -local total_passed_tests=0 -local total_failed_tests=0 +# Find all directories (under start_dir) that contain a __init__.py (i.e., Python packages) +find_python_subdirs() { + local start_dir="$1" + local pydirs + pydirs=$(find "$start_dir" -type f -name '__init__.py' -printf '%h\n' | sort -u) + echo "$pydirs" +} -cleanup() { - echo "Cleaning up..." - cd .. - rm -rf build +# Get list of files changed since last commit on master +get_modified_files() { + # Compare against master branch; adjust "master" to "origin/master" if needed + git diff --name-only master...HEAD } -for subdir in $subdirs; do - : > "$cpp_test_log" # truncate the log file - echo -e "\nRunning tests for C++ project at: $subdir" - cd "$subdir" - mkdir -p build && cd build - trap cleanup EXIT +test_cpp_projects() { + local current_dir + current_dir=$(pwd) + + # All C++ project directories (where CMakeLists.txt lives) + local all_subdirs + all_subdirs=$(find_cmake_subdirs .) + + # Files modified in this PR relative to master + local modified_files + modified_files=$(get_modified_files) + + # Filter to only those C++ subdirs in which at least one file was modified + local modified_subdirs="" + for subdir in $all_subdirs; do + if echo "$modified_files" | grep -q "^${subdir#./}/"; then + modified_subdirs="$modified_subdirs $subdir" + fi + done - cmake .. 1>/dev/null 2>&1 && make 1>/dev/null 2>&1 - ctest --verbose 2>&1 | tee -a "$cpp_test_log" + if [ -z "$modified_subdirs" ]; then + echo "No modified C++ projects to test." + return + fi - trap - EXIT - cleanup - cd "$current_dir" + local total_passed_tests=0 + local total_failed_tests=0 + local cpp_test_log - # count the number of passed and total tests - cpp_total_tests=$(grep -oP '\d+ tests from' "$cpp_test_log" | tail -1 | awk '{print $1}') - cpp_passed_tests=$(grep -oP '\[\s*PASSED\s*\] \d+' "$cpp_test_log" | tail -1 | awk '{print $4}') + cleanup() { + cd "$current_dir" + rm -rf build + } + echo "Running tests for modified C++ projects:" + for subdir in $modified_subdirs; do + echo -e "\nRunning tests for C++ project at: $subdir" + cd "$subdir" + mkdir -p build && cd build - echo "cpp_total_tests: $cpp_total_tests" - echo "cpp_passed_tests: $cpp_passed_tests" + # Ensure cleanup on exit from this block + trap cleanup EXIT -local cpp_failed_tests=$((cpp_total_tests - cpp_passed_tests)) + # Redirect cmake/make output to /dev/null + cmake .. 1>/dev/null 2>&1 && make 1>/dev/null 2>&1 - total_passed_tests=$((total_passed_tests + cpp_passed_tests)) - total_failed_tests=$((total_failed_tests + cpp_failed_tests)) + # Run tests and capture output + cpp_test_log="$current_dir/cpp_test_$(echo "$subdir" | tr '/' '_').log" + : > "$cpp_test_log" + ctest --verbose 2>&1 | tee -a "$cpp_test_log" - echo "C++ Tests summary for $subdir:" - echo -e "Passed: \e[32m$cpp_passed_tests\e[0m, Failed: \e[31m$cpp_failed_tests\e[0m" -done + trap - EXIT + cleanup + cd "$current_dir" -echo "Total C++ Tests summary:" -echo -e "Total Passed: \e[32m$total_passed_tests\e[0m, Total Failed: \e[31m$total_failed_tests\e[0m" + # Count total and passed tests in this subdir + local cpp_total_tests + cpp_total_tests=$(grep -oP '\d+(?= tests from)' "$cpp_test_log" | tail -1 || echo 0) + local cpp_passed_tests + cpp_passed_tests=$(grep -oP '(?<=\[ *PASSED *\] )\d+' "$cpp_test_log" | tail -1 || echo 0) + local cpp_failed_tests=$((cpp_total_tests - cpp_passed_tests)) -} + total_passed_tests=$((total_passed_tests + cpp_passed_tests)) + total_failed_tests=$((total_failed_tests + cpp_failed_tests)) - -find_python_subdirs() { - local start_dir="$1" - local pydirs=$(find "$start_dir" -type d -exec test -e '{}/__init__.py' \; -print -prune) - for pydir in $pydirs; do - echo "$pydir" + echo "C++ Tests summary for $subdir:" + echo -e " Passed: \e[32m$cpp_passed_tests\e[0m, Failed: \e[31m$cpp_failed_tests\e[0m" done + + echo -e "\nTotal C++ Tests summary for modified projects:" + echo -e " Total Passed: \e[32m$total_passed_tests\e[0m, Total Failed: \e[31m$total_failed_tests\e[0m" } test_python_projects() { - local subdirs=$(find_python_subdirs .) - local current_dir=$(pwd) + local current_dir + current_dir=$(pwd) + + # All Python project directories (where __init__.py lives) + local all_subdirs + all_subdirs=$(find_python_subdirs .) + + # Files modified in this PR relative to master + local modified_files + modified_files=$(get_modified_files) + + # Filter to only those Python subdirs in which at least one file was modified + local modified_subdirs="" + for subdir in $all_subdirs; do + if echo "$modified_files" | grep -q "^${subdir#./}/"; then + modified_subdirs="$modified_subdirs $subdir" + fi + done - local python_test_log="$current_dir/python_test_log" - : > "$python_test_log" # truncate the log file + if [ -z "$modified_subdirs" ]; then + echo "No modified Python projects to test." + return + fi local total_passed_tests=0 local total_failed_tests=0 + local python_test_log - for subdir in $subdirs; do + echo "Running tests for modified Python projects:" + for subdir in $modified_subdirs; do echo -e "\nRunning tests for Python project at: $subdir" cd "$subdir" - : > "$python_test_log" # truncate the log file + + python_test_log="$current_dir/python_test_$(echo "$subdir" | tr '/' '_').log" + : > "$python_test_log" + python3 -m unittest discover -v 2>&1 | tee -a "$python_test_log" cd "$current_dir" - # count the number of passed and total tests - local python_total_tests=$(grep -oP 'Ran \K\d+' "$python_test_log") - local python_passed_tests=$(grep -o '.*... ok' "$python_test_log" | wc -l) + # Count total and passed tests + local python_total_tests + python_total_tests=$(grep -oP '(?<=Ran )\d+' "$python_test_log" | head -1 || echo 0) + local python_passed_tests + python_passed_tests=$(grep -c '\.\.\. ok' "$python_test_log" || echo 0) local python_failed_tests=$((python_total_tests - python_passed_tests)) - # add the passed and failed tests to the total total_passed_tests=$((total_passed_tests + python_passed_tests)) total_failed_tests=$((total_failed_tests + python_failed_tests)) echo "Python Tests summary for $subdir:" - echo -e "Passed: \e[32m$python_passed_tests\e[0m, Failed: \e[31m$python_failed_tests\e[0m" + echo -e " Passed: \e[32m$python_passed_tests\e[0m, Failed: \e[31m$python_failed_tests\e[0m" done - echo -e "\nTotal Python Tests summary:" - echo -e "Total Passed: \e[32m$total_passed_tests\e[0m, Total Failed: \e[31m$total_failed_tests\e[0m" - + echo -e "\nTotal Python Tests summary for modified projects:" + echo -e " Total Passed: \e[32m$total_passed_tests\e[0m, Total Failed: \e[31m$total_failed_tests\e[0m" } - main() { if [ "$#" -eq 0 ]; then - echo "Running tests for all projects" - echo "Running tests for Python projects" + echo "Running tests only for projects modified since last master commit." + echo "---- Python Projects ----" test_python_projects - echo "Running tests for C++ projects" + echo "---- C++ Projects ----" test_cpp_projects + exit 0 fi if [ "$#" -eq 1 ]; then - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - echo "Usage: run_tests.sh [OPTION]" - echo "Run tests for all projects." - echo "" - echo "Options:" - echo " -h, --help Show this help message and exit" - echo " -p, --python Run tests for Python projects" - echo " -c, --cpp Run tests for C++ projects" - exit 0 - fi - if [ "$1" == "-p" ] || [ "$1" == "--python" ]; then - echo "Running tests for Python projects" - test_python_projects - exit 0 - fi - if [ "$1" == "-c" ] || [ "$1" == "--cpp" ]; then - echo "Running tests for C++ projects" - test_cpp_projects - exit 0 - fi + case "$1" in + -h|--help) + echo "Usage: run_tests.sh [OPTION]" + echo "Run tests for projects modified since last master commit." + echo "" + echo "Options:" + echo " -h, --help Show this help message and exit" + echo " -p, --python Run tests for modified Python projects only" + echo " -c, --cpp Run tests for modified C++ projects only" + exit 0 + ;; + -p|--python) + echo "Running tests for modified Python projects:" + test_python_projects + exit 0 + ;; + -c|--cpp) + echo "Running tests for modified C++ projects:" + test_cpp_projects + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Usage: run_tests.sh [OPTION]" + exit 1 + ;; + esac fi if [ "$#" -gt 1 ]; then echo "Too many arguments" + echo "Usage: run_tests.sh [OPTION]" exit 1 fi - } main "$@" - From d25c135be7e2f61b61d1561312e10a8dba386495 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:02:31 +0200 Subject: [PATCH 2/5] Update run_tests.sh --- run_tests.sh | 53 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index 36843f9..cc1017c 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -2,26 +2,36 @@ set -e +# Determine which branch to compare against: master or main +detect_base_branch() { + if git rev-parse --verify master >/dev/null 2>&1; then + echo "master" + elif git rev-parse --verify main >/dev/null 2>&1; then + echo "main" + else + echo "Error: neither 'master' nor 'main' exists in this repository." >&2 + exit 1 + fi +} + # Find all directories (under start_dir) that contain a CMakeLists.txt find_cmake_subdirs() { local start_dir="$1" - local cmakedirs - cmakedirs=$(find "$start_dir" -type f -name 'CMakeLists.txt' -printf '%h\n' | sort -u) - echo "$cmakedirs" + # print the parent directory of each CMakeLists.txt, remove duplicates, sort + find "$start_dir" -type f -name 'CMakeLists.txt' -printf '%h\n' | sort -u } -# Find all directories (under start_dir) that contain a __init__.py (i.e., Python packages) +# Find all directories (under start_dir) that contain a __init__.py (Python packages) find_python_subdirs() { local start_dir="$1" - local pydirs - pydirs=$(find "$start_dir" -type f -name '__init__.py' -printf '%h\n' | sort -u) - echo "$pydirs" + find "$start_dir" -type f -name '__init__.py' -printf '%h\n' | sort -u } -# Get list of files changed since last commit on master +# Get list of files changed since last base-branch commit get_modified_files() { - # Compare against master branch; adjust "master" to "origin/master" if needed - git diff --name-only master...HEAD + local base_branch + base_branch="$(detect_base_branch)" + git diff --name-only "$base_branch"...HEAD } test_cpp_projects() { @@ -32,14 +42,16 @@ test_cpp_projects() { local all_subdirs all_subdirs=$(find_cmake_subdirs .) - # Files modified in this PR relative to master + # Files modified in this PR relative to base branch local modified_files modified_files=$(get_modified_files) # Filter to only those C++ subdirs in which at least one file was modified local modified_subdirs="" for subdir in $all_subdirs; do - if echo "$modified_files" | grep -q "^${subdir#./}/"; then + # strip leading ./ if present when comparing to git output + local sub="${subdir#./}" + if echo "$modified_files" | grep -q "^$sub/"; then modified_subdirs="$modified_subdirs $subdir" fi done @@ -62,15 +74,13 @@ test_cpp_projects() { for subdir in $modified_subdirs; do echo -e "\nRunning tests for C++ project at: $subdir" cd "$subdir" - mkdir -p build && cd build - # Ensure cleanup on exit from this block + mkdir -p build && cd build trap cleanup EXIT - # Redirect cmake/make output to /dev/null + # hide cmake/make output cmake .. 1>/dev/null 2>&1 && make 1>/dev/null 2>&1 - # Run tests and capture output cpp_test_log="$current_dir/cpp_test_$(echo "$subdir" | tr '/' '_').log" : > "$cpp_test_log" ctest --verbose 2>&1 | tee -a "$cpp_test_log" @@ -79,7 +89,6 @@ test_cpp_projects() { cleanup cd "$current_dir" - # Count total and passed tests in this subdir local cpp_total_tests cpp_total_tests=$(grep -oP '\d+(?= tests from)' "$cpp_test_log" | tail -1 || echo 0) local cpp_passed_tests @@ -105,14 +114,15 @@ test_python_projects() { local all_subdirs all_subdirs=$(find_python_subdirs .) - # Files modified in this PR relative to master + # Files modified in this PR relative to base branch local modified_files modified_files=$(get_modified_files) # Filter to only those Python subdirs in which at least one file was modified local modified_subdirs="" for subdir in $all_subdirs; do - if echo "$modified_files" | grep -q "^${subdir#./}/"; then + local sub="${subdir#./}" + if echo "$modified_files" | grep -q "^$sub/"; then modified_subdirs="$modified_subdirs $subdir" fi done @@ -137,7 +147,6 @@ test_python_projects() { python3 -m unittest discover -v 2>&1 | tee -a "$python_test_log" cd "$current_dir" - # Count total and passed tests local python_total_tests python_total_tests=$(grep -oP '(?<=Ran )\d+' "$python_test_log" | head -1 || echo 0) local python_passed_tests @@ -157,7 +166,7 @@ test_python_projects() { main() { if [ "$#" -eq 0 ]; then - echo "Running tests only for projects modified since last master commit." + echo "Running tests only for projects modified since last commit on base branch." echo "---- Python Projects ----" test_python_projects echo "---- C++ Projects ----" @@ -169,7 +178,7 @@ main() { case "$1" in -h|--help) echo "Usage: run_tests.sh [OPTION]" - echo "Run tests for projects modified since last master commit." + echo "Run tests for projects modified since base branch." echo "" echo "Options:" echo " -h, --help Show this help message and exit" From 9393f47f22f81f2a1e5165ff6f30883745dc36d8 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:08:58 +0200 Subject: [PATCH 3/5] Update run_tests.sh --- run_tests.sh | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/run_tests.sh b/run_tests.sh index cc1017c..07cd3bf 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,33 +1,29 @@ #!/bin/bash - set -e -# Determine which branch to compare against: master or main +# Determine base branch by looking at the upstream. If no upstream is set, fall back to "master". detect_base_branch() { - if git rev-parse --verify master >/dev/null 2>&1; then - echo "master" - elif git rev-parse --verify main >/dev/null 2>&1; then - echo "main" + # Try to get the upstream name, e.g. "origin/master" or "origin/main" + if base="$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null)"; then + echo "$base" else - echo "Error: neither 'master' nor 'main' exists in this repository." >&2 - exit 1 + echo "master" fi } -# Find all directories (under start_dir) that contain a CMakeLists.txt +# Find all directories under start_dir that contain a CMakeLists.txt find_cmake_subdirs() { local start_dir="$1" - # print the parent directory of each CMakeLists.txt, remove duplicates, sort find "$start_dir" -type f -name 'CMakeLists.txt' -printf '%h\n' | sort -u } -# Find all directories (under start_dir) that contain a __init__.py (Python packages) +# Find all directories under start_dir that contain a __init__.py find_python_subdirs() { local start_dir="$1" find "$start_dir" -type f -name '__init__.py' -printf '%h\n' | sort -u } -# Get list of files changed since last base-branch commit +# Get the list of files changed since the last commit on base branch get_modified_files() { local base_branch base_branch="$(detect_base_branch)" @@ -38,18 +34,18 @@ test_cpp_projects() { local current_dir current_dir=$(pwd) - # All C++ project directories (where CMakeLists.txt lives) + # Find every directory that has a CMakeLists.txt local all_subdirs all_subdirs=$(find_cmake_subdirs .) - # Files modified in this PR relative to base branch + # Which files changed in this PR (relative to base) local modified_files modified_files=$(get_modified_files) - # Filter to only those C++ subdirs in which at least one file was modified + # Filter to only those C++ subdirs where at least one file was modified local modified_subdirs="" for subdir in $all_subdirs; do - # strip leading ./ if present when comparing to git output + # strip leading "./" for comparison against git output local sub="${subdir#./}" if echo "$modified_files" | grep -q "^$sub/"; then modified_subdirs="$modified_subdirs $subdir" @@ -78,7 +74,7 @@ test_cpp_projects() { mkdir -p build && cd build trap cleanup EXIT - # hide cmake/make output + # Hide cmake/make output cmake .. 1>/dev/null 2>&1 && make 1>/dev/null 2>&1 cpp_test_log="$current_dir/cpp_test_$(echo "$subdir" | tr '/' '_').log" @@ -110,15 +106,15 @@ test_python_projects() { local current_dir current_dir=$(pwd) - # All Python project directories (where __init__.py lives) + # Find every directory that has an __init__.py local all_subdirs all_subdirs=$(find_python_subdirs .) - # Files modified in this PR relative to base branch + # Which files changed in this PR (relative to base) local modified_files modified_files=$(get_modified_files) - # Filter to only those Python subdirs in which at least one file was modified + # Filter to only those Python subdirs where at least one file was modified local modified_subdirs="" for subdir in $all_subdirs; do local sub="${subdir#./}" From 1b351b1a8efd4d752f0f8f248ab3243c0595eb4e Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:13:32 +0200 Subject: [PATCH 4/5] Update all-tests.yml --- .github/workflows/all-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml index a8bdd79..9550050 100644 --- a/.github/workflows/all-tests.yml +++ b/.github/workflows/all-tests.yml @@ -9,6 +9,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: Setup Python uses: actions/setup-python@v2 From 9409238c071224469d00e7e6b1a20e23f0e15517 Mon Sep 17 00:00:00 2001 From: Adam Djellouli <37275728+djeada@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:19:36 +0200 Subject: [PATCH 5/5] Update all-tests.yml --- .github/workflows/all-tests.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml index 9550050..4d1ea21 100644 --- a/.github/workflows/all-tests.yml +++ b/.github/workflows/all-tests.yml @@ -7,10 +7,16 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Checkout repository (full history) uses: actions/checkout@v2 with: - fetch-depth: 0 + fetch-depth: 0 # ← fetch all branches and commits + + - name: Ensure master/main exist locally + run: | + # Try to fetch both master and main so that one of them is guaranteed to exist + git fetch origin master:master || true + git fetch origin main:main || true - name: Setup Python uses: actions/setup-python@v2 @@ -18,7 +24,7 @@ jobs: python-version: '3.x' - name: Install CMake and Make - run: sudo apt-get install -y cmake make + run: sudo apt-get update && sudo apt-get install -y cmake make - name: Run tests run: |