blob: ccdb93b64a367d85b8dfa5fbcee54d5fc9197df8 [file] [log] [blame]
// Copyright (c) 2013, 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.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
import "dart:async";
import "dart:io";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
void testCancelResubscribeServerSocket(int socketCount, int backlog) {
var acceptCount = 0;
var doneCount = 0;
var errorCount = 0;
var earlyErrorCount = 0;
asyncStart();
RawServerSocket.bind("127.0.0.1", 0, backlog: backlog).then((server) {
Expect.isTrue(server.port > 0);
void checkDone() {
if (doneCount + errorCount + earlyErrorCount == socketCount) {
asyncEnd();
// Be sure to close as subscription.cancel may not be called, if
// backlog prevents acceptCount to grow to socketCount / 2.
server.close();
}
}
var subscription;
subscription = server.listen((client) {
client.writeEventsEnabled = false;
client.listen((event) {
switch (event) {
case RawSocketEvent.read:
client.read();
break;
case RawSocketEvent.readClosed:
client.shutdown(SocketDirection.send);
break;
case RawSocketEvent.write:
Expect.fail("No write event expected");
break;
}
});
if (++acceptCount == socketCount / 2) {
// Cancel subscription and then attempt to resubscribe.
subscription.cancel();
Timer.run(() {
Expect.throws(() {
server.listen((_) {
// Server socket is closed on cancel, so no more events.
Expect.fail("Event after closed through cancel");
});
});
});
}
});
// Connect a number of sockets.
for (int i = 0; i < socketCount; i++) {
RawSocket.connect("127.0.0.1", server.port).then((socket) {
bool done = false;
var subscription;
subscription = socket.listen((event) {
switch (event) {
case RawSocketEvent.read:
Expect.fail("No read event expected");
break;
case RawSocketEvent.readClosed:
done = true;
doneCount++;
checkDone();
break;
case RawSocketEvent.write:
// We don't care if this write succeeds, so we don't check
// the return value (number of bytes written).
socket.write([1, 2, 3]);
socket.shutdown(SocketDirection.send);
break;
}
}, onDone: () {
if (!done) {
doneCount++;
checkDone();
}
}, onError: (e) {
// "Connection reset by peer" errors are handled here.
errorCount++;
checkDone();
}, cancelOnError: true);
}).catchError((e) {
// "Connection actively refused by host" errors are handled here.
earlyErrorCount++;
checkDone();
});
}
});
}
void main() {
testCancelResubscribeServerSocket(10, 20);
testCancelResubscribeServerSocket(20, 5);
}