Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches: [main]
pull_request:
branches: [main]
schedule:
# Nightly fork tests against testnet (issue #88).
- cron: '0 3 * * *'

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -259,3 +262,24 @@ jobs:
with:
name: coverage-lcov
path: lcov.info

# Scheduled fork tests against Stellar testnet (issue #88).
# Stubbed pending soroban-sdk ≥ 22.x upgrade; all tests are
# `#[ignore]`-d, so this job passes harmlessly until real fork-
# mode assertions land.
fork-test:
name: Fork Test (testnet nightly)
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
target: wasm32-unknown-unknown
- name: Build WASM
run: cargo build --release --target wasm32-unknown-unknown
- name: Run fork tests (--ignored)
run: cargo test --features fork -- --ignored
env:
STELLAR_RPC_URL: https://soroban-testnet.stellar.org
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Fork test skeleton: `tests/fork.rs` with stubs for Soroban fork-mode testing against testnet, gated behind `--features fork` and `#[ignore]` until the SDK is upgraded to ≥ 22.x (Issue #88)
- `Cargo.toml`: `[features]` section with `fork = []` flag (Issue #88)
- CI: nightly `fork-test` job that runs `cargo test --features fork -- --ignored` once per night (Issue #88)
- README: fork-test documentation explaining prerequisites and how to run `cargo test --features fork` (Issue #88)
- CI: `changelog` job that diffs `src/lib.rs`'s public API surface against the PR base and fails when `CHANGELOG.md` is not updated (Issue #112)
- `scripts/check_changelog.sh` – the bash check invoked by the new job; reusable locally via `BASE_REF=origin/main HEAD_REF=HEAD bash scripts/check_changelog.sh`
- `make check-changelog` – convenience target for running the check offline
Expand Down
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ soroban-sdk = "=21.7.7"
soroban-sdk = { version = "=21.7.7", features = ["testutils"] }
proptest = "1.4.0"

[features]
# Enable fork tests against Stellar testnet (requires RPC access).
# Usage: cargo test --features fork -- --ignored
fork = []

[profile.release]
opt-level = "z"
overflow-checks = true
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,19 @@ make lint
make check # fmt + lint + test + wasm-build
```

### Fork Tests (against testnet)

Fork tests validate the contract against a forked snapshot of the Stellar
testnet. They are gated behind the `fork` feature and ignored by default.

```bash
# Prerequisites: soroban-sdk ≥ 22.x, a testnet RPC endpoint
cargo test --features fork -- --ignored
```

These tests currently contain stubs pending the SDK upgrade to 22.x
(see `tests/fork.rs`). A CI job runs them nightly on schedule.

### Deploy (testnet)

```bash
Expand Down
87 changes: 87 additions & 0 deletions tests/fork.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//! # Soroban fork tests against Stellar testnet (issue #88)
//!
//! This module runs the same set of invariants as the unit tests in
//! `src/test.rs`, but against a **forked** testnet state rather than an
//! isolated `Env::default()` host.
//!
//! ## Why fork tests matter
//!
//! Soroban's emulated host is deterministic but not exhaustive. Fork tests
//! catch issues that only surface against real RPC behaviour, host-side
//! authorization verification, actual `symbol_short` truncations, and real
//! reclaim gas costs.
//!
//! ## Prerequisites
//!
//! Fork testing requires soroban-sdk ≥ 22.x (`test_snapshot`
//! infrastructure). This project currently pins soroban-sdk 21.7.7 for
//! stability (see `Cargo.toml`). **The fork tests are gated behind the
//! `fork` feature and ignored by default.**
//!
//! When the SDK is upgraded to 22.x (tracked in issue #88), replace the
//! stubs below with real fork-mode assertions.
//!
//! ## Running (post-upgrade)
//!
//! ```bash
//! export STELLAR_RPC_URL=https://soroban-testnet.stellar.org
//! cargo test --features fork -- --ignored
//! ```

// ---------------------------------------------------------------------------
// Stubs — TODO: replace with real fork tests after SDK 22.x upgrade
// ---------------------------------------------------------------------------

/// Entry point: validate the deployed contract WASM against forked testnet
/// state. All concrete assertions live in the helper modules below.
#[test]
#[ignore = "Fork tests require soroban-sdk ≥ 22.x (see module-level docs)"]
#[cfg(feature = "fork")]
fn fork_invariants() {
// TODO(#88): Replace this stub with a real fork-mode test.
//
// Expected structure (soroban-sdk 22.x):
// ```rust,ignore
// let env = Env::from_snapshot_file("testnet-snapshot.json")?;
// env.register_contract_wasm_from_file("target/wasm32-unknown-unknown/release/stellar_tip.wasm");
// // Replay the full unit-test invariant suite against forked state.
// ```
//
// Until then, this test is `#[ignore]`-d so CI passes without a
// testnet RPC.
}

/// Fork-mode test that replays registration invariants against testnet
/// state.
#[test]
#[ignore = "Fork tests require soroban-sdk ≥ 22.x"]
#[cfg(feature = "fork")]
fn fork_registration_invariants() {
// TODO(#88): register → assert profile exists → assert creator count.
}

/// Fork-mode test that replays tipping invariants against testnet state.
#[test]
#[ignore = "Fork tests require soroban-sdk ≥ 22.x"]
#[cfg(feature = "fork")]
fn fork_tipping_invariants() {
// TODO(#88): tip → assert balance updated → assert tip recorded.
}

/// Fork-mode test that replays withdrawal invariants against testnet
/// state.
#[test]
#[ignore = "Fork tests require soroban-sdk ≥ 22.x"]
#[cfg(feature = "fork")]
fn fork_withdrawal_invariants() {
// TODO(#88): withdraw → assert tokens transferred → assert balance zero.
}

/// Fork-mode test that replays admin-rotation invariants against testnet
/// state.
#[test]
#[ignore = "Fork tests require soroban-sdk ≥ 22.x"]
#[cfg(feature = "fork")]
fn fork_admin_invariants() {
// TODO(#88): pause → rotate admin → set fee recipient → unpause → tip.
}
Loading