Something went wrong. Try again.
A knot backed by enroute.sh forked from anirudh.fi/enroute-knot
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105#!/bin/sh# Pushes to one repository on a knot many times in parallel, as whoever goat# is logged in as (see skills/push-with-goat). That account must be the# repository's owner or a collaborator.# Each push goes to its own branch (stress/<run>/<n>) so parallel pushes don't race# on one ref, and carries a few freshly generated source files.## KNOT=enroute.anirudh.fi REPO=<repoDid> stress-push.sh [PUSHES] [PARALLEL] [FILES_PER_PUSH] [KB_PER_FILE]set -eu
KNOT=${KNOT:-enroute.anirudh.fi}REPO=${REPO:?set REPO to the repository's DID}GOAT=${GOAT:-$HOME/go/bin/goat}PUSHES=${1:-300}PARALLEL=${2:-16}FILES=${3:-4}KB=${4:-256}RUN=$(date +%H%M%S)WORK=$(mktemp -d /tmp/stress-push.XXXXXX)TOKEN_FILE=$WORK/tokenLOG=$WORK/results
# a push token, reused until it is 3 minutes old: the knot accepts a# receivePack token until it expires, and refuses any that lives over 300smint() { "$GOAT" account service-auth --aud "did:web:$KNOT" \ --lxm org.tangled.git.receivePack --duration-sec 280 >"$TOKEN_FILE.new" mv "$TOKEN_FILE.new" "$TOKEN_FILE"}mintminted=$(date +%s)
git init -q -b main "$WORK/base"git -C "$WORK/base" -c user.name=bot -c user.email=bot@anirudh.fi \ commit -q --allow-empty -m "stress base"
# source-looking text that doesn't compress away: random identifiers in Go-ish codegen_file() { # path kb seed awk -v kb="$2" -v seed="$3" 'BEGIN { srand(seed); target = kb * 1024; n = 0 print "package stress\n" while (n < target) { name = ""; for (i = 0; i < 12; i++) name = name sprintf("%c", 97 + int(rand() * 26)) line = sprintf("func %s(x int) int { return x*%d + %d } // %08x\n", name, int(rand()*1e6), int(rand()*1e6), int(rand()*4294967295)) printf "%s", line; n += length(line) } }' >"$1"}
push_one() { # n n=$1 dir=$WORK/w$n git clone -q --shared "$WORK/base" "$dir" mkdir -p "$dir/pkg$n" i=0 while [ "$i" -lt "$FILES" ]; do gen_file "$dir/pkg$n/file$i.go" "$KB" "$n$i$$" i=$((i + 1)) done git -C "$dir" add -A git -C "$dir" -c user.name=bot -c user.email=bot@anirudh.fi commit -q -m "stress push $n" start=$(date +%s.%N) if git -C "$dir" -c credential.helper= \ -c "credential.helper=!f() { [ \"\$1\" = get ] || exit 0; echo username=x; echo password=\$(cat $TOKEN_FILE); }; f" \ push -q "https://$KNOT/$REPO" "HEAD:refs/heads/stress/$RUN/$n" >"$dir.out" 2>&1; then status=ok else status=FAIL fi end=$(date +%s.%N) printf '%s %s %.2f\n' "$n" "$status" "$(awk -v a="$start" -v b="$end" 'BEGIN{print b-a}')" >>"$LOG" if [ "$status" != ok ] && [ "$(grep -c FAIL "$LOG")" -le 5 ]; then echo "push $n failed:"; sed "s/^/ /" "$dir.out" fi rm -rf "$dir"}
echo "pushing $PUSHES times, $PARALLEL at once, $FILES x ${KB}KB files each, to $REPO"export RUN WORK TOKEN_FILE LOG FILES KB KNOT REPOstarted=$(date +%s)n=1while [ "$n" -le "$PUSHES" ]; do if [ $(( $(date +%s) - minted )) -ge 180 ]; then mint; minted=$(date +%s) fi # a batch of PARALLEL pushes, then wait for all of it batch=0 while [ "$batch" -lt "$PARALLEL" ] && [ "$n" -le "$PUSHES" ]; do push_one "$n" & n=$((n + 1)); batch=$((batch + 1)) done wait printf "%d/%d done\n" "$(wc -l <"$LOG")" "$PUSHES"doneechook=$(grep -c ' ok ' "$LOG" || true)fail=$(grep -c ' FAIL ' "$LOG" || true)elapsed=$(( $(date +%s) - started ))echo "done in ${elapsed}s: $ok ok, $fail failed"[ "$fail" -le 5 ] || echo "(showed the first 5 failures; every push's status is in $LOG)"awk '$2=="ok"{print $3}' "$LOG" | sort -n | awk '{a[NR]=$1} END {if (NR) printf "push seconds: p50 %.2f p90 %.2f max %.2f\n", a[int(NR*0.5)+1], a[int(NR*0.9)+1], a[NR]}'echo "remote branches: $(git ls-remote "https://$KNOT/$REPO" "refs/heads/stress/$RUN/*" | wc -l)"echo "results: $LOG"[ "$fail" -eq 0 ]