From 5a5ba0891bd9adbd41435e8adefaec77d856b316 Mon Sep 17 00:00:00 2001 From: thrzl Date: Thu, 13 Aug 2026 00:42:07 -0400 Subject: [PATCH] bench: make script self-contained, fix hyperfine abs-time parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove dependency on /tmp/bench_env.sh. The script now: - Generates vage and age identity files on first run if missing - Creates test input files (1MB/10MB/100MB) with dd if missing - Extracts recipients from identity files using age-keygen -y or fallback to parsing the public key comment - Handles hyperfine's 'Time (abs ≡)' format for single-run mode --- bench.sh | 119 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/bench.sh b/bench.sh index 471b769..919748b 100755 --- a/bench.sh +++ b/bench.sh @@ -11,9 +11,8 @@ # Hyperfine is invoked with the same options as the original bench.sh: # --style basic -N --warmup --runs --prepare # -# Environment (from bench_env.sh): -# VAGE_RECIPIENT, AGE_RECIPIENT - bech32 identity keys for vage and age -# BIGFILE_1M, BIGFILE_100M - pre-generated test input files +# This script is self-contained: it generates identity key pairs and test +# input files on first run if they do not already exist. set -euo pipefail @@ -22,31 +21,77 @@ LABEL="${2:-unnamed}" WORKDIR="${BENCH_WORKDIR:-/tmp}" SOURCE_DIR="$(cd "$(dirname "$0")" && pwd)" -# Load environment: VAGE_RECIPIENT, AGE_RECIPIENT, BIGFILE_1M, BIGFILE_100M -source "$WORKDIR/bench_env.sh" - -if [[ ! -x "$VAGE_BIN" ]]; then - echo "FATAL: $VAGE_BIN is not executable" >&2 - exit 2 -fi - -# Detect age binary +# --------------------------------------------------------------------------- +# Detect tools +# --------------------------------------------------------------------------- AGE_BIN="" if command -v age >/dev/null 2>&1; then AGE_BIN="age" fi +# --------------------------------------------------------------------------- # Hyperfine options (same as original bench.sh) +# --------------------------------------------------------------------------- HYPERFINE_RUNS="${HYPERFINE_RUNS:-10}" HYPERFINE_WARMUP="${HYPERFINE_WARMUP:-3}" +# --------------------------------------------------------------------------- # CSV log +# --------------------------------------------------------------------------- LOG="$WORKDIR/vage_bench_log.csv" [[ -f "$LOG" ]] || echo "label,category,size_bytes,vage_mean_ms,vage_stddev_ms,age_mean_ms,age_stddev_ms" > "$LOG" -# Identity file paths (as used by the original bench.sh) -VAGE_ID_FILE="/tmp/vage_id" -AGE_ID_FILE="/tmp/age_id.txt" +# --------------------------------------------------------------------------- +# Identity files: generate if missing +# --------------------------------------------------------------------------- +VAGE_ID_FILE="$WORKDIR/vage_id" +AGE_ID_FILE="$WORKDIR/age_id.txt" + +VAGE_KEYGEN_BIN="$SOURCE_DIR/bin/vage-keygen" +if [[ ! -f "$VAGE_ID_FILE" ]]; then + echo "Generating vage identity..." + if [[ ! -x "$VAGE_KEYGEN_BIN" ]]; then + (cd "$SOURCE_DIR" && v -skip-unused -o "$VAGE_KEYGEN_BIN" cmd/vage-keygen.v 2>/dev/null) + fi + "$VAGE_KEYGEN_BIN" -o "$VAGE_ID_FILE" +fi +if [[ ! -f "$AGE_ID_FILE" ]]; then + if command -v age-keygen >/dev/null 2>&1; then + echo "Generating age identity..." + age-keygen -o "$AGE_ID_FILE" + else + # Reuse the vage keygen (same bech32 format) + if [[ ! -x "$VAGE_KEYGEN_BIN" ]]; then + (cd "$SOURCE_DIR" && v -skip-unused -o "$VAGE_KEYGEN_BIN" cmd/vage-keygen.v 2>/dev/null) + fi + echo "Generating age identity (via vage-keygen)..." + "$VAGE_KEYGEN_BIN" -o "$AGE_ID_FILE" + fi +fi + +# Extract recipients from identity files. +# Try age-keygen -y first (works for both Go age and vage identity files since +# they share the same bech32 format). Fall back to parsing the "# public key:" comment. +VAGE_RECIPIENT="" +AGE_RECIPIENT="" +if command -v age-keygen >/dev/null 2>&1; then + VAGE_RECIPIENT=$(age-keygen -y "$VAGE_ID_FILE" 2>/dev/null | head -1) + if [[ -n "$AGE_BIN" ]]; then + AGE_RECIPIENT=$(age-keygen -y "$AGE_ID_FILE" 2>/dev/null | head -1) + fi +elif [[ -x "$VAGE_KEYGEN_BIN" ]]; then + VAGE_RECIPIENT=$("$VAGE_KEYGEN_BIN" -y "$VAGE_ID_FILE" 2>/dev/null | head -1) + if [[ -n "$AGE_BIN" ]]; then + AGE_RECIPIENT=$("$VAGE_KEYGEN_BIN" -y "$AGE_ID_FILE" 2>/dev/null | head -1) + fi +fi +# Fallback: parse the "# public key:" comment from the identity file +if [[ -z "$VAGE_RECIPIENT" ]]; then + VAGE_RECIPIENT=$(grep '^# public key:' "$VAGE_ID_FILE" | awk '{print $4}') +fi +if [[ -z "$AGE_RECIPIENT" ]] && [[ -n "$AGE_BIN" ]]; then + AGE_RECIPIENT=$(grep '^# public key:' "$AGE_ID_FILE" | awk '{print $4}') +fi # --------------------------------------------------------------------------- # File sizes to benchmark (human_name:bytes) @@ -58,30 +103,21 @@ SIZES=( ) # --------------------------------------------------------------------------- -# Ensure input files exist for each size. -# Prefer existing bigfiles from bench_env.sh; create with dd if missing. +# Ensure input files exist for each size. Create with dd if missing. # --------------------------------------------------------------------------- declare -a INPUT_FILES=() for entry in "${SIZES[@]}"; do name="${entry%%:*}" size="${entry##*:}" - filepath="" - - case "$name" in - 1MB) filepath="${BIGFILE_1M:-/tmp/bigfile_1m}" ;; - 10MB) filepath="/tmp/bigfile_10m" ;; - 100MB) filepath="${BIGFILE_100M:-/tmp/bigfile_100m}" ;; - esac + filepath="$WORKDIR/bench_input_${name}.bin" if [[ ! -f "$filepath" ]]; then - filepath="/tmp/bench_input_${name}.bin" - if [[ ! -f "$filepath" ]]; then - echo "Generating $name test file ($size bytes)..." - dd if=/dev/zero of="$filepath" bs="$size" count=1 2>/dev/null - fi + echo "Generating $name test file ($size bytes)..." + dd if=/dev/zero of="$filepath" bs="$size" count=1 2>/dev/null fi INPUT_FILES+=("$name:$size:$filepath") done +echo # --------------------------------------------------------------------------- # run_hyperfine: run hyperfine with the standard options, parse mean+stddev. @@ -104,9 +140,10 @@ run_hyperfine() { "$cmd" > "$log_path" 2>&1 # Parse "Time (mean ± σ): X.X ms ± Y.Y ms" + # With --runs 1 hyperfine outputs "Time (abs ≡): X.X ms" (no stddev). # Handles both glued ("X.Xms") and spaced ("X.X ms") hyperfine formats. awk ' - /Time \(mean/ { + /Time \((mean|abs)/ { if (match($0, /[0-9]+\.[0-9]+ms/) > 0) { s = substr($0, RSTART, RLENGTH - 2) printf "%.3f ", s + 0 @@ -145,14 +182,14 @@ declare -a DEC_AGE=() for entry in "${INPUT_FILES[@]}"; do IFS=':' read -r name size filepath <<< "$entry" - v_enc="/tmp/bench_dec_vage_${name}.age" + v_enc="$WORKDIR/bench_dec_vage_${name}.age" rm -f "$v_enc" "$VAGE_BIN" -e -r "$VAGE_RECIPIENT" -o "$v_enc" "$filepath" 2>/dev/null DEC_NAMES+=("$name") DEC_VAGE+=("$v_enc") if [[ -n "$AGE_BIN" ]]; then - a_enc="/tmp/bench_dec_age_${name}.age" + a_enc="$WORKDIR/bench_dec_age_${name}.age" rm -f "$a_enc" "$AGE_BIN" -e -r "$AGE_RECIPIENT" -o "$a_enc" "$filepath" 2>/dev/null DEC_AGE+=("$a_enc") @@ -188,6 +225,8 @@ get_dec_file() { echo "=== Benchmark: $LABEL ===" echo "vage: $VAGE_BIN" echo "age: ${AGE_BIN:-}" +echo "vage recipient: $VAGE_RECIPIENT" +echo "age recipient: ${AGE_RECIPIENT:-}" echo "hyperfine: --style basic -N --warmup $HYPERFINE_WARMUP --runs $HYPERFINE_RUNS" echo @@ -198,15 +237,15 @@ for entry in "${INPUT_FILES[@]}"; do # ---- Encrypt ---- echo "--- $name encrypt ---" - v_out="/tmp/bench_enc_vage_${name}.out" - a_out="/tmp/bench_enc_age_${name}.out" + v_out="$WORKDIR/bench_enc_vage_${name}.out" + a_out="$WORKDIR/bench_enc_age_${name}.out" vage_enc_cmd="\"$VAGE_BIN\" -e -r $VAGE_RECIPIENT -o $v_out $filepath" - v_enc_ms=$(run_hyperfine "/tmp/bench_enc_vage_${name}.txt" "rm -f $v_out" "$vage_enc_cmd") + v_enc_ms=$(run_hyperfine "$WORKDIR/bench_enc_vage_${name}.txt" "rm -f $v_out" "$vage_enc_cmd") if [[ -n "$AGE_BIN" ]]; then age_enc_cmd="age -e -r $AGE_RECIPIENT -o $a_out $filepath" - a_enc_ms=$(run_hyperfine "/tmp/bench_enc_age_${name}.txt" "rm -f $a_out" "$age_enc_cmd") + a_enc_ms=$(run_hyperfine "$WORKDIR/bench_enc_age_${name}.txt" "rm -f $a_out" "$age_enc_cmd") else a_enc_ms="0.000 0.000" fi @@ -228,17 +267,17 @@ for entry in "${INPUT_FILES[@]}"; do # ---- Decrypt ---- echo "--- $name decrypt ---" - v_out="/tmp/bench_dec_vage_${name}.out" - a_out="/tmp/bench_dec_age_${name}.out" + v_out="$WORKDIR/bench_dec_vage_${name}.out" + a_out="$WORKDIR/bench_dec_age_${name}.out" v_dec_input=$(get_dec_file "$name" "vage") vage_dec_cmd="\"$VAGE_BIN\" -d -i $VAGE_ID_FILE -o $v_out $v_dec_input" - v_dec_ms=$(run_hyperfine "/tmp/bench_dec_vage_${name}.txt" "rm -f $v_out" "$vage_dec_cmd") + v_dec_ms=$(run_hyperfine "$WORKDIR/bench_dec_vage_${name}.txt" "rm -f $v_out" "$vage_dec_cmd") if [[ -n "$AGE_BIN" ]]; then a_dec_input=$(get_dec_file "$name" "age") age_dec_cmd="age -d -i $AGE_ID_FILE -o $a_out $a_dec_input" - a_dec_ms=$(run_hyperfine "/tmp/bench_dec_age_${name}.txt" "rm -f $a_out" "$age_dec_cmd") + a_dec_ms=$(run_hyperfine "$WORKDIR/bench_dec_age_${name}.txt" "rm -f $a_out" "$age_dec_cmd") else a_dec_ms="0.000 0.000" fi -- 2.51.2