[dart:io] add IOOverrides.serverSocketBind to enable overriding ServerSocket.bind()

Fix: github.com/dart-lang/sdk/issues/39094
Change-Id: Iaf8b224e89210027a62815596c759034cca1d4f1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123220
Commit-Queue: Zichang Guo <zichangguo@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
Zichang Guo 2019-10-28 22:04:39 +00:00 committed by commit-bot@chromium.org
parent 1505654f5c
commit 2e15d0eb8c
12 changed files with 130 additions and 9 deletions

View file

@ -77,6 +77,11 @@ main() { foo(() {}); }
* Default values of parameters of abstract methods are no longer available
via `dart:mirrors`.
#### `dart:io`
* **Breaking change**: Added `IOOverrides.serverSocketBind` to aid in writing
tests that wish to mock `ServerSocket.bind`.
#### `dart:developer`
* Added optional `parent` parameter to `TimelineTask` constructor to allow for

View file

@ -448,7 +448,7 @@ class RawServerSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog = 0, bool v6Only = false, bool shared = false}) {
throw UnsupportedError("ServerSocket.bind");
}

View file

@ -448,7 +448,7 @@ class RawServerSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
throw new UnsupportedError("ServerSocket.bind");
}

View file

@ -1506,7 +1506,7 @@ class _RawSocket extends Stream<RawSocketEvent> implements RawSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
return _ServerSocket.bind(address, port, backlog, v6Only, shared);
}

View file

@ -87,6 +87,11 @@ abstract class IOOverrides {
{dynamic sourceAddress})
socketStartConnect,
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared})
serverSocketBind,
// Optional Zone parameters
ZoneSpecification zoneSpecification,
Function onError}) {
@ -120,6 +125,9 @@ abstract class IOOverrides {
// Socket
socketConnect,
socketStartConnect,
// ServerSocket
serverSocketBind,
);
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
@ -274,6 +282,19 @@ abstract class IOOverrides {
{sourceAddress}) {
return Socket._startConnect(host, port, sourceAddress: sourceAddress);
}
// ServerSocket
/// Asynchronously returns a [ServerSocket] that connects to the given address
/// and port when successful.
///
/// When this override is installed, this functions overrides the behavior of
/// `ServerSocket.bind(...)`.
Future<ServerSocket> serverSocketBind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
return ServerSocket._bind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
}
class _IOOverridesScope extends IOOverrides {
@ -311,6 +332,10 @@ class _IOOverridesScope extends IOOverrides {
Future<ConnectionTask<Socket>> Function(dynamic, int, {dynamic sourceAddress})
_socketStartConnect;
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared}) _serverSocketBind;
_IOOverridesScope(
// Directory
this._createDirectory,
@ -341,6 +366,9 @@ class _IOOverridesScope extends IOOverrides {
// Socket
this._socketConnect,
this._socketStartConnect,
// ServerSocket
this._serverSocketBind,
);
// Directory
@ -478,4 +506,20 @@ class _IOOverridesScope extends IOOverrides {
}
return super.socketStartConnect(host, port, sourceAddress: sourceAddress);
}
// ServerSocket
@override
Future<ServerSocket> serverSocketBind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
if (_serverSocketBind != null) {
return _serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
if (_previous != null) {
return _previous.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
return super.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
}

View file

@ -327,7 +327,18 @@ abstract class ServerSocket implements Stream<Socket> {
* distributed among all the bound `ServerSocket`s. Connections can be
* distributed over multiple isolates this way.
*/
external static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
final IOOverrides overrides = IOOverrides.current;
if (overrides == null) {
return ServerSocket._bind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
return overrides.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
external static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false});
/**

View file

@ -450,7 +450,7 @@ class RawServerSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog = 0, bool v6Only = false, bool shared = false}) {
throw UnsupportedError("ServerSocket.bind");
}

View file

@ -450,7 +450,7 @@ class RawServerSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
throw new UnsupportedError("ServerSocket.bind");
}

View file

@ -1508,7 +1508,7 @@ class _RawSocket extends Stream<RawSocketEvent> implements RawSocket {
@patch
class ServerSocket {
@patch
static Future<ServerSocket> bind(address, int port,
static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
return _ServerSocket.bind(address, port, backlog, v6Only, shared);
}

View file

@ -89,6 +89,11 @@ abstract class IOOverrides {
{dynamic sourceAddress})
socketStartConnect,
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared})
serverSocketBind,
// Optional Zone parameters
ZoneSpecification zoneSpecification,
Function onError}) {
@ -122,6 +127,9 @@ abstract class IOOverrides {
// Socket
socketConnect,
socketStartConnect,
// ServerSocket
serverSocketBind,
);
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
@ -276,6 +284,19 @@ abstract class IOOverrides {
{sourceAddress}) {
return Socket._startConnect(host, port, sourceAddress: sourceAddress);
}
// ServerSocket
/// Asynchronously returns a [ServerSocket] that connects to the given address
/// and port when successful.
///
/// When this override is installed, this functions overrides the behavior of
/// `ServerSocket.bind(...)`.
Future<ServerSocket> serverSocketBind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
return ServerSocket._bind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
}
class _IOOverridesScope extends IOOverrides {
@ -313,6 +334,10 @@ class _IOOverridesScope extends IOOverrides {
Future<ConnectionTask<Socket>> Function(dynamic, int, {dynamic sourceAddress})
_socketStartConnect;
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared}) _serverSocketBind;
_IOOverridesScope(
// Directory
this._createDirectory,
@ -343,6 +368,9 @@ class _IOOverridesScope extends IOOverrides {
// Socket
this._socketConnect,
this._socketStartConnect,
// ServerSocket
this._serverSocketBind,
);
// Directory
@ -480,4 +508,20 @@ class _IOOverridesScope extends IOOverrides {
}
return super.socketStartConnect(host, port, sourceAddress: sourceAddress);
}
// ServerSocket
@override
Future<ServerSocket> serverSocketBind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
if (_serverSocketBind != null) {
return _serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
if (_previous != null) {
return _previous.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
return super.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
}

View file

@ -329,9 +329,19 @@ abstract class ServerSocket implements Stream<Socket> {
* distributed among all the bound `ServerSocket`s. Connections can be
* distributed over multiple isolates this way.
*/
external static Future<ServerSocket> bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false});
static Future<ServerSocket> bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
final IOOverrides overrides = IOOverrides.current;
if (overrides == null) {
return ServerSocket._bind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
return overrides.serverSocketBind(address, port,
backlog: backlog, v6Only: v6Only, shared: shared);
}
external static Future<ServerSocket> _bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false});
/**
* Returns the port used by this socket.
*/

View file

@ -168,6 +168,11 @@ Future<ConnectionTask<Socket>> socketStartConnect(host, int port,
return null;
}
Future<ServerSocket> serverSocketBind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) {
return null;
}
Future<Null> ioOverridesRunTest() async {
Future<Null> f = IOOverrides.runZoned(
() async {
@ -188,6 +193,7 @@ Future<Null> ioOverridesRunTest() async {
Expect.isTrue(new Link("link") is LinkMock);
Expect.isNull(Socket.connect(null, 0));
Expect.isNull(Socket.startConnect(null, 0));
Expect.isNull(ServerSocket.bind(null, 0));
},
createDirectory: DirectoryMock.createDirectory,
getCurrentDirectory: DirectoryMock.getCurrent,
@ -205,6 +211,7 @@ Future<Null> ioOverridesRunTest() async {
createLink: LinkMock.createLink,
socketConnect: socketConnect,
socketStartConnect: socketStartConnect,
serverSocketBind: serverSocketBind,
);
Expect.isFalse(new Directory("directory") is DirectoryMock);
Expect.isTrue(new Directory("directory") is Directory);