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 /net_util | |
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 'net_util')
-rw-r--r-- | net_util/src/lib.rs | 124 |
1 files changed, 112 insertions, 12 deletions
diff --git a/net_util/src/lib.rs b/net_util/src/lib.rs index 76de2ef..34cc686 100644 --- a/net_util/src/lib.rs +++ b/net_util/src/lib.rs @@ -67,9 +67,30 @@ pub struct Tap { if_name: [u8; 16usize], } -impl Tap { +pub trait TapT: Read + Write + AsRawFd + Pollable + Send + Sized { /// Create a new tap interface. - pub fn new() -> Result<Tap> { + fn new() -> Result<Self>; + + /// Set the host-side IP address for the tap interface. + fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()>; + + /// Set the netmask for the subnet that the tap interface will exist on. + fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()>; + + /// Set the offload flags for the tap interface. + fn set_offload(&self, flags: c_uint) -> Result<()>; + + /// Enable the tap interface. + fn enable(&self) -> Result<()>; + + /// Set the size of the vnet hdr. + fn set_vnet_hdr_size(&self, size: c_int) -> Result<()>; + + fn get_ifreq(&self) -> net_sys::ifreq; +} + +impl TapT for Tap { + fn new() -> Result<Tap> { // Open calls are safe because we give a constant nul-terminated // string and verify the result. let fd = unsafe { @@ -118,8 +139,7 @@ impl Tap { }) } - /// Set the host-side IP address for the tap interface. - pub fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()> { + fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()> { let sock = create_socket()?; let addr = create_sockaddr(ip_addr); @@ -141,8 +161,7 @@ impl Tap { Ok(()) } - /// Set the netmask for the subnet that the tap interface will exist on. - pub fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()> { + fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()> { let sock = create_socket()?; let addr = create_sockaddr(netmask); @@ -164,8 +183,7 @@ impl Tap { Ok(()) } - /// Set the offload flags for the tap interface. - pub fn set_offload(&self, flags: c_uint) -> Result<()> { + fn set_offload(&self, flags: c_uint) -> Result<()> { // ioctl is safe. Called with a valid tap fd, and we check the return. let ret = unsafe { ioctl_with_val(&self.tap_file, net_sys::TUNSETOFFLOAD(), flags as c_ulong) }; @@ -176,8 +194,7 @@ impl Tap { Ok(()) } - /// Enable the tap interface. - pub fn enable(&self) -> Result<()> { + fn enable(&self) -> Result<()> { let sock = create_socket()?; let mut ifreq = self.get_ifreq(); @@ -199,8 +216,7 @@ impl Tap { Ok(()) } - /// Set the size of the vnet hdr. - pub fn set_vnet_hdr_size(&self, size: c_int) -> Result<()> { + fn set_vnet_hdr_size(&self, size: c_int) -> Result<()> { // ioctl is safe. Called with a valid tap fd, and we check the return. let ret = unsafe { ioctl_with_ref(&self.tap_file, net_sys::TUNSETVNETHDRSZ(), &size) }; if ret < 0 { @@ -254,6 +270,90 @@ unsafe impl Pollable for Tap { } } +pub mod fakes { + use super::*; + use std::fs::OpenOptions; + use std::fs::remove_file; + + const TMP_FILE: &str = "/tmp/crosvm_tap_test_file"; + + pub struct FakeTap { + tap_file: File, + } + + impl TapT for FakeTap { + fn new() -> Result<FakeTap> { + Ok(FakeTap { + tap_file: OpenOptions::new() + .read(true) + .append(true) + .create(true) + .open(TMP_FILE) + .unwrap() + }) + } + + fn set_ip_addr(&self, _: net::Ipv4Addr) -> Result<()> { + Ok(()) + } + + fn set_netmask(&self, _: net::Ipv4Addr) -> Result<()> { + Ok(()) + } + + fn set_offload(&self, _: c_uint) -> Result<()> { + Ok(()) + } + + fn enable(&self) -> Result<()> { + Ok(()) + } + + fn set_vnet_hdr_size(&self, _: c_int) -> Result<()> { + Ok(()) + } + + fn get_ifreq(&self) -> net_sys::ifreq { + let ifreq: net_sys::ifreq = Default::default(); + ifreq + } + } + + impl Drop for FakeTap { + fn drop(&mut self) { + let _ = remove_file(TMP_FILE); + } + } + + impl Read for FakeTap { + fn read(&mut self, _: &mut [u8]) -> IoResult<usize> { + Ok(0) + } + } + + impl Write for FakeTap { + fn write(&mut self, _: &[u8]) -> IoResult<usize> { + Ok(0) + } + + fn flush(&mut self) -> IoResult<()> { + Ok(()) + } + } + + impl AsRawFd for FakeTap { + fn as_raw_fd(&self) -> RawFd { + self.tap_file.as_raw_fd() + } + } + + unsafe impl Pollable for FakeTap { + fn pollable_fd(&self) -> RawFd { + self.tap_file.as_raw_fd() + } + } +} + #[cfg(test)] mod tests { use super::*; |