-
Notifications
You must be signed in to change notification settings - Fork 1.9k
214 lines (197 loc) · 9.06 KB
/
Copy pathtests.yaml
File metadata and controls
214 lines (197 loc) · 9.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
name: Tests
on:
push:
branches:
- anchor-next
paths-ignore:
- "docs/**"
pull_request:
paths-ignore:
- "docs/**"
workflow_dispatch:
env:
SOLANA_VERSION: "3.1.10"
SBF_TOOLS_VERSION: "v1.52"
jobs:
test-v2:
name: v2 Tests
runs-on: ubuntu-latest
timeout-minutes: 60
env:
CARGO_INCREMENTAL: "0"
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup/
# tests-v2 runs `cargo build-sbf` on its member programs; the rest of
# the v2 stack doesn't need the Solana toolchain but installing it
# once for the whole job is cheaper than splitting the matrix.
- uses: ./.github/actions/setup-solana/
# Cache dependency downloads, but do not cache target directories here:
# coverage and debugger runs leave multi-GB artifacts behind, and saving
# or restoring those archives costs more than it buys in this job.
- uses: actions/cache@v4
name: Cache Cargo home
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: cargo-home-${{ runner.os }}-v2-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
cargo-home-${{ runner.os }}-v2-
# Install platform-tools up front so the concurrent `cargo build-sbf`
# invocations fired by parallel test threads don't race on the
# one-time extract-then-rename of the platform-tools directory (surfaces
# in CI as `Unable to rename: No such file or directory`).
# SBF_TOOLS_VERSION must match `tests-v2/src/lib.rs::build_program`.
#
# Cache the platform-tools directory separately from the Solana tool
# suite cache. The Solana cache is keyed by CLI version and may already
# be a hit before this directory exists, so it will not save platform
# tools that `cargo build-sbf --install-only` downloads later in the job.
- uses: actions/cache@v4
name: Cache SBF platform tools
with:
path: ~/.cache/solana/${{ env.SBF_TOOLS_VERSION }}/platform-tools
key: solana-platform-tools-${{ runner.os }}-${{ env.SBF_TOOLS_VERSION }}
- run: cargo build-sbf --tools-version "$SBF_TOOLS_VERSION" --install-only
# Tools for `make coverage-v2`:
# - lcov for merging sbf.lcov + host.lcov and generating the report.
# - cargo-llvm-cov for host-side instrumentation coverage.
#
# The three direct `cargo test -p anchor-{lang,spl}-v2` / `-p tests-v2`
# invocations that used to live here (including `anchor-lang-v2`'s
# `--features testing` flag for the Miri-witnesses scaffold) are
# subsumed by the coverage-v2 steps below — the Makefile's host
# coverage targets run the same packages under instrumentation.
- name: Install lcov
run: sudo apt-get install -y --no-install-recommends lcov
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
# Run the v2 test suite with coverage enabled, split across the same SBF
# and host-side coverage boundaries used by `make coverage-v2`. Each
# step still fails on test failure while keeping the slowest package
# boundary visible in the Actions UI.
- name: v2 SBF runtime coverage
run: make coverage-v2-sbf
- name: Prune v2 SBF coverage scratch
run: make coverage-v2-sbf-prune
- name: v2 host coverage setup
run: make coverage-v2-host-clean
- name: v2 host coverage for anchor-lang-v2
run: make coverage-v2-host-lang
- name: v2 host coverage for anchor-spl-v2
run: make coverage-v2-host-spl
- name: v2 host coverage for tests-v2
env:
CARGO_BUILD_JOBS: "1"
run: make coverage-v2-host-tests
- name: v2 host coverage for idl-build fixtures
run: make coverage-v2-host-idl-build
- name: Generate v2 coverage report
run: |
make coverage-v2-host-report
make coverage-v2-report
# Upload to Codecov. The action handles comment posting on PRs via
# the Codecov GitHub App — including fork PRs, where the token
# flows through their bot instead of our workflow's `GITHUB_TOKEN`.
#
# `token` is optional on public repos (Codecov supports tokenless
# uploads for open-source projects) but passing the repo-scoped
# secret when available speeds upload discovery and is required on
# anchor-next pushes. On fork PRs the secret is empty — the action
# falls through to the tokenless flow automatically.
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: target/coverage/combined.lcov
flags: v2
fail_ci_if_error: false
# Miri (Tree Borrows) — UB + aliasing + provenance checks on the
# same integration tests above. Catches things the default cargo
# test run can't: `AccountView` copy-aliasing, `Slab::header_ptr`
# write provenance, `AccountCursor::next` strict-provenance walks.
# Caches the nightly toolchain and miri component to avoid a
# per-run rustup fetch (~200 MB).
- uses: actions/cache@v4
name: Cache rustup nightly + miri
with:
path: |
~/.rustup/toolchains/
~/.rustup/update-hashes/
~/.rustup/settings.toml
key: rustup-miri-${{ runner.os }}-v2-${{ hashFiles('rust-toolchain*', '**/rust-toolchain*') }}
restore-keys: |
rustup-miri-${{ runner.os }}-v2-
- name: Install nightly + miri
run: |
rustup toolchain install nightly --component miri --profile minimal
cargo +nightly miri setup
- name: Miri (Tree Borrows) for anchor-lang-v2 + anchor-spl-v2
env:
MIRIFLAGS: '-Zmiri-tree-borrows'
run: cargo +nightly miri test -p anchor-lang-v2 -p anchor-spl-v2 --tests --features anchor-lang-v2/testing
# Kani harnesses live in-tree under `#[cfg(kani)]` and are runnable
# locally via `cargo kani -p anchor-lang-v2` / `-p anchor-spl-v2`,
# but are not wired into CI: kani-verifier 0.67.0 has an
# upstream-deterministic `.unwrap()` panic on CBMC `ERROR` status
# lines (kani#4519, fixed on main in #4540, not yet released).
# Re-enable once kani-verifier ≥ 0.68.0 ships on crates.io.
# CLI: unit-test + build sanity only. No anchor-binary install,
# no `anchor build`/`anchor test` flows, no tests/* integration.
- name: Run CLI Tests
run: cargo test -p anchor-cli
# Install the `anchor` bin to `~/.cargo/bin` (already on PATH via
# rustup). Shared `./target/` via `--target-dir` means the build
# reuses artifacts from prior `cargo test -p anchor-cli` instead
# of starting from scratch in a temp tree; `--debug` skips release
# opt (smoke test — runtime speed doesn't matter).
- name: Install CLI
run: cargo install --path cli --locked --debug --force --target-dir ./target
# `anchor debugger` smoke test. These bench crates have no
# Anchor.toml, so the CLI falls into loose mode and runs the full
# pipeline: `cargo build-sbf` → `cargo test --features profile` →
# TUI. We wrap in `script` so crossterm can enter raw mode on a
# pty (GHA stdin/stdout aren't ttys) and `timeout` kills the TUI
# once it's in its event loop.
#
# Failure handling: each `prog` is run in its own subshell so
# `cd` is scoped (no `popd` bookkeeping) and so `|| rc=$?`
# captures the inner pipeline's exit status directly. Build and
# TUI phases are kept distinct so a build break is reported as
# such instead of bleeding into a confusing TUI failure.
#
# Exit-code semantics for the TUI phase:
# 124 → timeout-killed (TUI was still alive — success)
# 0 → clean exit (rare in CI; legal)
# else → real failure; dump the pty log
- name: anchor debugger TUI launches for bench anchor-v2 programs
run: |
set -euo pipefail
fail=0
for prog in bench/programs/*/anchor-v2; do
echo "::group::anchor debugger in $prog"
log=$(mktemp)
# Build phase — surface build breaks as a distinct error.
if ! ( cd "$prog" && anchor coverage ); then
echo "::error::`anchor coverage` failed in $prog"
fail=1
rm -f "$log"
echo "::endgroup::"
continue
fi
# TUI phase — `|| rc=$?` captures the subshell exit cleanly
# without toggling `set +e`/`set -e` around it.
rc=0
( cd "$prog" && timeout --kill-after=30 30 \
script -qec 'anchor debugger --skip-build' "$log" ) || rc=$?
if [ "$rc" -ne 0 ] && [ "$rc" -ne 124 ]; then
echo "::error::anchor debugger failed in $prog (exit $rc)"
cat "$log"
fail=1
fi
rm -f "$log"
echo "::endgroup::"
done
exit "$fail"