Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
3392f09
pull initial work from branch load-testing
cjonas9 May 9, 2026
ffe27bc
add ledger generation test adapted for RPC
cjonas9 May 4, 2026
65da3b5
add apply load config
cjonas9 May 4, 2026
34f086d
add generated ledger output to infrastructure/testdata/
cjonas9 May 4, 2026
80c982d
add basic ingestion of synthetic ledgers phase
cjonas9 May 7, 2026
94c69b7
disable debug logs for load test for timeout reasons
cjonas9 May 7, 2026
f4a16f9
add functions for snapshotting + restoring test DB
cjonas9 May 8, 2026
1d53b96
improve ad restructure db restoration helpers/API
cjonas9 May 8, 2026
baf2255
finish DB restoration logic flow and wiring
cjonas9 May 8, 2026
1647464
skip migrations/fee-stats in load test mode
cjonas9 May 8, 2026
2f14765
ingest test: refactor, minor semantic fixes
cjonas9 May 8, 2026
d7c90a9
test.go: add retention window to config, fix fake history archive for…
cjonas9 May 8, 2026
0390757
minor db restore/trim helper fixes
cjonas9 May 8, 2026
e0a86e7
rename restore backed-up ledgers function for accuracy
cjonas9 May 8, 2026
f151a35
refactor, add env vars, change DB helpers to take sequences
cjonas9 May 12, 2026
bffb101
remove db restoration functionality
cjonas9 May 15, 2026
e04d51d
add performance metrics json emission functionality
cjonas9 May 15, 2026
bd8c784
migrate to polling getHealth, change ingest test limits to 1000 ledgers
cjonas9 May 15, 2026
c7bc001
remove ledger fixtures
cjonas9 May 15, 2026
786423d
add workflow and script
cjonas9 May 15, 2026
1606829
fix yaml referencing wrong path for script
cjonas9 May 15, 2026
7d41b1a
fix yml parsing indentation bug
cjonas9 May 15, 2026
b701108
use head-object for metadata rather than tags
cjonas9 May 15, 2026
b1cec1d
refine workflow + instance script
cjonas9 May 15, 2026
b9ef27e
add apply load cfg
cjonas9 May 15, 2026
73df1e7
testing: on-push runs
cjonas9 May 15, 2026
241bdf8
minor yml syntax fixes
cjonas9 May 15, 2026
1161e3f
set test e2e.yml + add debugging info from instance to ssm
cjonas9 May 15, 2026
47437f4
skip e2e.yml for testing, add retry loop for root volume lookup
cjonas9 May 15, 2026
008f327
build-libs over build-stellar-rpc to cut time back
cjonas9 May 15, 2026
9441749
further slim build phase with no-install-recommends
cjonas9 May 15, 2026
36c0a82
make instance script best-effort if head-object or stellar-core versi…
cjonas9 May 16, 2026
4535977
temporarily modify script to work on scratch dev box; increase timeout
cjonas9 May 16, 2026
54f0b41
fix cfg path error and run ID regression
cjonas9 May 16, 2026
44e093c
improve error logging
cjonas9 May 16, 2026
1ce515e
fix error logging wrapper
cjonas9 May 16, 2026
22a8e6e
patch premature exit due to err trap bug
cjonas9 May 16, 2026
e925d3c
fix empty GOPATH/GOMODCACHE
cjonas9 May 16, 2026
ffb3299
updated apply-load config for specific core on runner
cjonas9 May 16, 2026
bae2fdc
fix version check if warning prints
cjonas9 May 16, 2026
70eb9dc
bump all timeouts to >= 2 hours
cjonas9 May 17, 2026
705edec
increase ingest phase timeout
cjonas9 May 17, 2026
c697510
extend aws role lifetime
cjonas9 May 17, 2026
caec3f4
undo session time limit increase, use pre-generated synthetic ledgers
cjonas9 May 18, 2026
b32181d
require confirmed gp3 throttling, extend GHA AWS session to 4 hours
cjonas9 May 19, 2026
3a0571f
patch logic for throttling behavior
cjonas9 May 19, 2026
2c4a004
slim needless instance bootstrapping work
cjonas9 May 20, 2026
d620450
refactor ephemeral load test runner
cjonas9 May 27, 2026
41529f4
fix minor refactor false sha-verify failure
cjonas9 May 27, 2026
2a21c73
add support for multiple ledger profiles/files
cjonas9 Jun 11, 2026
04f0fe1
change log level to warn, decrease each soroban scenario meta to 1000…
cjonas9 Jun 12, 2026
02556cc
refactored duplicate/messy code
cjonas9 Jun 12, 2026
807ca42
stop grepping to determine success status, make GHA->ec2 parameter pa…
cjonas9 Jun 12, 2026
af9f7b9
split offline ledger generation out of the ingest benchmark
cjonas9 Jun 12, 2026
e4180dd
refactor and remove old apply load cfg
cjonas9 Jun 12, 2026
4c3394c
Merge remote-tracking branch 'origin/main' into apply-load
cjonas9 Jun 12, 2026
bc2e490
Merge branch 'main' into apply-load
cjonas9 Jun 15, 2026
555483e
Merge branch 'apply-load' of https://github.com/stellar/stellar-rpc i…
cjonas9 Jun 15, 2026
a620cdc
fix linter errors
cjonas9 Jun 15, 2026
2dabdf3
add json file providing configurability for eval thresholds
cjonas9 Jun 16, 2026
3f873f7
add basic coordinator for epic's tasks
cjonas9 Jun 16, 2026
8f4f1d1
make ec2 ingest load test callable
cjonas9 Jun 16, 2026
c1c437f
propogate apply load ingest test metrics to coordinator
cjonas9 Jun 17, 2026
b031d9d
add releaseeval package for subtest tooling and execution
cjonas9 Jun 17, 2026
61d4877
make ingest load test share perf schema w/ coordinator
cjonas9 Jun 17, 2026
65cb6ff
update go version
cjonas9 Jun 17, 2026
4aca1ef
update default ledger bundle/config to existent ones for test
cjonas9 Jun 17, 2026
3d61ceb
decompose ec2 script into go programs
cjonas9 Jun 17, 2026
9bef115
reduce comment verbosity, minor clean up
cjonas9 Jun 17, 2026
8b39ed5
install jq on load-test box for build-libs; surface build-libs errors
cjonas9 Jun 18, 2026
714b1fa
throttle load-test benchmark via cgroup io.max instead of EBS ModifyV…
cjonas9 Jun 18, 2026
d9987f6
drop accidentally-committed refresh tooling and orphaned apply-load.cfg
cjonas9 Jun 18, 2026
5058ad3
fix linter errors in load-test runner
cjonas9 Jun 18, 2026
8cf9f6b
make load-test ingest frequency and ledger count configurable via env
cjonas9 Jun 18, 2026
3b33626
EXPERIMENT: run load-test benchmark un-throttled at volume-provisione…
cjonas9 Jun 18, 2026
7e60661
use SDK's maxLedgersPerFile ceiling and multiple-bundle functionality
cjonas9 Jun 18, 2026
fdb1926
simplify verification walk
cjonas9 Jun 18, 2026
1f974a4
simplify and refactor, add ledger ingest stall timeout
cjonas9 Jun 22, 2026
19a3115
simplify correctness check, delegate apply-load config work to SDK
cjonas9 Jun 22, 2026
103b648
remove ingest phase dependence on unnecessary supplied apply load con…
cjonas9 Jun 23, 2026
7e13bf3
bump go sdk to v0.6.x
cjonas9 Jun 23, 2026
8333974
bump go sdk again, merge SDK main into loadtest-patch
cjonas9 Jun 23, 2026
f3f3d58
Merge remote-tracking branch 'origin/main' into apply-load
cjonas9 Jun 23, 2026
a6241f6
update comments in light of changes
cjonas9 Jun 23, 2026
855527c
merge apply-load recent work into coordinator
cjonas9 Jun 24, 2026
8d5f523
rework handshake into instance->s3 results push, fix minor leaks + OO…
cjonas9 Jun 24, 2026
21b8045
replace polling-based ledger timing computation with daemon hook
cjonas9 Jun 24, 2026
a8931fe
remove trigger-on-push behavior
cjonas9 Jun 25, 2026
97af867
Merge branch 'apply-load' into gha-coordinator
cjonas9 Jun 25, 2026
b15e2e3
simplify significantly, refactor into on-release-push job launcher + …
cjonas9 Jun 25, 2026
fbd8b2b
moved ingest load test go programs into separate folder
cjonas9 Jun 25, 2026
237578c
refactored coordinator logic into go
cjonas9 Jun 25, 2026
4651084
Merge remote-tracking branch 'origin/main' into gha-coordinator
cjonas9 Jun 26, 2026
f1b4473
add temporary trigger and log->s3 for testing
cjonas9 Jun 26, 2026
c601be5
bring main verbosity cleanups into coordinator
cjonas9 Jun 26, 2026
d846b52
decompose shared ec2/gha programming into reusable modular components
cjonas9 Jun 29, 2026
f83c4d8
move run-load-test.sh scripting into run_leg helper in common shell s…
cjonas9 Jun 29, 2026
c57a23b
add initial backfill-specific testing and wiring
cjonas9 Jun 29, 2026
3901d85
use callable workflows in coordinator
cjonas9 Jun 29, 2026
c91c61f
refactor into callable workflow, factor out common main Run() func
cjonas9 Jun 29, 2026
f5c4f3f
Merge branch 'gha-coordinator' into backfill-test
cjonas9 Jun 30, 2026
4d7084d
add push to branch backfill-test to coordinator triggers
cjonas9 Jun 30, 2026
0d261a6
resolve the PR by head without --base main
cjonas9 Jun 30, 2026
2bbb35e
in ec2, build daemon to a path that doesn't collide with the repo dir
cjonas9 Jun 30, 2026
cda0eb4
clean up comments, increase MaxSessionDuration and backfill time limits
cjonas9 Jun 30, 2026
1624ebe
keep ec2 box alive on job cancel + upload more logs
cjonas9 Jul 6, 2026
9d0cce9
Merge remote-tracking branch 'origin/main' into backfill-test
cjonas9 Jul 10, 2026
1a50e42
revert residual testing changes
cjonas9 Jul 10, 2026
b352ba9
minor: don't hard-code binaryPath in backfill's instantiate
cjonas9 Jul 10, 2026
8fbda79
add blaster leg skeleton to yml files
cjonas9 Jul 10, 2026
df2466c
add serving phase/stay-up functionality to backfill test
cjonas9 Jul 10, 2026
ec6b8fb
add rendezvous logic to coordinate between standing RPC box and new b…
cjonas9 Jul 10, 2026
612509d
add endpoint load test runner script + box runner code
cjonas9 Jul 10, 2026
c2eab96
adjust endpoint test time budget for true worst-case allowable
cjonas9 Jul 10, 2026
c1f1070
add push to this branch as trigger
cjonas9 Jul 10, 2026
b29c700
set endpoint request patterns + backfill to be minimal, pipe limit to…
cjonas9 Jul 10, 2026
6defac9
remove overly-granular deadlines, simplify/dedup around branch
cjonas9 Jul 11, 2026
ee0f5cb
add dedicated leg program
cjonas9 Jul 11, 2026
c6cd9d4
simplification pass + use blaster's exported limit in results json
cjonas9 Jul 13, 2026
89de217
minor comment changes
cjonas9 Jul 17, 2026
e6c36cc
Merge branch 'main' into blaster-test
cjonas9 Jul 17, 2026
431e788
remove getEvents from endpoint blast
cjonas9 Jul 17, 2026
94046f8
minor simplification pass
cjonas9 Jul 17, 2026
a9493eb
major refactor: remove ec2 rendezvous protocol, use gha in box coordi…
cjonas9 Jul 17, 2026
abec2ae
patch trigger to push on this branch
cjonas9 Jul 17, 2026
54c2ae4
simplify comments, use env parsing library
cjonas9 Jul 17, 2026
3e7d884
pull latest blaster commit, use cooloff parameter + sample endpoint cfg
cjonas9 Jul 17, 2026
63f6724
bump blaster ref to dev
cjonas9 Jul 20, 2026
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
47 changes: 43 additions & 4 deletions .github/workflows/ec2-leg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ name: Perf-eval EC2 leg (ephemeral)
# Does not post to the PR -- the coordinator owns human-facing output.
# Box bootstrap: perf-eval/bootstrap-common.sh + the leg script (inputs.leg_script);
# runner-side polling: perf-eval/gather.
# Legs can chain via keep_instance + adopt_run_label + the instance_ip output.

on:
# workflow_call is the only trigger: a leg runs through the coordinator.
Expand Down Expand Up @@ -62,6 +63,20 @@ on:
required: false
type: string
default: ''
keep_instance:
description: 'Leave a passing leg''s box running for a chained successor; the box then owns its shutdown. A failing leg terminates as usual.'
required: false
type: boolean
default: false
adopt_run_label:
description: 'run_label of a prior keep_instance leg whose box this leg also terminates when it passes'
required: false
type: string
default: ''
outputs:
instance_ip:
description: 'Private IPv4 of the launched box, for chained legs'
value: ${{ jobs.ec2-leg.outputs.instance_ip }}
secrets:
AWS_GHA_ROLE_ARN:
description: 'OIDC role ARN to assume for EC2 + S3 access'
Expand All @@ -75,6 +90,8 @@ permissions:
jobs:
ec2-leg:
name: Launch + await ephemeral perf-eval box
outputs:
instance_ip: ${{ steps.launch.outputs.instance_ip }}
# Non-cancelling group keyed on the test commit SHA + leg. An instance can run
# until the box’s self-terminate ceiling, so new runs queue.
concurrency:
Expand Down Expand Up @@ -149,7 +166,7 @@ jobs:
echo '#!/usr/bin/env bash'
echo "export TARGET_SHA=${{ steps.resolve.outputs.sha }} RUN_ID=${{ github.run_id }}-${{ github.run_attempt }}"
echo "export BUCKET=$BUCKET RESULT_KEY=$RESULT_KEY"
echo "export SELF_TERMINATE_MINUTES=$SELF_TERMINATE_MINUTES"
echo "export SELF_TERMINATE_MINUTES=$SELF_TERMINATE_MINUTES BUDGET_MINUTES=${{ inputs.budget_minutes }}"
if [ -n "$EXTRA_ENV" ]; then printf '%s\n' "$EXTRA_ENV"; fi
cat "$PERF_EVAL_DIR/bootstrap-common.sh"
cat "$LEG_SCRIPT"
Expand Down Expand Up @@ -190,6 +207,7 @@ jobs:

INSTANCE_ID=$(printf '%s' "$RUN_INSTANCES_JSON" | jq -r '.Instances[0].InstanceId')
echo "instance_id=$INSTANCE_ID" >> "$GITHUB_OUTPUT"
echo "instance_ip=$(printf '%s' "$RUN_INSTANCES_JSON" | jq -r '.Instances[0].PrivateIpAddress')" >> "$GITHUB_OUTPUT"

- name: Wait for SSM agent to register
env:
Expand Down Expand Up @@ -257,8 +275,29 @@ jobs:
exit 1
fi

# The adopted box is tag-discovered. Adoption fires only on a pass. Note that
# a failed leg leaves the box to its serve ceiling so a re-run can reuse it.
- name: Terminate instance
if: always() && steps.launch.outputs.instance_id != ''
if: always()
env:
INSTANCE_ID: ${{ steps.launch.outputs.instance_id }}
KEEP_INSTANCE: ${{ inputs.keep_instance }}
LEG_PASSED: ${{ steps.results.outputs.passed }}
ADOPT_RUN_LABEL: ${{ inputs.adopt_run_label }}
run: |
aws ec2 terminate-instances \
--instance-ids ${{ steps.launch.outputs.instance_id }} || true
if [ "$KEEP_INSTANCE" = "true" ] && [ "$LEG_PASSED" = "true" ]; then
echo "keep_instance: leaving $INSTANCE_ID running for the chained leg"
elif [ -n "$INSTANCE_ID" ]; then
aws ec2 terminate-instances --instance-ids "$INSTANCE_ID" || true
fi
if [ -n "$ADOPT_RUN_LABEL" ] && [ "$LEG_PASSED" = "true" ]; then
Comment thread
cjonas9 marked this conversation as resolved.
ADOPTED=$(aws ec2 describe-instances \
--filters "Name=tag:run-id,Values=${{ github.run_id }}" \
"Name=tag:Name,Values=perf-eval-$ADOPT_RUN_LABEL" \
"Name=instance-state-name,Values=pending,running" \
--query 'Reservations[].Instances[].InstanceId' --output text || true)
if [ -n "$ADOPTED" ]; then
echo "terminating adopted box(es): $ADOPTED"
aws ec2 terminate-instances --instance-ids $ADOPTED || true
fi
fi
57 changes: 48 additions & 9 deletions .github/workflows/load-test-coordinator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defaults:

on:
push:
branches: [release/**]
branches: [release/**, blaster-test]
Comment thread
cjonas9 marked this conversation as resolved.
workflow_dispatch:
inputs:
target_ref:
Expand Down Expand Up @@ -46,6 +46,7 @@ jobs:
target_sha: ${{ steps.ctx.outputs.target_sha }}
pr_number: ${{ steps.ctx.outputs.pr_number }}
legs: ${{ steps.ctx.outputs.legs }}
matrix_legs: ${{ steps.ctx.outputs.matrix_legs }}
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -62,24 +63,29 @@ jobs:
PR="$(gh pr list --repo "${{ github.repository }}" --state open \
--head "$REF" --json number --jq '.[0].number // ""' 2>/dev/null || true)"
fi
# One roster (comment order) drives both the report job and the
# matrix fan-out: entries carrying a script ride the matrix; the
# chained backfill + blaster pair runs as explicit jobs below.
LEGS='[
{"label":"Apply-load ingestion","run_label":"apply-load","script":"cmd/stellar-rpc/internal/integrationtest/infrastructure/perf-eval/ingest-load-test/run-load-test.sh","budget":225},
{"label":"Backfill ingestion","run_label":"backfill","script":"cmd/stellar-rpc/internal/integrationtest/infrastructure/perf-eval/backfill-test/run-backfill.sh","budget":345}
{"label":"Backfill ingestion","run_label":"backfill"},
{"label":"Endpoint load test","run_label":"blaster"}
]'
{
echo "target_sha=$SHA"
echo "pr_number=$PR"
echo "legs=$(jq -c . <<<"$LEGS")"
echo "matrix_legs=$(jq -c 'map(select(.script))' <<<"$LEGS")"
} >> "$GITHUB_OUTPUT"

# The fan-out: one matrix entry per leg.
# The fan-out: one matrix entry per independent leg.
load-test:
name: ${{ matrix.leg.label }}
needs: plan
strategy:
fail-fast: false # stops one leg's failure from cancelling other legs
matrix:
leg: ${{ fromJSON(needs.plan.outputs.legs) }}
leg: ${{ fromJSON(needs.plan.outputs.matrix_legs) }}
uses: ./.github/workflows/ec2-leg.yml
secrets: inherit
with:
Expand All @@ -88,9 +94,41 @@ jobs:
leg_script: ${{ matrix.leg.script }}
budget_minutes: ${{ matrix.leg.budget }}

# Chained pair, serving side (keep box's RPC serving for the blaster leg).
backfill:
name: Backfill ingestion
needs: plan
uses: ./.github/workflows/ec2-leg.yml
secrets: inherit
with:
target_ref: ${{ needs.plan.outputs.target_sha }}
run_label: backfill
leg_script: cmd/stellar-rpc/internal/integrationtest/infrastructure/perf-eval/backfill-test/run-backfill.sh
budget_minutes: 345
keep_instance: true
extra_env: |
export SERVE_AFTER_BACKFILL=true

# Chained pair, blasting side: starts once backfill's leg passes (its box then
# enters catchup), probes the handed-off address until healthy, then blasts.
blaster:
name: Endpoint load test
needs: [plan, backfill]
uses: ./.github/workflows/ec2-leg.yml
secrets: inherit
with:
target_ref: ${{ needs.plan.outputs.target_sha }}
run_label: blaster
leg_script: cmd/stellar-rpc/internal/integrationtest/infrastructure/perf-eval/endpoint-load-test/run-blaster.sh
budget_minutes: 255
root_volume_gb: 50
adopt_run_label: backfill
extra_env: |
export TARGET_RPC=http://${{ needs.backfill.outputs.instance_ip }}:8000

report:
name: Aggregate + report
needs: [plan, load-test]
needs: [plan, load-test, backfill, blaster]
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
timeout-minutes: 10
Expand Down Expand Up @@ -161,13 +199,14 @@ jobs:
fi
fi

# Authoritative gate: reflects the load-test legs, independent of whether
# the comment posted.
- name: Set overall status
if: always()
env:
NEEDS: ${{ toJSON(needs) }}
run: |
if [ "${{ needs.load-test.result }}" != "success" ]; then
echo "::error::one or more legs did not pass (aggregate result: ${{ needs.load-test.result }})"
FAILED=$(jq -r '[to_entries[] | select(.value.result != "success") | .key] | join(", ")' <<<"$NEEDS")
if [ -n "$FAILED" ]; then
echo "::error::jobs did not pass: $FAILED"
exit 1
fi
echo "all load-test legs passed"
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Backfill ingestion leg. Concatenated after bootstrap-common.sh in the rendered
# EC2 user-data, so it relies on that file's env, helpers, bootstrap_box, and
# run_leg. It hands off to `runner instantiate`, which builds stellar-rpc and
# times a backfill run against the pubnet datastore. The other half, `runner
# gather`, polls S3 for the result object.
# times a backfill run against the pubnet datastore. The other half, `runner
# gather`, polls S3 for the result object. With SERVE_AFTER_BACKFILL=true the
# box then keeps serving for the chained blaster leg.
LEG_TITLE="Backfill ingestion"

bootstrap_box
Expand Down
Loading
Loading