diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..c709b52421 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +src/flamenco/types/fd_types.h linguist-generated=true +src/flamenco/types/fd_types.c linguist-generated=true +src/flamenco/runtime/tests/generated/*.h filter=lfs diff=lfs merge=lfs -text diff --git a/.github/actions/deps/action.yml b/.github/actions/deps/action.yml new file mode 100644 index 0000000000..8a93386170 --- /dev/null +++ b/.github/actions/deps/action.yml @@ -0,0 +1,54 @@ +name: deps +description: 'Build and cache dependencies' +inputs: + deps-script-path: + description: 'Path of deps.sh script' + required: true + default: './deps.sh' + deps-bundle-path: + description: 'Path of deps-bundle.sh script' + required: true + default: './contrib/deps-bundle.sh' +outputs: {} +runs: + using: composite + steps: + - name: Has apt-get? + shell: bash + run: | + if command -v apt-get > /dev/null 2>&1; then + echo "HAS_APT_GET=1" >> $GITHUB_ENV + else + echo "HAS_APT_GET=0" >> $GITHUB_ENV + fi + + - name: apt-get update + shell: bash + run: sudo apt-get update + if: env.HAS_APT_GET == '1' + + - id: deps-sh-hash + shell: bash + run: sha256sum '${{ inputs.deps-script-path }}' | awk '{print "HASH=" $1}' >> "$GITHUB_OUTPUT" + + - id: deps-sh-cache + uses: actions/cache@v3 + with: + path: deps-bundle.tar.zst + key: ${{ runner.os }}-deps-sh-${{ steps.deps-sh-hash.outputs.HASH }} + + - name: Install system level dependencies + shell: bash + run: FD_AUTO_INSTALL_PACKAGES=1 '${{ inputs.deps-script-path }}' check + + - name: Install dependencies from cache + shell: bash + run: tar -Izstd -xvf deps-bundle.tar.zst + if: steps.deps-sh-cache.outputs.cache-hit == 'true' + + - name: Install dependencies from scratch + shell: bash + run: | + FD_AUTO_INSTALL_PACKAGES=1 '${{ inputs.deps-script-path }}' install + '${{ inputs.deps-bundle-path }}' + if: steps.deps-sh-cache.outputs.cache-hit != 'true' diff --git a/.github/actions/hugepages/action.yml b/.github/actions/hugepages/action.yml new file mode 100644 index 0000000000..43b39544eb --- /dev/null +++ b/.github/actions/hugepages/action.yml @@ -0,0 +1,18 @@ +name: hugepages +description: 'Setup 1 GiB gigantic pages' +inputs: + count: + description: 'Number of huge pages' + required: true + default: '64' +outputs: {} +runs: + using: composite + steps: + - shell: bash + run: | + set -x + sudo src/util/shmem/fd_shmem_cfg fini || true + sudo src/util/shmem/fd_shmem_cfg init 0666 $USER "" || true + sudo src/util/shmem/fd_shmem_cfg alloc '${{ inputs.count }}' gigantic 0 + sudo chown -R $USER:$USER /mnt/.fd diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..5ace4600a1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows-disabled/coverage.yml b/.github/workflows-disabled/coverage.yml new file mode 100644 index 0000000000..1ac939c653 --- /dev/null +++ b/.github/workflows-disabled/coverage.yml @@ -0,0 +1,119 @@ +name: All Coverage +on: + schedule: + - cron: '0 0 * * *' + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +jobs: + all-coverage: + name: All Coverage + runs-on: + group: github-v1 + environment: + name: github-pages + url: ${{ steps.pages-deploy.outputs.page_url }} + env: + CC: clang + EXTRAS: llvm-cov + steps: + - name: Install Dependencies + run: sudo apt-get update && sudo apt-get install -y llvm lcov + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: ./.github/actions/deps + - uses: ./.github/actions/hugepages + + - name: Build low unit tests + env: + MACHINE: linux_clang_combi_low + run: make -j -Otarget unit-test + + - name: Run low unit tests + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + ./test.sh -j --page-sz gigantic + + - name: Build high unit tests + env: + MACHINE: linux_clang_combi_low + run: make -j -Otarget unit-test + + - name: Run high unit tests + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + ./test.sh -j --page-sz gigantic + + - name: Make Test Coverage Report + run: | + make combicov-report + mkdir -p build/pages/ + mv build/combi-cov/html build/pages/cov + + - name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v1' + with: + credentials_json: ${{ secrets.FUZZ_SERVICE_ACCT_JSON_BUNDLE }} + + # Not using fuzzbot-builder because llvm-cov must be ran in the same environment otherwise paths will not match + - name: Build Fuzz Tests + env: + # Todo: use a matrix strategy + MACHINE: linux_clang_combi_high + EXTRAS: fuzz asan + run: make -j -Otarget fuzz-test + + - name: Fetch Corpus, Generate Fuzzing Coverage + run: ./.github/workflows/scripts/fuzzcov_generate.sh build/linux/clang/combi/high/fuzz-test/ + + - name: Publish Fuzzing Coverage to codecov.io + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: ./.github/workflows/scripts/fuzzcov_publish_codecov.sh + + - name: Generate HTML Fuzzing Coverage Reports + run: ./.github/workflows/scripts/fuzzcov_genhtml.sh "${{ github.sha }}" + + - name: Drop an Index + run: | + cat < build/pages/index.html + + + + 🔥💃 Pages + + + +

🔥💃 Pages

+

Links 🔗

+ + + + + EOS + + - name: Setup Pages + uses: actions/configure-pages@v3 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + # Upload entire repository + path: './build/pages/' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/.github/workflows-disabled/test_fuzz_regressions.yml b/.github/workflows-disabled/test_fuzz_regressions.yml new file mode 100644 index 0000000000..2fb5d15587 --- /dev/null +++ b/.github/workflows-disabled/test_fuzz_regressions.yml @@ -0,0 +1,28 @@ +name: Test Fuzz Regressions +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + make-fuzz: + name: Test Fuzz Regressions on ${{ matrix.feature_set }} + strategy: + matrix: + feature_set: [modern] + runs-on: + group: github-v1 + env: + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + EXTRAS: fuzz asan ubsan + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/deps + + - name: Build Fuzz Tests + run: make -j -Otarget fuzz-test + + - name: Run Fuzz Tests Against Corpora + run: make -k -j -Otarget run-fuzz-test diff --git a/.github/workflows/_publish_to_clusterfuzz.yml b/.github/workflows/_publish_to_clusterfuzz.yml new file mode 100644 index 0000000000..74035ca953 --- /dev/null +++ b/.github/workflows/_publish_to_clusterfuzz.yml @@ -0,0 +1,41 @@ +name: Clusterfuzz +on: + workflow_call: + workflow_dispatch: +jobs: + publish: + name: Build Fuzzers for ${{ matrix.feature_set }} feature set + strategy: + matrix: + feature_set: [modern, highend] + runs-on: + group: github-v1 + env: + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + EXTRAS: fuzz asan ubsan + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/hugepages + - uses: ./.github/actions/deps + + - run: sudo apt update && sudo apt install -y zip + + - uses: firedancer-io/fuzzbot-builder@main + name: Build fuzz tests + with: + command: make -j -Otarget fuzz-test + + - name: List Artifacts + run: | + ls build/linux/clang/combi/${{ matrix.feature_set }}/fuzz-test + + - uses: firedancer-io/clusterfuzz-action@main + name: Upload fuzz targets to ClusterFuzz + with: + bucket-name: firedancer-builds.isol-clusterfuzz.appspot.com + artifact-dir: build/linux/clang/combi/${{ matrix.feature_set }}/fuzz-test + object-prefix: main/libfuzzer/${{ matrix.feature_set }}/firedancer + project-id: isol-clusterfuzz + qualifier: ${{ matrix.feature_set }} + service-account-credentials: ${{ secrets.FUZZ_SERVICE_ACCT_JSON_BUNDLE }} diff --git a/.github/workflows/_test_fuzz_regressions.yml b/.github/workflows/_test_fuzz_regressions.yml new file mode 100644 index 0000000000..f056a973dc --- /dev/null +++ b/.github/workflows/_test_fuzz_regressions.yml @@ -0,0 +1,28 @@ +name: Test Fuzz Regressions +on: + workflow_call: + workflow_dispatch: +jobs: + test-fuzz-regressions: + name: Test Fuzz Regressions on ${{ matrix.feature_set }} + strategy: + matrix: + feature_set: [modern, highend] + runs-on: + group: ${{ matrix.feature_set == 'highend' && 'rhel85-icelake' || 'github-v1' }} + env: + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + EXTRAS: fuzz asan ubsan + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/deps + - uses: ./.github/actions/hugepages + + - name: Build Fuzz Tests + run: make -j -Otarget fuzz-test + + - name: Run Fuzz Tests Against Corpora + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + make -k -j -Otarget run-fuzz-test diff --git a/.github/workflows/_test_unit.yml b/.github/workflows/_test_unit.yml new file mode 100644 index 0000000000..1683453f90 --- /dev/null +++ b/.github/workflows/_test_unit.yml @@ -0,0 +1,33 @@ +name: Test Unit +on: + workflow_call: + workflow_dispatch: +jobs: + test-unit: + continue-on-error: true + strategy: + matrix: + feature_set: [modern, highend] + compiler: [gcc, clang] + fail-fast: true + runs-on: + group: ${{ matrix.feature_set == 'highend' && 'rhel85-icelake' || 'github-v1' }} + env: + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + CC: ${{ matrix.compiler }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: ./.github/actions/deps + + - name: Build unit tests + run: make -j unit-test + + - uses: ./.github/actions/hugepages + + - name: Run unit tests + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + ./test.sh -j --page-sz gigantic diff --git a/.github/workflows/_test_unit_with_sanitizers.yml b/.github/workflows/_test_unit_with_sanitizers.yml new file mode 100644 index 0000000000..61e5e836b0 --- /dev/null +++ b/.github/workflows/_test_unit_with_sanitizers.yml @@ -0,0 +1,31 @@ +name: Test Unit w/ Sanitizers +on: + workflow_call: + workflow_dispatch: +jobs: + test-with-sanitizers: + # Only run sanitizer tests if the gcc tests passed + continue-on-error: true + strategy: + matrix: + feature_set: [modern, highend] + runs-on: + group: ${{ matrix.feature_set == 'highend' && 'rhel85-icelake' || 'github-v1' }} + env: + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + EXTRAS: asan ubsan + steps: + - run: lscpu + + - uses: actions/checkout@v4 + + - uses: ./.github/actions/deps + - uses: ./.github/actions/hugepages + + - name: Build unit tests + run: make -j -Otarget unit-test + + - name: Run unit tests + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + ./test.sh -j --page-sz gigantic diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml new file mode 100644 index 0000000000..40c75f2148 --- /dev/null +++ b/.github/workflows/book.yml @@ -0,0 +1,65 @@ +# Largely copied from https://vitepress.dev/guide/deploy +name: Deploy VitePress book site to Pages + +on: + # Runs on pushes targeting the `main` branch. Change this to `master` if you're + # using the `master` branch as the default branch. + push: + branches: [main] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Not needed if lastUpdated is not enabled + # - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm + - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun + # - name: Setup Node + # uses: actions/setup-node@v3 + # with: + # node-version: 18 + # cache: npm # or pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: bun install --cwd ./book # or pnpm install / yarn install / bun install + - name: Build with VitePress + run: | + bun run --cwd ./book build # or pnpm docs:build / yarn docs:build / bun run docs:build + touch book/.vitepress/dist/.nojekyll + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: book/.vitepress/dist + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v3 diff --git a/.github/workflows/build_everything.yml b/.github/workflows/build_everything.yml new file mode 100644 index 0000000000..3b8bb00a11 --- /dev/null +++ b/.github/workflows/build_everything.yml @@ -0,0 +1,29 @@ +name: Build everything +on: + workflow_call: + workflow_dispatch: +jobs: + build-frankendancer: + strategy: + # Since this build is on main, it's not rushed for feedback. Avoid wasting runner minutes by limiting parallelism. + max-parallel: 1 + fail-fast: true + matrix: + compiler: [clang, gcc] + feature_set: [modern, highend] + runs-on: + group: github-v1 + env: + CC: ${{ matrix.compiler }} + MACHINE: linux_clang_combi_${{ matrix.feature_set }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: dtolnay/rust-toolchain@1.69.0 + + - uses: ./.github/actions/deps + + - name: Build everything + run: make -j -Otarget all rust diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..7c7f965c22 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,47 @@ +# Kick off a daily battery of extended tests. +# Only runs if latest commit was made within today. + +name: CodeQL +on: + workflow_call: + workflow_dispatch: + +jobs: + # Build and analyze with CodeQL + codeql: + name: Analyze + runs-on: + group: github-v1 + env: + CC: clang + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [cpp, python] # https://aka.ms/codeql-docs/language-support + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: dtolnay/rust-toolchain@1.73.0 + + - uses: ./.github/actions/deps + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Build + run: make -j -Otarget all rust + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" + threads: 0 diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 0000000000..ff22c4ab58 --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,39 @@ +# On every PR and main commit: +# - Build on GCC and Clang +# - Test on GCC + +name: Make +on: + pull_request: + push: + branches: + - main + - runtime + workflow_dispatch: +jobs: + make-build: + strategy: + fail-fast: false + matrix: + compiler: [gcc, clang] + runs-on: + group: github-v1 + env: + CC: ${{ matrix.compiler }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: ./.github/actions/deps + + - name: Build everything + run: make -j -Otarget + + - uses: ./.github/actions/hugepages + + - name: Run unit tests + run: | + sudo prlimit --pid $$ --memlock=-1:-1 + ./test.sh -j --page-sz gigantic + make run-runtime-test diff --git a/.github/workflows/on_daily.yml b/.github/workflows/on_daily.yml new file mode 100644 index 0000000000..513cc64f12 --- /dev/null +++ b/.github/workflows/on_daily.yml @@ -0,0 +1,55 @@ +# This workflow runs every day regardless of new commits + +name: On Daily +on: + schedule: + - cron: '0 0 * * *' + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + all-coverage: + name: All Coverage + runs-on: + group: rhel85-icelake + env: + CC: clang + EXTRAS: llvm-cov + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: ./.github/actions/deps + - uses: ./.github/actions/hugepages + + - name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v2' + with: + credentials_json: ${{ secrets.FUZZ_SERVICE_ACCT_JSON_BUNDLE }} + + - name: 'Set up Cloud SDK' + uses: 'google-github-actions/setup-gcloud@v2' + + - name: Generate all coverage + run: ./.github/workflows/scripts/cov_all.sh + + - name: Upload artifact + run: gcloud storage cp -r ./build/pages/* ${{ vars.COVERAGE_BUCKET }}${{ github.sha }}/ + + - name: Refresh top index + run: | + echo ' + + + + Redirecting to latest coverage... (${{ github.sha }})' > ./build/index.html + gcloud storage cp -r ./build/index.html ${{ vars.COVERAGE_BUCKET }}/ + + - name: Check fuzz canaries + run: ./contrib/find_uncovered_fuzz_canaries.py $(find ./build/ -name 'fuzz_*\.lcov' -type f) diff --git a/.github/workflows/on_daily_with_change.yml b/.github/workflows/on_daily_with_change.yml new file mode 100644 index 0000000000..f61b84c117 --- /dev/null +++ b/.github/workflows/on_daily_with_change.yml @@ -0,0 +1,28 @@ +# This workflow kicks off a daily battery of extended tests. +# It only runs if latest commit was made within today. + +name: On Daily Change +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: +jobs: + # Ensures that cron job is skipped if no commit was made on that day. + check-date: + runs-on: ubuntu-latest + name: Check date of last commit + steps: + - uses: actions/checkout@v4 + - id: should_run + continue-on-error: true + name: check latest commit is less than a day + if: ${{ github.event_name == 'schedule' }} + run: test -z $(git rev-list --after="24 hours" ${{ github.sha }}) && echo "::set-output name=should_run::false" + outputs: + should_run: ${{ github.event_name != 'schedule' || steps.should_run.outputs.should_run }} + + call-codeql: + needs: check-date + if: needs.check-date.outputs.should_run == 'true' + uses: ./.github/workflows/codeql.yml + secrets: inherit diff --git a/.github/workflows/on_main_push.yml b/.github/workflows/on_main_push.yml new file mode 100644 index 0000000000..044fbe68e9 --- /dev/null +++ b/.github/workflows/on_main_push.yml @@ -0,0 +1,34 @@ +name: On Main Push +on: + push: + branches: + - main + - next + workflow_dispatch: +jobs: + test-unit: + name: Unit Tests with Sanitizers Enabled + uses: ./.github/workflows/_test_unit_with_sanitizers.yml + secrets: inherit + + test-fuzz-regressions: + name: Test for Fuzzing Regressions + uses: ./.github/workflows/_test_fuzz_regressions.yml + secrets: inherit + + build-frankendancer: + name: Build Frankendancer + uses: ./.github/workflows/build_everything.yml + + test-functional: + name: Functional Tests + uses: ./.github/workflows/functional_tests.yml + + publish-to-clusterfuzz: + name: Publish to Clusterfuzz + uses: ./.github/workflows/_publish_to_clusterfuzz.yml + secrets: inherit + + whitespace-check: + name: Check for Whitespaces + uses: ./.github/workflows/trailing_whitespace.yml diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml new file mode 100644 index 0000000000..4a5ac8269d --- /dev/null +++ b/.github/workflows/on_pull_request.yml @@ -0,0 +1,20 @@ +name: On Pull Request +on: + pull_request: + workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true +jobs: + test-unit: + name: Unit Tests + uses: ./.github/workflows/_test_unit.yml + secrets: inherit + + build-frankandancer: + name: Build Frankendancer + uses: ./.github/workflows/build_everything.yml + + whitespace-check: + name: Check for Whitespaces + uses: ./.github/workflows/trailing_whitespace.yml diff --git a/.github/workflows/scripts/cov_all.sh b/.github/workflows/scripts/cov_all.sh new file mode 100755 index 0000000000..db82395711 --- /dev/null +++ b/.github/workflows/scripts/cov_all.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +set -uEexo pipefail + +sudo prlimit --pid $$ --memlock=-1:-1 +ulimit -a + +mkdir -p build/pages/cov/{test,fuzz} + +MACHINES=$(ls -1 config/linux_clang_combi_* | xargs -I{} basename {} .mk) + +# TEST COVERAGE + +# Build and run tests for all feature combinations +for MACHINE in $MACHINES; do + # Todo: enable lowend once it builds + if [[ $MACHINE == linux_clang_combi_lowend ]]; then + continue + fi + export MACHINE + export EXTRAS=llvm-cov + make clean + make -j -o=target all + ./test.sh -j --page-sz gigantic +done + +for LEVEL in $(ls -1 build/linux/clang/combi/); do + export MACHINE="linux_clang_combi_${LEVEL}" + # Run script tests + export LLVM_PROFILE_FILE="build/linux/clang/combi/${LEVEL}/cov/raw/script_tests_%p.profraw" + sudo --preserve-env=LLVM_PROFILE_FILE,MACHINE make run-script-test + make cov-report + + rm -rf "build/pages/cov/test/${LEVEL}" || true + mv "build/linux/clang/combi/${LEVEL}/cov/html/" "build/pages/cov/test/${LEVEL}" +done + +make combicov-report +rm -rf build/pages/cov/test/_combined || true +mv build/combi-cov/html build/pages/cov/test/_combined + + +FEATURE_SETS_BUILT=$(ls -1 build/linux/clang/combi/) + + +# FUZZ COVERAGE +mkdir -p build/fuzzcov/{profraw,profdata,lcov,corpus,corpus_unpacked} + +#ALL_AVAILABLE_CORPORA=$(printf '%s' "$(gcloud storage ls gs://backup.isol-clusterfuzz.appspot.com/corpus/libFuzzer/)") +ALL_AVAILABLE_CORPORA="$(gcloud storage ls gs://backup.isol-clusterfuzz.appspot.com/corpus/libFuzzer/)" + +# Let's use the previous run to figure out which corpora to fetch +for FEATURES in $FEATURE_SETS_BUILT; do + echo $FEATURES + echo $ALL_AVAILABLE_CORPORA + TO_CONSUME=$(echo -n $ALL_AVAILABLE_CORPORA | tr " " "\n" | awk "/-${FEATURES}\/$/") + + for CORPUS in $TO_CONSUME; do + BASE=$(basename $CORPUS) + gcloud storage cp "${CORPUS}latest.zip" "build/fuzzcov/corpus/${BASE}.zip" + unzip -o -q "build/fuzzcov/corpus/${BASE}.zip" -d build/fuzzcov/corpus_unpacked/${BASE} || true < <(yes) + done +done + +# Build Fuzzers and run coverage based on ClusterFuzz corpus +for FEATURES in $FEATURE_SETS_BUILT; do + export MACHINE=linux_clang_combi_${FEATURES} + export EXTRAS='llvm-cov fuzz' + make clean + make -j fuzz-test + + # Generate profraw and an html page for each fuzz target + for TARGET_NAME in $(ls -1 build/linux/clang/combi/${FEATURES}/fuzz-test/); do + TARGET=build/linux/clang/combi/${FEATURES}/fuzz-test/${TARGET_NAME}/${TARGET_NAME} || true + CORPUS_DIR="build/fuzzcov/corpus_unpacked/${TARGET_NAME}-${FEATURES}" + + if [[ -d "${CORPUS_DIR}" ]]; then + export LLVM_PROFILE_FILE="build/linux/clang/combi/${FEATURES}/cov/raw/${TARGET_NAME}.profraw" + $TARGET -timeout=10 -runs=10 $CORPUS_DIR || true + + llvm-profdata merge -o "build/linux/clang/combi/${FEATURES}/${TARGET_NAME}.profdata" build/linux/clang/combi/${FEATURES}/cov/raw/${TARGET_NAME}.profraw + llvm-cov export $TARGET -instr-profile="build/linux/clang/combi/${FEATURES}/${TARGET_NAME}.profdata" -format=lcov > "build/linux/clang/combi/${FEATURES}/${TARGET_NAME}.lcov" + genhtml --output-directory "build/pages/cov/fuzz/${FEATURES}/${TARGET_NAME}" "build/linux/clang/combi/${FEATURES}/${TARGET_NAME}.lcov" + + else + echo "corpus does not exist for ${TARGET}-${FEATURES}" + fi + done + + llvm-profdata merge -o "build/linux/clang/combi/${FEATURES}/cov.profdata" $(ls -1 build/linux/clang/combi/${FEATURES}/cov/raw/*.profraw) + llvm-cov export $TARGET -instr-profile="build/linux/clang/combi/${FEATURES}/cov.profdata" -format=lcov > "build/linux/clang/combi/${FEATURES}/cov.lcov" + make cov-report + rm -rf "build/pages/cov/fuzz/${FEATURES}/_combined" || true + mv build/linux/clang/combi/${FEATURES}/cov/html/ "build/pages/cov/fuzz/${FEATURES}/_combined" +done + + +make combicov-report +rm -rf build/pages/cov/fuzz/_combined || true +mv build/combi-cov/html/ build/pages/cov/fuzz/_combined + +export FEATURE_SETS_BUILT +.github/workflows/scripts/testcov_gen_index.sh diff --git a/.github/workflows/scripts/testcov_gen_index.sh b/.github/workflows/scripts/testcov_gen_index.sh new file mode 100755 index 0000000000..da17868bf3 --- /dev/null +++ b/.github/workflows/scripts/testcov_gen_index.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +set -uEexo pipefail + +# Generate indices + +FUZZ_TARGETS=$(ls -1 build/pages/cov/fuzz/) +TEST_TARGETS=$(ls -1 build/pages/cov/test/) + +# Generate fuzz index +for TARGET in $FEATURE_SETS_BUILT; do + DIRS=$(echo build/pages/cov/fuzz/$TARGET/) + PAGE="build/pages/cov/fuzz/$TARGET/index.html" + echo "

Fuzz / $TARGET

" > $PAGE + echo '
' >> $PAGE +done +echo '' >> $PAGE + + +PAGE="build/pages/cov/fuzz/index.html" +echo "

Fuzz /

" > $PAGE +echo '