diff --git a/.github/workflows/integration-chaos.yml b/.github/workflows/integration-chaos.yml new file mode 100644 index 0000000..2b7c1c7 --- /dev/null +++ b/.github/workflows/integration-chaos.yml @@ -0,0 +1,42 @@ +name: Stellar Chaos Tests + +on: + schedule: + - cron: "0 3 * * 0" # Weekly, Sunday 3am UTC + workflow_dispatch: # Manual trigger + +# Reviewed toolchain pins. Bump them only through the process in SUPPLY_CHAIN.md. +env: + RUST_TOOLCHAIN: '1.98.1' + STELLAR_CLI_VERSION: '28.0.0' + +jobs: + chaos: + name: Local chaos suite + runs-on: ubuntu-24.04 + continue-on-error: true # allow-flaky + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Install Rust + uses: dtolnay/rust-toolchain@02cb101ec7c40f2c49e1d9714d64511d8e1b74de # master + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + targets: wasm32-unknown-unknown + + - name: Install Stellar CLI + run: cargo install stellar-cli --version "=${STELLAR_CLI_VERSION}" --locked + + - name: Run integration tests + working-directory: stellar/integration-tests + env: + FUTURENET_SECRET: ${{ secrets.FUTURENET_TEST_SECRET }} + run: cargo test -- --nocapture 2>&1 | tee test-results.txt + + - name: Upload test results + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: always() + with: + name: chaos-test-results + path: stellar/integration-tests/test-results.txt \ No newline at end of file diff --git a/.github/workflows/integration-futurenet.yml b/.github/workflows/integration-futurenet.yml index 76fdb32..52bcc1c 100644 --- a/.github/workflows/integration-futurenet.yml +++ b/.github/workflows/integration-futurenet.yml @@ -1,4 +1,4 @@ -name: Stellar Futurenet Integration Tests +name: Stellar Futurenet Smoke Tests on: schedule: @@ -14,7 +14,6 @@ jobs: integration: name: Futurenet smoke tests runs-on: ubuntu-24.04 - continue-on-error: true # allow-flaky steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -28,15 +27,16 @@ jobs: - name: Install Stellar CLI run: cargo install stellar-cli --version "=${STELLAR_CLI_VERSION}" --locked - - name: Run integration tests - working-directory: stellar/integration-tests + - name: Run deployed-network smoke test env: - FUTURENET_SECRET: ${{ secrets.FUTURENET_TEST_SECRET }} - run: cargo test -- --nocapture 2>&1 | tee test-results.txt + STELLAR_ADMIN_SECRET: ${{ secrets.FUTURENET_TEST_SECRET }} + run: | + set -o pipefail + ./stellar/scripts/deploy-dryrun.sh 2>&1 | tee test-results.txt - name: Upload test results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: futurenet-test-results - path: stellar/integration-tests/test-results.txt \ No newline at end of file + path: test-results.txt \ No newline at end of file diff --git a/stellar/scripts/deploy-dryrun.sh b/stellar/scripts/deploy-dryrun.sh index 08a4ff2..d03126c 100755 --- a/stellar/scripts/deploy-dryrun.sh +++ b/stellar/scripts/deploy-dryrun.sh @@ -322,8 +322,8 @@ fi header "Smoke Tests" -# 1. Register a name in wraith-names -info "1/5 Registering name '$TEST_NAME' in wraith-names..." +# 1. Register a name in wraith-names (Happy path) +info "1/7 Registering name '$TEST_NAME' in wraith-names..." if $CLI contract invoke \ --id "$NAMES_ID" \ --source "$IDENTITY_NAME" \ @@ -338,8 +338,24 @@ else warn "name registration failed (may already exist on re-run)" fi -# 2. Resolve the name (prove wraith-names works) -info "2/5 Resolving name '$TEST_NAME'..." +# 1b. Register an already registered name (Rejected path) +info "1b/7 Registering already registered name in wraith-names..." +if $CLI contract invoke \ + --id "$NAMES_ID" \ + --source "$IDENTITY_NAME" \ + --network "$NETWORK" \ + -- \ + register \ + --owner "$ADMIN_ADDRESS" \ + --name "$TEST_NAME" \ + --stealth-meta-address "$TEST_META_ADDRESS" 2>&1 | grep -qi "AlreadyRegistered"; then + ok "duplicate name registration rejected (AlreadyRegistered)" +else + smoke_fail "duplicate name registration not rejected with AlreadyRegistered" +fi + +# 2. Resolve the name (Happy path) +info "2/7 Resolving name '$TEST_NAME'..." RESOLVED=$($CLI contract invoke \ --id "$NAMES_ID" \ --source "$IDENTITY_NAME" \ @@ -353,13 +369,26 @@ RESOLVED=$($CLI contract invoke \ if [ -n "$RESOLVED" ]; then ok "name resolved (64-byte meta-address)" else - # Only warn if resolve didn't outright fail (already handled above) [ -z "$RESOLVED" ] && [ "$SMOKE_FAILED" -eq 0 ] && \ warn "resolve returned empty result" fi -# 3. Announce an event (prove stealth-announcer works) -info "3/5 Announcing event via stealth-announcer..." +# 2b. Resolve non-existent name (Rejected path) +info "2b/7 Resolving non-existent name..." +if $CLI contract invoke \ + --id "$NAMES_ID" \ + --source "$IDENTITY_NAME" \ + --network "$NETWORK" \ + -- \ + resolve \ + --name "doesnotexist123" 2>&1 | grep -qi "NotFound"; then + ok "non-existent name resolution rejected (NotFound)" +else + smoke_fail "non-existent name resolution not rejected with NotFound" +fi + +# 3. Announce an event (Happy path) +info "3/7 Announcing event via stealth-announcer..." if $CLI contract invoke \ --id "$ANNOUNCER_ID" \ --source "$IDENTITY_NAME" \ @@ -375,8 +404,25 @@ else smoke_fail "announce failed" fi -# 4. Query the registry (prove stealth-registry works) -info "4/5 Querying stealth-registry..." +# 3b. Announce with invalid scheme ID (Rejected path) +info "3b/7 Announcing with invalid scheme ID..." +if $CLI contract invoke \ + --id "$ANNOUNCER_ID" \ + --source "$IDENTITY_NAME" \ + --network "$NETWORK" \ + -- \ + announce \ + --scheme-id 999 \ + --stealth-address "$ADMIN_ADDRESS" \ + --ephemeral-pub-key "$TEST_EPHEMERAL_KEY" \ + --metadata "$TEST_METADATA" 2>&1 | grep -qi "InvalidSchemeId"; then + ok "invalid scheme ID rejected (InvalidSchemeId)" +else + smoke_fail "invalid scheme ID not rejected with InvalidSchemeId" +fi + +# 4. Query the registry (Rejected / Happy path depending on state) +info "4/7 Querying stealth-registry..." REG_RESULT=$($CLI contract invoke \ --id "$REGISTRY_ID" \ --source "$IDENTITY_NAME" \ @@ -389,8 +435,8 @@ REG_RESULT=$($CLI contract invoke \ ok "registry is responsive (NotRegistered is expected)" } -# 5. Verify sender is initialized -info "5/5 Verifying stealth-sender initialization..." +# 5. Verify sender is initialized (Rejected path: AlreadyInitialized) +info "5/7 Verifying stealth-sender initialization (rejected path)..." if $CLI contract invoke \ --id "$SENDER_ID" \ --source "$IDENTITY_NAME" \ @@ -400,9 +446,9 @@ if $CLI contract invoke \ init \ --announcer "$ANNOUNCER_ID" \ --fee-basis-points 0 2>&1 | grep -qi "AlreadyInitialized\|already initialized"; then - ok "stealth-sender correctly initialized (AlreadyInitialized)" + ok "stealth-sender correctly rejected re-initialization (AlreadyInitialized)" else - smoke_fail "Could not confirm sender initialization" + smoke_fail "Could not confirm sender initialization rejection" fi # ──────────────────────────────────────────────────────────────────────────────