Files
dmc/app/test/transport/msp/msp_client_test.dart
T

119 lines
3.4 KiB
Dart

import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:dmc_app/transport/loopback/loopback_transport.dart';
import 'package:dmc_app/transport/msp/msp_client.dart';
import 'package:dmc_app/transport/msp/msp_commands.dart';
import 'package:dmc_app/transport/msp/msp_frame.dart';
import 'package:dmc_app/transport/msp/msp_frame_decoder.dart';
MspFrame _decodeSingle(Uint8List bytes) =>
MspFrameDecoder().addBytes(bytes).single;
void main() {
late LoopbackTransport transport;
setUp(() async {
transport = LoopbackTransport();
await transport.connect();
});
tearDown(() {
transport.dispose();
});
test('request() sendet einen MSPv2-Rahmen und liefert den Antwort-Payload',
() async {
final client = MspClient(transport);
final future = client.request(MspCommands.altitude);
await Future<void>.delayed(Duration.zero);
expect(transport.sentData, hasLength(1));
final sentFrame = _decodeSingle(transport.sentData.single);
expect(sentFrame.direction, MspDirection.request);
expect(sentFrame.function, MspCommands.altitude);
final payload = Uint8List.fromList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
transport.feed(
encodeMspV2Frame(MspDirection.response, MspCommands.altitude, payload),
);
expect(await future, payload);
client.dispose();
});
test('wirft nach Timeout + Wiederholungen MspRequestException und sendet '
'jedes Mal erneut', () async {
final client = MspClient(
transport,
requestTimeout: const Duration(milliseconds: 30),
maxRetries: 2,
);
await expectLater(
client.request(MspCommands.altitude),
throwsA(isA<MspRequestException>()),
);
// Erstversuch + 2 Wiederholungen = 3 gesendete Anfragen.
expect(transport.sentData, hasLength(3));
for (final sent in transport.sentData) {
expect(_decodeSingle(sent).function, MspCommands.altitude);
}
client.dispose();
});
test('Fehlerantwort (dir = \'!\') wirft sofort ohne weiteren Versuch',
() async {
final client = MspClient(
transport,
requestTimeout: const Duration(seconds: 5),
maxRetries: 2,
);
final future = client.request(MspCommands.altitude);
await Future<void>.delayed(Duration.zero);
transport.feed(
encodeMspV2Frame(MspDirection.error, MspCommands.altitude, Uint8List(0)),
);
await expectLater(future, throwsA(isA<MspRequestException>()));
expect(transport.sentData, hasLength(1));
client.dispose();
});
test('serialisiert ueberlappende Anfragen - immer nur eine offen', () async {
final client = MspClient(transport);
final future1 = client.request(MspCommands.rawGps);
final future2 = client.request(MspCommands.altitude);
await Future<void>.delayed(Duration.zero);
expect(transport.sentData, hasLength(1));
expect(_decodeSingle(transport.sentData.single).function,
MspCommands.rawGps);
transport.feed(encodeMspV2Frame(
MspDirection.response,
MspCommands.rawGps,
Uint8List(18),
));
await future1;
await Future<void>.delayed(Duration.zero);
expect(transport.sentData, hasLength(2));
expect(_decodeSingle(transport.sentData[1]).function,
MspCommands.altitude);
transport.feed(encodeMspV2Frame(
MspDirection.response,
MspCommands.altitude,
Uint8List(10),
));
await future2;
client.dispose();
});
}