use nbdkit::*;
use std::os::raw::c_char;
use std::sync::Once;
mod common;
use common::*;
static mut PLUGIN: Option<*const Plugin> = None;
static INIT: Once = Once::new();
plugin!(MockServer{});
pub fn initialize() {
INIT.call_once(|| {
let _m = MOCK_SERVER_MTX.lock().unwrap();
let config_help_ctx = MockServer::config_help_context();
config_help_ctx.expect()
.return_const(None);
let desc_ctx = MockServer::description_context();
desc_ctx.expect()
.return_const(None);
let longname_ctx = MockServer::longname_context();
longname_ctx.expect()
.return_const(None);
let magic_config_key_ctx = MockServer::magic_config_key_context();
magic_config_key_ctx.expect()
.return_const(Some("magic_config_key"));
let name_ctx = MockServer::name_context();
name_ctx.expect()
.return_const("Mock NBD Server");
let version_ctx = MockServer::version_context();
version_ctx.expect()
.return_const(None);
unsafe {
PLUGIN = Some(plugin_init());
}
});
}
fn with_fixture<F: FnMut(&mut Fixture)>(mut f: F) {
initialize();
let _m = MOCK_SERVER_MTX.lock().unwrap();
let mut mock = Box::<MockServer>::default();
mock.expect_get_size()
.returning(|| Ok(0x4200));
let mockp = (&mut mock) as *mut Box<MockServer>;
let open_ctx = MockServer::open_context();
open_ctx.expect()
.return_once(|_| Ok(mock));
let pluginp = unsafe { PLUGIN.unwrap()};
let plugin = unsafe {&*pluginp};
let handle = (plugin.open)(0);
let mut fixture = Fixture {
mockp,
plugin,
handle
};
f(&mut fixture);
(plugin.close)(handle);
}
#[test]
fn open_close() {
with_fixture(|fixture| {
let size = (fixture.plugin.get_size)(fixture.handle);
assert_eq!(0x4200, size);
});
}
mod pread {
use super::*;
#[test]
fn eio() {
with_fixture(|fixture| {
unsafe{ &mut *fixture.mockp }.expect_read_at()
.returning(|_, _| Err(Error::new(libc::EIO, "Mock error")));
let mut buf = vec![0u8; 512];
assert_eq!(-1, (fixture.plugin.pread)(fixture.handle,
buf.as_mut_ptr() as *mut c_char,
buf.len() as u32,
1024,
0));
ERRNO.with(|e| assert_eq!(libc::EIO, *e.borrow()));
ERRMSG.with(|e| assert_eq!("Mock error", *e.borrow()));
});
}
#[test]
fn ok() {
with_fixture(|fixture| {
unsafe{ &mut *fixture.mockp }.expect_read_at()
.withf(|buf, offset|
buf.len() == 512 &&
*offset == 1024
).returning(|buf, _offset| {
buf[0..10].copy_from_slice(b"0123456789");
Ok(())
});
let mut buf = vec![0u8; 512];
assert_eq!(0, (fixture.plugin.pread)(fixture.handle,
buf.as_mut_ptr() as *mut c_char,
buf.len() as u32,
1024,
0));
assert_eq!(&buf[0..10], b"0123456789");
});
}
}