Skip to content

Commit e61df1c

Browse files
committed
fixed issue tokio-rs#1080, re-enable failing udp tests on windows (tokio-rs#1167)
* fixed assert arguments order Signed-off-by: Daniel Tacalau <[email protected]> * fix issue tokio-rs#1080, re-enabled and fixed UDP tests failing on Windows. One tests needed to have interests reregistered by calling a blocking recv. Another tests needed a Windows specific assert error message. Signed-off-by: Daniel Tacalau <[email protected]> * Added a note in the read/peek(_from) docs that on Windows if the data is larger than the buffer specified, the buffer is filled with the first part of the data, and peek returns the error WSAEMSGSIZE(10040). The excess data is lost. Make sure to always use a sufficiently large buffer to hold the maximum UDP packet size, which can be up to 64 kilobytes in size. Signed-off-by: Daniel Tacalau <[email protected]> * Added two new tests verifying ET behavior for UDP sockets events. These tests rely on having a blocking recv(_from) reregistering the socket and reseting the interests. Signed-off-by: Daniel Tacalau <[email protected]> * replaces 64 kilobytes with 65536 bytes in the notes Signed-off-by: Daniel Tacalau <[email protected]> * changes after review for new et tests: removed unneeded block, expect a writable before actual write Signed-off-by: Daniel Tacalau <[email protected]>
1 parent f1edf7f commit e61df1c

File tree

3 files changed

+156
-8
lines changed

3 files changed

+156
-8
lines changed

src/net/udp.rs

+32
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,14 @@ impl UdpSocket {
228228
/// Receives data from the socket. On success, returns the number of bytes
229229
/// read and the address from whence the data came.
230230
///
231+
/// # Notes
232+
///
233+
/// On Windows, if the data is larger than the buffer specified, the buffer
234+
/// is filled with the first part of the data, and recv_from returns the error
235+
/// WSAEMSGSIZE(10040). The excess data is lost.
236+
/// Make sure to always use a sufficiently large buffer to hold the
237+
/// maximum UDP packet size, which can be up to 65536 bytes in size.
238+
///
231239
/// # Examples
232240
///
233241
/// ```no_run
@@ -256,6 +264,14 @@ impl UdpSocket {
256264
/// On success, returns the number of bytes read and the address from whence
257265
/// the data came.
258266
///
267+
/// # Notes
268+
///
269+
/// On Windows, if the data is larger than the buffer specified, the buffer
270+
/// is filled with the first part of the data, and peek_from returns the error
271+
/// WSAEMSGSIZE(10040). The excess data is lost.
272+
/// Make sure to always use a sufficiently large buffer to hold the
273+
/// maximum UDP packet size, which can be up to 65536 bytes in size.
274+
///
259275
/// # Examples
260276
///
261277
/// ```no_run
@@ -288,12 +304,28 @@ impl UdpSocket {
288304

289305
/// Receives data from the socket previously bound with connect(). On success, returns
290306
/// the number of bytes read.
307+
///
308+
/// # Notes
309+
///
310+
/// On Windows, if the data is larger than the buffer specified, the buffer
311+
/// is filled with the first part of the data, and recv returns the error
312+
/// WSAEMSGSIZE(10040). The excess data is lost.
313+
/// Make sure to always use a sufficiently large buffer to hold the
314+
/// maximum UDP packet size, which can be up to 65536 bytes in size.
291315
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
292316
self.sys.recv(buf)
293317
}
294318

295319
/// Receives data from the socket, without removing it from the input queue.
296320
/// On success, returns the number of bytes read.
321+
///
322+
/// # Notes
323+
///
324+
/// On Windows, if the data is larger than the buffer specified, the buffer
325+
/// is filled with the first part of the data, and peek returns the error
326+
/// WSAEMSGSIZE(10040). The excess data is lost.
327+
/// Make sure to always use a sufficiently large buffer to hold the
328+
/// maximum UDP packet size, which can be up to 65536 bytes in size.
297329
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
298330
self.sys.peek(buf)
299331
}

tests/udp_socket.rs

+123-7
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ fn reconnect_udp_socket_sending() {
288288
}
289289

290290
#[test]
291-
#[cfg_attr(windows, ignore = "fails on Windows, see #1080")]
292291
fn reconnect_udp_socket_receiving() {
293292
let (mut poll, mut events) = init_with_poll();
294293

@@ -334,7 +333,11 @@ fn reconnect_udp_socket_receiving() {
334333
let mut buf = [0; 20];
335334
expect_read!(socket1.recv(&mut buf), DATA1);
336335

336+
//this will reregister socket1 resetting the interests
337+
assert_would_block(socket1.recv(&mut buf));
338+
337339
socket1.connect(address3).unwrap();
340+
338341
checked_write!(socket3.send(DATA2));
339342

340343
expect_events(
@@ -343,12 +346,16 @@ fn reconnect_udp_socket_receiving() {
343346
vec![ExpectEvent::new(ID1, Interests::READABLE)],
344347
);
345348

346-
// Read only a part of the data.
347-
let max = 4;
348-
expect_read!(socket1.recv(&mut buf[..max]), &DATA2[..max]);
349+
// Read all data.
350+
// On Windows, reading part of data returns error WSAEMSGSIZE (10040).
351+
expect_read!(socket1.recv(&mut buf), DATA2);
349352

350-
// Now connect back to socket 2, dropping the unread data.
353+
//this will reregister socket1 resetting the interests
354+
assert_would_block(socket1.recv(&mut buf));
355+
356+
// Now connect back to socket 2.
351357
socket1.connect(address2).unwrap();
358+
352359
checked_write!(socket2.send(DATA2));
353360

354361
expect_events(
@@ -365,7 +372,6 @@ fn reconnect_udp_socket_receiving() {
365372
}
366373

367374
#[test]
368-
#[cfg_attr(windows, ignore = "fails on Windows, see #1080")]
369375
fn unconnected_udp_socket_connected_methods() {
370376
let (mut poll, mut events) = init_with_poll();
371377

@@ -387,7 +393,15 @@ fn unconnected_udp_socket_connected_methods() {
387393
);
388394

389395
// Socket is unconnected, but we're using an connected method.
390-
assert_error(socket1.send(DATA1), "address required");
396+
if cfg!(not(target_os = "windows")) {
397+
assert_error(socket1.send(DATA1), "address required");
398+
}
399+
if cfg!(target_os = "windows") {
400+
assert_error(
401+
socket1.send(DATA1),
402+
"no address was supplied. (os error 10057)",
403+
);
404+
}
391405

392406
// Now send some actual data.
393407
checked_write!(socket1.send_to(DATA1, address2));
@@ -848,3 +862,105 @@ pub fn multicast() {
848862
}
849863
}
850864
}
865+
866+
#[test]
867+
fn et_behavior_recv() {
868+
let (mut poll, mut events) = init_with_poll();
869+
870+
let socket1 = UdpSocket::bind(any_local_address()).unwrap();
871+
let socket2 = UdpSocket::bind(any_local_address()).unwrap();
872+
873+
let address2 = socket2.local_addr().unwrap();
874+
875+
poll.registry()
876+
.register(&socket1, ID1, Interests::WRITABLE)
877+
.expect("unable to register UDP socket");
878+
poll.registry()
879+
.register(&socket2, ID2, Interests::READABLE.add(Interests::WRITABLE))
880+
.expect("unable to register UDP socket");
881+
882+
expect_events(
883+
&mut poll,
884+
&mut events,
885+
vec![
886+
ExpectEvent::new(ID1, Interests::WRITABLE),
887+
ExpectEvent::new(ID2, Interests::WRITABLE),
888+
],
889+
);
890+
891+
socket1.connect(address2).unwrap();
892+
893+
let mut buf = [0; 20];
894+
checked_write!(socket1.send(DATA1));
895+
expect_events(
896+
&mut poll,
897+
&mut events,
898+
vec![ExpectEvent::new(ID2, Interests::READABLE)],
899+
);
900+
901+
expect_read!(socket2.recv(&mut buf), DATA1);
902+
903+
// this will reregister the socket2, resetting the interests
904+
assert_would_block(socket2.recv(&mut buf));
905+
checked_write!(socket1.send(DATA1));
906+
expect_events(
907+
&mut poll,
908+
&mut events,
909+
vec![ExpectEvent::new(ID2, Interests::READABLE)],
910+
);
911+
912+
let mut buf = [0; 20];
913+
expect_read!(socket2.recv(&mut buf), DATA1);
914+
}
915+
916+
#[test]
917+
fn et_behavior_recv_from() {
918+
let (mut poll, mut events) = init_with_poll();
919+
920+
let socket1 = UdpSocket::bind(any_local_address()).unwrap();
921+
let socket2 = UdpSocket::bind(any_local_address()).unwrap();
922+
923+
let address1 = socket1.local_addr().unwrap();
924+
let address2 = socket2.local_addr().unwrap();
925+
926+
poll.registry()
927+
.register(&socket1, ID1, Interests::READABLE.add(Interests::WRITABLE))
928+
.expect("unable to register UDP socket");
929+
poll.registry()
930+
.register(&socket2, ID2, Interests::READABLE.add(Interests::WRITABLE))
931+
.expect("unable to register UDP socket");
932+
933+
expect_events(
934+
&mut poll,
935+
&mut events,
936+
vec![
937+
ExpectEvent::new(ID1, Interests::WRITABLE),
938+
ExpectEvent::new(ID2, Interests::WRITABLE),
939+
],
940+
);
941+
942+
checked_write!(socket1.send_to(DATA1, address2));
943+
944+
expect_events(
945+
&mut poll,
946+
&mut events,
947+
vec![ExpectEvent::new(ID2, Interests::READABLE)],
948+
);
949+
950+
let mut buf = [0; 20];
951+
expect_read!(socket2.recv_from(&mut buf), DATA1, address1);
952+
953+
// this will reregister the socket2, resetting the interests
954+
assert_would_block(socket2.recv_from(&mut buf));
955+
checked_write!(socket1.send_to(DATA1, address2));
956+
expect_events(
957+
&mut poll,
958+
&mut events,
959+
vec![ExpectEvent::new(ID2, Interests::READABLE)],
960+
);
961+
962+
expect_read!(socket2.recv_from(&mut buf), DATA1, address1);
963+
964+
assert!(socket1.take_error().unwrap().is_none());
965+
assert!(socket2.take_error().unwrap().is_none());
966+
}

tests/util/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ pub fn assert_error<T, E: fmt::Display>(result: Result<T, E>, expected_msg: &str
172172
Err(err) => assert!(
173173
err.to_string().contains(expected_msg),
174174
"wanted: {}, got: {}",
175+
expected_msg,
175176
err,
176-
expected_msg
177177
),
178178
}
179179
}

0 commit comments

Comments
 (0)