mirror of
git://f0xx.org/android_cast
synced 2026-07-29 09:17:51 +03:00
197 lines
5.8 KiB
Bash
Executable File
197 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# VPN crash simulation lab — device (adb) and/or BE upload verification.
|
|
#
|
|
# Modes:
|
|
# MODE=device — trigger VpnCrashSimulator in :vpn via adb (debug APK)
|
|
# MODE=upload — POST synthetic vpn-process crash JSON to BE upload API
|
|
# MODE=both — device then verify BE (default when adb device present)
|
|
#
|
|
# Env:
|
|
# COUNT=70
|
|
# BASE=https://apps.f0xx.org/app/androidcast_project/crashes
|
|
# RUN_ID=YYYYMMDD_HHMMSS (batch tag for Issues search)
|
|
# PACKAGE=com.foxx.androidcast
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
COUNT="${COUNT:-70}"
|
|
BASE="${BASE:-https://apps.f0xx.org/app/androidcast_project/crashes}"
|
|
UPLOAD_URL="$BASE/api/upload.php"
|
|
PACKAGE="${PACKAGE:-com.foxx.androidcast}"
|
|
RUN_ID="${RUN_ID:-$(date -u +%Y%m%d_%H%M%S)}"
|
|
MODE="${MODE:-auto}"
|
|
JAR="${JAR:-/tmp/ac_vpn_crash_cookies.txt}"
|
|
DELAY_MS="${DELAY_MS:-80}"
|
|
VERIFY_LOGIN="${VERIFY_LOGIN:-1}"
|
|
|
|
log() { printf '[vpn-crash-sim] %s\n' "$*"; }
|
|
|
|
has_device() {
|
|
adb devices 2>/dev/null | awk 'NR>1 && $2=="device" { found=1 } END { exit !found }'
|
|
}
|
|
|
|
simulate_device() {
|
|
local n="$1"
|
|
local i seq
|
|
log "device: triggering $n VPN-process crash recordings via $PACKAGE"
|
|
for ((i = 1; i <= n; i++)); do
|
|
seq="$i"
|
|
adb shell am start-service \
|
|
-n "$PACKAGE/com.foxx.androidcast.vpn.AndroidCastVpnService" \
|
|
-a com.foxx.androidcast.vpn.SIMULATE_CRASH \
|
|
--ei sim_seq "$seq" >/dev/null 2>&1 \
|
|
|| adb shell am startservice \
|
|
-n "$PACKAGE/com.foxx.androidcast.vpn.AndroidCastVpnService" \
|
|
-a com.foxx.androidcast.vpn.SIMULATE_CRASH \
|
|
--ei sim_seq "$seq" >/dev/null 2>&1 \
|
|
|| true
|
|
if [[ "$DELAY_MS" -gt 0 ]]; then
|
|
sleep "$(awk "BEGIN { print $DELAY_MS / 1000 }")"
|
|
fi
|
|
if (( i % 10 == 0 )); then
|
|
log " device progress $i/$n"
|
|
fi
|
|
done
|
|
log "device: done — waiting for crash watcher upload sweep"
|
|
sleep 15
|
|
}
|
|
|
|
upload_one() {
|
|
local seq="$1"
|
|
local report_id="vpn_sim_${RUN_ID}_$(printf '%03d' "$seq")"
|
|
local ms
|
|
ms="$(date +%s)000"
|
|
local fp
|
|
fp="$(printf 'vpn_sim_%s_%03d' "$RUN_ID" "$seq" | sha256sum | awk '{print $1}')"
|
|
local body
|
|
body="$(cat <<EOF
|
|
{
|
|
"schema_version": 1,
|
|
"report_id": "$report_id",
|
|
"generated_at_epoch_ms": $ms,
|
|
"crash_type": "java",
|
|
"scenario": "vpn_service",
|
|
"process": "com.foxx.androidcast:vpn",
|
|
"fingerprint": "$fp",
|
|
"tags": ["vpn_sim", "$RUN_ID"],
|
|
"device": {
|
|
"manufacturer": "SimLab",
|
|
"brand": "AndroidCast",
|
|
"model": "VpnCrashSim",
|
|
"device": "vpn_sim",
|
|
"product": "vpn_sim",
|
|
"sdk_int": 34,
|
|
"release": "14",
|
|
"abis": ["arm64-v8a"]
|
|
},
|
|
"app": {
|
|
"package": "$PACKAGE",
|
|
"version_name": "0.1.0",
|
|
"version_code": 100
|
|
},
|
|
"build": { "debug": true, "git_commit": "vpn_sim" },
|
|
"runtime_context": { "vpn_sim_seq": $seq, "run_id": "$RUN_ID" },
|
|
"java": {
|
|
"thread": "androidcast-vpn-worker",
|
|
"exception": "java.lang.RuntimeException",
|
|
"message": "VpnCrashSimulation seq=$seq proc=com.foxx.androidcast:vpn",
|
|
"stack_frames": [
|
|
"com.foxx.androidcast.vpn.WireGuardVpnEngine.apply(WireGuardVpnEngine.java:40)",
|
|
"com.foxx.androidcast.vpn.AndroidCastVpnService\$1.applyWireGuardConfig(AndroidCastVpnService.java:60)",
|
|
"com.foxx.androidcast.vpn.AndroidCastVpnService.onStartCommand(AndroidCastVpnService.java:95)",
|
|
"android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5001)"
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
)"
|
|
curl -sk -w '\n%{http_code}' -H 'Content-Type: application/json' --data-binary "$body" "$UPLOAD_URL"
|
|
}
|
|
|
|
simulate_upload() {
|
|
local n="$1"
|
|
local ok=0 fail=0 dup=0
|
|
log "upload: posting $n vpn-process crash reports to $UPLOAD_URL (run_id=$RUN_ID)"
|
|
local i resp code
|
|
for ((i = 1; i <= n; i++)); do
|
|
resp="$(upload_one "$i")"
|
|
code="$(echo "$resp" | tail -n1)"
|
|
case "$code" in
|
|
200) ((ok++)) || true ;;
|
|
409) ((dup++)) || true ;;
|
|
*) ((fail++)) || true; log " FAIL seq=$i HTTP $code" ;;
|
|
esac
|
|
if (( i % 10 == 0 )); then
|
|
log " upload progress $i/$n (ok=$ok dup=$dup fail=$fail)"
|
|
fi
|
|
if [[ "$DELAY_MS" -gt 0 ]]; then
|
|
sleep "$(awk "BEGIN { print $DELAY_MS / 1000 }")"
|
|
fi
|
|
done
|
|
log "upload: ok=$ok duplicate=$dup failed=$fail / $n"
|
|
[[ "$fail" -eq 0 ]]
|
|
}
|
|
|
|
verify_be() {
|
|
if [[ "$VERIFY_LOGIN" != "1" ]]; then
|
|
log "verify: skipped (VERIFY_LOGIN=$VERIFY_LOGIN)"
|
|
return 0
|
|
fi
|
|
log "verify: login + search Issues for run_id=$RUN_ID"
|
|
curl -sk -c "$JAR" -b "$JAR" -L -X POST "$BASE/login" \
|
|
-d 'username=admin&password=admin' -o /dev/null || true
|
|
local json
|
|
local q="${QUERY:-$RUN_ID}"
|
|
json="$(curl -sk -b "$JAR" "$BASE/api/reports.php?q=${q}&per_page=200")"
|
|
local cnt
|
|
cnt="$(echo "$json" | python3 -c "
|
|
import json,sys
|
|
d=json.load(sys.stdin)
|
|
items=d.get('items') or []
|
|
print(len(items))
|
|
" 2>/dev/null || echo 0)"
|
|
log "verify: BE reports matching q=$q → $cnt (expected up to $COUNT)"
|
|
if [[ "$cnt" -lt 1 ]]; then
|
|
log "verify: WARN — Issues API returned 0 (login cookie may be invalid in automation)"
|
|
log "verify: open $BASE/?view=reports&q=$q in browser when logged in"
|
|
return 1
|
|
fi
|
|
echo "$json" | python3 -c "
|
|
import json,sys
|
|
d=json.load(sys.stdin)
|
|
for it in (d.get('items') or [])[:3]:
|
|
p=it.get('payload') or {}
|
|
j=p.get('java') or {}
|
|
print(' sample:', it.get('report_id'), 'process=', p.get('process'), 'frames=', len(j.get('stack_frames') or []))
|
|
" 2>/dev/null || true
|
|
}
|
|
|
|
if [[ "$MODE" == "auto" ]]; then
|
|
if has_device; then
|
|
MODE=both
|
|
else
|
|
MODE=upload
|
|
log "no adb device — using upload-only mode"
|
|
fi
|
|
fi
|
|
|
|
case "$MODE" in
|
|
device)
|
|
simulate_device "$COUNT"
|
|
;;
|
|
upload)
|
|
simulate_upload "$COUNT"
|
|
verify_be || true
|
|
;;
|
|
both)
|
|
simulate_device "$COUNT"
|
|
QUERY="${QUERY:-VpnCrashSimulation}" verify_be || true
|
|
;;
|
|
*)
|
|
echo "unknown MODE=$MODE (device|upload|both)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log "complete run_id=$RUN_ID — Issues: $BASE/?view=reports&q=$RUN_ID"
|