diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..04da0a572 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,279 @@ +version: 2.1 + +orbs: + codecov: codecov/codecov@5.2.0 + +executors: + linux-executor: + machine: + image: ubuntu-2004:current + python-executor: + docker: + - image: cimg/python:3.10 + macos-executor: + macos: + xcode: 15.4.0 + resource_class: m2pro.medium + +jobs: + setup_zig: + parameters: + target: + type: string + executor: linux-executor + steps: + - checkout + - run: + name: Download Zig + command: | + apt update && apt install -y wget unzip xz-utils + wget https://ziglang.org/download/0.13.0/zig-<< parameters.target >>-0.13.0.tar.xz + tar xf zig-<< parameters.target >>-0.13.0.tar.xz + mkdir -p workspace + mv zig-<< parameters.target >>-0.13.0 workspace/zig + - persist_to_workspace: + root: workspace + paths: + - '*' + + lint: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Lint + command: workspace/zig/zig fmt --check src/ build.zig + + check_style: + executor: python-executor + steps: + - checkout + - run: + name: Install dependencies + command: pip install --upgrade pip + - run: + name: Check style + command: python scripts/style.py --check src + + build_linux: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - restore_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-v6 + - run: + name: Build + command: | + apt update && apt install wget -y + ./scripts/proxy_workaround.sh workspace/zig/zig + workspace/zig/zig build -Denable-tsan=true -p workspace/zig-out -Dcpu=x86_64_v3 --summary all + - save_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-v6 + paths: + - .zig-cache + - ~/.cache/zig + - persist_to_workspace: + root: workspace + paths: + - "zig-out/bin/test" + + build_linux_release: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - restore_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-release-v3 + - run: + name: Build + command: | + apt update && apt install wget -y + ./scripts/proxy_workaround.sh workspace/zig/zig + workspace/zig/zig build sig fuzz -Dno-run -Denable-tsan=false -Doptimize=ReleaseSafe -Dcpu=x86_64_v3 -p workspace/zig-out-release --summary all + - save_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-release-v3 + paths: + - .zig-cache + - ~/.cache/zig + - persist_to_workspace: + root: workspace + paths: + - "zig-out-release/bin/sig" + - "zig-out-release/bin/fuzz" + + build_and_test_macos: + executor: macos-executor + steps: + - checkout + - attach_workspace: + at: workspace + - restore_cache: + key: macos-aarch64-0.13.0-{{ checksum "build.zig.zon" }} + - run: + name: Build + command: | + export PATH="workspace/zig:$PATH" + # it seems that the feature detection is a bit broken in CircleCI's virtual machines + # so we will manually say that it's an Apple M2. + zig build -Denable-tsan=false -Dno-run -Dcpu=apple_m2 --summary all + zig build test -Denable-tsan=false -Dblockstore=hashmap -Dfilter="ledger" -Dno-bin -Dcpu=apple_m2 + zig-out/bin/test + - save_cache: + key: macos-aarch64-0.13.0-{{ checksum "build.zig.zon" }} + paths: + - .zig-cache + - ~/.cache/zig + + build_and_test_hashmap: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - restore_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-v6 + - run: + name: Build and Test + command: workspace/zig/zig build test -Denable-tsan=true -Dblockstore=hashmap -Dcpu=x86_64_v3 -Dfilter="ledger" --color off --summary all + + test_linux: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + # Restore the cache in order to have access to the files which the DWARF info + # is referencing when dumping stack traces. + - restore_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-v6 + - run: + name: Test + command: workspace/zig/zig build test -Dcpu=x86_64_v3 -Denable-tsan=true --color off --summary all + + test_kcov_linux: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - restore_cache: + key: linux-x86_64-0.13.0-{{ checksum "build.zig.zon" }}-v6 + - run: + name: Build + command: workspace/zig/zig build test -Dcpu=x86_64_v3 -Denable-tsan=false -Dno-run --summary all + - run: + name: Test and Collect + command: | + docker run --security-opt seccomp=unconfined \ + -v .:/home/circleci/project \ + kcov/kcov \ + bash /home/circleci/project/scripts/kcov_ci.sh + - codecov/upload: + dir: kcov-merged/kcov-merged + + gossip: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Run Gossip + command: bash scripts/gossip_test.sh 120 workspace/zig-out-release/bin/sig + + gossip_service_fuzz: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Run Gossip Service Fuzzer + command: workspace/zig-out-release/bin/fuzz gossip_service 19 10000 + + gossip_table_fuzz: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Run Gossip Service Fuzzer + command: workspace/zig-out-release/bin/fuzz gossip_table 19 100000 + + allocators_fuzz: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Run Gossip Service Fuzzer + command: workspace/zig-out-release/bin/fuzz allocators 19 10000 + + ledger_fuzz: + executor: linux-executor + steps: + - checkout + - attach_workspace: + at: workspace + - run: + name: Run Gossip Service Fuzzer + command: workspace/zig-out-release/bin/fuzz ledger 19 10000 + + +workflows: + check_linux: + jobs: + - check_style + - setup_zig: + name: setup_zig_linux + target: "linux-x86_64" + - lint: + requires: + - setup_zig_linux + - build_linux_release: + requires: + - setup_zig_linux + - build_linux: + requires: + - setup_zig_linux + - build_and_test_hashmap: + requires: + - build_linux + - test_linux: + requires: + - build_linux + - test_kcov_linux: + requires: + - setup_zig_linux + - gossip: + requires: + - build_linux_release + - gossip_service_fuzz: + requires: + - build_linux_release + - gossip_table_fuzz: + requires: + - build_linux_release + - allocators_fuzz: + requires: + - build_linux_release + - ledger_fuzz: + requires: + - build_linux_release + + check_macos: + jobs: + - setup_zig: + name: setup_zig_macos + target: "macos-aarch64" + - build_and_test_macos: + requires: + - setup_zig_macos + \ No newline at end of file diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index 841eb1368..000000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,316 +0,0 @@ -name: check - -on: - push: - branches: [main, pre-release] - pull_request: - merge_group: - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: mlugg/setup-zig@v1 - with: - version: 0.13.0 - - - name: lint - run: zig fmt --check src/ build.zig - - check_style: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - - name: check style - run: python scripts/style.py --check src - - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: mlugg/setup-zig@v1 - with: - version: 0.13.0 - - - name: build - run: | - zig build test -Denable-tsan=true -Dno-run -p output/tsan - zig build test -Denable-tsan=false -Dno-run -p output/no-tsan/ - zig build test -Denable-tsan=true -Dblockstore=hashmap -Dfilter="ledger" -Dno-run -p output/hashmap - - # In order to not loose the execution permissions of the binaries, - # we tar everything together before uploading - - name: bundle - run: tar -cvf zig-build.tar output/ - - - uses: actions/upload-artifact@v4 - with: - name: zig-build - path: zig-build.tar - - # GitHub's CI runners for macos seem to alternate between using a x86 and an ARM machine - # which is annoying to handle and results in them having invalid hardware info configurations - # on the virtual machine. This leads to incorrect feature detection and the CI is flaky. - # - # If we at some point setup a self-hosted MacOS runner, we could work around the issue and - # enable full testing on MacOS! - build-macos: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: mlugg/setup-zig@v1 - with: - version: 0.13.0 - - - name: build - run: zig build -Dtarget=aarch64-macos -Dcpu=apple_m3 - - test: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build - - - name: test - run: output/tsan/bin/test - - - name: test-hashmap - run: output/hashmap/bin/test - - kcov_test: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build - - - name: Set up dependencies - run: sudo apt-get update - - - name: install kcov - run: | - wget https://github.com/SimonKagstrom/kcov/releases/download/v42/kcov-amd64.tar.gz - sudo tar xf kcov-amd64.tar.gz -C / - - - name: fix kcov dependencies - run: | - cd /usr/lib/x86_64-linux-gnu/ - sudo ln libopcodes-2.42-system.so libopcodes-2.38-system.so || echo libopcodes not found - sudo ln libbfd-2.42-system.so libbfd-2.38-system.so || echo libbfd not found - - - name: run kcov - run: bash scripts/kcov_test.sh output/no-tsan/bin/test - - - name: print coverage report - run: python scripts/parse_kcov.py kcov-output/test/coverage.json - - build-release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: mlugg/setup-zig@v1 - with: - version: 0.13.0 - - - name: build - run: zig build sig fuzz -Doptimize=ReleaseSafe -Dno-run - - - name: bundle - run: tar -cvf zig-build-release.tar zig-out/ - - - uses: actions/upload-artifact@v4 - with: - name: zig-build-release - path: zig-build-release.tar - - gossip: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build-release - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build-release - - - name: run gossip - run: bash scripts/gossip_test.sh 120 # in seconds - - gossip_service_fuzz: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - timeout-minutes: 60 - needs: build-release - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build-release - - - name: run - run: ./zig-out/bin/fuzz gossip_service 19 10000 - - gossip_table_fuzz: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build-release - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build-release - - - name: run - run: ./zig-out/bin/fuzz gossip_table 19 100000 - - allocators_fuzz: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build-release - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build-release - - - name: run - run: ./zig-out/bin/fuzz allocators 19 10000 - - ledger_fuzz: - strategy: - matrix: - os: [ubuntu-latest] - runs-on: ${{matrix.os}} - needs: build-release - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: ./.github/actions/setup - with: - name: zig-build-release - - - name: run - run: ./zig-out/bin/fuzz ledger 19 10000 - - # benchmarks: - # if: ${{ github.ref != 'refs/heads/main' }} - # strategy: - # matrix: - # os: [ubuntu-latest] - # runs-on: ${{matrix.os}} - # timeout-minutes: 60 - # steps: - # - name: checkout - # uses: actions/checkout@v2 - # with: - # submodules: recursive - # - name: setup zig - # uses: mlugg/setup-zig@v1 - # with: - # version: 0.13.0 - # - name: benchmarks - # run: zig build -Doptimize=ReleaseSafe benchmark -- all --metrics - - # # Download previous benchmark result from cache (if exists) - # - name: Download previous benchmark data - # uses: actions/cache@v4 - # with: - # path: ./cache - # key: ${{ runner.os }}-benchmark - - # # Run `github-action-benchmark` action - # - name: Store benchmark result - # uses: benchmark-action/github-action-benchmark@v1 - # with: - # # What benchmark tool the output.txt came from - # tool: "customSmallerIsBetter" - # # Where the output from the benchmark tool is stored - # output-file-path: results/output.json - # # Where the previous data file is stored - # external-data-json-path: ./cache/benchmark-data.json - # # Workflow will fail when an alert happens - # fail-on-alert: true - # # GitHub API token to make a commit comment - # github-token: ${{ secrets.GITHUB_TOKEN }} - # # Enable alert commit comment - # comment-on-alert: true - # # Upload the updated cache file for the next job by actions/cache - # # only when running on the main branch - # save-data-file: false - - # main_benchmarks: - # if: ${{ github.ref == 'refs/heads/main' }} - # strategy: - # matrix: - # os: [ubuntu-latest] - # runs-on: ${{matrix.os}} - # timeout-minutes: 60 - # steps: - # - name: checkout - # uses: actions/checkout@v2 - # with: - # submodules: recursive - # - name: setup zig - # uses: mlugg/setup-zig@v1 - # with: - # version: 0.13.0 - # - name: benchmarks - # run: zig build -Doptimize=ReleaseSafe benchmark -- all --metrics - - # # Download previous benchmark result from cache (if exists) - # - name: Download previous benchmark data - # uses: actions/cache@v4 - # with: - # path: ./cache - # key: ${{ runner.os }}-benchmark - - # # Run `github-action-benchmark` action - # - name: Store benchmark result - # uses: benchmark-action/github-action-benchmark@v1 - # with: - # # What benchmark tool the output.txt came from - # tool: "customSmallerIsBetter" - # # Where the output from the benchmark tool is stored - # output-file-path: results/output.json - # # Where the previous data file is stored - # external-data-json-path: ./cache/benchmark-data.json - # # Workflow will fail when an alert happens - # fail-on-alert: true - # # Upload the updated cache file for the next job by actions/cache - # # only when running on the main branch (see if:) - # save-data-file: true diff --git a/.gitignore b/.gitignore index f241b9a48..afd589ff2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /data/fuzz-data /gossip-dumps /kcov-output +/kcov-merged /results /validator /logs diff --git a/docs/imgs/ci.png b/docs/imgs/ci.png new file mode 100644 index 000000000..ca3f8deb6 Binary files /dev/null and b/docs/imgs/ci.png differ diff --git a/scripts/gossip_test.sh b/scripts/gossip_test.sh index 083879341..01b51319f 100644 --- a/scripts/gossip_test.sh +++ b/scripts/gossip_test.sh @@ -16,10 +16,15 @@ if ! [[ "$1" =~ ^[0-9]+$ ]]; then usage fi +sig_path="./zig-out/bin/sig" +if [ ! -z "$2" ]; then + sig_path=$2 +fi + echo "Running gossip test for $1 seconds" # build and run gossip -./zig-out/bin/sig gossip \ +$sig_path gossip \ -e entrypoint.testnet.solana.com:8001 \ -e entrypoint2.testnet.solana.com:8001 2>&1 & diff --git a/scripts/kcov_ci.sh b/scripts/kcov_ci.sh new file mode 100644 index 000000000..bbdc4c7c2 --- /dev/null +++ b/scripts/kcov_ci.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -exo pipefail + +cd /home/circleci/project +mkdir kcov-output + +echo "=> Running kcov on tests" +kcov \ + --collect-only \ + --include-pattern=src/ \ + --exclude-pattern=$HOME/.cache \ + kcov-output \ + zig-out/bin/test +kcov --merge kcov-merged kcov-output/ +echo "=> Done" \ No newline at end of file diff --git a/scripts/kcov_test.sh b/scripts/kcov_test.sh index 04a8fe0ee..016ed1e52 100755 --- a/scripts/kcov_test.sh +++ b/scripts/kcov_test.sh @@ -19,9 +19,10 @@ echo "=> Cleaning up" rm -rf kcov-output mkdir kcov-output + if [ -z "$1" ]; then echo "=> Building Sig" - zig build + zig build test_bin="./zig-out/bin/test" else test_bin="$1" @@ -29,10 +30,9 @@ fi echo "=> Running kcov on tests" kcov \ + --collect-only \ --include-pattern=src/ \ --exclude-pattern=$HOME/.cache \ kcov-output \ - $test_bin - -echo "=> Opening kcov-output/index.html" -open kcov-output/index.html || echo "=> Failed to open kcov-output/index.html" + $test_bin +kcov --merge kcov-merged kcov-output/ \ No newline at end of file diff --git a/scripts/proxy_workaround.sh b/scripts/proxy_workaround.sh new file mode 100755 index 000000000..077c841f8 --- /dev/null +++ b/scripts/proxy_workaround.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +forceupdate=false +if [ "$1" = "-f" ]; then + forceupdate=true + shift +fi + +zig_path="zig" +if [ ! -z "$1" ]; then + zig_path=$1 + shift +fi + +do_fetch() { + for d in `grep -o '^[[:space:]]*[^/[:space:]][^=]*url *=.*' $1 | cut -d = -f 2`; do + d=`echo $d | grep -o 'https://[^"]*'` + echo -e "\n>>> Deal with $d" + if echo $d | grep -q '\.tar\.gz$'; then + url=$d + elif echo $d | grep -q '#[.0-9a-z]*$'; then + url_base=`echo $d | awk -F \# '{print $1}'` + url_base=${url_base%.git} + url_commit=`echo $d | awk -F \# '{print $2}'` + url="${url_base}/archive/${url_commit}.tar.gz" + else + echo ">>> Ignored $d, unable to resolve it!" + continue + fi + hash=`grep -m 1 -A 1 "$d" $1 | grep hash | awk -F \" '{print $(NF-1)}'` + if [ -z "$hash" ]; then + forceupdate=true + fi + if ! $forceupdate && [ -e ~/.cache/zig/p/$hash ]; then + echo ">>> Found $url in cache, ignored" + continue + fi + wget $url + tarfile=${url##*/} + hash=`$zig_path fetch --debug-hash $tarfile | tail -n 1` + echo ">> hash of $d:" + echo -e "\t$hash" + rm $tarfile + if [ -e ~/.cache/zig/p/$hash/build.zig.zon ]; then + do_fetch ~/.cache/zig/p/$hash/build.zig.zon + fi + done + + for d in `grep -o 'path *=.*' $1 | cut -d = -f 2`; do + path=`echo $d | awk -F \" '{print $(NF-1)}'` + if [ -e $path/build.zig.zon ]; then + do_fetch $path/build.zig.zon + fi + done +} + +zonfile=$1 +if [ -z "$zonfile" ]; then + zonfile=build.zig.zon +fi + +if ! [ -e $zonfile ]; then + echo "can't find build.zig.zon!" + exit 1 +fi + +do_fetch $zonfile \ No newline at end of file