WIFI connection support added
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:dmc_app/transport/link_transport.dart';
|
||||
import 'package:dmc_app/transport/udp/udp_transport.dart';
|
||||
|
||||
void main() {
|
||||
// Port 0 laesst das Betriebssystem einen freien Port waehlen, damit die
|
||||
// Tests nicht mit einer echten mLRS-Bruecke oder parallelen Testlaeufen
|
||||
// um Port 14550 konkurrieren.
|
||||
Future<UdpTransport> openTransport({String? host}) async {
|
||||
final transport = UdpTransport(
|
||||
getHost: () async => host,
|
||||
getPort: () async => 0,
|
||||
);
|
||||
await transport.connect();
|
||||
return transport;
|
||||
}
|
||||
|
||||
test('connect() bindet einen lokalen Port und meldet connected', () async {
|
||||
final transport = await openTransport();
|
||||
final states = <LinkState>[];
|
||||
transport.state.listen(states.add);
|
||||
|
||||
expect(transport.currentState, LinkState.connected);
|
||||
expect(transport.boundPort, isNotNull);
|
||||
expect(transport.boundPort, greaterThan(0));
|
||||
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('eingehende Pakete kommen ueber incoming an und lernen die Gegenstelle',
|
||||
() async {
|
||||
final transport = await openTransport();
|
||||
final sender = await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, 0);
|
||||
|
||||
final received = <Uint8List>[];
|
||||
transport.incoming.listen(received.add);
|
||||
|
||||
sender.send(
|
||||
Uint8List.fromList([1, 2, 3]),
|
||||
InternetAddress.loopbackIPv4,
|
||||
transport.boundPort!,
|
||||
);
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
expect(received, [
|
||||
Uint8List.fromList([1, 2, 3]),
|
||||
]);
|
||||
expect(transport.peerDescription, contains(sender.port.toString()));
|
||||
|
||||
sender.close();
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('send() ohne bekannte Gegenstelle wirft LinkConnectException', () async {
|
||||
final transport = await openTransport();
|
||||
|
||||
expect(
|
||||
() => transport.send(Uint8List.fromList([1])),
|
||||
throwsA(isA<LinkConnectException>()),
|
||||
);
|
||||
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('send() schickt Bytes an die gelernte Gegenstelle', () async {
|
||||
final transport = await openTransport();
|
||||
final peer = await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, 0);
|
||||
|
||||
// Erst "sprechen" lassen, damit der Transport die Gegenstelle lernt
|
||||
// (Doku Kommunikationsschicht Abschnitt 3: "Gegenstelle aus dem Verkehr
|
||||
// lernen").
|
||||
peer.send(
|
||||
Uint8List.fromList([9]),
|
||||
InternetAddress.loopbackIPv4,
|
||||
transport.boundPort!,
|
||||
);
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
final receivedByPeer = <Uint8List>[];
|
||||
peer.listen((event) {
|
||||
if (event == RawSocketEvent.read) {
|
||||
final datagram = peer.receive();
|
||||
if (datagram != null) receivedByPeer.add(datagram.data);
|
||||
}
|
||||
});
|
||||
|
||||
await transport.send(Uint8List.fromList([7, 7, 7]));
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
|
||||
expect(receivedByPeer, [
|
||||
Uint8List.fromList([7, 7, 7]),
|
||||
]);
|
||||
|
||||
peer.close();
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('disconnect() setzt LinkState.disconnected', () async {
|
||||
final transport = await openTransport();
|
||||
|
||||
await transport.disconnect();
|
||||
|
||||
expect(transport.currentState, LinkState.disconnected);
|
||||
expect(transport.boundPort, isNull);
|
||||
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('weicht auf einen fluechtigen Port aus, wenn der konfigurierte belegt ist',
|
||||
() async {
|
||||
final occupied = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
|
||||
final transport = UdpTransport(
|
||||
getHost: () async => null,
|
||||
getPort: () async => occupied.port,
|
||||
);
|
||||
|
||||
await transport.connect();
|
||||
|
||||
expect(transport.currentState, LinkState.connected);
|
||||
expect(transport.boundPort, isNot(occupied.port));
|
||||
expect(transport.lastErrorMessage, contains('belegt'));
|
||||
|
||||
occupied.close();
|
||||
transport.dispose();
|
||||
});
|
||||
|
||||
test('konfigurierte Host-Vorgabe wird als initiale Gegenstelle uebernommen',
|
||||
() async {
|
||||
final transport = UdpTransport(
|
||||
getHost: () async => '127.0.0.1',
|
||||
getPort: () async => 0,
|
||||
);
|
||||
await transport.connect();
|
||||
|
||||
expect(transport.peerDescription, isNotNull);
|
||||
expect(transport.peerDescription, startsWith('127.0.0.1'));
|
||||
|
||||
transport.dispose();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user