blob: df0242087059ae76e9da5c8179f64b041ce6cd2e [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:http2/src/frames/frames.dart';
import 'package:http2/src/ping/ping_handler.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../error_matchers.dart';
void main() {
group('ping-handler', () {
test('successful-ping', () async {
var writer = FrameWriterMock();
var pingHandler = instantiateHandler(writer);
var p1 = pingHandler.ping();
var p2 = pingHandler.ping();
verifyInOrder([
writer.writePingFrame(1),
writer.writePingFrame(2),
]);
var header = FrameHeader(8, FrameType.PING, PingFrame.FLAG_ACK, 0);
pingHandler.processPingFrame(PingFrame(header, 1));
var header2 = FrameHeader(8, FrameType.PING, PingFrame.FLAG_ACK, 0);
pingHandler.processPingFrame(PingFrame(header2, 2));
await p1;
await p2;
verifyNoMoreInteractions(writer);
});
test('successful-ack-to-remote-ping', () async {
var writer = FrameWriterMock();
var pingHandler = instantiateHandler(writer);
var header = FrameHeader(8, FrameType.PING, 0, 0);
pingHandler.processPingFrame(PingFrame(header, 1));
var header2 = FrameHeader(8, FrameType.PING, 0, 0);
pingHandler.processPingFrame(PingFrame(header2, 2));
verifyInOrder([
writer.writePingFrame(1, ack: true),
writer.writePingFrame(2, ack: true)
]);
verifyNoMoreInteractions(writer);
});
test('ping-unknown-opaque-data', () async {
var writer = FrameWriterMock();
var pingHandler = instantiateHandler(writer);
var future = pingHandler.ping();
verify(writer.writePingFrame(1)).called(1);
var header = FrameHeader(8, FrameType.PING, PingFrame.FLAG_ACK, 0);
expect(() => pingHandler.processPingFrame(PingFrame(header, 2)),
throwsA(isProtocolException));
// Ensure outstanding pings will be completed with an error once we call
// `pingHandler.terminate()`.
unawaited(future.catchError(expectAsync2((Object error, Object _) {
expect(error, 'hello world');
})));
pingHandler.terminate('hello world');
verifyNoMoreInteractions(writer);
});
test('terminate-ping-handler', () async {
var writer = FrameWriterMock();
var pingHandler = instantiateHandler(writer);
pingHandler.terminate('hello world');
expect(
() => pingHandler.processPingFrame(PingFrame(
FrameHeader(8, FrameType.PING, PingFrame.FLAG_ACK, 1), 1)),
throwsA(isTerminatedException));
expect(pingHandler.ping(), throwsA(isTerminatedException));
verifyZeroInteractions(writer);
});
test('ping-non-zero-stream-id', () async {
var writer = FrameWriterMock();
var pingHandler = instantiateHandler(writer);
var header = FrameHeader(8, FrameType.PING, PingFrame.FLAG_ACK, 1);
expect(() => pingHandler.processPingFrame(PingFrame(header, 1)),
throwsA(isProtocolException));
verifyZeroInteractions(writer);
});
test('receiving-ping-calls-stream', () async {
final pings = <int>[];
final writer = FrameWriterMock();
final pingStream = StreamController<int>()..stream.listen(pings.add);
PingHandler(writer, pingStream)
..processPingFrame(PingFrame(
FrameHeader(8, FrameType.PING, 0, 0),
1,
))
..processPingFrame(PingFrame(
FrameHeader(8, FrameType.PING, 0, 0),
2,
));
await pingStream.close();
expect(pings, [1, 2]);
});
});
}
PingHandler instantiateHandler(FrameWriterMock writer) {
var controller = StreamController<int>();
return PingHandler(writer, controller);
}
class FrameWriterMock extends Mock implements FrameWriter {}