Skip to content

Commit eba2fc2

Browse files
committed
Make ScmTimestamp's doc test more robust
The old test made assumptions about the responsiveness of the test environment. The new test does not, and it's simpler too.
1 parent 3749858 commit eba2fc2

File tree

1 file changed

+33
-44
lines changed

1 file changed

+33
-44
lines changed

src/sys/socket/mod.rs

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -480,52 +480,41 @@ pub enum ControlMessage<'a> {
480480
/// use std::time::*;
481481
///
482482
/// // Set up
483-
/// let message1 = "Ohayō!".as_bytes();
484-
/// let message2 = "Jā ne".as_bytes();
485-
/// let in_socket = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
483+
/// let message = "Ohayō!".as_bytes();
484+
/// let in_socket = socket(
485+
/// AddressFamily::Inet,
486+
/// SockType::Datagram,
487+
/// SockFlag::empty(),
488+
/// None).unwrap();
486489
/// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
487-
/// bind(in_socket, &SockAddr::new_inet(InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0))).unwrap();
488-
/// let address = if let Ok(address) = getsockname(in_socket) { address } else { unreachable!() };
489-
///
490-
/// // Send both
491-
/// assert!(Ok(message1.len()) == sendmsg(in_socket, &[IoVec::from_slice(message1)], &[], MsgFlags::empty(), Some(&address)));
492-
/// let time = SystemTime::now();
493-
/// std::thread::sleep(Duration::from_millis(250));
494-
/// assert!(Ok(message2.len()) == sendmsg(in_socket, &[IoVec::from_slice(message2)], &[], MsgFlags::empty(), Some(&address)));
495-
/// let delay = time.elapsed().unwrap();
496-
///
497-
/// // Receive the first
498-
/// let mut buffer1 = vec![0u8; message1.len() + message2.len()];
499-
/// let mut time1: CmsgSpace<TimeVal> = CmsgSpace::new();
500-
/// let received1 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer1)], Some(&mut time1), MsgFlags::empty()).unwrap();
501-
/// let mut time1 = if let Some(ControlMessage::ScmTimestamp(&time1)) = received1.cmsgs().next() { time1 } else { panic!("Unexpected or no control message") };
502-
///
503-
/// // Receive the second
504-
/// let mut buffer2 = vec![0u8; message1.len() + message2.len()];
505-
/// let mut time2: CmsgSpace<TimeVal> = CmsgSpace::new();
506-
/// let received2 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer2)], Some(&mut time2), MsgFlags::empty()).unwrap();
507-
/// let mut time2 = if let Some(ControlMessage::ScmTimestamp(&time2)) = received2.cmsgs().next() { time2 } else { panic!("Unexpected or no control message") };
508-
///
509-
/// // Swap if needed; UDP is unordered
510-
/// match (received1.bytes, received2.bytes, message1.len(), message2.len()) {
511-
/// (l1, l2, m1, m2) if l1 == m1 && l2 == m2 => {},
512-
/// (l2, l1, m1, m2) if l1 == m1 && l2 == m2 => {
513-
/// std::mem::swap(&mut time1, &mut time2);
514-
/// std::mem::swap(&mut buffer1, &mut buffer2);
515-
/// },
516-
/// _ => panic!("Wrong packets"),
490+
/// let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0);
491+
/// bind(in_socket, &SockAddr::new_inet(localhost)).unwrap();
492+
/// let address = getsockname(in_socket).unwrap();
493+
/// // Get initial time
494+
/// let time0 = SystemTime::now();
495+
/// // Send the message
496+
/// let iov = [IoVec::from_slice(message)];
497+
/// let flags = MsgFlags::empty();
498+
/// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
499+
/// assert_eq!(message.len(), l);
500+
/// // Receive the message
501+
/// let mut buffer = vec![0u8; message.len()];
502+
/// let mut cmsgspace: CmsgSpace<TimeVal> = CmsgSpace::new();
503+
/// let iov = [IoVec::from_mut_slice(&mut buffer)];
504+
/// let r = recvmsg(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap();
505+
/// let rtime = match r.cmsgs().next() {
506+
/// Some(ControlMessage::ScmTimestamp(&rtime)) => rtime,
507+
/// Some(_) => panic!("Unexpected control message"),
508+
/// None => panic!("No control message")
517509
/// };
518-
///
519-
/// // Compare results
520-
/// println!("{:?} @ {:?}, {:?} @ {:?}, {:?}", buffer1, time1, buffer2, time2, delay);
521-
/// assert!(message1 == &buffer1[0..(message1.len())], "{:?} == {:?}", message1, buffer1);
522-
/// assert!(message2 == &buffer2[0..(message2.len())], "{:?} == {:?}", message2, buffer2);
523-
/// let time = time2 - time1;
524-
/// let time = Duration::new(time.num_seconds() as u64, time.num_nanoseconds() as u32);
525-
/// let difference = if delay < time { time - delay } else { delay - time };
526-
/// assert!(difference.subsec_nanos() < 5_000_000, "{}ns < 5ms", difference.subsec_nanos());
527-
/// assert!(difference.as_secs() == 0);
528-
///
510+
/// // Check the final time
511+
/// let time1 = SystemTime::now();
512+
/// // the packet's received timestamp should lie in-between the two system
513+
/// // times, unless the system clock was adjusted in the meantime.
514+
/// let rduration = Duration::new(rtime.tv_sec() as u64,
515+
/// rtime.tv_usec() as u32 * 1000);
516+
/// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
517+
/// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
529518
/// // Close socket
530519
/// nix::unistd::close(in_socket).unwrap();
531520
/// ```

0 commit comments

Comments
 (0)