Testing without Bluetooth
Real radios are slow to test with: you need devices, and they must be near
each other. package:dart_libp2p_ble/testing.dart gives in-memory radios
that behave as BLE links do, so you can test your protocol, or a whole mesh,
in flutter test.
import 'package:dart_libp2p_ble/testing.dart';A network of radios
Section titled “A network of radios”A FakeBleNetwork holds the radios. Every pair is in range unless you say
otherwise, so you can build a partial mesh:
final network = FakeBleNetwork();final radioA = network.newRadio();final radioB = network.newRadio();final radioC = network.newRadio();network.setInRange(radioA, radioC, false); // A and C cannot hear each otherGive each radio to a BleTransport in place of BluetoothLowEnergyRadio.
Everything above the radio is the real code: the transport, Noise, yamux,
discovery and your protocols.
/// A node on [radio]: a host with only the BLE transport, gossipsub, and/// discovery that connects to the nodes in range.Future<(Host, PubSub, BleDiscovery)> _node(BleRadio radio) async { final keyPair = await generateEd25519KeyPair(); final peerId = PeerId.fromPublicKey(keyPair.publicKey); final ble = BleTransport(radio: radio, localPeer: peerId); final host = await Libp2p.new_([ Libp2p.identity(keyPair), Libp2p.transport(ble), Libp2p.listenAddrs([ble.listenAddr]), Libp2p.autoNAT(false), Libp2p.relay(false), Libp2p.autoRelay(false), Libp2p.holePunching(false), ]); await host.start(); final pubsub = PubSub(host, GossipSubRouter()); await pubsub.start(); final discovery = BleDiscovery(host: host, transport: ble, yieldFor: const Duration(seconds: 1)); return (host, pubsub, discovery);}A shorter yieldFor makes the test faster. On devices, keep the default.
The whole program is example/mesh_in_memory.dart:
A sends a message on gossipsub, and C gets it through B.
flutter test test/examples_test.dartWhat you can control
Section titled “What you can control”| Setting | Default | What it does |
|---|---|---|
FakeBleNetwork(maxValueLength:) |
512 | Largest GATT value. Set 20 or 182 to test small MTUs: connections split their writes into more values. |
FakeBleNetwork(latency:) |
none | Delay of each value. Values stay in order. |
setInRange(a, b, false) |
in range | a and b do not see each other and cannot connect. Links that are open stay open. |
setRssi(a, b, dBm) |
-50 | The signal strength in the sightings a and b get of each other, for minRssi and swapMargin. |
radio.openLinks |
Number of links a radio has open, in both roles. |
What it does not cover
Section titled “What it does not cover”The in-memory radios have no platform behavior: no permissions, no advertising limits, no changing peripheral IDs, and no lost links. Test on devices too before you ship; Platforms lists what is different on each.