diff options
author | Jason D. Clinton <jclinton@chromium.org> | 2017-09-27 22:04:03 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-02-02 16:32:12 -0800 |
commit | 865323d0ed8b6913ed7dfe6e31c3b86eb46775bd (patch) | |
tree | be835e928e8932ab66dc00412d5f96430289e94c /vhost | |
parent | 19e57b9532f9be830fab7fad685957afc8f5ab78 (diff) | |
download | crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar.gz crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar.bz2 crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar.lz crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar.xz crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.tar.zst crosvm-865323d0ed8b6913ed7dfe6e31c3b86eb46775bd.zip |
hw/virtio/vhost: Add simple tests backed by fakes
This slightly advances the use of fakes to test higher level application logic. The fakes are rudimentary at this point, but I wanted to get feedback on the addition of generics in order to facilitate swaping concrete implementations out with fakes in higher level code. BUG=none TEST=./build_test and cargo test -p crosvm -p data_model -p syscall_defines -p kernel_loader -p net_util -p x86_64 -p virtio_sys -p kvm_sys -p vhost -p io_jail -p net_sys -p sys_util -p kvm Change-Id: Ib64581014391f49cff30ada10677bbbcd0088f20 Reviewed-on: https://chromium-review.googlesource.com/689740 Commit-Ready: Jason Clinton <jclinton@chromium.org> Tested-by: Jason Clinton <jclinton@chromium.org> Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'vhost')
-rw-r--r-- | vhost/src/lib.rs | 8 | ||||
-rw-r--r-- | vhost/src/net.rs | 69 |
2 files changed, 44 insertions, 33 deletions
diff --git a/vhost/src/lib.rs b/vhost/src/lib.rs index dc1bf81..e0aefdb 100644 --- a/vhost/src/lib.rs +++ b/vhost/src/lib.rs @@ -11,6 +11,7 @@ pub mod net; mod vsock; pub use net::Net; +pub use net::NetT; pub use vsock::Vsock; use std::io::Error as IoError; @@ -333,7 +334,8 @@ pub trait Vhost: AsRawFd + std::marker::Sized { mod tests { use super::*; - use net::tests::FakeNet; + use net::fakes::FakeNet; + use net_util::fakes::FakeTap; use std::result; use sys_util::{GuestAddress, GuestMemory, GuestMemoryError}; @@ -352,9 +354,9 @@ mod tests { } } - fn create_fake_vhost_net () -> FakeNet { + fn create_fake_vhost_net() -> FakeNet<FakeTap> { let gm = create_guest_memory().unwrap(); - FakeNet::new(&gm).unwrap() + FakeNet::<FakeTap>::new(&gm).unwrap() } #[test] diff --git a/vhost/src/net.rs b/vhost/src/net.rs index 0c6eaad..1d3f94e 100644 --- a/vhost/src/net.rs +++ b/vhost/src/net.rs @@ -3,8 +3,9 @@ // found in the LICENSE file. use libc; -use net_util; +use net_util::TapT; use std::fs::{File, OpenOptions}; +use std::marker::PhantomData; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::{AsRawFd, RawFd}; use virtio_sys; @@ -19,30 +20,37 @@ static DEVICE: &'static str = "/dev/vhost-net"; /// /// This provides a simple wrapper around a VHOST_NET file descriptor and /// methods that safely run ioctls on that file descriptor. -pub struct Net { +pub struct Net<T> { // fd must be dropped first, which will stop and tear down the // vhost-net worker before GuestMemory can potentially be unmapped. fd: File, mem: GuestMemory, + phantom: PhantomData<T>, } -pub trait NetT { +pub trait NetT<T: TapT>: Vhost + AsRawFd + Send + Sized { + /// Create a new NetT instance + fn new(mem: &GuestMemory) -> Result<Self>; + /// Set the tap file descriptor that will serve as the VHOST_NET backend. /// This will start the vhost worker for the given queue. /// /// # Arguments /// * `queue_index` - Index of the queue to modify. /// * `fd` - Tap interface that will be used as the backend. - fn set_backend(&self, queue_index: usize, fd: &net_util::Tap) -> Result<()>; + fn set_backend(&self, queue_index: usize, fd: &T) -> Result<()>; } -impl Net { +impl<T> NetT<T> for Net<T> +where + T: TapT, +{ /// Opens /dev/vhost-net and holds a file descriptor open for it. /// /// # Arguments /// * `mem` - Guest memory mapping. - pub fn new(mem: &GuestMemory) -> Result<Net> { - Ok(Net { + fn new(mem: &GuestMemory) -> Result<Net<T>> { + Ok(Net::<T> { fd: OpenOptions::new() .read(true) .write(true) @@ -50,12 +58,11 @@ impl Net { .open(DEVICE) .map_err(Error::VhostOpen)?, mem: mem.clone(), + phantom: PhantomData, }) } -} -impl NetT for Net { - fn set_backend(&self, queue_index: usize, fd: &net_util::Tap) -> Result<()> { + fn set_backend(&self, queue_index: usize, fd: &T) -> Result<()> { let vring_file = virtio_sys::vhost_vring_file { index: queue_index as u32, fd: fd.as_raw_fd(), @@ -72,64 +79,66 @@ impl NetT for Net { } } -impl Vhost for Net { +impl<T> Vhost for Net<T> { fn mem(&self) -> &GuestMemory { &self.mem } } -impl AsRawFd for Net { +impl<T> AsRawFd for Net<T> { fn as_raw_fd(&self) -> RawFd { self.fd.as_raw_fd() } } -#[cfg(test)] -pub mod tests { +pub mod fakes { use super::*; use std::fs::OpenOptions; use std::fs::remove_file; const TMP_FILE: &str = "/tmp/crosvm_vhost_test_file"; - pub struct FakeNet { + pub struct FakeNet<T> { fd: File, mem: GuestMemory, + phantom: PhantomData<T>, + } + + impl<T> Drop for FakeNet<T> { + fn drop(&mut self) { + let _ = remove_file(TMP_FILE); + } } - impl FakeNet { - pub fn new(mem: &GuestMemory) -> Result<FakeNet> { - Ok(FakeNet { + impl<T> NetT<T> for FakeNet<T> + where + T: TapT, + { + fn new(mem: &GuestMemory) -> Result<FakeNet<T>> { + Ok(FakeNet::<T> { fd: OpenOptions::new() .read(true) .append(true) .create(true) .open(TMP_FILE) .unwrap(), - mem: mem.clone() + mem: mem.clone(), + phantom: PhantomData, }) } - } - - impl Drop for FakeNet { - fn drop(&mut self) { - let _ = remove_file(TMP_FILE); - } - } - impl NetT for FakeNet { - fn set_backend(&self, _queue_index: usize, _fd: &net_util::Tap) -> Result<()> { + fn set_backend(&self, _queue_index: usize, _fd: &T) -> Result<()> { Ok(()) } } - impl Vhost for FakeNet { + impl<T> Vhost for FakeNet<T> { fn mem(&self) -> &GuestMemory { &self.mem } } - impl AsRawFd for FakeNet { + impl<T> AsRawFd for FakeNet<T> { fn as_raw_fd(&self) -> RawFd { self.fd.as_raw_fd() } |