mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
congestion-stress said the transport drop-detection path "is exercised by nothing". Widening the scan beyond this one scenario finds it firing in six others, so the path is live and what is dead is this scenario's ability to provoke it. Records the arithmetic that explains why: at the 1 Mbps cap the receive queue needs tens of milliseconds of reader stall to overflow, and the ingress policer discards the same traffic a layer below the socket. mixed-technology said the implementation does not do what its criteria say. It does. The criteria were conditioned on a tree rooted at n01 while the mesh rooted at n09, under which n08's choice was settled by depth before link technology could matter. The archived parent distributions are relabelled as describing the old root so nobody calibrates against them. cost-reeval now records why it had no assertion about its own subject: its designated subject was the root, so the parent switch it exists to observe could not occur. The historical logs show the switch on n04 in 13 of 14 runs when the root still wandered, and only on n01 in the five runs before the fix. Each header now names what remains to be done and where it is tracked, rather than leaving a disproved conclusion in place for the next reader to inherit.
149 lines
4.5 KiB
YAML
149 lines
4.5 KiB
YAML
# Mixed Technology: 10-node heterogeneous network
|
|
#
|
|
# Explicit topology with Bluetooth (L2CAP), WiFi, and fiber links.
|
|
# Tests that cost-based parent selection produces a tree favoring
|
|
# low-cost paths when multiple link technologies coexist.
|
|
#
|
|
# Topology:
|
|
#
|
|
# n01 (root)
|
|
# / | \
|
|
# f f f
|
|
# / | \
|
|
# n02 n03 n04
|
|
# | \ | \ | \
|
|
# f BT f f BT f
|
|
# | \ | | \ |
|
|
# n05 n06 n07 n08 n09
|
|
# \ /
|
|
# wifi---wifi
|
|
# n10
|
|
#
|
|
# Edges and link types:
|
|
# Fiber: n01-n02, n01-n03, n01-n04, n02-n05, n03-n07, n04-n09
|
|
# Bluetooth: n02-n06, n04-n08
|
|
# WiFi: n03-n06, n08-n10
|
|
# Fiber: n03-n08, n06-n10
|
|
#
|
|
# Test subjects:
|
|
# - n06 has fiber (n03) and Bluetooth (n02) parents — should pick n03
|
|
# - n08 has fiber (n03) and Bluetooth (n04) parents — should pick n03
|
|
#
|
|
# Netem mutation shifts fiber-only links between normal and degraded.
|
|
#
|
|
# NEITHER TEST SUBJECT IS ASSERTED YET, and the reason has been found and
|
|
# fixed at the root rather than papered over here.
|
|
#
|
|
# The diagram above puts n01 at the top, and both test subjects only make
|
|
# sense in a tree rooted there. The mesh does not root by topology: it roots
|
|
# at the numerically smallest NodeAddr (src/tree/state.rs:363-390), which is a
|
|
# hash of the node's key and bears no relation to the numbering. Until
|
|
# 2026-07-23 this scenario rooted at **n09** in every run, which put both
|
|
# criteria out of reach. Under that root n08's two candidates were not at
|
|
# equal depth, so its choice was settled by depth long before link technology
|
|
# could matter, and n08 taking n04 was CORRECT behaviour that these comments
|
|
# made look like a defect.
|
|
#
|
|
# What the archive shows, for anyone re-deriving this later: across the five
|
|
# runs under the old root, n06's parent is n10 in three and n03 in two, and
|
|
# n08's is n04 in four and n03 in one. Those numbers describe a tree rooted at
|
|
# n09 and must not be used to calibrate anything now.
|
|
#
|
|
# `topology.pin_root` (default true) now assigns identities in NodeAddr order,
|
|
# so n01 holds the smallest and the diagram describes the tree that forms.
|
|
# Both criteria should therefore become reachable and assertable.
|
|
#
|
|
# STILL TO DO: run this under the pinned root, confirm n06 and n08 both take
|
|
# n03, and encode `tree_parents` for them. Until then the baseline block below
|
|
# is a floor and not a substitute — it holds the mesh to forming a tree and
|
|
# carrying traffic, and nothing here yet checks that the tree is the one these
|
|
# comments describe. Tracked in ISSUE-2026-0085.
|
|
|
|
scenario:
|
|
name: "mixed-technology"
|
|
seed: 42
|
|
duration_secs: 90
|
|
|
|
topology:
|
|
algorithm: explicit
|
|
num_nodes: 10
|
|
params:
|
|
adjacency:
|
|
- [n01, n02]
|
|
- [n01, n03]
|
|
- [n01, n04]
|
|
- [n02, n05]
|
|
- [n02, n06]
|
|
- [n03, n06]
|
|
- [n03, n07]
|
|
- [n03, n08]
|
|
- [n04, n08]
|
|
- [n04, n09]
|
|
- [n06, n10]
|
|
- [n08, n10]
|
|
subnet: "172.20.0.0/24"
|
|
ip_start: 10
|
|
|
|
netem:
|
|
enabled: true
|
|
default_policy:
|
|
# Fiber-like defaults
|
|
delay_ms: [1, 5]
|
|
jitter_ms: [0, 1]
|
|
loss_pct: [0, 0.5]
|
|
link_policies:
|
|
# Bluetooth (L2CAP) links
|
|
- edges: ["n02-n06", "n04-n08"]
|
|
policy:
|
|
delay_ms: [15, 40]
|
|
jitter_ms: [5, 15]
|
|
loss_pct: [2, 8]
|
|
# WiFi links (moderate latency, low loss)
|
|
- edges: ["n03-n06", "n08-n10"]
|
|
policy:
|
|
delay_ms: [5, 20]
|
|
jitter_ms: [2, 5]
|
|
loss_pct: [1, 3]
|
|
mutation:
|
|
interval_secs: {min: 30, max: 60}
|
|
fraction: 0.2
|
|
policies:
|
|
normal:
|
|
delay_ms: [1, 10]
|
|
loss_pct: [0, 1]
|
|
degraded:
|
|
delay_ms: [50, 100]
|
|
jitter_ms: [10, 30]
|
|
loss_pct: [3, 8]
|
|
|
|
link_flaps:
|
|
enabled: false
|
|
|
|
traffic:
|
|
enabled: true
|
|
max_concurrent: 3
|
|
interval_secs: {min: 10, max: 30}
|
|
duration_secs: {min: 5, max: 15}
|
|
parallel_streams: 4
|
|
|
|
# Baseline: the mesh came up, agreed on a root, and took parents. This
|
|
# asserts nothing about parent choice, which this scenario cannot
|
|
# currently assert; it exists so that a run in which the mesh never formed
|
|
# cannot report success, which until now it could,
|
|
# because this scenario carried no assertions at all.
|
|
#
|
|
# Ten nodes, one root, nine parented and six to eight sessions across
|
|
# the five provably-completed archived runs. The session floor is set
|
|
# below the observed minimum deliberately: it is here to catch a mesh
|
|
# that carries no traffic at all, not to pin a throughput.
|
|
assertions:
|
|
baseline:
|
|
min_nodes_reporting: 10
|
|
max_roots: 1
|
|
min_nodes_parented: 9
|
|
min_sessions: 3
|
|
|
|
logging:
|
|
rust_log: "info"
|
|
output_dir: "./sim-results"
|