@@ -94,9 +94,9 @@ delivery with the same `@fedify/fedify` signer a real peer uses, so the measured
9494crypto cost is real.
9595
9696> [ !NOTE]
97- > This version runs the ` inbox ` and ` webfinger ` scenario types. The scenario
98- > format can express the others ( ` actor ` , ` object ` , ` fanout ` , ` collection ` ,
99- > ` failure ` , and ` mixed ` ), but they are not executed yet. Within the runnable
97+ > This version runs the ` inbox ` , ` webfinger ` , ` actor ` , ` object ` , ` fanout ` ,
98+ > ` failure ` , and ` mixed ` scenario types. The ` collection ` scenario type is
99+ > reserved by the suite format but is not executed yet. Within the runnable
100100> types, a few options the format accepts are also not implemented yet and are
101101> rejected up front with a clear message:
102102>
@@ -115,7 +115,7 @@ is a superset). The suite declares the `target`, shared `defaults`, the
115115block of pass/fail thresholds:
116116
117117~~~~ yaml
118- # yaml-language-server: $schema=https://json-schema.fedify.dev/bench/scenario-v1 .json
118+ # yaml-language-server: $schema=https://json-schema.fedify.dev/bench/scenario-v2 .json
119119version : 1
120120target : http://localhost:3000
121121defaults :
@@ -161,7 +161,56 @@ list, deliveries are rotated across the recipients (and across the synthetic
161161` actors ` signing them), modeling a server that receives from many peers into
162162many local inboxes.
163163
164- [ published schema ] : https://json-schema.fedify.dev/bench/scenario-v1.json
164+ [ published schema ] : https://json-schema.fedify.dev/bench/scenario-v2.json
165+
166+ ### Scenario types
167+
168+ The runnable scenario types cover the main benchmark surfaces:
169+
170+ - ` inbox ` : discovers recipient inboxes and sends signed ` Create(Note) `
171+ deliveries through the target's inbound ActivityPub path.
172+ - ` webfinger ` : drives direct ` /.well-known/webfinger ` lookups on the target.
173+ - ` actor ` : resolves actor URLs from the scenario recipients and fetches actor
174+ documents. Set ` authenticated: true ` to sign those GET requests.
175+ - ` object ` : fetches object URLs from ` source ` . Set ` authenticated: true ` to
176+ sign those GET requests.
177+ - ` fanout ` : posts to ` /.well-known/fedify/bench/trigger ` so the target calls
178+ ` sendActivity() ` and drains its fanout/outbox queue to benchmark-owned sink
179+ inboxes. The command starts those sink inboxes locally. A non-loopback
180+ target therefore needs ` --advertise-host ` unless the scenario sets
181+ ` sinkBase ` to a reachable ` http://host:port/ ` URL. The target must either
182+ allow the generated sink inboxes through ` triggerSinks ` or run with
183+ ` allowUnsafeTriggerRecipients ` in a controlled benchmark environment. Use
184+ ` sinkBase ` when you want those inboxes to be deterministic, for example
185+ ` http://127.0.0.1:9090/inbox/0 ` through
186+ ` http://127.0.0.1:9090/inbox/4 ` for ` followers: 5 ` .
187+ ` fedify bench ` does not switch the target's queue backend; run the same
188+ suite against targets configured with the queue implementations you want to
189+ compare. Fanout triggers are serialized while the runner observes queue
190+ drain, so client latency includes time spent waiting for earlier fanout
191+ drains under high-rate or concurrent load. Use ` deliveryThroughput ` and
192+ ` queueDrain ` expectations for delivery performance, and keep request
193+ latency expectations conservative for this scenario type.
194+ - ` failure ` : records expected fault outcomes as successes. For this
195+ scenario type, ` successRate ` means “the expected failure was observed,”
196+ not “the HTTP request succeeded.” The ` invalid-signature ` and
197+ ` missing-actor ` faults send malformed signed deliveries to a recipient
198+ inbox. The ` remote-404 ` , ` remote-410 ` , ` slow-inbox ` , and ` network-error `
199+ faults post to the benchmark trigger endpoint with ` sender ` , so the target
200+ uses its normal outbound delivery path against controlled benchmark-owned
201+ sink inboxes. Like ` fanout ` , these remote failure faults need
202+ ` --advertise-host ` for a non-loopback target unless ` sinkBase ` gives a
203+ reachable, fixed sink base URL that the target's ` triggerSinks ` can
204+ preconfigure. Remote failure deliveries are also serialized while the
205+ runner waits for the target's queue to
206+ observe the expected failure or retry signal, so request latency can include
207+ earlier wait time when the configured load is concurrent or high-rate.
208+ - ` mixed ` : runs referenced child scenarios concurrently, splitting the
209+ ` mixed ` scenario's load by each entry's ` weight ` . The referenced
210+ scenarios are named scenarios in the same suite and are still run as normal
211+ suite entries when listed. The mixed result merges client-side request,
212+ throughput, delivery throughput, latency, and error measurements;
213+ server-side metric snapshots are not merged across child runners.
165214
166215### Actors
167216
@@ -239,7 +288,7 @@ CI check. Keep CI gates on robust signals such as success rate, error counts,
239288and gross throughput or latency floors; precise latency-percentile regression
240289belongs in a controlled environment, not a shared CI runner.
241290
242- [ report schema ] : https://json-schema.fedify.dev/bench/report-v1 .json
291+ [ report schema ] : https://json-schema.fedify.dev/bench/report-v2 .json
243292
244293### Safety
245294
@@ -347,6 +396,11 @@ allowlist. To bypass this guard for a controlled run, set
347396` ~FederationBenchmarkOptions.allowUnsafeTriggerRecipients ` to ` true ` in the
348397application configuration.
349398
399+ For ` fanout ` and remote ` failure ` scenarios, set a ` sinkBase ` value such as
400+ ` http://host:port/ ` in the scenario when the target keeps the safe default and
401+ you need stable sink URLs for ` triggerSinks ` . With ` followers: 5 ` , the runner
402+ generates ` /inbox/0 ` through ` /inbox/4 ` under that base.
403+
350404A successful trigger returns ` 202 Accepted ` :
351405
352406~~~~ json
0 commit comments