Skip to content

Commit 43c61f2

Browse files
六滔adamqqqplay
六滔
authored andcommitted
api/server: add unit test for fuser server api
Signed-off-by: Qinqi Qu <quqinqi@linux.alibaba.com>
1 parent e1f234d commit 43c61f2

File tree

2 files changed

+189
-1
lines changed

2 files changed

+189
-1
lines changed

src/api/server/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ impl<'a, F: FileSystem, S: BitmapSlice> SrvContext<'a, F, S> {
213213
#[cfg(test)]
214214
mod tests {
215215
use super::*;
216+
#[cfg(feature = "fusedev")]
217+
use crate::transport::FuseBuf;
216218

217219
#[test]
218220
fn test_extract_cstrs() {
@@ -249,4 +251,42 @@ mod tests {
249251
ServerUtil::extract_two_cstrs(&[0x1u8, 0x2u8, 0x0]).unwrap_err();
250252
ServerUtil::extract_two_cstrs(&[0x1u8, 0x2u8]).unwrap_err();
251253
}
254+
255+
#[cfg(feature = "fusedev")]
256+
#[test]
257+
fn test_get_message_body() {
258+
let mut read_buf = [0u8; 4096];
259+
260+
let mut r = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut read_buf)).unwrap();
261+
let in_header = InHeader {
262+
len: 0x1000,
263+
..Default::default()
264+
};
265+
let buf = ServerUtil::get_message_body(&mut r, &in_header, 0).unwrap();
266+
assert_eq!(buf.len(), 0x1000 - size_of::<InHeader>());
267+
268+
let mut r = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut read_buf)).unwrap();
269+
let in_header = InHeader {
270+
len: 0x1000,
271+
..Default::default()
272+
};
273+
let buf = ServerUtil::get_message_body(&mut r, &in_header, 0x100).unwrap();
274+
assert_eq!(buf.len(), 0x1000 - size_of::<InHeader>() - 0x100);
275+
276+
let mut r = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut read_buf)).unwrap();
277+
let in_header = InHeader {
278+
len: 0x1000,
279+
..Default::default()
280+
};
281+
// shoutld fail because of invalid sub header size
282+
assert!(ServerUtil::get_message_body(&mut r, &in_header, 0x1000).is_err());
283+
284+
let mut r = Reader::<()>::from_fuse_buffer(FuseBuf::new(&mut read_buf)).unwrap();
285+
let in_header = InHeader {
286+
len: 0x1000,
287+
..Default::default()
288+
};
289+
// shoutld fail because of invalid sub header size
290+
assert!(ServerUtil::get_message_body(&mut r, &in_header, 0x1001).is_err());
291+
}
252292
}

src/api/server/sync_io.rs

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ impl<F: FileSystem + Sync> Server<F> {
229229

230230
pub(super) fn forget<S: BitmapSlice>(&self, mut ctx: SrvContext<'_, F, S>) -> Result<usize> {
231231
let ForgetIn { nlookup } = ctx.r.read_obj().map_err(Error::DecodeMessage)?;
232-
233232
self.fs.forget(ctx.context(), ctx.nodeid(), nlookup);
234233

235234
// There is no reply for forget messages.
@@ -1401,3 +1400,152 @@ fn add_dirent<S: BitmapSlice>(
14011400
Ok(total_len)
14021401
}
14031402
}
1403+
1404+
#[cfg(test)]
1405+
mod tests {
1406+
1407+
#[cfg(feature = "fusedev")]
1408+
mod tests_fusedev {
1409+
use super::super::*;
1410+
use crate::passthrough::{Config, PassthroughFs};
1411+
use crate::transport::FuseBuf;
1412+
1413+
use std::fs::File;
1414+
use std::os::unix::io::AsRawFd;
1415+
use vmm_sys_util::tempfile::TempFile;
1416+
1417+
fn prepare_srvcontext<'a>(
1418+
read_buf: &'a mut [u8],
1419+
write_buf: &'a mut [u8],
1420+
) -> (SrvContext<'a, PassthroughFs>, File) {
1421+
let file = TempFile::new().unwrap().into_file();
1422+
let reader = Reader::<()>::from_fuse_buffer(FuseBuf::new(read_buf)).unwrap();
1423+
let writer = FuseDevWriter::<()>::new(file.as_raw_fd(), write_buf).unwrap();
1424+
let in_header = InHeader::default();
1425+
(
1426+
SrvContext::<PassthroughFs>::new(in_header, reader, writer.into()),
1427+
file,
1428+
)
1429+
}
1430+
1431+
#[test]
1432+
fn test_server_init() {
1433+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1434+
let server = Server::new(fs);
1435+
1436+
let mut read_buf = [
1437+
0x8u8, 0x0, 0x0, 0x0, // major = 0x0008
1438+
0x0u8, 0x0, 0x0, 0x0, // minor = 0x0008
1439+
0x0, 0x0, 0x0, 0x0, // max_readahead = 0x0000
1440+
0x0, 0x0, 0x0, 0x0, // flags = 0x0000
1441+
];
1442+
let mut write_buf = [0u8; 4096];
1443+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1444+
1445+
let res = server.init(ctx).unwrap();
1446+
assert_eq!(res, 80);
1447+
1448+
let mut read_buf1 = [
1449+
0x7u8, 0x0, 0x0, 0x0, // major = 0x0007
1450+
0x0u8, 0x0, 0x0, 0x0, // minor = 0x0000
1451+
0x0, 0x0, 0x0, 0x0, // max_readahead = 0x0000
1452+
0x0, 0x0, 0x0, 0x0, // flags = 0x0000
1453+
];
1454+
let mut write_buf1 = [0u8; 4096];
1455+
let (ctx1, _file) = prepare_srvcontext(&mut read_buf1, &mut write_buf1);
1456+
1457+
let res = server.init(ctx1).unwrap();
1458+
assert_eq!(res, 24);
1459+
}
1460+
1461+
#[test]
1462+
fn test_server_write() {
1463+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1464+
let server = Server::new(fs);
1465+
1466+
let mut read_buf = [0u8; 4096];
1467+
let mut write_buf = [0u8; 4096];
1468+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1469+
1470+
let res = server.write(ctx).unwrap();
1471+
assert_eq!(res, 16);
1472+
}
1473+
1474+
#[test]
1475+
fn test_server_read() {
1476+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1477+
let server = Server::new(fs);
1478+
1479+
let mut read_buf = [0u8; 4096];
1480+
let mut write_buf = [0u8; 4096];
1481+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1482+
1483+
let res = server.read(ctx).unwrap();
1484+
assert_eq!(res, 16);
1485+
}
1486+
1487+
#[test]
1488+
fn test_server_readdir() {
1489+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1490+
let server = Server::new(fs);
1491+
1492+
let mut read_buf = [0u8; 4096];
1493+
let mut write_buf = [0u8; 4096];
1494+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1495+
1496+
let res = server.do_readdir(ctx, true).unwrap();
1497+
assert_eq!(res, 16);
1498+
}
1499+
1500+
#[test]
1501+
fn test_server_ioctl() {
1502+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1503+
let server = Server::new(fs);
1504+
1505+
let mut read_buf = [0u8; 4096];
1506+
let mut write_buf = [0u8; 4096];
1507+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1508+
1509+
let res = server.ioctl(ctx).unwrap();
1510+
assert!(res > 0);
1511+
1512+
// construct IoctlIn with invalid in_size
1513+
let mut read_buf_fail = [
1514+
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //fh = 0
1515+
0x0, 0x0, 0x0, 0x0, //flags = 0
1516+
0x0, 0x0, 0x0, 0x0, //cmd = 0
1517+
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //arg = 0
1518+
0x7u8, 0x3u8, 0x0, 0x0, //in_size = 0x307
1519+
0x0, 0x0, 0x0, 0x0, //out_size = 0
1520+
];
1521+
let mut write_buf_fail = [0u8; 48];
1522+
let (ctx_fail, _file) = prepare_srvcontext(&mut read_buf_fail, &mut write_buf_fail);
1523+
let res = server.ioctl(ctx_fail).unwrap();
1524+
assert!(res > 0);
1525+
}
1526+
1527+
#[test]
1528+
fn test_server_batch_forget() {
1529+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1530+
let server = Server::new(fs);
1531+
1532+
let mut read_buf = [0u8; 4096];
1533+
let mut write_buf = [0u8; 4096];
1534+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1535+
// forget should return 0 anyway
1536+
assert_eq!(server.batch_forget(ctx).unwrap(), 0);
1537+
}
1538+
1539+
#[test]
1540+
fn test_server_forget() {
1541+
let fs = PassthroughFs::<()>::new(Config::default()).unwrap();
1542+
let server = Server::new(fs);
1543+
1544+
let mut read_buf = [0x1u8, 0x2u8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
1545+
let mut write_buf = [0u8; 4096];
1546+
let (ctx, _file) = prepare_srvcontext(&mut read_buf, &mut write_buf);
1547+
1548+
assert_eq!(server.forget(ctx).unwrap(), 0);
1549+
}
1550+
}
1551+
}

0 commit comments

Comments
 (0)