(
results: list[Result], bucket_seconds: float, duration: float
)
| 201 | |
| 202 | |
| 203 | def _bucket_stats( |
| 204 | results: list[Result], bucket_seconds: float, duration: float |
| 205 | ) -> list[dict]: |
| 206 | n_buckets = max(1, int(duration // bucket_seconds) + 1) |
| 207 | buckets: list[list[Result]] = [[] for _ in range(n_buckets)] |
| 208 | for r in results: |
| 209 | b = int(r.t_end_s // bucket_seconds) |
| 210 | if 0 <= b < n_buckets: |
| 211 | buckets[b].append(r) |
| 212 | rows = [] |
| 213 | for i, rs in enumerate(buckets): |
| 214 | if not rs: |
| 215 | rows.append({"bucket_s": i * bucket_seconds, "n": 0}) |
| 216 | continue |
| 217 | oks = [r for r in rs if r.ok] |
| 218 | lats = [r.latency_ms for r in oks] |
| 219 | st = pcts(lats) if lats else {} |
| 220 | rows.append( |
| 221 | { |
| 222 | "bucket_s": i * bucket_seconds, |
| 223 | "n": len(rs), |
| 224 | "ok": len(oks), |
| 225 | "fail": len(rs) - len(oks), |
| 226 | "rps": len(rs) / bucket_seconds, |
| 227 | "p50": st.get("p50"), |
| 228 | "p95": st.get("p95"), |
| 229 | "p99": st.get("p99"), |
| 230 | "max": st.get("max"), |
| 231 | } |
| 232 | ) |
| 233 | return rows |
| 234 | |
| 235 | |
| 236 | # --- HTTP load generation --------------------------------------------------- |
no test coverage detected