Skip to content
Merged
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
69 changes: 66 additions & 3 deletions .github/workflows/shreds-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
contents: read
outputs:
shreds-sha: ${{ steps.checkout-shreds.outputs.commit }}
matrix: ${{ steps.shard.outputs.matrix }}
steps:
- name: Checkout doublezero-shreds
id: checkout-shreds
Expand Down Expand Up @@ -62,11 +63,73 @@ jobs:
docker push ${{ env.SHRED_IMAGE_REPO }}/activator:${{ env.SHRED_IMAGE_TAG }}
docker push ${{ env.SHRED_IMAGE_REPO }}/oracle:${{ env.SHRED_IMAGE_TAG }}
docker push ${{ env.SHRED_IMAGE_REPO }}/client:${{ env.SHRED_IMAGE_TAG }}
- name: Discover tests and distribute across shards
id: shard
working-directory: e2e/
run: |
# Find all TestE2E_* functions in files with the e2e build tag.
tests=$(grep -rl '^//go:build e2e$' *_test.go \
| xargs grep -h '^func TestE2E_' \
| sed 's/func \(TestE2E_[a-zA-Z0-9_]*\).*/\1/' \
| sort)

count=$(echo "$tests" | wc -l)
echo "Discovered $count tests"
echo "$tests"

# Pinned heavy tests: each gets its own shard slot to keep the two
# biggest rocks off the same runner. Update this list if a new test
# exceeds ~5min, or if a pinned test is renamed/removed upstream
# (the validation below will fail fast in that case).
pinned_1="TestE2E_MultiUserInstantAllocationAndWithdrawal"
pinned_2="TestE2E_DeviceScale"

# Fail fast if a pinned test no longer exists in the shreds repo —
# otherwise its shard would silently run zero tests.
for pin in "$pinned_1" "$pinned_2"; do
if ! echo "$tests" | grep -qxF "$pin"; then
echo "::error::Pinned test '$pin' not found in doublezero-shreds. Update the pin list in this workflow."
exit 1
fi
done

e2e:
# Remaining tests round-robin across shards 3 and 4.
remaining=$(echo "$tests" | grep -vE "^(${pinned_1}|${pinned_2})$")

ROUND_ROBIN_SHARDS=2
declare -a shards
for ((i=0; i<ROUND_ROBIN_SHARDS; i++)); do shards[$i]=""; done
i=0
while IFS= read -r test; do
idx=$((i % ROUND_ROBIN_SHARDS))
if [ -n "${shards[$idx]}" ]; then
shards[$idx]="${shards[$idx]}|${test}"
else
shards[$idx]="$test"
fi
i=$((i + 1))
done <<< "$remaining"

# Build JSON matrix: shards 1-2 are pinned, shards 3-4 are round-robin.
matrix="[{\"shard\":1,\"run\":\"^(${pinned_1})$\"}"
matrix="${matrix},{\"shard\":2,\"run\":\"^(${pinned_2})$\"}"
for ((i=0; i<ROUND_ROBIN_SHARDS; i++)); do
matrix="${matrix},{\"shard\":$((i + 3)),\"run\":\"^(${shards[$i]})$\"}"
done
matrix="${matrix}]"

echo "Matrix: $matrix"
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"

shard-e2e:
name: shard-e2e (shard ${{ matrix.shard }})
needs: setup
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.setup.outputs.matrix) }}
runs-on: doublezero-k8s-ci
timeout-minutes: 20
timeout-minutes: 15
permissions:
packages: read
contents: read
Expand Down Expand Up @@ -117,4 +180,4 @@ jobs:
- name: Run e2e tests
env:
SHRED_E2E_NO_BUILD: "1"
run: go test -tags=e2e -timeout=20m -v -count=1 .
run: go test -tags=e2e -timeout=12m -count=1 -run '${{ matrix.run }}' -v .
Loading