mirror of https://github.com/grpc/grpc-dart.git
132 lines
3.8 KiB
Dart
132 lines
3.8 KiB
Dart
// Copyright (c) 2024, the gRPC project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:fake_async/fake_async.dart';
|
|
import 'package:grpc/src/server/server_keepalive.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
void main() {
|
|
late StreamController pingStream;
|
|
late StreamController dataStream;
|
|
late int maxBadPings;
|
|
|
|
var goAway = false;
|
|
|
|
void initServer([ServerKeepAliveOptions? options]) => ServerKeepAlive(
|
|
options: options ??
|
|
ServerKeepAliveOptions(
|
|
maxBadPings: maxBadPings,
|
|
minIntervalBetweenPingsWithoutData: Duration(milliseconds: 5),
|
|
),
|
|
pingNotifier: pingStream.stream,
|
|
dataNotifier: dataStream.stream,
|
|
tooManyBadPings: () async => goAway = true,
|
|
).handle();
|
|
|
|
setUp(() {
|
|
pingStream = StreamController();
|
|
dataStream = StreamController();
|
|
maxBadPings = 10;
|
|
goAway = false;
|
|
});
|
|
|
|
tearDown(() {
|
|
pingStream.close();
|
|
dataStream.close();
|
|
});
|
|
|
|
final timeAfterPing = Duration(milliseconds: 10);
|
|
|
|
test('Sending too many pings without data kills connection', () async {
|
|
FakeAsync().run((async) {
|
|
initServer();
|
|
// Send good ping
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
|
|
// Send [maxBadPings] bad pings, that's still ok
|
|
for (var i = 0; i < maxBadPings; i++) {
|
|
pingStream.sink.add(null);
|
|
}
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, false);
|
|
|
|
// Send another bad ping; that's one too many!
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, true);
|
|
});
|
|
});
|
|
test(
|
|
'Sending too many pings without data doesn`t kill connection if the server doesn`t care',
|
|
() async {
|
|
FakeAsync().run((async) {
|
|
initServer(ServerKeepAliveOptions(
|
|
maxBadPings: null,
|
|
minIntervalBetweenPingsWithoutData: Duration(milliseconds: 5),
|
|
));
|
|
// Send good ping
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
|
|
// Send a lot of bad pings, that's still ok.
|
|
for (var i = 0; i < 50; i++) {
|
|
pingStream.sink.add(null);
|
|
}
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, false);
|
|
});
|
|
});
|
|
|
|
test('Sending many pings with data doesn`t kill connection', () async {
|
|
FakeAsync().run((async) {
|
|
initServer();
|
|
|
|
// Send good ping
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
|
|
// Send [maxBadPings] bad pings, that's still ok
|
|
for (var i = 0; i < maxBadPings; i++) {
|
|
pingStream.sink.add(null);
|
|
}
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, false);
|
|
|
|
// Sending data resets the bad ping count
|
|
dataStream.add(null);
|
|
async.elapse(timeAfterPing);
|
|
|
|
// Send good ping
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
|
|
// Send [maxBadPings] bad pings, that's still ok
|
|
for (var i = 0; i < maxBadPings; i++) {
|
|
pingStream.sink.add(null);
|
|
}
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, false);
|
|
|
|
// Send another bad ping; that's one too many!
|
|
pingStream.sink.add(null);
|
|
async.elapse(timeAfterPing);
|
|
expect(goAway, true);
|
|
});
|
|
});
|
|
}
|