From 61a46f72750c9e5d80f4b9c1db9896ce02822648 Mon Sep 17 00:00:00 2001 From: Clarissa Garvey Date: Fri, 29 Jul 2022 16:35:11 +0000 Subject: [PATCH] base/src: Add tests to Unix Tube This CL adds tests for Unix Tube: a test for the platform-specific Tube::new function, and a serialization/deserialization test that existed previously in Windows and now is shared between platforms. Bug: b:231641496 Change-Id: Iabbc15f847b995affd0bfd5b304fd70d34b171b5 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3794509 Tested-by: Clarissa Garvey Commit-Queue: Clarissa Garvey Reviewed-by: Noah Gold --- base/src/sys/unix/tube.rs | 57 ++++++++++++++++++++++++++++++++++++ base/src/sys/windows/tube.rs | 50 ------------------------------- base/src/tube.rs | 50 +++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 50 deletions(-) diff --git a/base/src/sys/unix/tube.rs b/base/src/sys/unix/tube.rs index c324df7baa..900d7e3ea3 100644 --- a/base/src/sys/unix/tube.rs +++ b/base/src/sys/unix/tube.rs @@ -153,3 +153,60 @@ impl AsRawDescriptor for RecvTube { self.0.as_raw_descriptor() } } + +#[cfg(test)] +mod test { + use std::time; + + use super::*; + use crate::EventContext; + use crate::EventToken; + use crate::ReadNotifier; + + #[derive(EventToken, Debug, Eq, PartialEq, Copy, Clone)] + enum Token { + ReceivedData, + } + + const EVENT_WAIT_TIME: time::Duration = time::Duration::from_secs(10); + + #[test] + fn test_serialize_tube_new() { + let (sock_send, sock_recv) = UnixSeqpacket::pair().unwrap(); + let tube_send = Tube::new(sock_send); + let tube_recv = Tube::new(sock_recv); + + // Serialize the Tube + let msg_serialize = SerializeDescriptors::new(&tube_send); + let serialized = serde_json::to_vec(&msg_serialize).unwrap(); + let msg_descriptors = msg_serialize.into_descriptors(); + + // Deserialize the Tube + let mut msg_descriptors_safe = msg_descriptors + .into_iter() + .map(|v| Some(unsafe { SafeDescriptor::from_raw_descriptor(v) })) + .collect(); + let tube_deserialized: Tube = deserialize_with_descriptors( + || serde_json::from_slice(&serialized), + &mut msg_descriptors_safe, + ) + .unwrap(); + + // Send a message through deserialized Tube + tube_deserialized.send(&"hi".to_string()).unwrap(); + + // Wait for the message to arrive + let event_ctx: EventContext = + EventContext::build_with(&[(tube_recv.get_read_notifier(), Token::ReceivedData)]) + .unwrap(); + let events = event_ctx.wait_timeout(EVENT_WAIT_TIME).unwrap(); + let tokens: Vec = events + .iter() + .filter(|e| e.is_readable) + .map(|e| e.token) + .collect(); + assert_eq!(tokens, vec! {Token::ReceivedData}); + + assert_eq!(tube_recv.recv::().unwrap(), "hi"); + } +} diff --git a/base/src/sys/windows/tube.rs b/base/src/sys/windows/tube.rs index 656901280f..5f25c86c8a 100644 --- a/base/src/sys/windows/tube.rs +++ b/base/src/sys/windows/tube.rs @@ -411,53 +411,3 @@ impl DuplicateHandleTube { .ok_or(Error::BrokerDupDescriptor) } } - -#[cfg(test)] -mod tests { - use std::time; - - use super::*; - use crate::EventContext; - use crate::EventToken; - use crate::EventTrigger; - use crate::ReadNotifier; - - const EVENT_WAIT_TIME: time::Duration = time::Duration::from_secs(10); - - #[derive(EventToken, Debug, Eq, PartialEq, Copy, Clone)] - enum Token { - ReceivedData, - } - - #[test] - fn test_serialize_tube() { - let (tube_1, tube_2) = Tube::pair().unwrap(); - let event_ctx: EventContext = EventContext::build_with(&[EventTrigger::from( - tube_2.get_read_notifier(), - Token::ReceivedData, - )]) - .unwrap(); - - // Serialize the Tube - let msg_serialize = SerializeDescriptors::new(&tube_1); - let serialized = serde_json::to_vec(&msg_serialize).unwrap(); - let msg_descriptors = msg_serialize.into_descriptors(); - - // Deserialize the Tube - let mut msg_descriptors_safe = msg_descriptors - .into_iter() - .map(|v| Some(unsafe { SafeDescriptor::from_raw_descriptor(v) })) - .collect(); - let tube_deserialized: Tube = deserialize_with_descriptors( - || serde_json::from_slice(&serialized), - &mut msg_descriptors_safe, - ) - .unwrap(); - - // Send a message through deserialized Tube - tube_deserialized.send(&"hi".to_string()).unwrap(); - - assert_eq!(event_ctx.wait_timeout(EVENT_WAIT_TIME).unwrap().len(), 1); - assert_eq!(tube_2.recv::().unwrap(), "hi"); - } -} diff --git a/base/src/tube.rs b/base/src/tube.rs index f548207525..6f91d7174d 100644 --- a/base/src/tube.rs +++ b/base/src/tube.rs @@ -144,13 +144,25 @@ mod tests { use serde::Serialize; use super::*; + use crate::descriptor::FromRawDescriptor; + use crate::descriptor::SafeDescriptor; + use crate::platform::deserialize_with_descriptors; + use crate::platform::SerializeDescriptors; use crate::Event; + use crate::EventToken; + use crate::ReadNotifier; + use crate::WaitContext; #[derive(Serialize, Deserialize)] struct DataStruct { x: u32, } + #[derive(EventToken, Debug, Eq, PartialEq, Copy, Clone)] + enum Token { + ReceivedData, + } + // Magics to identify which producer sent a message (& detect corruption). const PRODUCER_ID_1: u32 = 801279273; const PRODUCER_ID_2: u32 = 345234861; @@ -233,6 +245,44 @@ mod tests { (tube, id1_count, id2_count) } + #[test] + fn test_serialize_tube_pair() { + let (tube_send, tube_recv) = Tube::pair().unwrap(); + + // Serialize the Tube + let msg_serialize = SerializeDescriptors::new(&tube_send); + let serialized = serde_json::to_vec(&msg_serialize).unwrap(); + let msg_descriptors = msg_serialize.into_descriptors(); + + // Deserialize the Tube + let mut msg_descriptors_safe = msg_descriptors + .into_iter() + .map(|v| Some(unsafe { SafeDescriptor::from_raw_descriptor(v) })) + .collect(); + let tube_deserialized: Tube = deserialize_with_descriptors( + || serde_json::from_slice(&serialized), + &mut msg_descriptors_safe, + ) + .unwrap(); + + // Send a message through deserialized Tube + tube_deserialized.send(&"hi".to_string()).unwrap(); + + // Wait for the message to arrive + let wait_ctx: WaitContext = + WaitContext::build_with(&[(tube_recv.get_read_notifier(), Token::ReceivedData)]) + .unwrap(); + let events = wait_ctx.wait_timeout(Duration::from_secs(10)).unwrap(); + let tokens: Vec = events + .iter() + .filter(|e| e.is_readable) + .map(|e| e.token) + .collect(); + assert_eq!(tokens, vec! {Token::ReceivedData}); + + assert_eq!(tube_recv.recv::().unwrap(), "hi"); + } + #[test] fn send_recv_mpsc() { let (p1, consumer) = Tube::directional_pair().unwrap();