summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-07 16:02:21 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-07 16:02:21 +0000
commitc2923ea5ea048eaa9024d17ce4f50335a9dd13ab (patch)
tree39d6e5d87691cf0a5db636c0420b04540dd32744 /src/sys
parent3749858199155259c055e1e5621b20ffffd70712 (diff)
parenteba2fc2e6702f4a8c38a38b61427c1453b5e997d (diff)
downloadnix-c2923ea5ea048eaa9024d17ce4f50335a9dd13ab.zip
Merge #1005
1005: Make ScmTimestamp's doc test more robust r=asomers a=asomers The old test made assumptions about the responsiveness of the test environment. The new test does not, and it's simpler too. Co-authored-by: Alan Somers <asomers@gmail.com>
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/socket/mod.rs77
1 files changed, 33 insertions, 44 deletions
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 1659bd1e..62c0ea74 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -480,52 +480,41 @@ pub enum ControlMessage<'a> {
/// use std::time::*;
///
/// // Set up
- /// let message1 = "Ohayō!".as_bytes();
- /// let message2 = "Jā ne".as_bytes();
- /// let in_socket = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
+ /// let message = "Ohayō!".as_bytes();
+ /// let in_socket = socket(
+ /// AddressFamily::Inet,
+ /// SockType::Datagram,
+ /// SockFlag::empty(),
+ /// None).unwrap();
/// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
- /// bind(in_socket, &SockAddr::new_inet(InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0))).unwrap();
- /// let address = if let Ok(address) = getsockname(in_socket) { address } else { unreachable!() };
- ///
- /// // Send both
- /// assert!(Ok(message1.len()) == sendmsg(in_socket, &[IoVec::from_slice(message1)], &[], MsgFlags::empty(), Some(&address)));
- /// let time = SystemTime::now();
- /// std::thread::sleep(Duration::from_millis(250));
- /// assert!(Ok(message2.len()) == sendmsg(in_socket, &[IoVec::from_slice(message2)], &[], MsgFlags::empty(), Some(&address)));
- /// let delay = time.elapsed().unwrap();
- ///
- /// // Receive the first
- /// let mut buffer1 = vec![0u8; message1.len() + message2.len()];
- /// let mut time1: CmsgSpace<TimeVal> = CmsgSpace::new();
- /// let received1 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer1)], Some(&mut time1), MsgFlags::empty()).unwrap();
- /// let mut time1 = if let Some(ControlMessage::ScmTimestamp(&time1)) = received1.cmsgs().next() { time1 } else { panic!("Unexpected or no control message") };
- ///
- /// // Receive the second
- /// let mut buffer2 = vec![0u8; message1.len() + message2.len()];
- /// let mut time2: CmsgSpace<TimeVal> = CmsgSpace::new();
- /// let received2 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer2)], Some(&mut time2), MsgFlags::empty()).unwrap();
- /// let mut time2 = if let Some(ControlMessage::ScmTimestamp(&time2)) = received2.cmsgs().next() { time2 } else { panic!("Unexpected or no control message") };
- ///
- /// // Swap if needed; UDP is unordered
- /// match (received1.bytes, received2.bytes, message1.len(), message2.len()) {
- /// (l1, l2, m1, m2) if l1 == m1 && l2 == m2 => {},
- /// (l2, l1, m1, m2) if l1 == m1 && l2 == m2 => {
- /// std::mem::swap(&mut time1, &mut time2);
- /// std::mem::swap(&mut buffer1, &mut buffer2);
- /// },
- /// _ => panic!("Wrong packets"),
+ /// let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0);
+ /// bind(in_socket, &SockAddr::new_inet(localhost)).unwrap();
+ /// let address = getsockname(in_socket).unwrap();
+ /// // Get initial time
+ /// let time0 = SystemTime::now();
+ /// // Send the message
+ /// let iov = [IoVec::from_slice(message)];
+ /// let flags = MsgFlags::empty();
+ /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
+ /// assert_eq!(message.len(), l);
+ /// // Receive the message
+ /// let mut buffer = vec![0u8; message.len()];
+ /// let mut cmsgspace: CmsgSpace<TimeVal> = CmsgSpace::new();
+ /// let iov = [IoVec::from_mut_slice(&mut buffer)];
+ /// let r = recvmsg(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap();
+ /// let rtime = match r.cmsgs().next() {
+ /// Some(ControlMessage::ScmTimestamp(&rtime)) => rtime,
+ /// Some(_) => panic!("Unexpected control message"),
+ /// None => panic!("No control message")
/// };
- ///
- /// // Compare results
- /// println!("{:?} @ {:?}, {:?} @ {:?}, {:?}", buffer1, time1, buffer2, time2, delay);
- /// assert!(message1 == &buffer1[0..(message1.len())], "{:?} == {:?}", message1, buffer1);
- /// assert!(message2 == &buffer2[0..(message2.len())], "{:?} == {:?}", message2, buffer2);
- /// let time = time2 - time1;
- /// let time = Duration::new(time.num_seconds() as u64, time.num_nanoseconds() as u32);
- /// let difference = if delay < time { time - delay } else { delay - time };
- /// assert!(difference.subsec_nanos() < 5_000_000, "{}ns < 5ms", difference.subsec_nanos());
- /// assert!(difference.as_secs() == 0);
- ///
+ /// // Check the final time
+ /// let time1 = SystemTime::now();
+ /// // the packet's received timestamp should lie in-between the two system
+ /// // times, unless the system clock was adjusted in the meantime.
+ /// let rduration = Duration::new(rtime.tv_sec() as u64,
+ /// rtime.tv_usec() as u32 * 1000);
+ /// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
+ /// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
/// // Close socket
/// nix::unistd::close(in_socket).unwrap();
/// ```