()
| 733 | |
| 734 | |
| 735 | def main() -> int: |
| 736 | ap = argparse.ArgumentParser() |
| 737 | sub = ap.add_subparsers(dest="mode", required=True) |
| 738 | |
| 739 | h = sub.add_parser("http") |
| 740 | h.add_argument("--url", default="http://127.0.0.1:5000") |
| 741 | h.add_argument( |
| 742 | "-c", |
| 743 | "--concurrency", |
| 744 | type=int, |
| 745 | default=8, |
| 746 | help="closed-loop: worker count; open-loop: in-flight cap", |
| 747 | ) |
| 748 | h.add_argument("-d", "--duration", type=int, default=30) |
| 749 | h.add_argument("--seed", type=int, default=42) |
| 750 | h.add_argument( |
| 751 | "--rps", |
| 752 | type=float, |
| 753 | default=0.0, |
| 754 | help="target arrival rate (open-loop). 0 = closed-loop (fixed concurrency)", |
| 755 | ) |
| 756 | h.add_argument( |
| 757 | "--simple-ratio", |
| 758 | type=float, |
| 759 | default=0.0, |
| 760 | help="fraction of requests that are simple (non-bot) commands", |
| 761 | ) |
| 762 | h.add_argument( |
| 763 | "--bucket-seconds", |
| 764 | type=float, |
| 765 | default=0.0, |
| 766 | help="if > 0, emit per-bucket latency rows (p50/p95/p99) over test duration", |
| 767 | ) |
| 768 | h.add_argument( |
| 769 | "--json", |
| 770 | action="store_true", |
| 771 | help="emit JSON report to stdout instead of human-readable text", |
| 772 | ) |
| 773 | |
| 774 | p = sub.add_parser("profile") |
| 775 | p.add_argument("--db", default="explainshell.db") |
| 776 | p.add_argument("-n", type=int, default=50) |
| 777 | p.add_argument("--seed", type=int, default=42) |
| 778 | |
| 779 | sr = sub.add_parser("slowread", help="slow-read attack (park gthread workers)") |
| 780 | sr.add_argument("--url", default="http://127.0.0.1:5000") |
| 781 | sr.add_argument("-c", "--concurrency", type=int, default=16) |
| 782 | sr.add_argument("-d", "--duration", type=int, default=60) |
| 783 | sr.add_argument("--seed", type=int, default=42) |
| 784 | sr.add_argument( |
| 785 | "--read-bps", type=int, default=512, help="per-connection read rate (bytes/s)" |
| 786 | ) |
| 787 | sr.add_argument("--chunk", type=int, default=128, help="read chunk size (bytes)") |
| 788 | sr.add_argument( |
| 789 | "--witness-interval", |
| 790 | type=float, |
| 791 | default=2.0, |
| 792 | help="seconds between witness GET / probes (0 disables)", |
no test coverage detected