Add pack profile capture workflow
Some checks failed
build / Windows Build (push) Has been cancelled
Some checks failed
build / Windows Build (push) Has been cancelled
This commit is contained in:
193
scripts/capture-pack-profile.sh
Executable file
193
scripts/capture-pack-profile.sh
Executable file
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
capture-pack-profile.sh [options] [build-bin-dir] [-- <client args...>]
|
||||
|
||||
Examples:
|
||||
capture-pack-profile.sh --label pck
|
||||
capture-pack-profile.sh --runtime-root ../m2dev-client --label baseline
|
||||
capture-pack-profile.sh ./build-mingw64-lld/bin -- --m2pack-strict-hash 1
|
||||
|
||||
Options:
|
||||
--runtime-root DIR Stage runtime content from DIR before launching
|
||||
--label NAME Output label for the captured report
|
||||
--out-dir DIR Directory for archived raw + summary reports
|
||||
--timeout SEC Overrides M2_TIMEOUT for the headless run
|
||||
--copy-runtime Materialize runtime instead of symlinking it
|
||||
-h, --help Show this help
|
||||
|
||||
Behavior:
|
||||
- Enables M2PACK_PROFILE=1 for the client run
|
||||
- Archives build-bin-dir/log/pack_profile.txt under --out-dir
|
||||
- Writes a parsed summary next to the raw report
|
||||
- Treats timeout exit codes (124/137) as acceptable if the report exists
|
||||
|
||||
Environment overrides:
|
||||
M2_STAGE_RUNTIME_SCRIPT path to stage-linux-runtime.sh
|
||||
M2_HEADLESS_RUN_SCRIPT path to run-wine-headless.sh
|
||||
M2_PACK_PROFILE_PARSER path to pack-profile-report.py
|
||||
EOF
|
||||
}
|
||||
|
||||
sanitize_label() {
|
||||
printf '%s' "$1" \
|
||||
| tr '[:upper:]' '[:lower:]' \
|
||||
| sed -E 's/[^a-z0-9._-]+/-/g; s/^-+//; s/-+$//; s/-{2,}/-/g'
|
||||
}
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(realpath "$script_dir/..")"
|
||||
default_build_bin_dir="$repo_root/build-mingw64-lld/bin"
|
||||
default_runtime_root="$repo_root/../m2dev-client"
|
||||
|
||||
stage_script="${M2_STAGE_RUNTIME_SCRIPT:-$script_dir/stage-linux-runtime.sh}"
|
||||
run_script="${M2_HEADLESS_RUN_SCRIPT:-$script_dir/run-wine-headless.sh}"
|
||||
parser_script="${M2_PACK_PROFILE_PARSER:-$script_dir/pack-profile-report.py}"
|
||||
|
||||
runtime_root=""
|
||||
label=""
|
||||
out_dir=""
|
||||
timeout_seconds="${M2_TIMEOUT:-20}"
|
||||
copy_runtime=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--runtime-root)
|
||||
runtime_root="$2"
|
||||
shift 2
|
||||
;;
|
||||
--label)
|
||||
label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
out_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--timeout)
|
||||
timeout_seconds="$2"
|
||||
shift 2
|
||||
;;
|
||||
--copy-runtime)
|
||||
copy_runtime=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
build_bin_dir="${1:-$default_build_bin_dir}"
|
||||
if [[ $# -gt 0 ]]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
build_bin_dir="$(realpath -m "$build_bin_dir")"
|
||||
|
||||
if [[ -z "$label" ]]; then
|
||||
label="$(date +%Y%m%d-%H%M%S)"
|
||||
fi
|
||||
|
||||
safe_label="$(sanitize_label "$label")"
|
||||
if [[ -z "$safe_label" ]]; then
|
||||
safe_label="capture"
|
||||
fi
|
||||
|
||||
if [[ -z "$out_dir" ]]; then
|
||||
out_dir="$build_bin_dir/log/pack-profile-runs"
|
||||
fi
|
||||
out_dir="$(realpath -m "$out_dir")"
|
||||
|
||||
if [[ -z "$runtime_root" ]]; then
|
||||
if [[ ! -e "$build_bin_dir/config/locale.cfg" || ! -e "$build_bin_dir/pack" ]]; then
|
||||
if [[ -d "$default_runtime_root" ]]; then
|
||||
runtime_root="$default_runtime_root"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$runtime_root" ]]; then
|
||||
runtime_root="$(realpath "$runtime_root")"
|
||||
fi
|
||||
|
||||
if [[ ! -x "$run_script" ]]; then
|
||||
echo "headless runner not executable: $run_script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$parser_script" ]]; then
|
||||
echo "pack profile parser not found: $parser_script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v python3 >/dev/null 2>&1; then
|
||||
echo "python3 not found in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$build_bin_dir/log" "$out_dir"
|
||||
|
||||
if [[ -n "$runtime_root" ]]; then
|
||||
if [[ ! -x "$stage_script" ]]; then
|
||||
echo "runtime staging script not executable: $stage_script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
stage_args=()
|
||||
if [[ "$copy_runtime" -eq 1 ]]; then
|
||||
stage_args+=(--copy)
|
||||
fi
|
||||
stage_args+=("$runtime_root" "$build_bin_dir")
|
||||
"$stage_script" "${stage_args[@]}"
|
||||
fi
|
||||
|
||||
report_path="$build_bin_dir/log/pack_profile.txt"
|
||||
raw_out="$out_dir/$safe_label.pack_profile.txt"
|
||||
summary_out="$out_dir/$safe_label.summary.txt"
|
||||
|
||||
rm -f "$report_path"
|
||||
|
||||
set +e
|
||||
M2PACK_PROFILE=1 M2_TIMEOUT="$timeout_seconds" "$run_script" "$build_bin_dir" -- "$@"
|
||||
run_exit=$?
|
||||
set -e
|
||||
|
||||
if [[ ! -f "$report_path" ]]; then
|
||||
echo "pack profile report was not generated: $report_path" >&2
|
||||
exit "$run_exit"
|
||||
fi
|
||||
|
||||
cp "$report_path" "$raw_out"
|
||||
python3 "$parser_script" "$raw_out" > "$summary_out"
|
||||
|
||||
case "$run_exit" in
|
||||
0|124|137)
|
||||
;;
|
||||
*)
|
||||
echo "client run exited with $run_exit; archived report anyway:" >&2
|
||||
echo " raw: $raw_out" >&2
|
||||
echo " summary: $summary_out" >&2
|
||||
exit "$run_exit"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "captured pack profile:"
|
||||
echo " raw: $raw_out"
|
||||
echo " summary: $summary_out"
|
||||
176
scripts/compare-pack-profile-runs.sh
Executable file
176
scripts/compare-pack-profile-runs.sh
Executable file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
compare-pack-profile-runs.sh [options] [build-bin-dir] [-- <client args...>]
|
||||
|
||||
Examples:
|
||||
compare-pack-profile-runs.sh \
|
||||
--left-label pck \
|
||||
--left-runtime-root /srv/client-runtime-pck \
|
||||
--right-label m2p \
|
||||
--right-runtime-root /srv/client-runtime-m2p
|
||||
|
||||
compare-pack-profile-runs.sh \
|
||||
--left-label legacy \
|
||||
--left-runtime-root ../runtime-pck \
|
||||
--right-label secure \
|
||||
--right-runtime-root ../runtime-m2p \
|
||||
./build-mingw64-lld/bin -- --m2pack-strict-hash 0
|
||||
|
||||
Options:
|
||||
--left-runtime-root DIR Runtime root for the first run
|
||||
--right-runtime-root DIR Runtime root for the second run
|
||||
--left-label NAME Label for the first run (default: left)
|
||||
--right-label NAME Label for the second run (default: right)
|
||||
--out-dir DIR Directory for archived reports and compare output
|
||||
--timeout SEC Overrides M2_TIMEOUT for both runs
|
||||
--copy-runtime Materialize runtime instead of symlinking it
|
||||
-h, --help Show this help
|
||||
|
||||
Behavior:
|
||||
- Runs two captures back-to-back into the same build output
|
||||
- Archives both raw reports and summaries
|
||||
- Writes a combined compare report and prints it to stdout
|
||||
EOF
|
||||
}
|
||||
|
||||
sanitize_label() {
|
||||
printf '%s' "$1" \
|
||||
| tr '[:upper:]' '[:lower:]' \
|
||||
| sed -E 's/[^a-z0-9._-]+/-/g; s/^-+//; s/-+$//; s/-{2,}/-/g'
|
||||
}
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(realpath "$script_dir/..")"
|
||||
default_build_bin_dir="$repo_root/build-mingw64-lld/bin"
|
||||
|
||||
capture_script="${M2_CAPTURE_PACK_PROFILE_SCRIPT:-$script_dir/capture-pack-profile.sh}"
|
||||
parser_script="${M2_PACK_PROFILE_PARSER:-$script_dir/pack-profile-report.py}"
|
||||
|
||||
left_runtime_root=""
|
||||
right_runtime_root=""
|
||||
left_label="left"
|
||||
right_label="right"
|
||||
out_dir=""
|
||||
timeout_seconds="${M2_TIMEOUT:-20}"
|
||||
copy_runtime=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--left-runtime-root)
|
||||
left_runtime_root="$2"
|
||||
shift 2
|
||||
;;
|
||||
--right-runtime-root)
|
||||
right_runtime_root="$2"
|
||||
shift 2
|
||||
;;
|
||||
--left-label)
|
||||
left_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--right-label)
|
||||
right_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
out_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--timeout)
|
||||
timeout_seconds="$2"
|
||||
shift 2
|
||||
;;
|
||||
--copy-runtime)
|
||||
copy_runtime=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$left_runtime_root" || -z "$right_runtime_root" ]]; then
|
||||
echo "both --left-runtime-root and --right-runtime-root are required" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build_bin_dir="${1:-$default_build_bin_dir}"
|
||||
if [[ $# -gt 0 ]]; then
|
||||
shift
|
||||
fi
|
||||
build_bin_dir="$(realpath -m "$build_bin_dir")"
|
||||
|
||||
if [[ -z "$out_dir" ]]; then
|
||||
out_dir="$build_bin_dir/log/pack-profile-runs/$(date +%Y%m%d-%H%M%S)"
|
||||
fi
|
||||
out_dir="$(realpath -m "$out_dir")"
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
if [[ ! -x "$capture_script" ]]; then
|
||||
echo "capture script not executable: $capture_script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$parser_script" ]]; then
|
||||
echo "pack profile parser not found: $parser_script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v python3 >/dev/null 2>&1; then
|
||||
echo "python3 not found in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
capture_common_args=(
|
||||
--out-dir "$out_dir"
|
||||
--timeout "$timeout_seconds"
|
||||
)
|
||||
if [[ "$copy_runtime" -eq 1 ]]; then
|
||||
capture_common_args+=(--copy-runtime)
|
||||
fi
|
||||
|
||||
"$capture_script" \
|
||||
"${capture_common_args[@]}" \
|
||||
--runtime-root "$left_runtime_root" \
|
||||
--label "$left_label" \
|
||||
"$build_bin_dir" \
|
||||
-- "$@"
|
||||
|
||||
"$capture_script" \
|
||||
"${capture_common_args[@]}" \
|
||||
--runtime-root "$right_runtime_root" \
|
||||
--label "$right_label" \
|
||||
"$build_bin_dir" \
|
||||
-- "$@"
|
||||
|
||||
left_safe_label="$(sanitize_label "$left_label")"
|
||||
right_safe_label="$(sanitize_label "$right_label")"
|
||||
left_report="$out_dir/$left_safe_label.pack_profile.txt"
|
||||
right_report="$out_dir/$right_safe_label.pack_profile.txt"
|
||||
compare_path="$out_dir/compare-$left_safe_label-vs-$right_safe_label.txt"
|
||||
|
||||
python3 "$parser_script" \
|
||||
"$left_label=$left_report" \
|
||||
"$right_label=$right_report" | tee "$compare_path"
|
||||
|
||||
echo
|
||||
echo "saved compare report: $compare_path"
|
||||
Reference in New Issue
Block a user