Skip to content

Commit 566ed60

Browse files
committed
improve coverage and documentation
1 parent 2dbe2ec commit 566ed60

File tree

3 files changed

+138
-22
lines changed

3 files changed

+138
-22
lines changed

ic-wasi-polyfill/src/lib.rs

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,13 +1867,16 @@ pub unsafe extern "C" fn raw_init(seed: *const u8, len: usize) {
18671867
})
18681868
}
18691869

1870-
// the init function ensures the module is not thrown away by the linker
1871-
// seed - The seed of the random numbers, up to 32 byte array can be used.
1872-
// env_pairs - The pre-defined environment variables.
1873-
//
1874-
// Example:
1875-
// init(&[12,3,54,1], &[("PATH", "/usr/bin"), ("UID", "1028"), ("HOME", "/home/user")]);
1876-
#[allow(clippy::missing_safety_doc)]
1870+
/// Initializes the runtime environment and random number generator.
1871+
///
1872+
/// # Parameters
1873+
/// - `seed`: A byte slice (up to 32 bytes) used to seed the random number generator.
1874+
/// - `env_pairs`: A list of key-value pairs representing environment variables to initialize.
1875+
///
1876+
/// # Safety
1877+
/// This function calls an `unsafe` function `raw_init`, passing a raw pointer and length of the seed slice.
1878+
/// It is safe to call this function as long as `seed` is a valid slice.
1879+
///
18771880
pub fn init(seed: &[u8], env_pairs: &[(&str, &str)]) {
18781881
ENV.with(|env| {
18791882
let mut env = env.borrow_mut();
@@ -1916,10 +1919,12 @@ pub fn init_with_memory_manager<M: Memory + 'static>(
19161919
init(seed, env_pairs);
19171920
}
19181921

1919-
// mount external memory onto a file to speed-up file access. All further file reads and writes be forwarded to this memory.
1920-
// file_name - Name of the host file to mount on
1921-
// memory - Memory to use as file storage
1922-
//
1922+
/// Mounts external memory onto a file to speed-up file access. All further file reads and writes be forwarded to this memory.
1923+
///
1924+
/// # Parameters
1925+
/// - `file_name` - Name of the host file to mount on
1926+
/// - `memory` - Memory to use as an actual file storage
1927+
///
19231928
pub fn mount_memory_file(file_name: &str, memory: Box<dyn Memory>) -> i32 {
19241929
FS.with(|fs| {
19251930
let mut fs = fs.borrow_mut();
@@ -1933,9 +1938,11 @@ pub fn mount_memory_file(file_name: &str, memory: Box<dyn Memory>) -> i32 {
19331938
})
19341939
}
19351940

1936-
// unmount external memory from a host file. All further file reads and writes are written to a normal file.
1937-
// file_name - Name of the host file holding the mount
1938-
//
1941+
/// unmounts external memory from a host file. All further file reads and writes are written to a normal file.
1942+
///
1943+
/// # Parameters
1944+
/// `file_name` - Name of the host file holding the mount
1945+
///
19391946
pub fn unmount_memory_file(file_name: &str) -> i32 {
19401947
FS.with(|fs| {
19411948
let mut fs = fs.borrow_mut();
@@ -1949,9 +1956,11 @@ pub fn unmount_memory_file(file_name: &str) -> i32 {
19491956
})
19501957
}
19511958

1952-
// initialize mouned memory with the contents of the host file.
1953-
// file_name - Name of the host file holding the mount
1954-
//
1959+
/// Initializes mouned memory with the contents of the host file.
1960+
///
1961+
/// # Parameters
1962+
/// `file_name` - Name of the host file holding the mount
1963+
///
19551964
pub fn init_memory_file(file_name: &str) -> i32 {
19561965
FS.with(|fs| {
19571966
let mut fs = fs.borrow_mut();
@@ -1965,9 +1974,11 @@ pub fn init_memory_file(file_name: &str) -> i32 {
19651974
})
19661975
}
19671976

1968-
// Store memory contents into the host file.
1969-
// file_name - Name of the host file holding the mount
1970-
//
1977+
/// Store memory contents into the host file.
1978+
///
1979+
/// # Parameters
1980+
/// `file_name` - Name of the host file holding the mount
1981+
///
19711982
pub fn store_memory_file(file_name: &str) -> i32 {
19721983
FS.with(|fs| {
19731984
let mut fs = fs.borrow_mut();

ic-wasi-polyfill/tests/common.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ pub fn create_test_file_with_content(parent_fd: Fd, file_name: &str, content: Ve
4242
0,
4343
new_file_name.as_ptr(),
4444
new_file_name.len() as i32,
45-
(wasi::OFLAGS_CREAT | wasi::OFLAGS_TRUNC | wasi::OFLAGS_EXCL) as i32,
45+
(wasi::OFLAGS_CREAT | wasi::OFLAGS_TRUNC) as i32,
4646
DEFAULT_RIGHTS,
4747
DEFAULT_RIGHTS,
4848
0,
4949
(&mut file_fd) as *mut u32,
5050
)
5151
};
52-
assert!(res == 0);
52+
assert_eq!(res, 0);
5353

5454
let mut src = Vec::new();
5555

@@ -138,3 +138,48 @@ pub fn read_directory(root_fd: Fd) -> Vec<String> {
138138

139139
folders
140140
}
141+
142+
#[allow(clippy::missing_safety_doc)]
143+
pub fn fd_close(fd: Fd) {
144+
__ic_custom_fd_close(fd);
145+
}
146+
147+
#[allow(clippy::missing_safety_doc)]
148+
pub fn read_file_to_string(file: &str) -> String {
149+
let mut file_fd = 0u32;
150+
151+
let res = unsafe {
152+
__ic_custom_path_open(
153+
3,
154+
0,
155+
file.as_ptr(),
156+
file.len() as i32,
157+
0,
158+
DEFAULT_RIGHTS,
159+
DEFAULT_RIGHTS,
160+
0,
161+
(&mut file_fd) as *mut u32,
162+
)
163+
};
164+
165+
assert_eq!(res, 0);
166+
167+
// read buffers
168+
let mut buf_to_read = vec![0u8; 1024];
169+
170+
let read_buf = [wasi::Iovec {
171+
buf: buf_to_read.as_mut_ptr(),
172+
buf_len: buf_to_read.len(),
173+
}];
174+
175+
let mut bytes_read: wasi::Size = 0;
176+
177+
// reading from root folder
178+
let res: i32 = unsafe { __ic_custom_fd_read(file_fd, read_buf.as_ptr(), 1, &mut bytes_read) };
179+
assert_eq!(res, 0, "fd_read error");
180+
181+
buf_to_read.truncate(bytes_read);
182+
183+
// Convert to UTF-8 String (returning String or panic if invalid UTF-8)
184+
String::from_utf8(buf_to_read).expect("Invalid UTF-8 in file")
185+
}

ic-wasi-polyfill/tests/lib_tests.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mod common;
22

3+
use std::fs::read_to_string;
4+
35
use common::*;
46
use ic_wasi_polyfill::wasi::{self, Fd};
57
use ic_wasi_polyfill::wasi_helpers::DIRENT_SIZE;
@@ -1405,3 +1407,61 @@ fn test_ic_custom_fd_fdstat_set_rights_success() {
14051407
assert_eq!(fdstat.fs_rights_inheriting, 6 & common::DEFAULT_RIGHTS);
14061408
}
14071409
}
1410+
1411+
#[test]
1412+
fn test_mounts() {
1413+
let dir_fd = 3;
1414+
1415+
init(&[], &[]);
1416+
1417+
let memory = new_vector_memory();
1418+
let file_name = "file.txt";
1419+
let hello_message = "Hello host".to_string();
1420+
let hello_message2 = "Hello from regular file".to_string();
1421+
1422+
mount_memory_file(file_name, Box::new(memory.clone()));
1423+
1424+
// write something into a host memory file
1425+
let fd = create_test_file_with_content(dir_fd, file_name, vec![hello_message.clone()]);
1426+
fd_close(fd);
1427+
1428+
// the memory should contain the file now
1429+
let v: Vec<u8> = memory.borrow().clone();
1430+
assert_eq!(&v[0..hello_message.len()], hello_message.as_bytes());
1431+
1432+
let str = read_file_to_string(file_name);
1433+
assert_eq!(str, hello_message);
1434+
1435+
// unmount file, the file.txt should become empty
1436+
unmount_memory_file(file_name);
1437+
let str = read_file_to_string(file_name);
1438+
assert_eq!(str, "".to_string());
1439+
1440+
// mount again, the old content should recover
1441+
mount_memory_file(file_name, Box::new(memory.clone()));
1442+
let str = read_file_to_string(file_name);
1443+
assert_eq!(str, hello_message);
1444+
1445+
// store mounted contents into the host file, check the host file content is renewed
1446+
store_memory_file(file_name);
1447+
unmount_memory_file(file_name);
1448+
let str = read_file_to_string(file_name);
1449+
assert_eq!(str, hello_message);
1450+
1451+
// write some other content message,
1452+
// check there is a new content now
1453+
let fd = create_test_file_with_content(dir_fd, file_name, vec![hello_message2.clone()]);
1454+
fd_close(fd);
1455+
let str = read_file_to_string(file_name);
1456+
assert_eq!(str, hello_message2);
1457+
1458+
// after mounting, we still have the old content
1459+
mount_memory_file(file_name, Box::new(memory.clone()));
1460+
let str = read_file_to_string(file_name);
1461+
assert_eq!(str, hello_message);
1462+
1463+
// initializing should recover the data from the host file to the mounted memory
1464+
init_memory_file(file_name);
1465+
let str = read_file_to_string(file_name);
1466+
assert_eq!(str, hello_message2);
1467+
}

0 commit comments

Comments
 (0)