elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
qemu-uip-http-stress.sh
File editor
#!/bin/sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) MFS=${MFS:-"$SCRIPT_DIR/elks/tools/bin/mfs"} IMAGE=${IMAGE:-"$SCRIPT_DIR/image/fd1440.img"} GUEST_IP=${GUEST_IP:-10.0.2.15} GATEWAY_IP=${GATEWAY_IP:-10.0.2.2} NETMASK=${NETMASK:-255.255.255.0} WORKDIR=${WORKDIR:-$(mktemp -d /tmp/elks-uip-stress.XXXXXX)} SUMMARY_FILE=$WORKDIR/summary.txt HTTP_PORT= QEMU_PID= QEMU_LOG= usage() { echo "Usage: $0 [matrix|burst N|rounds N [ROUNDS]]" exit 1 } find_qemu() { if [ -n "${QEMU:-}" ]; then printf '%s\n' "$QEMU" return fi for bin in qemu-system-i386 qemu-system-x86_64; do if command -v "$bin" >/dev/null 2>&1; then command -v "$bin" return fi done echo "QEMU system emulator not found" >&2 exit 1 } QEMU_BIN=$(find_qemu) cleanup_qemu() { if [ -n "${QEMU_PID:-}" ]; then kill "$QEMU_PID" >/dev/null 2>&1 || true wait "$QEMU_PID" 2>/dev/null || true QEMU_PID= fi QEMU_LOG= } cleanup_all() { cleanup_qemu } trap cleanup_all EXIT INT TERM require_host_tools() { if ! command -v python3 >/dev/null 2>&1; then echo "python3 not found" >&2 exit 1 fi if [ ! -x "$MFS" ]; then echo "mfs tool not found at $MFS" >&2 exit 1 fi if [ ! -f "$IMAGE" ]; then echo "image not found at $IMAGE" >&2 exit 1 fi } pick_http_port() { HTTP_PORT=$(python3 - <<'PY' import socket with socket.socket() as sock: sock.bind(("127.0.0.1", 0)) print(sock.getsockname()[1]) PY ) } render_rc() { rcfile=$1 cat >"$rcfile" <<EOF exec > /boot.log 2>&1 umask 022 export PATH=/bin export UIP_TRACE=/tmp/uip.trace clock -s -u uip -b -p ne0 $GUEST_IP $GATEWAY_IP $NETMASK || exit 1 sleep 2 httpd while true do sync sleep 10 done EOF } prepare_image() { base_image=$1 out_image=$2 rcfile=$3 cp "$base_image" "$out_image" render_rc "$rcfile" "$MFS" "$out_image" rm /etc/rc.sys >/dev/null 2>&1 || true "$MFS" "$out_image" cp "$rcfile" /etc/rc.sys } start_qemu() { image_file=$1 log_file=$2 pick_http_port QEMU_LOG=$log_file "$QEMU_BIN" \ -nodefaults \ -machine isapc \ -cpu 486,tsc \ -m 8M \ -rtc base=utc \ -display none \ -monitor none \ -serial none \ -drive file="$image_file",if=floppy,format=raw \ -boot a \ -netdev user,id=mynet,hostfwd=tcp:127.0.0.1:"$HTTP_PORT"-"$GUEST_IP":80 \ -device ne2k_isa,irq=12,netdev=mynet >"$QEMU_LOG" 2>&1 & QEMU_PID=$! } extract_guest_file() { image_file=$1 guest_path=$2 host_path=$3 if "$MFS" -f "$image_file" cat "$guest_path" >"$host_path" 2>/dev/null; then return 0 fi : >"$host_path" return 1 } collect_artifacts() { image_file=$1 outdir=$2 extract_guest_file "$image_file" /boot.log "$outdir/boot.log" || true extract_guest_file "$image_file" /tmp/uip.trace "$outdir/uip.trace" || true } http_probe() { port=$1 outfile=$2 python3 - "$port" "$outfile" <<'PY' import http.client import sys port = int(sys.argv[1]) outfile = sys.argv[2] conn = http.client.HTTPConnection("127.0.0.1", port, timeout=5) try: conn.request("GET", "/") resp = conn.getresponse() body = resp.read() finally: conn.close() with open(outfile, "wb") as fh: fh.write(body) if resp.status != 200 or b"It worked!!" not in body: raise SystemExit(1) PY } wait_for_http() { port=$1 outfile=$2 for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do if http_probe "$port" "$outfile" >/dev/null 2>&1; then return 0 fi sleep 1 done return 1 } http_burst() { port=$1 concurrency=$2 outfile=$3 python3 - "$port" "$concurrency" "$outfile" <<'PY' import concurrent.futures import http.client import sys port = int(sys.argv[1]) concurrency = int(sys.argv[2]) outfile = sys.argv[3] def fetch(_idx): conn = None try: conn = http.client.HTTPConnection("127.0.0.1", port, timeout=5) conn.request("GET", "/") resp = conn.getresponse() body = resp.read() return resp.status == 200 and b"It worked!!" in body except Exception: return False finally: if conn is not None: conn.close() ok = 0 with concurrent.futures.ThreadPoolExecutor(max_workers=concurrency) as pool: for result in pool.map(fetch, range(concurrency)): if result: ok += 1 with open(outfile, "w", encoding="ascii") as fh: fh.write(f"{ok}\n") print(ok) PY } run_burst() { concurrency=$1 outdir=$WORKDIR/burst-$concurrency image_file=$outdir/test.img rcfile=$outdir/rc.sys log_file=$outdir/qemu.log ready_file=$outdir/ready.http post_file=$outdir/post.http ok_file=$outdir/ok.txt summary=$outdir/summary.txt mkdir -p "$outdir" prepare_image "$IMAGE" "$image_file" "$rcfile" start_qemu "$image_file" "$log_file" if ! wait_for_http "$HTTP_PORT" "$ready_file"; then cleanup_qemu collect_artifacts "$image_file" "$outdir" echo "burst conc=$concurrency ok=0 post=False" | tee "$summary" >>"$SUMMARY_FILE" return 1 fi ok=$(http_burst "$HTTP_PORT" "$concurrency" "$ok_file") if http_probe "$HTTP_PORT" "$post_file" >/dev/null 2>&1; then post=True else post=False fi cleanup_qemu collect_artifacts "$image_file" "$outdir" line="burst conc=$concurrency ok=$ok post=$post" printf '%s\n' "$line" | tee "$summary" >>"$SUMMARY_FILE" } run_rounds() { concurrency=$1 rounds=${2:-8} outdir=$WORKDIR/rounds image_file=$outdir/test.img rcfile=$outdir/rc.sys log_file=$outdir/qemu.log ready_file=$outdir/ready.http summary=$outdir/summary.txt mkdir -p "$outdir" : >"$summary" prepare_image "$IMAGE" "$image_file" "$rcfile" start_qemu "$image_file" "$log_file" if ! wait_for_http "$HTTP_PORT" "$ready_file"; then cleanup_qemu collect_artifacts "$image_file" "$outdir" echo "round 0 ok 0 post False" | tee -a "$summary" >>"$SUMMARY_FILE" return 1 fi round=1 while [ "$round" -le "$rounds" ]; do ok_file=$outdir/round-$round.ok.txt post_file=$outdir/round-$round.post.http ok=$(http_burst "$HTTP_PORT" "$concurrency" "$ok_file") if http_probe "$HTTP_PORT" "$post_file" >/dev/null 2>&1; then post=True else post=False fi line="round $round ok $ok post $post" printf '%s\n' "$line" | tee -a "$summary" >>"$SUMMARY_FILE" if [ "$ok" -ne "$concurrency" ] || [ "$post" != True ]; then break fi round=$((round + 1)) done cleanup_qemu collect_artifacts "$image_file" "$outdir" } run_matrix() { : >"$SUMMARY_FILE" for concurrency in 1 2 4 8 12 16; do run_burst "$concurrency" || true done run_rounds 4 8 || true echo "Artifacts saved in $WORKDIR" } require_host_tools case "${1:-matrix}" in matrix|smoke) run_matrix ;; burst) [ $# -eq 2 ] || usage : >"$SUMMARY_FILE" run_burst "$2" echo "Artifacts saved in $WORKDIR" ;; rounds) [ $# -ge 2 ] && [ $# -le 3 ] || usage : >"$SUMMARY_FILE" run_rounds "$2" "${3:-8}" echo "Artifacts saved in $WORKDIR" ;; *) usage ;; esac
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history