Merge nucleic/sleek-thistle-egret-fyej into dev
This commit is contained in:
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/python3
|
||||
import argparse
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-b", "--base-results", dest="base_results_file_path", type=str, help="Path to base results output file", required=True)
|
||||
parser.add_argument("-t", "--test-results", dest="test_results_file_path", type=str, help="Path to test results output file", required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@dataclass
|
||||
class Benchmark:
|
||||
test_name: str
|
||||
duration_in_ns: int
|
||||
plus_or_minus_in_ns: int
|
||||
|
||||
def parse_benchmarks_results(file_path: str) -> Dict[str, Benchmark]:
|
||||
benchmarks = {}
|
||||
|
||||
with open(file_path, "r") as file:
|
||||
for line in file.readlines():
|
||||
match = re.match(r"test (.*) \.\.\. bench: +([\d,]+) ns/iter \(\+/- ([\d,]+)\)", line.strip())
|
||||
if match:
|
||||
benchmark = Benchmark(
|
||||
test_name=match.group(1),
|
||||
duration_in_ns=int(match.group(2).replace(',', '')),
|
||||
plus_or_minus_in_ns=int(match.group(3).replace(',', ''))
|
||||
)
|
||||
|
||||
benchmarks[benchmark.test_name] = benchmark
|
||||
|
||||
return benchmarks
|
||||
|
||||
base_results = parse_benchmarks_results(args.base_results_file_path)
|
||||
test_results = parse_benchmarks_results(args.test_results_file_path)
|
||||
|
||||
base_test_names = set(base_results.keys())
|
||||
test_test_names = set(test_results.keys())
|
||||
|
||||
removed_from_base = base_test_names - test_test_names
|
||||
added_by_test = test_test_names - base_test_names
|
||||
common = base_test_names & test_test_names
|
||||
|
||||
print("# Performance Benchmark Report")
|
||||
|
||||
if common:
|
||||
print(f"| {'Benchmark name':38} | {'Baseline (μs)':>13} | {'Test/PR (μs)':>13} | {'Delta (μs)':>13} | {'Delta %':15} |")
|
||||
print(f"| {'-' * 38} | {'-' * 13} | {'-' * 13} | {'-' * 13} | {'-' * 15} |")
|
||||
for name in sorted(common):
|
||||
# Retrieve base data
|
||||
base_duration = base_results[name].duration_in_ns / 1000.0
|
||||
base_plus_or_minus = base_results[name].plus_or_minus_in_ns / 1000.0
|
||||
base_plus_or_minus_percentage = (100.0 * base_plus_or_minus) / base_duration
|
||||
|
||||
# Retrieve test data
|
||||
test_duration = test_results[name].duration_in_ns / 1000.0
|
||||
test_plus_or_minus = test_results[name].plus_or_minus_in_ns / 1000.0
|
||||
test_plus_or_minus_percentage = (100.0 * test_plus_or_minus) / test_duration
|
||||
|
||||
# Compute delta
|
||||
delta_duration = test_duration - base_duration
|
||||
delta_percentage = (100.0 * delta_duration) / base_duration
|
||||
abs_delta_percentage = abs(delta_percentage)
|
||||
max_plus_or_minus_percentage = max(base_plus_or_minus_percentage, test_plus_or_minus_percentage)
|
||||
|
||||
# Format
|
||||
delta_str = f"{delta_duration:8.2f}"
|
||||
|
||||
if abs_delta_percentage > max_plus_or_minus_percentage:
|
||||
if delta_percentage < 0:
|
||||
delta_prefix = "🟢 "
|
||||
elif delta_percentage > 0:
|
||||
delta_prefix = "🟠 +"
|
||||
else:
|
||||
delta_prefix = "⚪ "
|
||||
|
||||
delta_percentage_str = f"{delta_prefix}{delta_percentage:.2f}%"
|
||||
else:
|
||||
delta_percentage_str = "⚪ Unchanged"
|
||||
|
||||
print(f"| `{name:36}` | `{base_duration:8.2f} μs` | `{test_duration:8.2f} μs` | `{delta_str:>8} μs` | `{delta_percentage_str:12}` |")
|
||||
|
||||
if removed_from_base:
|
||||
print()
|
||||
print("Benchmarks removed:")
|
||||
for name in removed_from_base:
|
||||
print(f" - {name}")
|
||||
|
||||
if added_by_test:
|
||||
print()
|
||||
print("Benchmarks added:")
|
||||
for name in added_by_test:
|
||||
print(f" - {name}")
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '
|
||||
.workspace_members as $members
|
||||
| .packages[]
|
||||
| select(.id as $id | $members | index($id))
|
||||
| select(any(.targets[]?; any(.kind[]?; . == "lib")))
|
||||
| .name
|
||||
'
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/python3
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description='Format API diff report')
|
||||
parser.add_argument("-p", dest="crate_name", type=str, help="Name of the crate", required=True)
|
||||
parser.add_argument("diff_path", type=str, help="Path to API diff file from cargo-public-api")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.diff_path, "r") as diff_file:
|
||||
diff_lines = diff_file.readlines()
|
||||
|
||||
removed_lines = []
|
||||
added_lines = []
|
||||
changed_lines = []
|
||||
|
||||
current_section = None
|
||||
|
||||
for line in diff_lines:
|
||||
line = line.strip()
|
||||
|
||||
if "Removed items" in line:
|
||||
current_section = removed_lines
|
||||
elif "Added items" in line:
|
||||
current_section = added_lines
|
||||
elif "Changed items" in line:
|
||||
current_section = changed_lines
|
||||
elif "============" in line:
|
||||
continue
|
||||
elif line == "(none)":
|
||||
continue
|
||||
elif not line:
|
||||
continue
|
||||
elif current_section is not None:
|
||||
current_section.append(line)
|
||||
|
||||
if not removed_lines and not added_lines and not changed_lines:
|
||||
sys.stderr.write("note: no API changes detected\n")
|
||||
sys.exit(0)
|
||||
|
||||
print(f"# Public API changes for crate: {args.crate_name}")
|
||||
|
||||
if removed_lines:
|
||||
print()
|
||||
print("## Removed items")
|
||||
|
||||
print("```")
|
||||
for line in removed_lines:
|
||||
print(line)
|
||||
print("```")
|
||||
|
||||
if added_lines:
|
||||
print()
|
||||
print("## Added items")
|
||||
|
||||
print("```")
|
||||
for line in added_lines:
|
||||
print(line)
|
||||
print("```")
|
||||
|
||||
if changed_lines:
|
||||
print()
|
||||
print("## Changed items")
|
||||
|
||||
print("```")
|
||||
for line in changed_lines:
|
||||
print(line)
|
||||
print("```")
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--rebuild-container-image",
|
||||
help="Rebuild the devcontainer image and recreate the container before entering",
|
||||
dest="rebuild_container_image",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--restart-container",
|
||||
help="Restart the devcontainer before entering",
|
||||
dest="restart_container",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--command",
|
||||
help="Command to run",
|
||||
dest="command",
|
||||
default="bash",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--quiet",
|
||||
help="Only generate minimal output",
|
||||
dest="quiet",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--env-file",
|
||||
help="Environment file to pass into the container",
|
||||
dest="env_file",
|
||||
type=str,
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.rebuild_container_image:
|
||||
# One implies the other.
|
||||
args.restart_container = True
|
||||
|
||||
this_script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
source_root = os.path.join(this_script_dir, "..")
|
||||
|
||||
if not os.path.isdir(os.path.join(source_root, ".devcontainer")):
|
||||
sys.stderr.write("error: couldn't find repo root\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not shutil.which("devcontainer"):
|
||||
sys.stderr.write(
|
||||
"error: couldn't find devcontainer CLI; did you install it as a prerequisite?\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
devcontainer_cli_args = [
|
||||
"devcontainer",
|
||||
"up",
|
||||
"--workspace-folder",
|
||||
source_root,
|
||||
]
|
||||
|
||||
if args.rebuild_container_image or args.restart_container:
|
||||
restart_args = devcontainer_cli_args.copy()
|
||||
|
||||
if args.rebuild_container_image:
|
||||
restart_args.append("--build-no-cache")
|
||||
if args.restart_container:
|
||||
restart_args.append("--remove-existing-container")
|
||||
|
||||
if args.rebuild_container_image:
|
||||
sys.stderr.write("Rebuilding devcontainer image...\n")
|
||||
else:
|
||||
sys.stderr.write("Restarting devcontainer...\n")
|
||||
|
||||
subprocess.run(restart_args, check=True, capture_output=args.quiet)
|
||||
|
||||
if not args.quiet:
|
||||
sys.stderr.write("Ensuring devcontainer is up...\n")
|
||||
|
||||
up_result = subprocess.run(devcontainer_cli_args, check=False, capture_output=True)
|
||||
|
||||
if up_result.returncode != 0:
|
||||
sys.stderr.write("error: devcontainer start-up failed\n")
|
||||
sys.stderr.write(up_result.stderr.decode("utf-8"))
|
||||
sys.exit(1)
|
||||
|
||||
result_data = json.loads(up_result.stdout.decode("utf-8"))
|
||||
|
||||
if "outcome" not in result_data:
|
||||
sys.stderr.write("error: couldn't determine outcome of devcontainer start-up\n")
|
||||
sys.exit(1)
|
||||
|
||||
if result_data["outcome"] != "success":
|
||||
sys.stderr.write("error: devcontainer start-up failed\n")
|
||||
sys.exit(1)
|
||||
|
||||
if "containerId" not in result_data:
|
||||
sys.stderr.write("error: couldn't determine container ID\n")
|
||||
sys.exit(1)
|
||||
|
||||
if "remoteWorkspaceFolder" not in result_data:
|
||||
sys.stderr.write("error: couldn't determine remote workspace folder\n")
|
||||
sys.exit(1)
|
||||
|
||||
container_id = result_data["containerId"]
|
||||
remote_workspace_folder = result_data["remoteWorkspaceFolder"]
|
||||
|
||||
if not args.quiet:
|
||||
sys.stderr.write("Launching shell in devcontainer...\n")
|
||||
|
||||
exec_args = [
|
||||
"docker",
|
||||
"container",
|
||||
"exec",
|
||||
"-it",
|
||||
"--workdir",
|
||||
remote_workspace_folder,
|
||||
]
|
||||
|
||||
if args.env_file:
|
||||
exec_args += ["--env-file", args.env_file]
|
||||
|
||||
exec_args.append(container_id)
|
||||
|
||||
exec_args += shlex.split(args.command)
|
||||
|
||||
exec_result = subprocess.run(exec_args, check=False)
|
||||
|
||||
sys.stderr.write("Command exited; devcontainer will remain running.\n")
|
||||
|
||||
sys.exit(exec_result.returncode)
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python3
|
||||
import argparse
|
||||
import json
|
||||
|
||||
parser = argparse.ArgumentParser(description='Summarize pytest results')
|
||||
parser.add_argument("-r", "--results", dest="results_file_path", type=str, required=True, help="Path to .json pytest results file")
|
||||
parser.add_argument("--title", dest="title", type=str, default="Pytest results", help="Title to display")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.results_file_path, "r") as results_file:
|
||||
results = json.load(results_file)
|
||||
|
||||
summary = results["summary"]
|
||||
|
||||
error_count = summary.get("error") or 0
|
||||
fail_count = summary.get("failed") or 0
|
||||
pass_count = summary.get("passed") or 0
|
||||
skip_count = summary.get("skipped") or 0
|
||||
expected_fail_count = summary.get("xfailed") or 0
|
||||
unexpected_pass_count = summary.get("xpassed") or 0
|
||||
|
||||
total_count = summary.get("total") or 0
|
||||
collected_count = summary.get("collected") or 0
|
||||
deselected_count = summary.get("deselected") or 0
|
||||
|
||||
#
|
||||
# Output
|
||||
#
|
||||
|
||||
print(f"# {args.title}")
|
||||
|
||||
print(f"| Outcome | Count | Percentage |")
|
||||
print(f"| ------------------ | ----------------------: | ---------: |")
|
||||
print(f"| ✅ Pass | {pass_count} | <span style='color:green'>{pass_count * 100 / total_count:.2f}</span> |")
|
||||
|
||||
if error_count > 0:
|
||||
print(f"| ❗️ Error | {error_count} | <span style='color:red'>{error_count * 100 / total_count:.2f}</span> |")
|
||||
if fail_count > 0:
|
||||
print(f"| ❌ Fail | {fail_count} | <span style='color:red'>{fail_count * 100 / total_count:.2f}</span> |")
|
||||
if skip_count > 0:
|
||||
print(f"| ⏩ Skip | {skip_count} | {skip_count * 100 / total_count:.2f} |")
|
||||
if expected_fail_count > 0:
|
||||
print(f"| ❎ Expected Fail | {expected_fail_count} | {expected_fail_count * 100 / total_count:.2f} |")
|
||||
if unexpected_pass_count > 0:
|
||||
print(f"| ✔️ Unexpected Pass | {unexpected_pass_count} | <span style='color:red'>{unexpected_pass_count * 100 / total_count:.2f}</span> |")
|
||||
|
||||
print(f"| 📊 Total | {total_count} | {total_count * 100 / total_count:.2f} |")
|
||||
Executable
+217
@@ -0,0 +1,217 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Script to test shell script execution across different shells with detailed tracing
|
||||
# Usage: test-across-shells.sh --output-dir=DIR --oracle-shell=SHELL --test-shell=SHELL SCRIPT [ARGS...]
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
usage() {
|
||||
cat >&2 <<EOF
|
||||
Usage: $0 [OPTIONS] [--] SCRIPT [ARGS...]
|
||||
|
||||
Execute a shell script under both an oracle shell and a test shell, capturing
|
||||
stdout, stderr, and execution traces for comparison.
|
||||
|
||||
Required Options:
|
||||
--output-dir=DIR Directory where output files will be placed
|
||||
--test-shell=SHELL Path to the shell under test
|
||||
|
||||
Optional Options:
|
||||
--oracle-shell=SHELL Path to the oracle shell (default: bash)
|
||||
|
||||
Arguments:
|
||||
-- Stop processing options (useful if SCRIPT starts with -)
|
||||
SCRIPT Path to the shell script to execute
|
||||
ARGS... Arguments to pass to the script (may include options like -v)
|
||||
|
||||
Output Structure:
|
||||
<output-dir>/
|
||||
oracle/
|
||||
stdout.txt Standard output from oracle shell
|
||||
stderr.txt Standard error from oracle shell
|
||||
trace.txt Execution trace (set -x output)
|
||||
exit_code.txt Exit code from oracle shell
|
||||
test/
|
||||
stdout.txt Standard output from test shell
|
||||
stderr.txt Standard error from test shell
|
||||
trace.txt Execution trace (set -x output)
|
||||
exit_code.txt Exit code from test shell
|
||||
|
||||
The script sets BASH_XTRACEFD=3 to redirect trace output to fd 3, enables
|
||||
tracing with 'set -x', and sets PS4 to include script name and line number.
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command-line arguments
|
||||
output_dir=""
|
||||
oracle_shell="bash"
|
||||
test_shell=""
|
||||
script_path=""
|
||||
declare -a script_args=()
|
||||
parsing_options=true
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if [[ "$parsing_options" == true ]]; then
|
||||
case "$1" in
|
||||
--output-dir=*)
|
||||
output_dir="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--oracle-shell=*)
|
||||
oracle_shell="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--test-shell=*)
|
||||
test_shell="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
usage
|
||||
;;
|
||||
--)
|
||||
# Stop parsing options, everything after this is for the script
|
||||
parsing_options=false
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo -e "${RED}Error: Unknown option: $1${NC}" >&2
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
# First non-option argument is the script path
|
||||
script_path="$1"
|
||||
parsing_options=false
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# We've stopped parsing options
|
||||
if [[ -z "$script_path" ]]; then
|
||||
script_path="$1"
|
||||
else
|
||||
script_args+=("$1")
|
||||
fi
|
||||
shift
|
||||
fi
|
||||
done
|
||||
|
||||
# Validate required arguments
|
||||
if [[ -z "$output_dir" ]]; then
|
||||
echo -e "${RED}Error: --output-dir is required${NC}" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
if [[ -z "$test_shell" ]]; then
|
||||
echo -e "${RED}Error: --test-shell is required${NC}" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
if [[ -z "$script_path" ]]; then
|
||||
echo -e "${RED}Error: SCRIPT path is required${NC}" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
if [[ ! -f "$script_path" ]]; then
|
||||
echo -e "${RED}Error: Script file not found: $script_path${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify shells exist and are executable
|
||||
for shell_name in oracle_shell test_shell; do
|
||||
shell_path="${!shell_name}"
|
||||
if ! command -v "$shell_path" >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: Shell not found or not executable: $shell_path${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Create output directory structure
|
||||
mkdir -p "$output_dir/oracle"
|
||||
mkdir -p "$output_dir/test"
|
||||
|
||||
# Log the parsed configuration
|
||||
echo -e "${BLUE}📋 Configuration:${NC}"
|
||||
echo " Oracle shell: $oracle_shell"
|
||||
echo " Test shell: $test_shell"
|
||||
echo " Script: $script_path"
|
||||
if [[ ${#script_args[@]} -gt 0 ]]; then
|
||||
echo " Arguments: ${script_args[*]}"
|
||||
else
|
||||
echo " Arguments: (none)"
|
||||
fi
|
||||
echo " Output dir: $output_dir"
|
||||
echo ""
|
||||
|
||||
# Function to execute script under a given shell
|
||||
execute_with_shell() {
|
||||
local shell_path="$1"
|
||||
local output_subdir="$2"
|
||||
local stdout_file="$output_dir/$output_subdir/stdout.txt"
|
||||
local stderr_file="$output_dir/$output_subdir/stderr.txt"
|
||||
local trace_file="$output_dir/$output_subdir/trace.txt"
|
||||
local exit_code_file="$output_dir/$output_subdir/exit_code.txt"
|
||||
|
||||
# Execute the shell with:
|
||||
# - BASH_XTRACEFD=3 set in the environment
|
||||
# - PS4 set to include script name and line number
|
||||
# - fd 3 redirected to trace file
|
||||
# - -x flag to enable tracing
|
||||
# - stdout to stdout file
|
||||
# - stderr to stderr file
|
||||
env BASH_XTRACEFD=3 PS4='+${BASH_SOURCE:-}:${LINENO:-}: ' \
|
||||
"$shell_path" -x "$script_path" "${script_args[@]}" \
|
||||
>"$stdout_file" \
|
||||
2>"$stderr_file" \
|
||||
3>"$trace_file"
|
||||
|
||||
local exit_code=$?
|
||||
echo "$exit_code" > "$exit_code_file"
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
# Execute under oracle shell
|
||||
echo -e "${BLUE}🔍 Executing under oracle shell ($oracle_shell)...${NC}"
|
||||
if execute_with_shell "$oracle_shell" "oracle"; then
|
||||
oracle_exit=0
|
||||
echo -e "${GREEN}✅ Oracle shell completed successfully (exit code: 0)${NC}"
|
||||
else
|
||||
oracle_exit=$?
|
||||
echo -e "${YELLOW}⚠️ Oracle shell exited with code: $oracle_exit${NC}"
|
||||
fi
|
||||
|
||||
# Execute under test shell
|
||||
echo -e "${BLUE}🧪 Executing under test shell ($test_shell)...${NC}"
|
||||
if execute_with_shell "$test_shell" "test"; then
|
||||
test_exit=0
|
||||
echo -e "${GREEN}✅ Test shell completed successfully (exit code: 0)${NC}"
|
||||
else
|
||||
test_exit=$?
|
||||
echo -e "${YELLOW}⚠️ Test shell exited with code: $test_exit${NC}"
|
||||
fi
|
||||
|
||||
# Report results
|
||||
echo ""
|
||||
echo -e "📁 Execution complete. Output written to: $output_dir"
|
||||
echo " Oracle shell exit code: $oracle_exit"
|
||||
echo " Test shell exit code: $test_exit"
|
||||
echo ""
|
||||
|
||||
if [[ $oracle_exit -eq $test_exit ]]; then
|
||||
echo -e "${GREEN}✅ Exit codes match ✓${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Exit codes differ ✗${NC}"
|
||||
fi
|
||||
|
||||
# Exit with non-zero if the test results differ
|
||||
if [[ $oracle_exit -ne $test_exit ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
workspace_root="$(realpath "${script_dir}/..")"
|
||||
|
||||
export CARGO_TARGET_DIR="${workspace_root}/target/cov"
|
||||
|
||||
cd "${workspace_root}"
|
||||
source <(cargo llvm-cov show-env --export-prefix)
|
||||
|
||||
cargo llvm-cov clean --workspace
|
||||
|
||||
cargo test -- --show-output || true
|
||||
|
||||
cargo llvm-cov report --html --ignore-filename-regex "target/.*"
|
||||
Reference in New Issue
Block a user