1 // Copyright 2022 The Chromium OS Authors. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 //! Unix specific code that keeps rest of the code in the crate platform independent. 5 6 #[cfg(all(test, feature = "vmm"))] 7 pub(crate) mod tests { 8 use crate::connection::{ 9 socket::Endpoint as SocketEndpoint, socket::Listener as SocketListener, Listener, 10 }; 11 use crate::master::Master; 12 use crate::message::MasterReq; 13 use tempfile::{Builder, TempDir}; 14 #[cfg(feature = "device")] 15 use { 16 crate::{ 17 slave::SlaveListener, 18 slave_req_handler::{SlaveReqHandler, VhostUserSlaveReqHandler}, 19 }, 20 std::sync::Arc, 21 }; 22 23 pub(crate) type TestMaster = Master<SocketEndpoint<MasterReq>>; 24 pub(crate) type TestEndpoint = SocketEndpoint<MasterReq>; temp_dir() -> TempDir25 pub(crate) fn temp_dir() -> TempDir { 26 Builder::new().prefix("/tmp/vhost_test").tempdir().unwrap() 27 } 28 create_pair() -> (Master<SocketEndpoint<MasterReq>>, SocketEndpoint<MasterReq>)29 pub(crate) fn create_pair() -> (Master<SocketEndpoint<MasterReq>>, SocketEndpoint<MasterReq>) { 30 let dir = temp_dir(); 31 let mut path = dir.path().to_owned(); 32 path.push("sock"); 33 let mut listener = SocketListener::new(&path, true).unwrap(); 34 listener.set_nonblocking(true).unwrap(); 35 let master = Master::connect(path, 2).unwrap(); 36 let slave = listener.accept().unwrap().unwrap(); 37 (master, SocketEndpoint::from(slave)) 38 } 39 40 #[cfg(feature = "device")] create_master_slave_pair<S>( backend: Arc<S>, ) -> (TestMaster, SlaveReqHandler<S, TestEndpoint>) where S: VhostUserSlaveReqHandler,41 pub(crate) fn create_master_slave_pair<S>( 42 backend: Arc<S>, 43 ) -> (TestMaster, SlaveReqHandler<S, TestEndpoint>) 44 where 45 S: VhostUserSlaveReqHandler, 46 { 47 let dir = Builder::new().prefix("/tmp/vhost_test").tempdir().unwrap(); 48 let mut path = dir.path().to_owned(); 49 path.push("sock"); 50 let listener = SocketListener::new(&path, true).unwrap(); 51 let mut slave_listener = SlaveListener::new(listener, backend).unwrap(); 52 let master = Master::connect(&path, 1).unwrap(); 53 (master, slave_listener.accept().unwrap().unwrap()) 54 } 55 56 // Create failures don't happen on using Tubes because there is no "connection". (The channel is 57 // already up when we invoke this library.) 58 #[test] test_create_failure()59 fn test_create_failure() { 60 let dir = temp_dir(); 61 let mut path = dir.path().to_owned(); 62 path.push("sock"); 63 let _ = SocketListener::new(&path, true).unwrap(); 64 let _ = SocketListener::new(&path, false).is_err(); 65 assert!(Master::<SocketEndpoint<_>>::connect(&path, 1).is_err()); 66 67 let mut listener = SocketListener::new(&path, true).unwrap(); 68 assert!(SocketListener::new(&path, false).is_err()); 69 listener.set_nonblocking(true).unwrap(); 70 71 let _master = Master::<SocketEndpoint<_>>::connect(&path, 1).unwrap(); 72 let _slave = listener.accept().unwrap().unwrap(); 73 } 74 } 75